Commit graph

1 commit

Author SHA1 Message Date
d8de7ff777
MVUM Layer 2c: exclude_polygons for closure-avoiding routing (#24)
Backend-only. For strict-boundary motorized routes, turn MVUM-closed segments into
buffered Valhalla exclude_polygons so routing actively avoids them. pragmatic/emergency
keep Layer-1 annotate-only behavior; foot is never excluded.

- mvum_exclude.py (new): build_exclude_polygons(start,end,mode,spatial_index,on_date,
  boundary_mode) -> GeoJSON Polygon dicts, or None when not applicable (foot / non-strict
  / no index / unmappable mode). Queries the Layer-0 index over a 5km-expanded bbox,
  keeps only features closed to the mode (via mvum_annotate._status_for_feature), buffers
  each ~15m (lat-corrected), emits one Polygon per part (MultiPolygon split). Caps at 500
  with a warning.
- router.py: route() computes self._exclude_polygons once per call (after mode validation;
  has boundary_mode), so each Auto candidate probes against its own exclusions. Both
  Valhalla /route builders (_route_D_network_only and _valhalla_route) inject
  exclude_polygons in array-of-rings form (outer ring per Polygon); omitted when None/empty.
- 6 tests: strict builds polygons, pragmatic/emergency/foot -> None, open not excluded,
  1000 closed -> capped at 500 + warning.

No frontend changes (Layer-1 closure warning still fires for residual closures). Wilderness
pathfinder, Layer-0 index, and Layer-1 annotation untouched.

Co-authored-by: Matt <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 19:54:28 -06:00