Can any trig or GPS experts help me out here? I'm trying to create a geo-spacial bounding box (rectangle) calculation returning the maximum latitude and longitude using the following method that I've retrieved. I am calling the method once for each of the for bearings: north, south, east and west. With these four values I intend to query my Core Data store for all objects within the box.
-(CLLocation*) offsetLocation:(CLLocation*)startLocation:(double)offsetMeters:(double)bearing {
double EARTH_MEAN_RADIUS_METERS = 6372796.99;
double newLatitude = asin( sin(startLocation.coordinate.latitude) * cos(offsetMeters/EARTH_MEAN_RADIUS_METERS) + cos(startLocation.coordinate.latitude) * sin(offsetMeters/EARTH_MEAN_RADIUS_METERS) * cos(bearing) );
double newLongitude = startLocation.coordinate.longitude + atan2( sin(bearing) * sin(offsetMeters/EARTH_MEAN_RADIUS_METERS) * cos(startLocation.coordinate.latitude), cos(offsetMeters/EARTH_MEAN_RADIUS_METERS) - sin(startLocation.coordinate.latitude) * sin(newLatitude));
CLLocation *tempLocation = [[CLLocation alloc] initWithLatitude:newLatitude longitude:newLongitude];
[tempLocation autorelease];
return tempLocation;
}
The problem is the calculation for the newLatitude offset is definitely incorrect. Given the following:
startLocation: latitude 37.331688999999997, longitude -122.030731 offsetMeters : 1000 bearing : 0 (north)
newLatitude returns -0.36726592610659514 (incorrect).
Any suggestions? I've coded around this particular formula until now and this one has me stumped. I've also tried translating a different formula from PHP to no avail. I figure the above is exactly what I need if it can be tweaked.
Thanks, b.dot
I haven't looked at your code, but you could also use the MapKit function MKCoordinateRegionMakeWithDistance()
to have the framework calculate a bounding box for you.
CLLocationCoordinate2D center = { 37.3, -122.0 };
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(center, 2000.0, 2000.0);
CLLocationCoordinate2D northWestCorner, southEastCorner;
northWestCorner.latitude = center.latitude - (region.span.latitudeDelta / 2.0);
northWestCorner.longitude = center.longitude + (region.span.longitudeDelta / 2.0);
southEastCorner.latitude = center.latitude + (region.span.latitudeDelta / 2.0);
southEastCorner.longitude = center.longitude - (region.span.longitudeDelta / 2.0);
CLLocationCoordinate2D stores coordinates in degrees, but the trig functions you're using require radian units. If you convert to radians (multiply by M_PI/180, or 0.017453293f), it will probably work.
How are you guys setting up the NSPredicates?
I seem to run into performance issues with mine.
NSPredicate *northWestLat = [NSPredicate predicateWithFormat:@"ANY locations.lat > %lf", northWestCorner.latitude];
NSPredicate *southhWestLat = [NSPredicate predicateWithFormat:@"ANY locations.lat < %lf", southEastCorner.latitude];
NSPredicate *latitudePredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:northWestLat, southhWestLat, nil]];
NSPredicate *northWestLng = [NSPredicate predicateWithFormat:@"ANY locations.lng < %lf", northWestCorner.longitude];
NSPredicate *southEastLng = [NSPredicate predicateWithFormat:@"ANY locations.lng > %lf", southEastCorner.longitude];
NSPredicate *longitudePredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:northWestLng, southEastLng, nil]];
NSPredicate *coordPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:latitudePredicate, longitudePredicate, nil]];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With