2014-12-13 4 views
4

У меня есть линейные сегменты, определенные с началом и конечной точкой:Вычислить расстояние между точкой и отрезка по широте и долготе

A: 
x1 = 10.7196405787775 
y1 = 59.9050401935882 

B: 
x2 = 10.7109989561813 
y2 = 59.9018650448204 

где х определяет долготы и широты определяет у.

У меня также есть пункт:

P: 
x0 = 10.6542116666667 
y0 = 59.429105 

Как вычислить кратчайшее расстояние между отрезком и точкой? Я знаю, как это сделать в декартовых координатах, но не в координатах long/lat.

+2

google 'haversine': http://en.wikipedia.org/wiki/Haversine_formula –

+1

Для вопросов типа GIS вы можете рассмотреть возможность публикации в [Stack Exchange - Географические информационные системы] (http://gis.stackexchange.com/). Затем опубликуйте актуальные проблемы с кодированием. Это может представлять интерес - [Какие инструменты в Python доступны для создания большого расстояния круга + создание линии?] (Http://gis.stackexchange.com/q/47/23174) – wwii

+1

http://stackoverflow.com/a/865080/948550 –

ответ

2

Использование полезной Python геокодирования библиотеки geopy, и формула для средней точки большого круга из Chris Veness's geodesy formulae, мы можем найти расстояние между отличным дуга окружности и заданная точка:

from math import sin, cos, atan2, sqrt, degrees, radians, pi 
from geopy.distance import great_circle as distance 
from geopy.point import Point 


def midpoint(a, b): 
    a_lat, a_lon = radians(a.latitude), radians(a.longitude) 
    b_lat, b_lon = radians(b.latitude), radians(b.longitude) 
    delta_lon = b_lon - a_lon 
    B_x = cos(b_lat) * cos(delta_lon) 
    B_y = cos(b_lat) * sin(delta_lon) 
    mid_lat = atan2(
     sin(a_lat) + sin(b_lat), 
     sqrt(((cos(a_lat) + B_x)**2 + B_y**2)) 
    ) 
    mid_lon = a_lon + atan2(B_y, cos(a_lat) + B_x) 
    # Normalise 
    mid_lon = (mid_lon + 3*pi) % (2*pi) - pi 
    return Point(latitude=degrees(mid_lat), longitude=degrees(mid_lon)) 

Что в этом примере дает:

# Example: 
a = Point(latitude=59.9050401935882, longitude=10.7196405787775) 
b = Point(latitude=59.9018650448204, longitude=10.7109989561813) 
p = Point(latitude=59.429105, longitude=10.6542116666667) 

d = distance(midpoint(a, b), p) 
print d.km 
# 52.8714586903 
+2

Это дает расстояние до середины. Это не то же самое, что расстояние до сегмента линии - например, если p близко к a, d должно быть намного меньше половины расстояния от a до b. – Skyler

2

Вот реализация формулы от Wikipedia:

def distance(p0, p1, p2): # p3 is the point 
    x0, y0 = p0 
    x1, y1 = p1 
    x2, y2 = p2 
    nom = abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) 
    denom = ((y2 - y1)**2 + (x2 - x1) ** 2) ** 0.5 
    result = nom/denom 
    return result 

print distance((0, 0), (3, 4), (5, 6)) 

# should probably test less obvious cases 
assert 1 == distance((0, 0), (1, 1), (2, 1)) 
# change 0.001 to whatever accuracy you demand on testing. 
# Notice that it's never perfect... 
assert 0.5 * (2 ** 0.5) - distance((0, 0), (1, 0), (0, 1)) < 0.001 
Смежные вопросы