How is a 1000ft or 1/2 mile distance determined with mapkit? Either a radius from some pin or the distance between two pins.
For example, I center the map on pin A. Pins B, C, and D are also on the map at various distances from pin A. B and C are within 1/2 mile from A but D is 1 mile away. I'd like to know that B and C are within 1/2 mile from A. How can I calculate that?
Since you've stated that the two different points are "pins", I'm going to assume you're using MKPinAnnotationView (or some other annotation view). If not, you're going to have to get the location some other way.
If you have pointers to the annotation objects for these locations, then you can easily call -coordinate
on them, create CLLocations from these coordinates (using -initWithLatitude:longitude:
), and then use the method -getDistanceFrom
to retrieve the distance in meters. From there, it's an easy conversion to miles. All told, the code would look something like this:
CLLocationCoordinate2D pointACoordinate = [pointAAnnotation coordinate];
CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:pointACoordinate.latitude longitude:pointACoordinate.longitude];
CLLocationCoordinate2D pointBCoordinate = [pointBAnnotation coordinate];
CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:pointBCoordinate.latitude longitude:pointBCoordinate.longitude];
double distanceMeters = [pointALocation getDistanceFrom:pointBLocation];
double distanceMiles = (distanceMeters / 1609.344);
You'll end up with the distance in miles, and can compare it from there. Hope this helps.
getDistanceFrom
is now deprecated so here's an alternative answer for anyone looking to do this.
CLLocationCoordinate2D pointACoordinate = [pointAAnnotation coordinate];
CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:pointACoordinate.latitude longitude:pointACoordinate.longitude];
CLLocationCoordinate2D pointBCoordinate = [pointBAnnotation coordinate];
CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:pointBCoordinate.latitude longitude:pointBCoordinate.longitude];
float distanceMeters = [pointALocation distanceFromLocation:pointBLocation];
float distanceMiles = (distanceMeters / 1609.344);
[pointALocation release];
[pointBLocation release];
As above, you could use float
instead of double
and you could cast the results to an int if you don't require the precision of the float
like so:
int distanceCastToInt = (int) [pointALocation distanceFromLocation:pointBLocation];
The int
is handy if you wanted to give a rough idea of distance in the annotation like so:
pointAAnnotation.title = @"Point A";
pointAAnnotation.subtitle = [NSString stringWithFormat: @"Distance: %im",distanceCastToInt];
The subtitle of the annotation would read "Distance: 50m" for example.
This is Swift 3 equivalent of the given answer:
let pointACoordinate = pointAAnnotation.coordinate
let pointALocation = CLLocation(latitude: pointACoordinate.latitude, longitude: pointACoordinate.longitude)
let pointBCoordinate = pointBAnnotation.coordinate
let pointBLocation = CLLocation(latitude: pointBCoordinate.latitude, longitude: pointBCoordinate.longitude)
let distanceMeters = pointALocation.distance(from: pointBLocation)
let distanceMiles = (distanceMeters / 1609.344)