pythongeoosmnx

`osmnx.shortest_path` returns `None` for valid origin and destination nodes


Description

When calculating the shortest path between two locations with OSMnx, ox.shortest_path() failed to get any route and returns None

origin_lat=42.482, origin_lon=-70.910, dest_lat=42.472, dest_lon=-70.957

The points I am querying are quite normal, i.e. they are not super far/close to each other, and there are clear road network between them.

Here is the result when I use OSM webpage: Routing Results with OSM Webpage

My Questions:

  1. What is the root cause for this issue?
  2. What can I do to prevent this issue?
  3. If this is unpreventable in some cases, what are the recommended backup / alternatives for me to keep my code running with reasonable routes/distances?

Minimal reproducible example

from shapely.geometry import Polygon
import osmnx as ox

region_bounds = [
    [42.49897315546415, -70.97752844338558],
    [42.497310679689555, -70.89216747227316],
    [42.45989329011355, -70.90617955621047],
    [42.457041524105065, -70.97768950182164],
]
region_bounds.append(region_bounds[-1])

region_polygon = Polygon([bounds[::-1] for bounds in region_bounds])

mode = "drive"

G = ox.graph_from_polygon(polygon=region_polygon, network_type=mode)
G = ox.add_edge_speeds(G)
G = ox.add_edge_travel_times(G)

origin_lat = 42.482
origin_lon = -70.910

dest_lat = 42.472
dest_lon = -70.957

origin_nodes = ox.distance.nearest_nodes(G, origin_lon, origin_lat)
dest_nodes = ox.distance.nearest_nodes(G, dest_lon, dest_lat)

routes = ox.shortest_path(G, origin_nodes, dest_nodes)

print(origin_nodes, dest_nodes, routes)

The outputs are 68758830 65236189 None which means that the ox.distance.nearest_nodes found valid origin and destination nodes, but the ox.shortest_path failed.

Expected behavior

When I changed the query a little bit to be

origin_lat = 42.452
origin_lon = -70.910

dest_lat = 42.472
dest_lon = -70.957

The code above can find valid routes

68754328 65236189 [68754328, 68752028, 68757205, 68766524, 68769796, 68777219, 68761577, 68759405, 68766786, 68747897, 68755811, 68764727, 68765868, 68755029, 2041487395, 2041487385, 68758705, 68771074, 68751303, 68770735, 68747441, 65186124, 65232064, 65258971, 65258184, 65198797, 65243553, 2041154812, 65261211, 65218821, 65210373, 65208978, 65255290, 65231546, 65190866, 65226679, 65193542, 65239462, 65225225, 2041270157, 65257919, 65186045, 2041270160, 65262590, 2041270186, 65252676, 65232296, 65242158, 65261501, 65221801, 65251183, 65190759, 65218681, 65222417, 2043144587, 65250858, 2043144592, 65247406, 65224701, 65231219, 65202428, 65242218, 65235268, 65197313, 65240735, 65207550, 2045575158, 65227845, 65229809, 65190291, 65217006, 2045610191, 9966458026, 65195913, 65214016, 65241686, 65240704, 65202519, 65201239, 65242936, 65233288, 65186829, 65199167, 65239099, 65242030, 65237992, 65236189]

Solution

  • What is the root cause for this issue?

    The reason is this OSM way: https://www.openstreetmap.org/way/1243001416

    It is digitized as a one-way street inbound into this community. There is no outbound way digitized. Therefore, you can solve routes inbound to the community, but you cannot solve routes outbound from it due to the one-way.

    What can I do to prevent this issue?

    Presumably, this is an incorrect digitization since there are no other routes into or out of this community. It's impossible for it to be only one-way and for there to be no egress from this community. If so, the best way to prevent this issue is to make a correction on OpenStreetMap itself.

    The alternative would be to edit your OSMnx model to add in a reciprocal one-way edge to allow bidirectional access.

    If this is unpreventable in some cases, what are the recommended backup / alternatives for me to keep my code running with reasonable routes/distances?

    It's not unpreventable. If the model exhibits an impossible situation like this, one of the solutions mentioned above will resolve it. Either fix the underlying digitization error on OpenStreetMap, or fix it in your OSMnx model (e.g., adding an edge).