Using Block sortedArrayUsingComparator:^(id a, id b) - ios

In my project, I try to compare a known location to an inputted location by using block sortedArrayUsingComparator:^(id a, id b). I have a dictionary array called locationArray containing a lat long and a station number that corresponds to that lat long point. I try to compare each locationArray station to the inputted station. I do this by taking the absolute value of the difference between the two which gives me a distance. Then I try to sort locationArray based on the distance from the inputted station from closest to furthest away.
//locationArray
#define kStation #"station"
#define kLatitude #"latitude"
#define kLongitude #"longitude"
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"499CSV" ofType:#"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *CSVArray = [NSMutableArray array];
NSCharacterSet *whiteSPNewLine = [NSCharacterSet whitespaceAndNewlineCharacterSet];
for (NSString * location in locations)
{
NSArray *components = [location componentsSeparatedByString:#","];
double latitude = [[components[0] stringByTrimmingCharactersInSet:whiteSPNewLine] doubleValue];
double longitude = [[components[1] stringByTrimmingCharactersInSet:whiteSPNewLine] doubleValue];
NSString *station = [components[2] stringByTrimmingCharactersInSet:whiteSPNewLine];
NSDictionary *dict = #{kLatitude: #(latitude),
kLongitude: #(longitude),
kStation: station};
[CSVArray addObject:dict];
}
NSLog(#"The contents of CSVArray = %#",[CSVArray description]);
{
latitude = "41.674364";
longitude = "-81.23700700000001";
station = 40150;
},
{
latitude = "41.67517";
longitude = "-81.235038";
station = 40763;
},
{
latitude = "41.673106";
longitude = "-81.24017499999999";
station = 39175;
}, ...
My block code that directly follows locationArray.
NSArray *orderedPlaces = [CSVArray sortedArrayUsingComparator:^(id a, id b) {
NSDictionary *dictA;
NSDictionary *dictB;
NSString *locA;
NSString *locB;
int distanceA;
int distanceB;
dictA = (NSDictionary *)a;
dictB = (NSDictionary *)b;
NSLog(#"dictA = %#", dictA);
NSLog(#"dictB = %#", dictB);
locA = [dictA objectForKey:kStation];
locB = [dictB objectForKey:kStation];
NSLog(#"locA = %#", locA);
NSLog(#"locB = %#", locB);
distanceA = abs(stationNumber-[locA intValue]);
distanceB = abs(stationNumber-[locB intValue]);
NSLog(#"distanceA = %d", distanceA);
NSLog(#"distanceB = %d", distanceB);
if (distanceA < distanceB) {
return NSOrderedAscending;
} else if (distanceA > distanceB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
NSLog(#"The contents of array = %#",[orderedPlaces description]);
The block runs but it's not sorting locationsArray as intended. orderedPlaces returns an unsorted locationsArray. By running NSLOG on the block components, I see that it successfully recognizes locationsArray and creates the distance object. I must be missing something because I use the same code in a different part of my project where I compare locationsArray to the lat long of the user's location and it works well. Please help me identify the issue keeping it from working as intended.
*If you need any more information or clarification, just ask.

I don't understand your sort block. You're calculating distance A as abs(stationNumber-[locA intValue]).
What is stationNumber? Is that some fixed integer index? How can the difference between a fixed station number and the station numbers in your array have anything to do with distances?
It seems to me that your distance values should be
(target.lat - this_station.lat)^2 + (target.long - this_station.long)^2
That will give you the square of the pythagorean distance between your target point and one of the stations you are comparing. Then in your comparison you select the item who's distance squared is less.
You can skip the square root, because you're just comparing them. That will make your distance calculations much faster.

Try this:
NSArray *orderedPlaces = [CSVArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
^(id a, id b) means ^void (id a, id b) and your return value is ignored.

Related

How to access array of dictionaries and use the dictionary objects in Objective C?

This is my "po array" looks like.
<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-
DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
}),
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-
DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “13.067439”
longitude = "80.237617";
type = enrty;
entryName = Chennai;
})
The above JSON is stored in and I'm retrieving using the below code.
+(NSArray*) routePlan
{
NSString* aircraftJSONString = [NSString stringWithContentsOfURL [[NSBundle mainBundle] URLForResource:#"Documents/DataJson" withExtension:nil]
encoding:NSUTF8StringEncoding error:nil];
NSArray* aircraftJsonFplWaypoints = [aircraftJSONString componentsSeparatedByString:#","];
}
I can access the array[0] but not the objects in array[0]. I need the latitude and longitude. Any idea how to strip down to the inside dictionary values.
The dictionaries seem to be instances of an NSManagedObject subclass named Entry.
Just use a loop to iterate over the entries
for (Entry *entry in array) {
NSLog(#"lat: %# - long: %#", entry.latitude, entry.longitude);
}
You have an array of dictionaries and you need to parse through it.
I haven't tried running this code but this should work. Later on you can add some safety checks for nil values.
NSDictionary *dict = array[0];
NSString *latitude = dict["latitude"];
NSString *longitude = dict["longitude"];
You can use key value coding :
[array[0] valueForKey:#"latitude"];
Simply use objective c fast enumeration for getting data from ArrayList.
for (NSDictionary *dic in array) {
NSLog(#"dic values %#",[dic objectForKey:#"data"]);
NSDictionary *data = [dic objectForKey:#"data"];
NSString *lat = [data objectForKey:#"latitude"];
}

NSMutableArray parsing csv not working?

I have this code where I use NSMutableArray to parse a csv file. There are no errors that stop me from running the app however the map doesn't display anything.
NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:#"Data2" ofType:#"csv"];
NSString *dataStr = [NSString stringWithContentsOfFile:csvFilePath encoding:NSUTF8StringEncoding error:nil];
NSMutableArray *allLinedStrings = [[NSMutableArray alloc]initWithArray:[dataStr componentsSeparatedByString:#"\r"]];
NSMutableArray *latitude = [[NSMutableArray alloc]init];
NSMutableArray *longitude = [[NSMutableArray alloc]init];
NSMutableArray *description = [[NSMutableArray alloc]init];
NSMutableArray *address = [[NSMutableArray alloc]init];
NSMutableArray *temperature = [[NSMutableArray alloc]init];
NSMutableArray *time = [[NSMutableArray alloc]init];
NSMutableArray *ambient = [[NSMutableArray alloc]init];
NSMutableArray *filteredLocations = [NSMutableArray array];
MKMapPoint* pointArr = malloc(sizeof(MKMapPoint) * filteredLocations.count);
for (int idx = 0; idx < [allLinedStrings count]; idx++)
{
NSMutableArray *infos = [[NSMutableArray alloc]initWithArray:[[allLinedStrings objectAtIndex:idx] componentsSeparatedByString:#","]];
if ([infos count] > 1)
{
[latitude addObject:[infos objectAtIndex:4]];
[longitude addObject:[infos objectAtIndex:5]];
[description addObject:[infos objectAtIndex:0]];
[address addObject:[infos objectAtIndex:10]];
[temperature addObject:[infos objectAtIndex:6]];
[time addObject:[infos objectAtIndex:15]];
[ambient addObject:[infos objectAtIndex:8]];
if([[latitude objectAtIndex:4] isEqualToString:#"NULL"] || [[longitude objectAtIndex:5] isEqualToString:#"NULL"] || [[description objectAtIndex:0] isEqualToString:#"NULL"] || [[address objectAtIndex:10]isEqualToString:#"NULL"] || [[temperature objectAtIndex:6] isEqualToString:#"NULL"] || [[time objectAtIndex:15]isEqualToString:#"NULL"] || [[ambient objectAtIndex:8] isEqualToString:#"NULL"]) {continue;}
CLLocationCoordinate2D coordinate;
coordinate.latitude = [[latitude objectAtIndex:4] doubleValue];
coordinate.longitude = [[longitude objectAtIndex:5] doubleValue];
Location *annotation = [[Location alloc] initWithName:[description objectAtIndex:0] address:[address objectAtIndex:10] temperature:[temperature objectAtIndex:6] time:[time objectAtIndex:15] ambient:[ambient objectAtIndex:8] coordinate:coordinate] ;
[mapview addAnnotation:annotation];
[filteredLocations addObject:annotation];
MKMapPoint point = MKMapPointForCoordinate(coordinate);
pointArr[idx] = point;
}
}
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:filteredLocations.count];
[self.mapview addOverlay:self.routeLine];
free(pointArr);
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapview.annotations)
{
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[mapview setVisibleMapRect:zoomRect animated:YES];
self.mapview.delegate = self;
}
I guess there must be something wrong with how I'm calling the objects or maybe the MKMapPoint but I don't manage to find what's blocking the app from displaying the data. I've tried using both "initWithObjects" and removing "if ([infos count] > 1){" but when ran it crashed showing a breakdown point in "NSMutableArray *latitude = [[NSMutableArray alloc]init];".
Based on your previous questions about this project, you want to do the following at a high level:
Parse a CSV file where each line has coordinate data. Ignore lines that have "null" data. (For the purpose of this answer, let's ignore that one could use a pre-built CSV parser, or use a different format altogether.)
Show annotations for lines with "good" data.
Connect all the annotations with a line.
For requirement 1 (R1), you already know how to load the CSV file, loop through the lines, and identify the lines with "null" data.
For requirement 2 (R2), after some research, you know that you can create and add annotations to the map one at a time and the map doesn't need to know ahead of time how many you will add so that means the first two requirements could be done in the same loop.
For requirement 3 (R3), after some research, you know that to create and add a polyline to the map, you need to know ahead of time how many points will be in the line.
For R1 and R2, you will be looping through the lines of the CSV and identify the non-null lines.
So that means you will know how many points will be in the polyline after the loop that handles R1 and R2. That means the polyline must be created after that loop.
But to create the polyline, you need not just the point count but the coordinates for each point as well.
That means while looping through the lines in the CSV, you need to save the coordinate data somewhere (in the same order it appeared in the CSV).
In Objective-C, a convenient structure that allows you to add data to it without knowing in advance how many objects will be added is an NSMutableArray.
So now we have this very high-level plan:
Loop through the CSV file, ignore lines with null data, create and add annotations, add the line data to an NSMutableArray (NSMA).
Create a polyline using the point data in NSMA, add the polyline to the map.
With this plan, we see we need one NSMutableArray. Notice that in the existing code, you have a Location class that holds (or could hold) all the data from each line of the CSV.
That means we could simply add these Location objects to the NSMA. NSMutableArrays can hold any type of object (they don't have to be just NSStrings).
So here's a slightly more detailed plan:
Initialize an NSMutableArray called filteredLocations (eg. NSMutableArray *filteredLocations = [NSMutableArray array];).
Loop through the CSV file, ignore lines with null data, create a Location object and add as an annotation, add the Location object to filteredLocations (eg. [filteredLocations addObject:annotation];).
Initialize (malloc) a C array to hold the points of the polyline with the point count being the count of filteredLocations.
Loop through filteredLocations, add point from filteredLocations to the C array.
Create and add a polyline to the map.
In this plan note we have two separate loops: The first one is for R1 and R2. The second one is for R3.
If required, I will post sample code that implements this plan.
First, just to explain your latest NSRangeException error, it is happening on this line:
if([[latitude objectAtIndex:4] isEqualToString:#"NULL"] || ...
because you've declared latitude as an array and the first time the if executes in the loop, latitude only has one object (a few lines above this if you do [latitude addObject:...). The index of an array starts at zero so the bounds of an array with one object are zero to zero hence the error message saying index 4 beyond bounds [0 .. 0].
There are many other issues with the rest of the code.
There is not enough room in this answer to explain in detail.
I urge you, if possible, to stop, step back and re-start with a much simpler project or tutorials and, most importantly, learn the absolute basics of programming in general.
Here is an example of code that should work based on your sample data:
-(void)viewDidLoad
{
[super viewDidLoad];
self.mapview.delegate = self;
NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:#"Data2" ofType:#"csv"];
NSString *dataStr = [NSString stringWithContentsOfFile:csvFilePath encoding:NSUTF8StringEncoding error:nil];
NSArray *allLinedStrings = [dataStr componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *filteredLocations = [NSMutableArray array];
for (int idx = 0; idx < [allLinedStrings count]; idx++)
{
NSArray *infos = [[allLinedStrings objectAtIndex:idx] componentsSeparatedByString:#","];
if ([infos count] > 15)
{
NSString *latitude = [infos objectAtIndex:4];
NSString *longitude = [infos objectAtIndex:5];
NSString *description = [infos objectAtIndex:0];
NSString *address = [infos objectAtIndex:10];
NSString *temperature = [infos objectAtIndex:6];
NSString *time = [infos objectAtIndex:15];
NSString *ambient = [infos objectAtIndex:8];
if([latitude isEqualToString:#"NULL"]
|| [longitude isEqualToString:#"NULL"]
|| [description isEqualToString:#"NULL"]
|| [address isEqualToString:#"NULL"]
|| [temperature isEqualToString:#"NULL"]
|| [time isEqualToString:#"NULL"]
|| [ambient isEqualToString:#"NULL"])
{
continue;
}
CLLocationCoordinate2D coordinate;
coordinate.latitude = [latitude doubleValue];
coordinate.longitude = [longitude doubleValue];
Location *annotation = [[Location alloc] initWithName:description
address:address
temperature:temperature
time:time
ambient:ambient
coordinate:coordinate];
[mapview addAnnotation:annotation];
[filteredLocations addObject:annotation];
}
}
MKMapPoint* pointArr = malloc(sizeof(MKMapPoint) * filteredLocations.count);
for (int flIndex = 0; flIndex < filteredLocations.count; flIndex++)
{
Location *location = [filteredLocations objectAtIndex:flIndex];
MKMapPoint point = MKMapPointForCoordinate(location.coordinate);
pointArr[flIndex] = point;
}
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:filteredLocations.count];
[self.mapview addOverlay:self.routeLine];
free(pointArr);
[self.mapview showAnnotations:self.mapview.annotations animated:YES];
}

Weathermap API not able to parse completely in iOS

I'm able to retrieve data from the weather map api, however I can't figure out how to exactly parse the data. I'm able to do it only for a certain part of it.
This is the JSON data:
{
base = "cmc stations";
clouds = {
all = 56;
};
cod = 200;
coord = {
lat = "29.66";
lon = "-82.3";
};
dt = 1403641995;
id = 4156404;
main = {
humidity = 74;
pressure = 1018;
temp = "304.08";
"temp_max" = "306.48";
"temp_min" = "302.15";
};
name = Gainesville;
rain = {
3h = 0;
};
sys = {
country = US;
message = "0.2087";
sunrise = 1403605821;
sunset = 1403656392;
};
weather = (
{
description = "broken clouds";
icon = 04d;
id = 803;
main = Clouds;
}
);
wind = {
deg = 153;
gust = "1.54";
speed = "0.51";
};
}
Now I am able to get only one part of it :
base = "cmc stations"
like this:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSLog(#"values %#",json);
NSLog(#"Checking values ------------ %#",[json objectForKey:#"cloud"]);
}
But when I try to do the same for other fields like
clouds
coord
main
I can't. I get a null value.
I'm guessing I need an additional NSDictionary or NSArray but just not sure how to go about it. Can someone please tell how can I do this? I'm mainly looking to get data from the main block :
humidity
temp
temp_max
temp_min
rain
sunrise
sunset
I think I have found a solution:
Here's how I'm getting the data:
NSString* base = [json objectForKey:#"base"];
NSLog(#"Value of first base variable: %#",base);
// NSArray* base = [json objectAtIndex:0];
NSArray *clouds = [json objectForKey:#"clouds"];
NSLog(#"Value of first clouds‹ variable: %#",clouds);
NSArray *coord = [json objectForKey:#"coord"];
NSLog(#"Value of first coord variable: %#",coord);
NSDictionary *main = [json objectForKey:#"main"];
NSLog(#"Value of first coord variable: %#",main);
NSArray* humidity = [main objectForKey:#"humidity"];
NSLog(#"humidity levels found manually : %#",humidity);
NSArray* temp_max = [main objectForKey:#"temp_max"];
NSLog(#"max temp levels found manually : %#",temp_max);
The problem is that most of those values are dictionaries, not arrays. When you see { } and colons (:) that will generally indicate the presence of a dictionary of key-value pairs, even though some of them may only have one such pair which might make it appear like an array or a stand-alone object.
To get clouds for instance:
NSDictionary *clouds = [json objectForKey:#"clouds"];
NSNumber *allClouds = [clouds objectForKey:#"all"];
NSLog(#"Value of first clouds‹ variable: %#",allClouds);
To get coord:
NSDictionary *coords = [json objectForKey:#"coord"];
NSNumber *lon = [coords objectForKey:#"lon"];
NSNumber *lat = [coords objectForKey:#"lat"];
NSLog(#"Value of lon is: %#",lon);

Get values out of data from NSJSONSerialization

I have some JSON data which is pulled from a URL. The code I have written works fine to download the JSON and parse it, but I cannot seem to access it how I need too, especially where the data is contained as a sub-element of another one.
Here is the JSON format:
{
address = "<null>";
city = "<null>";
country = UK;
"country_code" = GB;
daylight = 1;
for = daily;
items = (
{
asr = "5:22 pm";
"date_for" = "2013-7-1";
dhuhr = "1:01 pm";
fajr = "2:15 am";
isha = "11:47 pm";
maghrib = "9:24 pm";
shurooq = "4:39 am";
}
);
latitude = "50.9994081";
link = "http://muslimsalat.com/UK";
longitude = "0.5039011";
"map_image" = "http://maps.google.com/maps/api/staticmap?center=50.9994081,0.5039011&sensor=false&zoom=13&size=300x300";
"postal_code" = "<null>";
"prayer_method_name" = "Muslim World League";
"qibla_direction" = "119.26";
query = "51.000000,0.500000";
state = "<null>";
timezone = 0;
title = UK;
"today_weather" = {
pressure = 1020;
temperature = 14;
};
}
(These are Islamic prayer times.)
My Objective-C so far is this:
-(CLLocationCoordinate2D) getLocation{
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
return coordinate;
}
//class to convert JSON to NSData
- (IBAction)getDataFromJson:(id)sender {
//get the coords:
CLLocationCoordinate2D coordinate = [self getLocation];
NSString *latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
NSLog(#"*dLatitude : %#", latitude);
NSLog(#"*dLongitude : %#",longitude);
//load in the times from the json
NSString *myURLString = [NSString stringWithFormat:#"http://muslimsalat.com/%#,%#/daily/5.json", latitude, longitude];
NSURL *url = [NSURL URLWithString:myURLString];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
if(jsonData != nil)
{
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSArray *jsonArray = (NSArray *)result; //convert to an array
if (error == nil)
NSLog(#"%#", result);
NSLog(#"%#", jsonArray);
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
}
}
When running this code, the only output I get is a list of element names (address, city, country, so on). items is given, but not its child elements. I understand that this is what I am asking the code for with:
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
but I do not know how to move onto the next step.
The only data values which I require are in fact the times themselves (so, items>asr, items>dhuhr, etc).
How can I get these values themselves and then save them as values I can work with?
Thank you!
(...); - is Array
{...}; - is Dictionary
so your "element" is Dictionary
use objectForKey:
example:
for (id element in jsonArray) {
NSLog(#"Element asr: %#", [element objectForKey:#"asr"]); // or element[#"asr"]
}
NSArray *jsonArray = (NSArray *)result; //convert to an array
This doesn't 'convert', it's just you promising the compiler that result is really an NSArray. And in this case it's a lie.
Your code is currently just printing a list of the keys in the dictionary that is returned in the JSON. Try this to get to the list of items (it's an array so you need to deal with there possibly being multiple entries):
NSDictionary *result = [NSJSONSerialization ...
for (NSDictionary *itemDict in result[#"items"]) {
NSLog(#"item: %#", itemDict);
}
Then you can extract the times.
You can extract info by following:
NSError* error = nil;
NSDictionary *userInfo; //your main data
if([NSJSONSerialization class])
userInfo = [NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error];
//to extract items
NSDictionary *items = [[[userInfo objectForKey:#"items"] JSONValue] objectAtIndex:0];

I need to get the penultimate result from a for loop

I have an array of waypoints stored which have latitude and longitude values. I have created a for loop to loop through the array and compare my current CLLocation positions latitude and longitude to find which of the waypoints i am closest to. I also need to get the second closest waypoint and store this ac s a CLLocation object as well but cannot get it working.
The logic would be something like this
am I closest
yes
move closest location to second closest
set as second closest
loop again to get the closest point
My code:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
//set latestlocation as the last object from the locations array
CLLocation *currentLocation = [locations lastObject];
//declare a closestpoint object
CLLocation *closestWayPointToCurrentLocation;
//declare a second closest point object
CLLocation *secondClosestWayPointToCurrentLocation;
//set the distance to a high number
float distance = 10000000;
float secondClosestWaypointDistance = 10000000;
//load in plist
NSString *plistName = [self.mapsInfo objectForKey:#"plistName"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Chester" ofType:#"plist"];
NSString *path = [[NSBundle mainBundle] pathForResource:plistName ofType:#"plist"];
//store in array called waypoints
NSArray *waypoints= [NSArray arrayWithContentsOfFile:path];
//declare a variable for locationNum (the waypoints)
int locationNum = 0;
for (NSDictionary *point in waypoints) {
CLLocation *waypointLocation = [[CLLocation alloc]initWithLatitude:[(NSNumber *)[point objectForKey:#"Lat"]floatValue] longitude:[(NSNumber *)[point objectForKey:#"Long"]floatValue]];
float waypointDistanceFromCurrentLocation = [currentLocation distanceFromLocation:waypointLocation];
//secondClosestWayPointToCurrentLocation = waypointLocation;
if(waypointDistanceFromCurrentLocation < distance) {
//todo: move the current closestWayPointToCurrentLocation into second postion
//update the second closest waypoint distance variable also with distance
distance = waypointDistanceFromCurrentLocation;
closestWayPointToCurrentLocation = waypointLocation;
if(closestWayPointToCurrentLocation == waypointLocation) {
}
}
else
{
//check against the second position
//if closer than second position, replace it with new waypoint with code similar to above
}
If you are sure the point you is always the penultimate then you can retrive it like this
int totalNumberOfWaypoints = [waypoints count];
//Get penultimate waypoints
NSDictionary *penultimateWaypoint = [waypoints objectAtIndex:(totalNumberOfWaypoints - 2)];
Why dont you just make a sorted array of points, sorted by distance in ascending order?
NSMutableArray *waypoints= [NSArray arrayWithContentsOfFile:path];
for (NSDictionary *point in waypoints) {
[waypoints sortUsingComparator: (NSComparisonResult) ^ (id obj1, id obj2) {
CLLocation *waypointLocation1 = [[CLLocation alloc]initWithLatitude:[(NSNumber *)[obj1 objectForKey:#"Lat"]floatValue] longitude:[(NSNumber *)[obj1 objectForKey:#"Long"]floatValue]];
CLLocation *waypointLocation2 = [[CLLocation alloc]initWithLatitude:[(NSNumber *)[obj2 objectForKey:#"Lat"]floatValue] longitude:[(NSNumber *)[obj2 objectForKey:#"Long"]floatValue]];
float distance1 = [currentLocation distanceFromLocation:waypointLocation1];
float distance2 = [currentLocation distanceFromLocation:waypointLocation2];
if (distance1 < distance2) {
return NSOrderedAscending;
}
else if (distance1 > distance2) {
return NSOrderedDescending
}
else
return NSOrderedSame;
}];
This way you can always have the closest point at [waypoints objectAtIndex:0] and second closest point at [waypoints objectAtIndex:1] and so on.
less work, better result IMHO

Resources