2012-01-13 15 views
8

Estoy configurando un pequeño programa para tomar 2 coordenadas geográficas de un usuario y luego calcular la distancia entre ellas (teniendo en cuenta la curvatura de la tierra). Así que busqué en wikipedia cuál es la fórmula here.Necesita ayuda para calcular la distancia geográfica

básicamente creé mi función de Python basado en eso y esto es lo que ocurrió:

def geocalc(start_lat, start_long, end_lat, end_long): 
    start_lat = math.radians(start_lat) 
    start_long = math.radians(start_long) 
    end_lat = math.radians(end_long) 
    end_long = math.radians(end_long) 

    d_lat = start_lat - end_lat 
    d_long = start_long - end_long 

    EARTH_R = 6372.8 

    c = math.atan((math.sqrt((math.cos(end_lat)*d_long)**2 +((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2))/((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long)))) 

    return EARTH_R*c 

El problema es que los resultados salen muy inexacta. ¡Soy nuevo en Python, así que un poco de ayuda o consejo sería muy apreciado!

+2

favor dar un ejemplo concreto (entrada, salida era de esperar, la salida real). –

+0

Ingresé estas coordenadas (-6.508, 55.071) y (-8.886, 51.622). La salida esperada era 414Km. El resultado real fue 6473Km – Darkphenom

+0

Diría que esto es más que inexacto, esto está mal>. hochl

Respuesta

10

Tienes 4 o 5 o 6 problemas:

(1) end_lat = math.radians(end_long) debería ser end_lat = math.radians(end_lat)

(2) se echa en falta algunas cosas como alguien ya se ha mencionado, la mayoría probablemente porque

(3) su código es ilegible (línea lejanos, paréntesis demasiado largos redundantes, 17 instancias sin sentido de "matemáticas").

(4) que no se dio cuenta el comentario en el artículo de Wikipedia sobre el uso de atan2()

(5) Es posible que haya estado intercambiando lat y lon al introducir sus coordenadas

(6) delta(latitude) se calcula innecesariamente; no aparece en la fórmula

Poniendo todo junto:

from math import radians, sqrt, sin, cos, atan2 

def geocalc(lat1, lon1, lat2, lon2): 
    lat1 = radians(lat1) 
    lon1 = radians(lon1) 
    lat2 = radians(lat2) 
    lon2 = radians(lon2) 

    dlon = lon1 - lon2 

    EARTH_R = 6372.8 

    y = sqrt(
     (cos(lat2) * sin(dlon)) ** 2 
     + (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)) ** 2 
     ) 
    x = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlon) 
    c = atan2(y, x) 
    return EARTH_R * c 



>>> geocalc(36.12, -86.67, 33.94, -118.40) 
2887.2599506071115 
>>> geocalc(-6.508, 55.071, -8.886, 51.622) 
463.09798886300376 
>>> geocalc(55.071, -6.508, 51.622, -8.886) 
414.7830891822618 
+0

Gracias por señalar todos esos problemas. ¡Ciertamente parece mucho más limpio que lo que hice y funciona! – Darkphenom

4

Usted puede utilizar el módulo geopy que tiene una función incorporada para los cálculos de distancia, desplácese hacia abajo para "el cálculo de distancias" en el siguiente enlace: https://pypi.python.org/pypi/geopy

+0

Esa es una buena sugerencia, pero tu respuesta sería mejor si pudieras incluir algún código sobre cómo lograr el objetivo de OP . – MERose

3

Creo que se ha perdido un math.sin (d_long) hacia el principio, tal vez debería ser la siguiente:

c = math.atan((math.sqrt((math.cos(end_lat)*math.sin(d_long))**2 +((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2))/((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long)))) 
+0

Estás en lo correcto allí. Sin embargo, todavía recibo respuestas completamente incorrectas. – Darkphenom

4

esto funciona (impresión f devuelve 2887.26 km según el ejemplo trabajado @http://en.wikipedia.org/wiki/Great-circle_distance):

import math 

def geocalc(start_lat, start_long, end_lat, end_long): 

    start_lat = math.radians(start_lat) 
    start_long = math.radians(start_long) 
    end_lat = math.radians(end_lat) 
    end_long = math.radians(end_long) 

    d_lat = math.fabs(start_lat - end_lat) 
    d_long = math.fabs(start_long - end_long) 

    EARTH_R = 6372.8 

    y = ((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long))) 

    x = math.sqrt((math.cos(end_lat)*math.sin(d_long))**2 + ((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2) 

    c = math.atan(x/y) 

    return EARTH_R*c 

f = geocalc(36.12, -86.67, 33.94, -118.40) 
print f 

Aviso esta línea en su presentación: end_lat = math.radians(end_long)

+0

No necesita 'fabs()', porque 'cos (-x) == cos (x)' –

+0

-1 Esto puede ir espectacularmente mal porque está usando 'atan' en lugar de' atan2'. Ejemplos: ir hacia el sur desde 45 grados lat hasta -45 grados lat es 10010 km (OK) pero de 45.1 grados a -45.1 grados (una distancia ligeramente más larga) produce MÍNIMO 9988 km. ¡Un viaje desde el polo norte al polo sur produce ZERO km! –

+0

@JohnMachin con respecto a los fabs() comenta que es correcto para esta implementación en particular, pero cuando se enseña el concepto de deltas, el uso de valores absolutos es correcto, no una simple resta. – sgallen

Cuestiones relacionadas