bc463188d5
feat(offroute): Phase O4 — multi-mode cost functions (foot/mtb/atv/vehicle)
...
- Add ModeProfile dataclass for data-driven mode configuration
- Implement three speed functions:
* Tobler off-path hiking (foot)
* Herzog wheeled-transport polynomial (mtb/atv)
* Linear speed degradation (vehicle)
- Add WildernessReader for PAD-US Des_Tp=WA wilderness areas
- Mode-specific terrain friction overrides:
* Forest impassable for ATV/vehicle, high friction for MTB
* Wetland/mangrove impassable for all wheeled modes
- Trail access rules:
* Foot trails (value 25) impassable for ATV/vehicle
- Wilderness blocking for mtb/atv/vehicle modes
- Vehicle mode allows flat grassland/cropland traversal
- Memory optimization: limit entry points, constrain bbox size
- Update router to pass mode and wilderness to cost function
- Add vehicle to API mode validation
Validated all four modes with test route:
- foot: 0.46km off-network, 12.11km network, 89% on trail
- mtb: 0.47km off-network, 13.13km network, 90% on trail
- atv: 0.47km off-network, 12.81km network, 90% on trail
- vehicle: 0.46km off-network, 12.81km network, 89% on trail
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 14:11:56 +00:00
1a9dfc8f8d
feat(offroute): Phase O3b — trail entry index, Valhalla stitching, /api/offroute endpoint
...
Phase A: Trail Entry Point Index
- Extract highway endpoints from idaho-latest.osm.pbf using osmium + ogr2ogr
- Store 740,430 entry points in /mnt/nav/navi.db (SQLite with spatial index)
- Entry points by class: service (271k), footway (152k), residential (146k),
track (111k), path (26k), unclassified (16k), tertiary (9k), secondary (4k),
primary (4k), bridleway (15)
Phase B: Pathfinder → Valhalla Stitching (router.py)
- OffrouteRouter orchestrates wilderness pathfinding + Valhalla on-network routing
- Queries entry points within 50km (expanding to 100km if needed)
- MCP pathfinder routes to nearest reachable entry point
- Calls Valhalla pedestrian/bicycle/auto costing for on-network segment
- Returns GeoJSON FeatureCollection with wilderness + network + combined segments
Phase C: Flask Endpoint
- POST /api/offroute with start/end coordinates, mode, boundary_mode
- Returns GeoJSON route with per-segment metadata and turn-by-turn maneuvers
Validated: 42.35,-114.30 → Twin Falls downtown
- Wilderness: 0.5km, 9min | Network: 36km, 413min | Total: ~421min
- 21 turn-by-turn instructions, segments connect at entry point
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 13:44:34 +00:00
3293cb4238
feat(offroute): Phase O3a — trail burn-in, pathfinder seeks trail corridors
...
Trail friction REPLACES land cover friction where trails exist:
- Road (value 5): 0.1× friction
- Track (value 15): 0.3× friction
- Foot trail (value 25): 0.5× friction
TrailReader loads /mnt/nav/worldcover/trails.tif rasterized from OSM highways.
Validation shows trail-seeking behavior:
- On-trail travel: 17.3% → 98.7%
- Effort time: 1047 min → 155 min (-85.2%)
- Path travels farther but stays on roads for speed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 07:26:25 +00:00
e0eedcedfd
feat(offroute): Phase O2c — PAD-US barriers with three-mode boundary respect
...
- Add barriers.py: PAD-US raster reader + build_barriers_raster() function
- Rasterize PAD-US Pub_Access=XA (Closed) polygons to CONUS GeoTIFF
- Modify cost.py: boundary_mode parameter (strict/pragmatic/emergency)
- strict: private land = impassable (np.inf)
- pragmatic: private land = 5x friction penalty (default)
- emergency: private land barriers ignored
- Modify prototype.py: three-way comparison output
- Output: padus_barriers.tif at /mnt/nav/worldcover/ (144MB, ~33m resolution)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 06:56:36 +00:00
26d4bc7478
feat(offroute): Phase O2b — WorldCover friction integration, lake avoidance validated
...
- New friction.py: reads WorldCover friction VRT, resamples to match
elevation grid, provides point sampling for validation
- Modified cost.py: accepts optional friction array, multiplies Tobler
time cost by friction multiplier, inf for water/nodata (255/0)
- Modified prototype.py: loads friction layer, passes to cost function,
validates path avoids water cells (friction=255)
Validated on Idaho test bbox:
- Path avoids Murtaugh Lake (no water cells on path)
- Friction along path: min=10, max=20, mean=10.2
- Effort increased 3.4% vs Phase O1 due to friction multipliers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 06:33:45 +00:00
f2a0f81580
feat(offroute): Phase O1 foundation — PMTiles decoder, Tobler cost, MCP pathfinder prototype
...
- dem.py: Terrarium-encoded PMTiles tile reader with LRU cache
- Decodes WebP tiles from planet-dem.pmtiles
- Stitches tiles into numpy elevation grids for arbitrary bboxes
- Provides pixel-to-latlon coordinate conversion
- cost.py: Tobler off-path hiking cost function
- speed = 0.6 * 6.0 * exp(-3.5 * |grade + 0.05|) km/h
- Max slope cutoff: 40 degrees → impassable
- Returns time-to-traverse (seconds/cell) as cost metric
- prototype.py: Standalone validation on Idaho test bbox
- 43km × 80km bbox (~17M cells at 14m resolution)
- scikit-image MCP_Geometric Dijkstra pathfinder
- Outputs GeoJSON LineString with path metadata
- Validated: 61.6km path, 21.3 hours effort time
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-07 23:43:56 +00:00