Shortest paths and OD matrices¶
This notebook covers the shortest-path helpers available for UrbanGraph. Distances are returned in the units of the selected edge weight: minutes for time_min and meters for length_meter.
# To install IduEdu in a clean environment:
# !pip install IduEdu
OSM_ID = 1114252
from iduedu import get_walk_graph
G_walk = get_walk_graph(osm_id=OSM_ID, simplify=True, keep_largest_subgraph=True)
G_walk.update_adjacency_matrix(weight="time_min")
sample_nodes = G_walk.nodes_gdf.index[:6].tolist()
source = sample_nodes[0]
destinations = sample_nodes[1:]
print(sample_nodes)
2026-07-07 15:18:59.464 | WARNING | Removing 332 nodes outside the largest connected component. Retaining 19588 of 19920 nodes.
[0, 1, 2, 3, 4, 5]
Single-source distances¶
Use this for one origin and many possible destinations, for example a walking catchment around one point.
from iduedu import single_source_dijkstra_path_length
single = single_source_dijkstra_path_length(
G_walk,
source,
weight="time_min",
cutoff=15,
)
single.sort_values().head(10)
node
0 0.0
2 0.21
17080 0.323
17081 0.338
3 0.438
4 0.658
11 1.563
13 1.605
12 1.648
14 1.689
Name: dist, dtype: Sparse[float32, inf]
Multi-source distance to the closest source¶
All sources are inserted into one Dijkstra queue. The result gives the distance to the nearest source, not one row per source.
from iduedu import multi_source_dijkstra_path_length
multi = multi_source_dijkstra_path_length(
G_walk,
source_nodes=sample_nodes[:3],
weight="time_min",
cutoff=15,
)
multi.sort_values().head(10)
node
0 0.0
1 0.0
2 0.0
3 0.228
17080 0.323
17081 0.338
17082 0.367
4 0.448
6 0.793
5 0.844
Name: dist, dtype: Sparse[float32, inf]
Nearest source label and distance¶
Use this when the winning source node is needed along with the shortest distance.
from iduedu import multi_source_dijkstra_nearest_source
nearest = multi_source_dijkstra_nearest_source(
G_walk,
source_nodes=sample_nodes[:3],
weight="time_min",
cutoff=15,
)
nearest.head(10)
| source_node | dist | |
|---|---|---|
| node | ||
| 0 | 0 | 0.0 |
| 1 | 1 | 0.0 |
| 2 | 2 | 0.0 |
| 3 | 2 | 0.228 |
| 4 | 2 | 0.448 |
| 5 | 1 | 0.844 |
| 6 | 1 | 0.793 |
| 7 | 1 | 1.019 |
| 8 | 1 | 0.972 |
| 9 | 1 | 1.583 |
Independent parallel searches¶
dijkstra_path_length_parallel keeps one sparse row per source. This is useful when each origin needs its own accessibility profile.
from iduedu import dijkstra_path_length_parallel
parallel = dijkstra_path_length_parallel(
G_walk,
source_nodes=sample_nodes[:3],
weight="time_min",
cutoff=15,
max_workers=4,
)
parallel.iloc[:, :8]
| node | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 0 | 0.0 | 3.18 | 0.21 | 0.438 | 0.658 | 2.477 | 2.387 | 2.302 |
| 1 | 3.18 | 0.0 | 2.97 | 2.742 | 2.522 | 0.844 | 0.793 | 1.019 |
| 2 | 0.21 | 2.97 | 0.0 | 0.228 | 0.448 | 2.267 | 2.177 | 2.092 |
Origin-destination matrix¶
od_matrix accepts graph node ids or GeoDataFrames. With node ids, rows follow origins_nodes and columns follow destination_nodes.
from iduedu import od_matrix
od = od_matrix(
G_walk,
origins_nodes=sample_nodes[:3],
destination_nodes=destinations,
weight="time_min",
threshold=30,
max_workers=4,
)
od
| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| 0 | 3.18 | 0.21 | 0.438 | 0.658 | 2.477 |
| 1 | 0.0 | 2.97 | 2.742 | 2.522 | 0.844 |
| 2 | 2.97 | 0.0 | 0.228 | 0.448 | 2.267 |
Method equivalents¶
The same helpers are also available as UrbanGraph methods.
G_walk.single_source_dijkstra_path_length(source, cutoff=15).head()
G_walk.multi_source_dijkstra_path_length(source_nodes=sample_nodes[:3], cutoff=15).head()
G_walk.multi_source_dijkstra_nearest_source(source_nodes=sample_nodes[:3], cutoff=15).head()
G_walk.dijkstra_path_length_parallel(source_nodes=sample_nodes[:3], cutoff=15, max_workers=4).iloc[:, :5]
G_walk.od_matrix(origins_nodes=sample_nodes[:3], destination_nodes=destinations, threshold=30)
| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| 0 | 3.18 | 0.21 | 0.438 | 0.658 | 2.477 |
| 1 | 0.0 | 2.97 | 2.742 | 2.522 | 0.844 |
| 2 | 2.97 | 0.0 | 0.228 | 0.448 | 2.267 |