Simple calculations for working with lat/lon and km distance?

Viewed 172584

Is there a simple calculation I can do which will convert km into a value which I can add to a lat or lon float to calculate a bounding box for searches? It doesn't need to be completely accurate.

For instance: if I were given a lat/lon for London, England (51.5001524, -0.1262362) and I wanted calculate what the lat would be 25km east/west from that point, and what the lon would be 25km north/south of that point, what would I need to do to convert the 25km into a decimal to add to the values above?

I'm looking for a general rule-of-thumb, ie: 1km == +/- 0.XXX

Edit:

My original search for "lat lon" didn't return this result:

How to calculate the bounding box for a given lat/lng location?

The accepted answer seems adequate for my requirements.

6 Answers

The approximate conversions are:

  • Latitude: 1 deg = 110.574 km
  • Longitude: 1 deg = 111.320*cos(latitude) km

This doesn't fully correct for the Earth's polar flattening - for that you'd probably want a more complicated formula using the WGS84 reference ellipsoid (the model used for GPS). But the error is probably negligible for your purposes.

Source: http://en.wikipedia.org/wiki/Latitude

Caution: Be aware that latlong coordinates are expressed in degrees, while the cos function in most (all?) languages typically accepts radians, therefore a degree to radians conversion is needed.

If you're using Java, Javascript or PHP, then there's a library that will do these calculations exactly, using some amusingly complicated (but still fast) trigonometry:

http://www.jstott.me.uk/jcoord/

Thanks Jim Lewis for his great answer and I would like to illustrate this solution by my function in Swift:

func getRandomLocation(forLocation location: CLLocation, withOffsetKM offset: Double) -> CLLocation {
        let latDistance = (Double(arc4random()) / Double(UInt32.max)) * offset * 2.0 - offset
        let longDistanceMax = sqrt(offset * offset - latDistance * latDistance)
        let longDistance = (Double(arc4random()) / Double(UInt32.max)) * longDistanceMax * 2.0 - longDistanceMax

        let lat: CLLocationDegrees = location.coordinate.latitude + latDistance / 110.574
        let lng: CLLocationDegrees = location.coordinate.longitude + longDistance / (111.320 * cos(lat / .pi / 180))
        return CLLocation(latitude: lat, longitude: lng)
    }

In this function to convert distance I use following formulas:

latDistance / 110.574
longDistance / (111.320 * cos(lat / .pi / 180))

Why not use properly formulated geospatial queries???

Here is the SQL server reference page on the STContains geospatial function:

https://docs.microsoft.com/en-us/sql/t-sql/spatial-geography/stcontains-geography-data-type?view=sql-server-ver15

or if you do not waant to use box and radian conversion , you cna always use the distance function to find the points that you need:

DECLARE @CurrentLocation geography; 
SET @CurrentLocation  = geography::Point(12.822222, 80.222222, 4326)

SELECT * , Round (GeoLocation.STDistance(@CurrentLocation ),0) AS Distance FROM [Landmark]
WHERE GeoLocation.STDistance(@CurrentLocation )<= 2000 -- 2 Km

There should be similar functionality for almost any database out there.

If you have implemented geospatial indexing correctly your searches would be way faster than the approach you are using

Related