## Tuesday, September 7, 2010

### Calculating degree deltas for distances on the surface of the Earth

Here is the scenario: you've got your GPS coordinates (latitude & longitude in degrees) of your current position and you want to find the number of degrees north/south and east/west needed to contain an area of some size around you. I know, this sounds contrived, but it comes up if you use the iPhone's MapKit framework and want to zoom a MKMapView to a level where only a certain distance around a location is displayed. In that case, you need a MKCoordinateRegion to pass to the setRegion:animated: method.

One might think that if you know the rate of conversion between meters (or if you prefer, miles) and degrees, this would be a straightforward conversion. The problem is that it isn't so simple. Since the earth is a sphere, the number of meters in one degree of longitude depends on your latitude. For example, at the equator, there are 111.32 kilometers per degree of longitude; at the poles, however, there are 0 meters per degree.

A MKCoordinateRegion is comprised of two components: the coordinates of the center of the region and a span of latitudinal and longitudinal deltas. Let's assume the center is known; for example, it could be your user's current location. To calculate the span, here is a simple function that takes into account the curvature of the earth:
`/*! * Calculate longitudinal and latitudinal deltas in * degrees for the given linear horizontal and vertical * distances in kilometers.  Longitudinal degrees per * kilometer vary with latitude, so a coordinate is * needed as a frame of reference. * * @param coord - point of reference. * @param xDistance - east-west distance in kilometers. * @param yDistance - north-south distance in kilometers. * @return MKCoordinateSpan representing the distances *         in degrees at the given coordinate. */staticMKCoordinateSpanspanForDistancesAtCoordinate(CLLocationCoordinate2D coord,                             double xDistance,                             double yDistance){    const double kilometersPerDegree = 111.0;    MKCoordinateSpan span;        // Calculate the latitude and longitude deltas that    // correspond to the distance (in kilometers) at    // the given coordinate.  Note that the longitude    // degrees calculation is complicated by virtue of    // the fact that the number of meters per degree    // varies depending on the coordinate's latitude.    span.latitudeDelta = xDistance / kilometersPerDegree;    span.longitudeDelta = yDistance / (kilometersPerDegree * cos(coord.latitude * M_PI / 180.0));    return span;}`

The user's current location, which will become the center of the MKCoordinateRegion, should be passed as the point-of-reference coord argument. This is used to calculate the number of meters per degree at the user's current latitude.

The xDistance and yDistance parameters are the number of kilometers east-west and north-south, respectively, that define the region.

Note that the constant kilometersPerDegree represents the number of kilometers per degree of latitude or the number of kilometers per degree of longitude at the equator; it is only an estimate. Since the Earth isn't a perfect sphere, the actual number varies, but for the sake of most iPhone apps, the estimate of 111.0 kilometers/degree should be sufficient.