Phillip B Oldham
Phillip B Oldham

Reputation: 19395

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

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.

Upvotes: 159

Views: 222321

Answers (7)

Coder Gautam YT
Coder Gautam YT

Reputation: 2207

This is more accurate (Haversin formula) we use the radius of the earth

// distance (in km) between two points specified by latitude/longitude
function calcDistance(lat1, lon1, lat2, lon2) {
  var R = 6371; // km
  var dLat = (lat2-lat1).toRad();
  var dLon = (lon2-lon1).toRad();
  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
          Math.sin(dLon/2) * Math.sin(dLon/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;
  return d;
}

Upvotes: 0

Serj Kultenko
Serj Kultenko

Reputation: 169

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))

Upvotes: 6

George Karadov
George Karadov

Reputation: 7

Why not use properly formulated geospatial queries???

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

https://learn.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

Upvotes: -1

Mircea
Mircea

Reputation: 1277

Interesting that I didn't see a mention of UTM coordinates.

https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system.

At least if you want to add km to the same zone, it should be straightforward (in Python : https://pypi.org/project/utm/ )

utm.from_latlon and utm.to_latlon.

Upvotes: 1

Nikhil Dinesh
Nikhil Dinesh

Reputation: 3409

http://www.jstott.me.uk/jcoord/ - use this library

            LatLng lld1 = new LatLng(40.718119, -73.995667);
            LatLng lld2 = new LatLng(51.499981, -0.125313);
            Double distance = lld1.distance(lld2);
            Log.d(TAG, "Distance in kilometers " + distance);

Upvotes: 1

Jim Lewis
Jim Lewis

Reputation: 45125

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.

Upvotes: 296

skaffman
skaffman

Reputation: 403581

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/

Upvotes: 5

Related Questions