perf(offroute): tighter wilderness bbox (5 entry points, 1.5km pad)

The wilderness bbox covered origin + 10 nearest entry points + 5km pad, giving
11-17km grids regardless of route distance. Shrink to origin + 5 nearest entry points
(MAX_ENTRY_POINTS 10->5 at the three scenario callers) + 1.5km pad (padding 0.05->0.015
in _pathfind_wilderness). Typical bbox drops to ~3-5km/side -> roughly 10x fewer cells
and a proportional A*/raster speedup. MAX_BBOX_DEGREES=2.0 absolute clamp unchanged.

2 tests: _route_A slices entry points to 5; _pathfind_wilderness bbox pad is 0.015 deg.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-25 15:40:23 +00:00
commit 46d3077c35
2 changed files with 66 additions and 6 deletions

View file

@ -933,7 +933,7 @@ class OffrouteRouter:
valid_highways = MODE_TO_VALID_HIGHWAYS.get(mode)
# Find entry points near start, filtered by mode
MAX_ENTRY_POINTS = 10
MAX_ENTRY_POINTS = 5 # tighter wilderness bbox: origin + 5 nearest entry points
entry_points = self.entry_index.query_radius(
start_lat, start_lon, DEFAULT_SEARCH_RADIUS_KM, valid_highways
)
@ -1013,7 +1013,7 @@ class OffrouteRouter:
valid_highways = MODE_TO_VALID_HIGHWAYS.get(mode)
# Find entry points near END (destination)
MAX_ENTRY_POINTS = 10
MAX_ENTRY_POINTS = 5 # tighter wilderness bbox: origin + 5 nearest entry points
entry_points = self.entry_index.query_radius(
end_lat, end_lon, DEFAULT_SEARCH_RADIUS_KM, valid_highways
)
@ -1091,7 +1091,7 @@ class OffrouteRouter:
}
valid_highways = MODE_TO_VALID_HIGHWAYS.get(mode)
MAX_ENTRY_POINTS = 10
MAX_ENTRY_POINTS = 5 # tighter wilderness bbox: origin + 5 nearest entry points
# Find entry points near START
entry_points_start = self.entry_index.query_radius(
@ -1194,13 +1194,15 @@ class OffrouteRouter:
{"status": "ok", "coords": [...], "stats": {...}, "entry_point": {...}}
or {"status": "error", "message": "..."}
"""
# Build bbox - only include origin and entry points, NOT distant destination
# The destination is handled by Valhalla, wilderness only needs to reach entry points
# Build a tight bbox around origin + the (<=5) nearest entry points, NOT the distant
# destination (Valhalla handles the network leg). A small pad keeps the pathfinder
# off the grid edge; typical spans land ~3-5 km/side. MAX_BBOX_DEGREES is the
# absolute safety clamp, unchanged.
MAX_BBOX_DEGREES = 2.0
all_lats = [origin_lat] + [p["lat"] for p in entry_points]
all_lons = [origin_lon] + [p["lon"] for p in entry_points]
padding = 0.05
padding = 0.015 # ~1.5 km
bbox = {
"south": min(all_lats) - padding,
"north": max(all_lats) + padding,

View file

@ -765,3 +765,61 @@ def test_signed_grade_at_max_threshold():
expected = 30.0 * 3.6 / _speed_kmh(mg, 0, 6.0, mg) # penalty = 1.0 at threshold
assert idx == 0
assert abs(cost - expected) < 1e-6
# ── Tighter wilderness bbox (#20): 5 entry points + 1.5 km pad ─────────────
def test_route_a_slices_entry_points_to_five(monkeypatch):
# query_radius yields 8; _route_A must hand _pathfind_wilderness at most 5.
eps = [{"lat": 44.0 + i * 0.001, "lon": -115.0, "highway_class": "track",
"name": str(i), "land_status": "open"} for i in range(8)]
captured = {}
def fake_pf(self, olat, olon, dlat, dlon, entry_points, boundary_mode, label, mode="foot"):
captured["n"] = len(entry_points)
return {"status": "error", "message": "stop"}
monkeypatch.setattr(OffrouteRouter, "_pathfind_wilderness", fake_pf)
r = object.__new__(OffrouteRouter)
r.entry_index = type("I", (), {
"has_entry_points": lambda self: True,
"query_radius": lambda self, *a, **k: list(eps),
})()
out = r._route_A_wilderness_to_network(44.0, -115.0, 44.5, -115.5, "foot", "pragmatic")
assert out["status"] == "error"
assert captured["n"] == 5
def test_pathfind_wilderness_bbox_pad_is_1_5km(monkeypatch):
# Capture the bbox passed to get_elevation_grid; with origin == the single entry point,
# the span is purely the padding -> 0.015 deg (~1.5 km) on each side.
bounds = {}
class _CapDEM:
def get_elevation_grid(self, south, north, west, east):
bounds.update(south=south, north=north, west=west, east=east)
return _np.zeros((10, 10), dtype=_np.float64), {"cell_size_m": 30.0}
def latlon_to_pixel(self, lat, lon, meta):
return (0, 0)
def pixel_to_latlon(self, row, col, meta):
return (44.0 + row * 0.001, -115.0 + col * 0.001)
monkeypatch.setattr(_router_mod, "compute_cost_multiplier_grid",
lambda *a, **k: _np.ones((10, 10), dtype=_np.float64))
monkeypatch.setattr(_router_mod, "astar_multigoal",
lambda *a, **k: (0, _np.array([[0, 0]], dtype=_np.int64), 5.0))
monkeypatch.setattr(OffrouteRouter, "_init_readers", lambda self: None)
r = object.__new__(OffrouteRouter)
r.dem_reader = _CapDEM()
r.friction_reader = type("F", (), {"get_friction_grid": lambda self, **k: _np.full((10, 10), 30, dtype=_np.uint8)})()
r.barrier_reader = type("B", (), {"get_barrier_grid": lambda self, **k: _np.zeros((10, 10), dtype=_np.uint8)})()
r.trail_reader = type("T", (), {"get_trails_grid": lambda self, **k: _np.zeros((10, 10), dtype=_np.uint8)})()
r.wilderness_reader = None
ep = [{"lat": 44.0, "lon": -115.0, "highway_class": "track", "name": "t", "land_status": "open"}]
out = r._pathfind_wilderness(44.0, -115.0, 44.0, -115.0, ep, "pragmatic", "start", mode="foot")
assert out["status"] == "ok"
assert abs((bounds["north"] - 44.0) - 0.015) < 1e-9
assert abs((44.0 - bounds["south"]) - 0.015) < 1e-9
assert abs((bounds["east"] - (-115.0)) - 0.015) < 1e-9