navi-offroute: Auto bypass — trust _auto_eligible_modes vehicle judgment (PR 48)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mj 2026-05-27 23:43:03 -06:00
commit b4f2d46cd6
2 changed files with 28 additions and 31 deletions

View file

@ -754,26 +754,6 @@ class OffrouteRouter:
return CATEGORY_ELIGIBLE_MODES.get(f"{key}:*") return CATEGORY_ELIGIBLE_MODES.get(f"{key}:*")
return None return None
def _bypass_eligible(self, lat: float, lon: float,
category: Optional[str], snap_cache: dict) -> bool:
"""True when this endpoint is clearly ON a paved road. Gates the Valhalla bypass
in _route_auto. Two safe paths:
1. positive OSM category hint (CATEGORY_ELIGIBLE_MODES grants "vehicle"), OR
2. cached auto-snap is tight (<= AUTO_SNAP_TIGHT_M) AND the snapped road is a
paved highway class.
Deliberately EXCLUDES the relaxed-snap-with-flat case (d_auto <= 100m + flat
terrain), which can grant 'vehicle' eligibility up to 100m off a road bypassing
there would silently re-snap a wilderness/park-lot click to the road and lose any
walk-then-drive leg the unified flow would have produced."""
typed = self._eligible_modes_from_category(category)
if typed is not None:
return "vehicle" in typed
snap = snap_cache.get((lat, lon, "auto"))
if snap is None:
return False # tagged-endpoint short-circuit didn't pre-populate; safe default
return (snap["snap_distance_m"] <= AUTO_SNAP_TIGHT_M
and snap.get("road_class") in PAVED_HIGHWAY_CLASSES)
def _is_terrain_flat(self, lat: float, lon: float) -> bool: def _is_terrain_flat(self, lat: float, lon: float) -> bool:
"""True if the DEM is flat (max-min < FLAT_TERRAIN_DELTA_M) across the center """True if the DEM is flat (max-min < FLAT_TERRAIN_DELTA_M) across the center
and four cardinal points FLAT_SAMPLE_RADIUS_M away. Conservative: any DEM read and four cardinal points FLAT_SAMPLE_RADIUS_M away. Conservative: any DEM read
@ -859,15 +839,15 @@ class OffrouteRouter:
seed_set = sorted(start_eligible | end_eligible) seed_set = sorted(start_eligible | end_eligible)
# === Valhalla bypass: pure road↔road skips the raster pipeline entirely === # === Valhalla bypass: pure road↔road skips the raster pipeline entirely ===
# When BOTH endpoints are clearly ON a paved road -- by vehicle-eligible category hint # Fires when both endpoints have "vehicle" in _auto_eligible_modes's judgment (computed
# OR a tight (<=5m) auto-snap to a paved highway (_bypass_eligible) -- the trip is # above) -- covers tagged road categories AND raw map clicks that land tight OR
# on-road end-to-end, so hand it to the same inline-Valhalla path explicit vehicle # relaxed+flat+paved near a road. The _is_terrain_flat check inside
# requests use, saving the ~7.5s raster build + unified A*. Untagged raw-coordinate # _spatial_eligible_modes gates out wilderness/mountain false positives, so a relaxed
# clicks now qualify via the tight-snap path; the relaxed (<=100m) snap is excluded so # (<=100m) snap only grants vehicle on benign flat ground (lot/shoulder/field) where a
# an off-road click isn't silently re-snapped to the road. Boundary-mode MVUM # pure road route is the right answer. Hands off to the same inline-Valhalla path
# exclusions aren't applied here (urban roads aren't MVUM-gated). # explicit vehicle requests use, saving the ~7.5s raster build + unified A*. Boundary-mode
if (self._bypass_eligible(start_lat, start_lon, start_category, snap_cache) # MVUM exclusions aren't applied here (urban roads aren't MVUM-gated).
and self._bypass_eligible(end_lat, end_lon, end_category, snap_cache)): if "vehicle" in start_eligible and "vehicle" in end_eligible:
_bt0 = time.perf_counter() _bt0 = time.perf_counter()
bypass = self._route_D_network_only(start_lat, start_lon, end_lat, end_lon, "vehicle") bypass = self._route_D_network_only(start_lat, start_lon, end_lat, end_lon, "vehicle")
if bypass.get("status") == "ok": if bypass.get("status") == "ok":

View file

@ -1405,15 +1405,32 @@ def test_route_auto_untagged_tight_snap_fires_bypass(monkeypatch):
assert out["summary"]["auto_bypass"] is True assert out["summary"]["auto_bypass"] is True
def test_route_auto_untagged_relaxed_snap_skips_bypass(monkeypatch): def test_route_auto_untagged_relaxed_snap_fires_bypass(monkeypatch):
# PR #48: a relaxed (50m) snap that still grants "vehicle" (paved + flat-terrain grace in
# _spatial_eligible_modes) now fires the bypass -- we trust _auto_eligible_modes's judgment.
r = object.__new__(OffrouteRouter) r = object.__new__(OffrouteRouter)
monkeypatch.setattr(OffrouteRouter, "_spatial_eligible_modes", _spatial_relaxed_paved) monkeypatch.setattr(OffrouteRouter, "_spatial_eligible_modes", _spatial_relaxed_paved)
monkeypatch.setattr(OffrouteRouter, "_fetch_auto_rasters", _bp_fetch_should_not_run)
monkeypatch.setattr(_p4router.requests, "post", lambda *a, **k: _BypassOKResp())
out = r._route_auto(42.5558, -114.4701, 42.5644, -114.4631, "pragmatic") # no categories
assert out["status"] == "ok"
assert out["selected_mode"] == "vehicle"
assert out["summary"]["auto_bypass"] is True
def test_route_auto_untagged_no_vehicle_in_eligibility_skips_bypass(monkeypatch):
# Safety gate (preserved from PR #47 test 6): when _spatial_eligible_modes withholds
# "vehicle" -- e.g. _is_terrain_flat rejected a non-flat wilderness click near a road --
# the bypass declines and the unified flow runs (preserving any walk-then-drive plan).
r = object.__new__(OffrouteRouter)
monkeypatch.setattr(OffrouteRouter, "_spatial_eligible_modes",
lambda self, lat, lon, cache: frozenset({"foot"}))
monkeypatch.setattr(OffrouteRouter, "_route_D_network_only", monkeypatch.setattr(OffrouteRouter, "_route_D_network_only",
lambda *a, **k: (_ for _ in ()).throw(AssertionError("D must not run"))) lambda *a, **k: (_ for _ in ()).throw(AssertionError("D must not run")))
monkeypatch.setattr(OffrouteRouter, "_fetch_auto_rasters", _bp_fetch_sentinel) monkeypatch.setattr(OffrouteRouter, "_fetch_auto_rasters", _bp_fetch_sentinel)
out = r._route_auto(42.5558, -114.4701, 42.5644, -114.4631, "pragmatic") # no categories out = r._route_auto(42.5558, -114.4701, 42.5644, -114.4631, "pragmatic") # no categories
assert out["status"] == "error" assert out["status"] == "error"
assert "Failed to load terrain" in out["message"] # relaxed snap rejected -> unified flow assert "Failed to load terrain" in out["message"] # no vehicle -> unified flow
def test_route_auto_e2e_http_in_town_fires_bypass(client, monkeypatch): def test_route_auto_e2e_http_in_town_fires_bypass(client, monkeypatch):