Question

I am developing iOS app, in which i want to find all locations within a some radius.

Is there any way in objective-c that will allow me to specify a fixed radius and a location, and that will tell me which locations are within that radius ?

I have done some researching and i got this code snippet,

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:locationManager.location
                   completionHandler:^(NSArray *placemarks, NSError *error) 
                   {
                       NSLog(@"reverseGeocodeLocation:completionHandler: Completion Handler called!");

                       if (error)
                       {
                           NSLog(@"Geocode failed with error: %@", error);
                           return;
                       }


                       CLLocationDistance radius = 30;
                       CLLocation* target = [[CLLocation alloc] initWithLatitude:51.5028 longitude:0.0031];

                       NSArray *locationsWithinRadius = [placemarks objectsAtIndexes:
                                                         [placemarks indexesOfObjectsPassingTest:
                                                          ^BOOL(id obj, NSUInteger idx, BOOL *stop) {

                                                              return [(CLLocation*)obj distanceFromLocation:target] < radius;

                                                          }]];

                       NSLog(@"locationsWithinRadius=%@",locationsWithinRadius);


                   }];

but it gets crashes and shows error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CLPlacemark distanceFromLocation:]:

Am i going on right way ? is this a way, to find all locations from my specified locations ?

Thanks in advance.

EDIT:

NSArray *testLocations = @[[[CLLocation alloc] initWithLatitude:19.0759 longitude:72.8776]];

                   CLLocationDistance maxRadius = 3000; // in meters
                   CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude]; //Current location coordinate..

                   NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(CLLocation *testLocation, NSDictionary *bindings) {
                       return ([testLocation distanceFromLocation:targetLocation] <= maxRadius);
                   }];

                   NSArray *closeLocations = [testLocations filteredArrayUsingPredicate:predicate];

                   NSLog(@"closeLocations=%@",closeLocations);

When i log my closeLocations array it shows null(Empty) value. Coordinate which i provided in testLocations is near to my current location.

Was it helpful?

Solution

What you're trying to do in your code is geocoding, this is the process of translating coordinates to addresses and isn't what you want to do. Instead you need to more basic coordinate bounding. You could use the distanceFromLocation: method in your code above and just iterate through your coordinates, converting them into CLLocation objects (if they aren't already) and then checking the distance to your center point.

Rather than using indexesOfObjectsPassingTest, I'd probably use filteredArrayUsingPredicate and a predicate created with predicateWithBlock to do your distance check (unless you actually want the indices for some reason).


NSArray *testLocations = @[ [[CLLocation alloc] initWithLatitude:11.2233 longitude:13.2244], ... ];

CLLocationDistance maxRadius = 30; // in meters
CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:51.5028 longitude:0.0031];

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(CLLocation *testLocation, NSDictionary *bindings) {
    return ([testLocation distanceFromLocation:targetLocation] <= maxRadius);
}];

NSArray *closeLocations = [testLocations filteredArrayUsingPredicate:predicate];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top