¿Cálculos simples para trabajar con lat / lon y km de distancia?

119

¿Hay un cálculo simple que pueda hacer que convierta km en un valor que pueda agregar a un flotante lat o lon para calcular un cuadro delimitador para las búsquedas? No es necesario que sea completamente preciso.

Por ejemplo: si me dieran lat / lon para Londres, Inglaterra (51.5001524, -0.1262362) y quisiera calcular cuál sería la latitud a 25 km al este / oeste desde ese punto, y cuál sería la longitud a 25 km al norte / sur de ese punto. punto, ¿qué tendría que hacer para convertir los 25 km en un decimal para agregar a los valores anteriores?

Estoy buscando una regla general, es decir: 1km == +/- 0.XXX

Editar:

Mi búsqueda original de "lat lon" no arrojó este resultado:

¿Cómo calcular el cuadro delimitador para una ubicación de lat / lng determinada?

La respuesta aceptada parece adecuada para mis requisitos.

Phillip B. Oldham
fuente

Respuestas:

220

Las conversiones aproximadas son:

  • Latitud: 1 grado = 110,574 km
  • Longitud: 1 grado = 111,320 * cos (latitud) km

Esto no corrige completamente el aplanamiento polar de la Tierra, para eso probablemente querrá una fórmula más complicada usando el elipsoide de referencia WGS84 (el modelo usado para GPS). Pero el error probablemente sea insignificante para sus propósitos.

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

Precaución : tenga en cuenta que las coordenadas de latitud se expresan en grados, mientras que la cosfunción en la mayoría de los idiomas (¿todos?) Generalmente acepta radianes, por lo que se necesita una conversión de grados a radianes .

Jim Lewis
fuente
¿Quiere decir cos (longitud) en la segunda fórmula?
Odys
1
¿Cómo se te ocurrió esto? Me estoy perdiendo algo, ¿podría explicar los cálculos de longitud? Ty
Odys
5
@Odys: si está comparando dos puntos que se encuentran en la misma línea de longitud (norte / sur), se encuentran en un círculo máximo y el factor de conversión es solo la circunferencia polar de la Tierra dividida por 360 grados. Pero es diferente para las mediciones de este a oeste, porque (a excepción del ecuador) no está midiendo a lo largo de un "círculo máximo", por lo que la "circunferencia" en una latitud determinada es más pequeña. Y el factor de corrección resulta ser el coseno de la latitud.
Jim Lewis
17
Mi explicación: cos(0°) = 1=> Por lo tanto, no se aplica ningún factor de corrección al hacer el cálculo en el ecuador. Las longitudes son las más anchas allí. cos(90°) = 0=> En los polos las longitudes se encuentran en un punto. No hay distancia que calcular.
Jenny O'Reilly
4
@Stijn: debe convertir de grados a radianes antes de llamar a Math.cos ().
Jim Lewis
5

Si está usando Java, Javascript o PHP, entonces hay una biblioteca que hará estos cálculos exactamente, usando una trigonometría divertidamente complicada (pero aún rápida):

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

skaffman
fuente
El sitio tiene la biblioteca ahora.
midfield99
2
¡El vínculo está roto!
chatzich
Para PHP, puede usar esta bifurcación: github.com/dvdoug/PHPCoord
dearsina
1

http://www.jstott.me.uk/jcoord/ - use esta biblioteca

            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);
Nikhil Dinesh
fuente
1

Gracias Jim Lewis por su gran respuesta y me gustaría ilustrar esta solución con mi función en 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)
    }

En esta función para convertir la distancia utilizo las siguientes fórmulas:

latDistance / 110.574
longDistance / (111.320 * cos(lat / .pi / 180))
Serj Kultenko
fuente
Creo que debería ser "lat * pi / 180"
magamig
1

¿Por qué no utilizar consultas geoespaciales correctamente formuladas?

Aquí está la página de referencia del servidor SQL en la función geoespacial STContains:

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

o si no desea usar la conversión de caja y radianes, siempre puede usar la función de distancia para encontrar los puntos que necesita:

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

Debería haber una funcionalidad similar para casi cualquier base de datos.

Si ha implementado la indexación geoespacial correctamente, sus búsquedas serían mucho más rápidas que el enfoque que está utilizando

George Karadov
fuente
1
Tómese un momento para leer la ayuda de edición en el Centro de ayuda . El formato en Stack Overflow es diferente al de otros sitios.
Dharman