WanderLust / src /discoverroute /data /build_graph.py
Tristan Leduc
Wanderlust: taste-aware Paris discovery routing
f00d669
Raw
History Blame Contribute Delete
1.79 kB
"""Offline: download the Paris OSM extract and build the walk/bike routing graph.
Run once (cached for the Space):
python -m discoverroute.data.build_graph
Produces ``data/paris_walk.graphml``. The graph is mode-agnostic: edges carry
length in metres; travel time is derived per mode at runtime from
``config.speed_ms`` so a single graph serves both walking and cycling. (Bikes on
the pedestrian network is a documented v1 approximation — see README.)
"""
from __future__ import annotations
import time
import osmnx as ox
from discoverroute import config
def build_walk_graph(place: str = config.PARIS_PLACE):
"""Download and return the Paris walking network as a networkx MultiDiGraph."""
ox.settings.use_cache = True
ox.settings.log_console = True
print(f"[build_graph] downloading walk network for: {place!r}")
t0 = time.time()
graph = ox.graph_from_place(place, network_type="walk")
print(
f"[build_graph] downloaded {graph.number_of_nodes():,} nodes / "
f"{graph.number_of_edges():,} edges in {time.time() - t0:.1f}s"
)
# Keep only the largest strongly connected component so every node is
# reachable from every other — avoids "no path" failures on islands.
graph = ox.truncate.largest_component(graph, strongly=True)
print(
f"[build_graph] largest strongly-connected component: "
f"{graph.number_of_nodes():,} nodes / {graph.number_of_edges():,} edges"
)
return graph
def main() -> None:
graph = build_walk_graph()
config.GRAPH_WALK_PATH.parent.mkdir(parents=True, exist_ok=True)
print(f"[build_graph] saving to {config.GRAPH_WALK_PATH}")
ox.save_graphml(graph, config.GRAPH_WALK_PATH)
print("[build_graph] done.")
if __name__ == "__main__":
main()