Calculate distance between coordinates and list nearby places in that order
I have an array of locations
NSArray *locations = [[NSArray alloc]initWithObjects:loc1, loc2, loc3, loc4, loc5, loc6, loc7, loc8, loc9, nil];
I iterate through the array and store the different distances from my current location to loc1, loc2 and so on in another array, and sort them from nearest to furthest. That works like a charm.
However, I need to associate the distance with the name of the location. Ex: If loc5 is the nearest place, that should be on the top of the list. I know the names of the different locations, I just need to associate them somehow.
Any suggestions?
EDIT:
Taking your advice into consideration, I figured that I could do something like this:
I have an array with all the stored distances, let's call the array a.
NSMutableDictionary *dic = [[NSMutableDictionary alloc]initWithObjects:locations forKeys:a];
NSArray *sortedArray = [a sortedArrayUsingSelector:@selector(compare:)];
for(int i = 0; i <[sortedArray count]; i++){
CLLocation *loc = [dic valueForKey:[sortedArray objectAtIndex:i]];
NSLog(@"Lat: %f , Lng: %f" , loc.coordinate.latitude , loc.coordinate.longitude);
}
This way I will get开发者_StackOverflow中文版 the latitude and longitude for the different distances, which I can check against my locally stored coordinates. However this gives me an error saying:
-[NSCFNumber length]: unrecognized selector sent to instance 0x1891f0 * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber length]: unrecognized selector sent to instance 0x1891f0'
And it points me to the line
CLLocation *loc = [dic valueForKey:[sortedArray objectAtIndex:i]];
Thread 1: Program received signal: "SIGABRT".
Any idea how I can fix this?
I would create an information holder object that holds all the data for your different locations (name, location, last calculated distance, etc.), put all those objects into an NSMutableArray
, then sort it using the sortUsingSelector:
or sortUsingComparator:
methods on NSMutableArray
.
The former would require you to define a selector on your info holder that returns an NSComparisonResult
, while the latter (IIRC) allows you to define a block that does the same thing.
You could also theoretically store the names as keys of an NSDictionary
, with the CLLocation
s as the values, then use the keysSortedByValueUsingComparator:
method to determine the distance using a block that acts on the CLLocations
and your reference location.
This would no longer require an explicit info holder, but you're liable to rack up a lot of processor time as you would need to calculate the distance from your reference location and TWO CLLocation
s for each run of the NSComparator
block.
First implement these delegates - (assuming you have included coreLocation
framework & have registered for location updates.
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// Handle location updates
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// Handle error
}
The distance between two CLLocation
points may be calculated by calling the distanceFromLocation:
method of the end location and passing through the start location as an argument. For example, the following code calculates the distance between the points specified by newLocation and oldLocation:
CLLocationDistance distance = [newLocation distanceFromLocation:oldLocation];
精彩评论