Я пытаюсь вычислить расстояние между двумя точками (широта, долгота), используя пакет osmnx
.
Во время тестирования osmnx.nearest_nodes()
, чтобы сначала найти ближайший узел от точки, я заметил, что он, похоже, не учитывает направление улицы при вычислении ближайшего узла (например, когда точка находится на улице с односторонним движением).
Например: если я возьму эту (широта, долгота) точку (48.921281, 2.517598), расположенную на улице с односторонним движением, ближайший узел будет найден только с учетом расстояния от нее (узел n°OSMID 288965181 найден с nearest_nodes()
: 48.9217176 , 2.5180361).
nearest_nodes()
похоже не учитывает тип сети, которую я выбрал (диск).
Если да, то найденный узел должен был быть узлом 288964629 (48.9203235, 2.5166429).
Почему ? Потому что с точки (48.921281, 2.517598) узел 288965181 не является ближайшим узлом с учетом управляющей сети, а узел 288964629 — ближайшим.
Вот пример кода:
import osmnx as ox
import networkx as nx
#creating the graph from a point coordinates
centreCoord = (48.920576, 2.529185)
G= ox.graph_from_point(centreCoord, dist=2000, network_type='drive')
#origin and destination point
originCoord = (48.921281, 2.517598)
destinationCoord = (48.921454, 2.518696)
#calculating the nearest nodes from origin and destination points
origin_node = ox.nearest_nodes(G, originCoord[1], originCoord[0])
destination_node = ox.nearest_nodes(G, destinationCoord[1], destinationCoord[0])
#computing the driving path
route = nx.shortest_path(G, source=origin_node, target=destination_node, weight='length')
Вот простой сюжет, где:
networkx.shortest_path()
Я добавил :
Я мог иногда пропустить или сделать что-то не так.
Я прочитал osmnx
документацию. Пробовал несколько комбинаций (параметры network_type
, ox.settings.bidirectional_network_types
), пытался отлаживать вычисления, чтобы понять, как выбираются узлы.
Прежде чем спрашивать, я искал похожие темы. Много интересных вещей, но я не нашел подходящих ответов.
Я застрял на этом в течение нескольких дней.
Любая помощь будет здорово!
Возможный обходной путь может быть следующим:
ox.nearest_edges()
. Вы получите дорогу с односторонним движением;# Get the nearest edge from the origin point
u, v, k = ox.nearest_edges(G, originCoord[1], originCoord[0])
destination_node = ox.nearest_nodes(G, destinationCoord[1], destinationCoord[0])
# computing the driving path
route = nx.shortest_path(G, source=v, target=destination_node, weight='length')
Вот сюжет, используя ox.plot_graph_route(G, route)
:
Обратите внимание, что описанный подход прекрасно работает с дорогами с односторонним движением, состоящими всего из двух узлов.
Конечно, это все еще возможно ... Но предположим, что у вас есть более длинная дорога с односторонним движением со многими узлами: описанный мной подход всегда будет выбирать конечный узел пути как ближайший к исходной точке, а не ближайший средние узлы
Это касается примера, который я привел: дорога с односторонним движением в моем примере состоит из нескольких узлов. nearest_edges(G, pointA_lon, pointA_lat)
вернет ближайший край дороги, поэтому я думаю, что ваш подход все еще должен работать.
Тогда все в порядке, надеюсь, это лучший ответ ✅
Спасибо @dnyll! Я не думал об использовании
nearest_edges()
таким образом. Я буду реализовывать этот подход. Однако один вопрос: что вы подразумеваете под «отлично работает с односторонними дорогами, состоящими только из двух узлов»? Можно ли найти ребро с более чем двумя узлами?