Shapely: Получить ближайшую точку на Линии

Созданный на 18 окт. 2014  ·  3Комментарии  ·  Источник: Toblerity/Shapely

Привет,
Учитывая точку, я пытаюсь найти ближайшую точку на строке. Кажется, он отлично работает для простой строки, например
Python 3.4.0 (по умолчанию, 11 апреля 2014 г., 13:05:11)
[GCC 4.8.2] в Linux
Для получения дополнительной информации введите «помощь», «авторские права», «кредиты» или «лицензия».

из shapely.geometry import Point, LineString
line = LineString ([(0,0), (5,7), (12,6)])
p = Балл (4,8)
np = line.interpolate (line.project (p))
печать (нп)
ТОЧКА (5 7)

Однако для сложной линии я не получаю желаемых результатов. Например

route = LineString ([(19.119318,72.902800), (19.119660,72.901455), (19.119673,72.901401), (19.119848,72.900553), (19.119975,72.899972), (19.120129,72.899675), (19.120388,72) 72.899162), (19.121131,72.898909), (19.121597,72.898739), (19.122330,72.898471), (19.122696,72.898429), (19.123296,72.897991), (19.123680,72.897623), (19.124094095) 72.8 , (19.124483,72.896177), (19.124573,72.895796), (19.124585,72.895470), (19.124603,72.895014), (19.124652,72.894291), (19.124686,72.894067), (19.124929), 72.8917749, (19.124929) 72.89177, (19.124929) 72.89177 19.125097,72.892666), (19.125214,72.892323), (19.125450,72.891802), (19.125757,72.891281), (19.125951,72.890874), (19.126170,72.890413), (19.126833,72.8894173179), (19.125450,72.8894173) 72.886714), (19.129060,72.886402), (19.129109,72.886299), (19.129238,72.885913), (19.129302,72.885370), (19.129372,72.881686), (19.129396,72.880652), (198079413,72), (1980794137) , (19.129382,72.880070), (19.129419,72.879849), (19.129509,72.879205), (19.129709,72. 877766), (19.129969,72.876684), (19.130029,72.876511), (19.128367,72.875341), (19.127365,72.874602), (19.125882,72.873536), (19.125160,72.873014), (19.1247157137,72.8 , (19.123149,72.871568), (19.122517,72.871091), (19.122162,72.870822), (19.121981,72.870749), (19.121736,72.870651), (19.121013,72.870576), (19.119933,72.870.170432), (19.119933,72.870.170432), (19.119933,72.87046432), (19.119933,72.87046432), (19.119933,72.87046432), (19.119933,72.87046432)

список (route.coords)
[(19.119318, 72.9028), (19.11966, 72.901455), (19.119673, 72.901401), (19.119848, 72.900553), (19.119975, 72.899972), (19.120129, 72.899675), (19.120308, 72.89938205), (19.89938205), (19.119673) 19.121131, 72.898909), (19.121597, 72.898739), (19.12233, 72.898471), (19.122696, 72.898429), (19.123296, 72.897991), (19.12368, 72.897623), (19.124095, 72.897035), (19.12411482), (19.12411482) 72.896177), (19.124573, 72.895796), (19.124585, 72.89547), (19.124603, 72.895014), (19.124652, 72.894291), (19.124686, 72.894067), (19.124929, 72.893177), (19.1246971), (19.1246971), (19.12450971) , (19.125214, 72.892323), (19.12545, 72.891802), (19.125757, 72.891281), (19.125951, 72.890874), (19.12617, 72.890413), (19.126833, 72.889417), (19.127319, 72.888.1287314), (19.127319, 72.888.1287314) 19.12906, 72.886402), (19.129109, 72.886299), (19.129238, 72.885913), (19.129302, 72.88537), (19.129372, 72.881686), (19.129396, 72.880652), (19.129413, 72.880169), (19.1293169), (19.1293169), (19.1293169) 72.88007), (19 .129419, 72.879849), (19.129509, 72.879205), (19.129709, 72.877766), (19.129969, 72.876684), (19.130029, 72.876511), (19.128367, 72.875341), (19.127365, 72.87460882), (19.8735216), (19.127352) , 72.873014), (19.124815, 72.872761), (19.124413, 72.872457), (19.123149, 72.871568), (19.122517, 72.871091), (19.122162, 72.870822), (19.121981, 72.870749), (1970575736), (1970575736), (197012171) ), (19.119933, 72.870464), (19.119596, 72.870432)]

конец = Точка (19.125150,72.893218)

np = route.interpolate (route.project (конец))

печать (нп)
ТОЧКА (19.12493833590478 72.89314854771877)

Я ожидал, что результат будет 19.124929, 72.893177. Я что-то делаю неправильно? Любая помощь приветствуется.

Спасибо!

Самый полезный комментарий

Возвращенная точка - это ближайшая точка на линии к исходной точке. Ближайшая точка _не_ обязательно существующая вершина в LineString, и в данном случае это не так.

end = Point(19.125150,72.893218)
np = Point(19.12493833590478, 72.89314854771877)
expected = Point(19.124929, 72.893177)

print end.distance(np) # 0.000222767386696
print end.distance(expected) # 0.000224770994572

Если вы хотите найти ближайшую вершину, вы должны сначала преобразовать LineString в геометрию MultiPoint, а затем использовать операцию nearest_points (обратите внимание на небольшую ошибку с плавающей запятой):

from shapely.ops import nearest_points
from shapely.geometry import MultiPoint
mp = MultiPoint(route)
print nearest_points(mp, end)[0] # POINT (19.124929 72.89317699999999)

Этот запрос требует вычисления расстояния между исходной точкой и каждой вершиной исходной линии. Для очень сложных маршрутов это может быть довольно медленным. В этом случае вам следует рассмотреть возможность использования модуля rtree , который использует пространственное индексирование, чтобы сделать этот тип запроса очень быстрым:

http://toblerity.org/rtree/tutorial.html

Все 3 Комментарий

Возвращенная точка - это ближайшая точка на линии к исходной точке. Ближайшая точка _не_ обязательно существующая вершина в LineString, и в данном случае это не так.

end = Point(19.125150,72.893218)
np = Point(19.12493833590478, 72.89314854771877)
expected = Point(19.124929, 72.893177)

print end.distance(np) # 0.000222767386696
print end.distance(expected) # 0.000224770994572

Если вы хотите найти ближайшую вершину, вы должны сначала преобразовать LineString в геометрию MultiPoint, а затем использовать операцию nearest_points (обратите внимание на небольшую ошибку с плавающей запятой):

from shapely.ops import nearest_points
from shapely.geometry import MultiPoint
mp = MultiPoint(route)
print nearest_points(mp, end)[0] # POINT (19.124929 72.89317699999999)

Этот запрос требует вычисления расстояния между исходной точкой и каждой вершиной исходной линии. Для очень сложных маршрутов это может быть довольно медленным. В этом случае вам следует рассмотреть возможность использования модуля rtree , который использует пространственное индексирование, чтобы сделать этот тип запроса очень быстрым:

http://toblerity.org/rtree/tutorial.html

О, хорошо, спасибо за ваш ответ.

@snorfalorpagus . Я искал что-то подобное. какие-нибудь умные предложения по избавлению от ошибки с плавающей запятой? Та же проблема существует и с этим инструментом.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги