fix(offroute): _locate_on_network sets verbose=true; reads edge_info.classification.classification

PR #10s _spatial_eligible_modes read edge.get("road_class"), but Valhalla /locate
returns no class without verbose, and even with verbose=true the class is NOT named
road_class — it lives at edge.classification.classification (lowercase, e.g.
"secondary"). Without it, every paved/track/path gate failed and Auto collapsed to
foot for untyped endpoints.

Fix: add verbose=true to the /locate body and read the class via a defensive
edge.get("edge",{}).get("classification",{}).get("classification") chain, kept under
the same road_class key so downstream eligibility is unchanged. Live-verified against
Valhalla: (43.621,-116.205) -> road_class=secondary, snap 5.0m, PAVED=True.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-25 02:56:17 +00:00
commit c6acbbc88f

View file

@ -537,7 +537,7 @@ class OffrouteRouter:
try:
resp = requests.post(
f"{VALHALLA_URL}/locate",
json={"locations": [{"lat": lat, "lon": lon}], "costing": costing},
json={"locations": [{"lat": lat, "lon": lon}], "costing": costing, "verbose": True},
timeout=10
)
@ -553,7 +553,9 @@ class OffrouteRouter:
"snap_distance_m": snap_dist,
"snapped_lat": snap_lat,
"snapped_lon": snap_lon,
"road_class": edge.get("road_class"),
# Valhalla puts the highway class under edge.classification.classification
# (verbose=true); defensive .get chain so missing keys yield None.
"road_class": edge.get("edge", {}).get("classification", {}).get("classification"),
}
except Exception:
pass