Osmnx не может найти путь между узлами в составном графе?

Я пытаюсь использовать osmnx для определения расстояний между точкой отправления (широта / долгота) и ближайшей инфраструктурой, такой как железные дороги, водные объекты или парки.

1) Я получаю весь график из области с network_type='walk'.

2) Получите необходимую инфраструктуру, например железная дорога в том же районе.

3) Скомпонуйте два графика в один.

4) Найдите ближайший узел от исходной точки в исходном графе.

5) Найдите ближайший узел от исходной точки в графе инфраструктуры

6) Найдите кратчайшую длину маршрута между двумя узлами.

Если вы запустите приведенный ниже пример, вы увидите, что ему не хватает 20% данных, потому что он не может найти маршрут между узлами. Для infrastructure='way["leisure"~"park"]' или infrastructure='way["natural"~"wood"]' это еще хуже, 80-90% узлов не подключены.


Минимальный воспроизводимый пример:

import osmnx as ox
import networkx as nx

bbox = [55.5267243, 55.8467243, 12.4100724, 12.7300724]

g = ox.graph_from_bbox(bbox[0], bbox[1], bbox[2], bbox[3], 
                       retain_all=True, 
                       truncate_by_edge=True, 
                       simplify=False,
                       network_type='walk')


points = [(55.6790884456018, 12.568493971506154),
 (55.6790884456018, 12.568493971506154),
 (55.6867418740291, 12.58232314016353),
 (55.6867418740291, 12.58232314016353),
 (55.6867418740291, 12.58232314016353),
 (55.67119624894504, 12.587201455313153),
 (55.677406927839506, 12.57651997656002),
 (55.6856574907879, 12.590500429002823),
 (55.6856574907879, 12.590500429002823),
 (55.68465359365924, 12.585474365063224),
 (55.68153666806675, 12.582594757267945),
 (55.67796979175, 12.583111746311117),
 (55.68767346629932, 12.610040871066179),
 (55.6830855237578, 12.575431380892427),
 (55.68746749645466, 12.589488615911913),
 (55.67514254640597, 12.574308210656602),
 (55.67812748568291, 12.568454119053886),
 (55.67812748568291, 12.568454119053886),
 (55.6701733527419, 12.58989203029166),
 (55.677700136266616, 12.582800629527789)]

railway = ox.graph_from_bbox(bbox[0], bbox[1], bbox[2], bbox[3], 
                               retain_all=True, 
                               truncate_by_edge=True, 
                               simplify=False,
                               network_type='walk', 
                               infrastructure='way["railway"]')

g_rail = nx.compose(g, railway)

l_rail = []

for point in points:

    nearest_node = ox.get_nearest_node(g, point)

    rail_nn = ox.get_nearest_node(railway, point)

    if nx.has_path(g_rail, nearest_node, rail_nn):
        l_rail.append(nx.shortest_path_length(g_rail, nearest_node, rail_nn, weight='length'))
    else:
        l_rail.append(-1)


person tmo    schedule 20.06.2019    source источник


Ответы (1)


Мое внимание привлекли 2 вещи.

  1. В документации OSMNX указано, что параметры ox.graph_from_bbox должны быть указаны в следующем порядке: север, юг, восток, запад (https://osmnx.readthedocs.io/en/stable/osmnx.html). Я упоминаю об этом, потому что, когда я пытался запустить ваш код, я получал пустые графики.

  2. Параметр «keep_all = True» является ключевым, как вы, возможно, уже знаете. Если установлено значение true, он сохраняет все узлы в графе, даже если они не связаны ни с одним из других узлов в графе. Это происходит в первую очередь из-за неполноты OpenStreetMap, который содержит добровольно предоставленную географическую информацию. Я предлагаю вам установить «keep_all = False», что означает, что ваш график теперь содержит только подключенные узлы. Таким образом, вы получите полный список без -1.

Надеюсь, это поможет.

g = ox.graph_from_bbox(bbox[1], bbox[0], bbox[3], bbox[2], 
                       retain_all=False, 
                       truncate_by_edge=True, 
                       simplify=False,
                       network_type='walk')

railway = ox.graph_from_bbox(bbox[1], bbox[0], bbox[3], bbox[2], 
                               retain_all=False, 
                               truncate_by_edge=True, 
                               simplify=False,
                               network_type='walk', 
                               infrastructure='way["railway"]')

g_rail = nx.compose(g, railway)

l_rail = []

for point in points:

    nearest_node = ox.get_nearest_node(g, point)

    rail_nn = ox.get_nearest_node(railway, point)

    if nx.has_path(g_rail, nearest_node, rail_nn):
        l_rail.append(nx.shortest_path_length(g_rail, nearest_node, rail_nn, weight='length'))
    else:
        l_rail.append(-1)

print(l_rail)
Out[60]: 
[7182.002999999995,
 7182.002999999995,
 5060.562000000002,
 5060.562000000002,
 5060.562000000002,
 6380.099999999999,
 7127.429999999996,
 4707.014000000001,
 4707.014000000001,
 5324.400000000003,
 6153.250000000002,
 6821.213000000002,
 8336.863999999998,
 6471.305,
 4509.258000000001,
 5673.294999999996,
 6964.213999999994,
 6964.213999999994,
 6213.673,
 6860.350000000001]
person Debjit Bhowmick    schedule 02.07.2019
comment
Обратите внимание, что параметр infrastructure устарел и заменен на custom_filter в последних выпусках. - person gboeing; 07.06.2020