From 10960ca8860cfaf58fca2628c9f09e6d58fd29db Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 24 May 2026 16:34:03 +0000 Subject: [PATCH] fix(navi): vehicle skips off-network gate; boundary chips show for non-Drive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vehicle is pure Valhalla road routing — Valhalla snaps endpoints to the nearest road automatically, so the off-network classifier (OFF_NETWORK_THRESHOLD_M) is irrelevant for it. Add an early branch in route() that sends vehicle straight to _route_D_network_only, instead of bandaiding the threshold. Foot/MTB/ATV keep the gate so users can intentionally pin backcountry points; Auto inherits the skip via its recursive mode=vehicle probe. Threshold stays at 10. Frontend: boundary-mode chips now show for all modes except Drive (vehicle). Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/services/navi_offroute/router.py | 11 +++++++++++ frontend/src/components/DirectionsPanel.jsx | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/backend/services/navi_offroute/router.py b/backend/services/navi_offroute/router.py index 40f444b..8ab0fd9 100755 --- a/backend/services/navi_offroute/router.py +++ b/backend/services/navi_offroute/router.py @@ -543,6 +543,17 @@ class OffrouteRouter: if mode not in MODE_TO_COSTING: return {"status": "error", "message": f"Unknown mode: {mode}"} + # Vehicle is pure Valhalla road routing: Valhalla snaps endpoints to the + # nearest road automatically, so the off-network classifier is irrelevant + # (and a tight threshold would wrongly push normal road routes into + # wilderness pathfinding). Foot/MTB/ATV still use the threshold gate so + # users can intentionally pin backcountry points. Auto inherits this via + # its recursive self.route(..., mode="vehicle", ...) probe. + if mode == "vehicle": + return self._route_D_network_only( + start_lat, start_lon, end_lat, end_lon, mode + ) + # Detect network status for both endpoints start_status = self._locate_on_network(start_lat, start_lon, mode) end_status = self._locate_on_network(end_lat, end_lon, mode) diff --git a/frontend/src/components/DirectionsPanel.jsx b/frontend/src/components/DirectionsPanel.jsx index 428abee..d8ac724 100644 --- a/frontend/src/components/DirectionsPanel.jsx +++ b/frontend/src/components/DirectionsPanel.jsx @@ -325,8 +325,9 @@ export default function DirectionsPanel({ onClose }) { )} - {/* Boundary mode selector (only for non-auto modes) */} - {routeMode !== "auto" && ( + {/* Boundary mode selector — hidden only for Drive (vehicle), which is pure + Valhalla road routing; Auto/Foot/MTB/ATV may traverse wilderness. */} + {routeMode !== "vehicle" && (
{BOUNDARY_MODES.map((m) => { const active = boundaryMode === m.id