From c6acbbc88f9f110a74f3ce4a667f39dd0dc7534d Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 25 May 2026 02:56:17 +0000 Subject: [PATCH] fix(offroute): _locate_on_network sets verbose=true; reads edge_info.classification.classification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- backend/services/navi_offroute/router.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/services/navi_offroute/router.py b/backend/services/navi_offroute/router.py index 322c62c..7fdab1a 100755 --- a/backend/services/navi_offroute/router.py +++ b/backend/services/navi_offroute/router.py @@ -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