zumzum
zumzum

Reputation: 20138

Calculating bounding box given center lat /long and distance on iOS?

In my iOS app I have a lat and long that gives me my location. I want to be able to calculate the bounding box that satisfies a certain distance d from my location. How can I do this?

TRY 1: So I tried the solution given by @Neeku. I can see how it's supposed to return the right information but unfortunately it's off. So I don't think I can use it.

The code I wrote is this and I pass in 1000 meters:

MKCoordinateRegion startRegion = MKCoordinateRegionMakeWithDistance(center, meters, meters);

CLLocationCoordinate2D northWestCorner, southEastCorner;

northWestCorner.latitude = startRegion.center.latitude + .5 * startRegion.span.latitudeDelta;
northWestCorner.longitude = startRegion.center.longitude - .5 * startRegion.span.longitudeDelta;
southEastCorner.latitude = startRegion.center.latitude - .5 * startRegion.span.latitudeDelta;
southEastCorner.longitude = startRegion.center.longitude - .5 * startRegion.span.longitudeDelta;

NSLog(@"CENTER <%@,%@>", @(center.latitude),@(center.longitude));
NSLog(@"NW <%@,%@>, SE <%@,%@>",@(northWestCorner.latitude),@(northWestCorner.longitude),@(southEastCorner.latitude),@(southEastCorner.longitude));

So then the result is: CENTER <38.0826682,46.3028721> NW <38.08717278501047,46.29717303828632>, SE <38.07816361498953,46.29717303828632>

I then put that in google maps and get this: (see screenshot)

enter image description here

So then to my understanding the 1000 meters should go from the center to the sides of the box. The map is measuring the corner which should be OVER 1000 meters and it's actually just over 800 meters. This is the problem I am trying to solve.

I tried this method before and the distances simply aren't accurate. So, this solution has not worked for me. If you have more suggestions or maybe want to point out what is done wrong here please let me know.

Thank you

Upvotes: 3

Views: 5509

Answers (2)

Neeku
Neeku

Reputation: 3653

You can add/subtract half of the span from the latitude and longitude respectively and you get the values that you need:

CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(38.0826682, 46.3028721);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(centerCoord, 1000, 1000);

double latMin = region.center.latitude - .5 * startRegion.span.latitudeDelta;
double latMax = region.center.latitude + .5 * startRegion.span.latitudeDelta;
double lonMin = region.center.longitude - .5 * startRegion.span.longitudeDelta;
double lonMax = region.center.longitude + .5 * startRegion.span.longitudeDelta;

Just remember that:

latitudeDelta

The amount of north-to-south distance (measured in degrees) to display on the map. Unlike longitudinal distances, which vary based on the latitude, one degree of latitude is always approximately 111 kilometers (69 miles).


longitudeDelta

The amount of east-to-west distance (measured in degrees) to display for the map region. The number of kilometers spanned by a longitude range varies based on the current latitude. For example, one degree of longitude spans a distance of approximately 111 kilometers (69 miles) at the equator but shrinks to 0 kilometers at the poles.

Upvotes: 2

Rinat Khanov
Rinat Khanov

Reputation: 1576

Let's say that your desired distance is 111 meters. Then you use the following code:

    // 111 kilometers / 1000 = 111 meters.
    // 1 degree of latitude = ~111 kilometers.
    // 1 / 1000 means an offset of coordinate by 111 meters.

    float offset = 1.0 / 1000.0;
    float latMax = location.latitude + offset;
    float latMin = location.latitude - offset;

    // With longitude, things are a bit more complex.
    // 1 degree of longitude = 111km only at equator (gradually shrinks to zero at the poles)
    // So need to take into account latitude too, using cos(lat).

    float lngOffset = offset * cos(location.latitude * M_PI / 180.0);
    float lngMax = location.longitude + lngOffset;
    float lngMin = location.longitude - lngOffset;

latMax, latMin, lngMax, lngMin will give you your bounding box coordinates.

(You can change this code pretty easily if you need distance other than 111 meters. Just update offset variable accordingly).

Upvotes: 5

Related Questions