Tengo algunos usuarios registrados en mi aplicación Django y quiero simplemente ser capaz de calcular la distancia, geográficamente, entre dos usuarios en función de su código postal y luego ordenar una lista basada en eso. Me imagino que esta funcionalidad no está integrada en Django. Estaba viendo algunas opciones y me encontré con geodjango, que parece ser excesivo para mis necesidades.Django: ¿cómo puedo encontrar la distancia entre dos ubicaciones?
Respuesta
Siguiendo la sugerencia de tcarobruce, aquí está mi comentario anterior como una respuesta:
El Zip Code Database Project tiene una base de datos de las latitudes y longitudes de los códigos postales de EE.UU., ya sea como SQL o como CSV. También proporcionan el siguiente código para el cálculo de la distancia (editado slighlty por mí):
from math import sin, cos, radians, degrees, acos
def calc_dist(lat_a, long_a, lat_b, long_b):
lat_a = radians(lat_a)
lat_b = radians(lat_b)
long_diff = radians(long_a - long_b)
distance = (sin(lat_a) * sin(lat_b) +
cos(lat_a) * cos(lat_b) * cos(long_diff))
return degrees(acos(distance)) * 69.09
Tenga en cuenta que el resultado se da en millas terrestres.
Edición: Correcciones debidas a John Machin.
Debería haber resistido la tentación de editar ligeramente el código original sin probar el resultado. Ver mi respuesta –
http://code.google.com/apis/maps/documentation/directions/
Usted podría hacer instrucciones para cada ubicación. La distancia total está dada. La API parece dar salida a JSON; podría analizar la respuesta por el lado del servidor o la distancia calculada por JavaScript.
Hacer esto sería contrario a los términos de servicio de Google, a menos que sea cliente de Maps for Business, por cierto. – Jordan
Este es un gran comentario sobre el código publicado en la respuesta (actualmente aceptada) por @Sven Marnach.
Código original de la página web del proyecto postal, la muesca editado por mí:
from math import *
def calcDist(lat_A, long_A, lat_B, long_B):
distance = (sin(radians(lat_A)) *
sin(radians(lat_B)) +
cos(radians(lat_A)) *
cos(radians(lat_B)) *
cos(radians(long_A - long_B)))
distance = (degrees(acos(distance))) * 69.09
return distance
Código publicado por Sven:
from math import sin, cos, radians, degrees
def calc_dist(lat_a, long_a, lat_b, long_b):
lat_a = radians(lat_a)
lat_b = radians(lat_b)
distance = (sin(lat_a) * sin(lat_b) +
cos(lat_a) * cos(lat_b) * cos(long_a - long_b))
return degrees(acos(distance)) * 69.09
Problema 1: no se ejecutará: necesita importar acos
Problema 2: RESPUESTAS INCORRECTA: necesita para convertir la diferencia de longitud a radianes en la segunda última línea
Problema 3: El nombre de la variable "distancia" es un término inapropiado. Esa cantidad es en realidad el cos del ángulo entre las dos líneas desde el centro de la tierra hasta los puntos de entrada. Cambie a "cos_x"
Problema 4: No es necesario convertir el ángulo x en grados. Simplemente multiplicar x por el radio de la Tierra en unidades elegidas (km, nm, o "millas terrestres")
Después de arreglar todo esto, obtenemos:
from math import sin, cos, radians, acos
# http://en.wikipedia.org/wiki/Earth_radius
# """For Earth, the mean radius is 6,371.009 km (˜3,958.761 mi; ˜3,440.069 nmi)"""
EARTH_RADIUS_IN_MILES = 3958.761
def calc_dist_fixed(lat_a, long_a, lat_b, long_b):
"""all angles in degrees, result in miles"""
lat_a = radians(lat_a)
lat_b = radians(lat_b)
delta_long = radians(long_a - long_b)
cos_x = (
sin(lat_a) * sin(lat_b) +
cos(lat_a) * cos(lat_b) * cos(delta_long)
)
return acos(cos_x) * EARTH_RADIUS_IN_MILES
Nota: Después de arreglar los problemas 1 y 2, este es la "ley esférica de los cosenos" como generalmente se implementa. Está bien para aplicaciones como "distancia entre dos códigos postales de EE. UU.".
Advertencia 1: No es preciso para distancias pequeñas, como desde la puerta de entrada a la calle, tanto que puede dar una distancia distinta de cero o generar una excepción (cos_x> 1.0) si los dos puntos son idénticos ; esta situación puede ser especial.
Advertencia 2: Si los dos puntos son antipodales (la ruta en línea recta pasa por el centro de la tierra), puede generar una excepción (cos_x < -1.0). Cualquiera que esté preocupado por eso puede verificar cos_x antes de hacer acos (cos_x).
Ejemplo:
SFO (37.676, -122.433) a NYC (40.733, -73.917)
calcDist -> 2,570.7758043869976
calc_dist -> 5,038.599866130089
calc_dist_fixed -> 2,570.9028268899356
A Sitio web del gobierno de EE. UU. (Http://www.nhc.noaa.gov/gccalc.shtml) -> 2569
Este sitio web (http://www.timeanddate.com /worldclock/distanceresult.html?p1=179 & p2 = 224), de la que me dieron las coordenadas de la OFS y la ciudad de Nueva York, -> 2577
@Sven Marnach: vuelva a examinar su código. Hay exactamente dos ocurrencias de 'radianes', cada una aplicada a una latitud, ninguna a una longitud. Reexamina mi código. 'radianes' se aplica UNA VEZ a la diferencia de longitud. Intente probar los códigos y explique por qué los suyos son extraños. –
@Sven Marnach: Eso es gracioso; Podría haber jurado que vi un comentario donde dijiste que mi código estaba equivocado. SO necesita un seguimiento de auditoría :-) –
Perdón por eso. El comentario estuvo allí por unos segundos, pero inmediatamente noté que estaba equivocado. No pensé que hubieras cargado la página en ese pequeño marco de tiempo :) –
Otra manera simple:
Debajo función devuelve distancia entre dos espacios después de calcular latitudes y longitudes desde el código postal.
lat1
, long1
son las latitudes y longitudes de la primera ubicación.
lat2
, long2
son las latitudes y longitudes de la segunda ubicación.
from decimal import Decimal
from math import sin, cos, sqrt, atan2, radians
def distance(lat1, lat2, long1, long2):
r = 6373.0
lat1 = radians(lat1)
lat2 = radians(lat2)
long1 = radians(long1)
long2 = radians(long2)
d_lat = lat2 - lat1
d_long = long2 - long1
a = (sin(d_lat/2))**2 + cos(lat1) * cos(lat2) * (sin(d_long/2))**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
# distance in miles
dis = r * c
# distance in KM
dis /= 1.609344
return dis
- 1. Android distancia calcular entre dos ubicaciones
- 2. Distancia entre dos ubicaciones: Google Maps
- 3. cómo encontrar la distancia entre dos geopoints?
- 4. La distancia entre dos ubicaciones no es correcta
- 5. Encontrar la distancia entre dos círculos
- 6. Android: mejor método para calcular la distancia entre dos ubicaciones
- 7. ¿Cómo encontrar la distancia entre dos direcciones? (Java server side)
- 8. ¿Cómo encuentro la distancia entre dos puntos?
- 9. Cómo obtener la distancia entre dos divs
- 10. Encontrar la distancia entre CLLocationCoordinate2D puntos
- 11. ¿Cómo puedo calcular la distancia entre dos puntos en MkMapview?
- 12. ¿Cómo puedo obtener la distancia entre dos puntos latlng?
- 13. Manera eficiente de encontrar la distancia entre dos puntos 3D
- 14. Obtener la distancia entre dos puntos geográficos
- 15. distanceFromLocation - Calcular la distancia entre dos puntos
- 16. Calcular rodamiento entre dos ubicaciones (lat, largo)
- 17. Distancia entre dos teléfonos Android
- 18. Cálculo de la distancia entre dos puntos
- 19. Calcule la distancia social entre dos usuarios
- 20. la distancia entre dos puntos Android
- 21. Android - Distancia entre dos ciudades
- 22. Distancia física entre dos lugares
- 23. Medir la distancia entre dos dispositivos iOS
- 24. ¿Cómo encontrar la distancia desde la latitud y la longitud de dos lugares?
- 25. Distancia entre dos lat, lon puntos
- 26. ¿Cómo puedo encontrar la diferencia entre dos fechas usando Javascript
- 27. ¿Cómo se mide la distancia en metros entre dos CLLocations?
- 28. Distancia de retorno entre dos ubicaciones en SQL Server 2008 usando latitud y longitud
- 29. ¿Cómo encontrar la distancia entre dos ZipCodes usando el código Java?
- 30. Distancia entre dos coordenadas con CoreLocation
Aquí se presenta una [receta ActiveState] (http://code.activestate.com/recipes/393241-calculating-the-distance-between-zip-codes/) para este propósito. Es casi seguro que no está integrado en Django. –
Eche un vistazo al [Proyecto de base de datos de código postal] (http://zips.sourceforge.net/), también. También proporcionan el código de Python para el cálculo de distancia en la página vinculada. –
@Sven Marnach: publique el Proyecto de Base de Datos de Código Postal como una respuesta, es una buena idea. (Y sí, GeoDjango es probablemente excesivo para esto.) – tcarobruce