2017-02-16 17 views
1

Я работаю над проектом Python, где у меня две пары lat/long, и я хочу рассчитать расстояние между ними. В других проектах я рассчитал расстояние в Postgres, используя ST_Distance_Sphere (a.loc_point, b.loc_point), но я бы хотел, чтобы я не загружал все мои данные в Postgres, чтобы я мог рассчитать разницу расстояний. Я искал, но не смог найти то, что хотел бы, что является чисто реализацией Python, поэтому мне не нужно загружать мои данные в Postgres.ST_Distance_Sphere() в Python?

Я знаю, что существуют другие расчеты расстояний, которые рассматривают землю как идеальную сферу, но они недостаточно хороши из-за плохой точности, поэтому я хотел бы использовать функцию PostGIS ST_Distance_Sphere() (или эквивалентную).

Вот несколько образцов Lat/Longs, что я хотел бы вычислить расстояние:

Lat, Long 1: (49.8755, 6.07594) 
Lat, Long 2: (49.87257, 6.0784) 

Я не могу себе представить, я первый человек, чтобы спросить, но кто-нибудь знает о способ использовать ST_Distance_Sphere() для вычислений lat/long на основе только скрипта Python?

ответ

1

Это элементарная функция, используемая для вычисления расстояния между двумя координатами на идеальной сфере с радиусом = радиусом Земли

from math import pi , acos , sin , cos 
def calcd(y1,x1, y2,x2): 
    # 
    y1 = float(y1) 
    x1 = float(x1) 
    y2 = float(y2) 
    x2 = float(x2) 
    # 
    R = 3958.76 # miles 
    # 
    y1 *= pi/180.0 
    x1 *= pi/180.0 
    y2 *= pi/180.0 
    x2 *= pi/180.0 
    # 
    # approximate great circle distance with law of cosines 
    # 
    x = sin(y1)*sin(y2) + cos(y1)*cos(y2)*cos(x2-x1) 
    if x > 1: 
     x = 1 
    return acos(x) * R 

Надеется, что это помогает!

+0

Как вы можете получить ответ в метрах с помощью этого решения? –

+0

В линии R = 3958.76 # мили просто установите R в радиус земли в метрах (6,331 миллиона метров), и это должно возвращать ответы в терминах метров –

1

Смотреть это How can I quickly estimate the distance between two (latitude, longitude) points?

from math import radians, cos, sin, asin, sqrt 
def haversine(lon1, lat1, lon2, lat2): 
    """ 
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees) 
    """ 
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) 
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c 
    return km 

Аароном D

Вы можете изменить его, чтобы вернуть миль путем добавления miles = km * 0.621371

3

Я бы рекомендовал geopy пакет - смотрите раздел Measuring Distance в документации ...

Для ваших участников ular case:

from geopy.distance import great_circle 

p1 = (49.8755, 6.07594) 
p2 = (49.87257, 6.0784) 

print(great_circle(p1, p2).kilometers) 
0

С тех пор я нашел другой способ в дополнение к ответам, представленным здесь. Использование модуля haversine python.

from haversine import haversine as h 

# Return results in meters (*1000) 
print '{0:30}{1:12}'.format("haversine module:", h(a, b)*1000) 

Я проверил все три ответа плюс модуль гаверсинуса против того, что я получил с помощью ST_Distance_Sphere (а, б) в Postgres. Все ответы были отличными (спасибо), но самый математический ответ (calcd) из Sishaar Rao был самым близким. Вот результаты:

# Short Distance Test 
ST_Distance_Sphere(a, b):  370.43790478  
vincenty:      370.778186438 
great_circle:     370.541763803 
calcd:      370.437386736 
haversine function:   370.20481753 
haversine module:    370.437394767 

#Long Distance test: 
ST_Distance_Sphere(a, b):  1011734.50495159 
vincenty:      1013450.40832 
great_circle:     1012018.16318 
calcd:      1011733.11203 
haversine function:   1011097.90053 
haversine module:    1011733.11203 

 Смежные вопросы

  • Нет связанных вопросов^_^