trails/openspec/changes/planner-route-interactions/tasks.md
Ullrich Schäfer b080a15fb1
Add route interactions: click-to-split, drag-to-reshape, colored route rendering
- Enrich BRouter response with per-point 3D coordinates and segment boundary
  tracking (EnrichedRoute interface)
- ColoredRoute component: plain, elevation gradient (green→yellow→red), and
  surface color modes with invisible wide polyline for click targeting
- Click-to-split: click on route polyline inserts waypoint at nearest point,
  mapped to correct segment via boundary indices
- MidpointHandles: draggable CircleMarkers at route segment midpoints for
  reshaping, hidden below zoom 12, opaque on hover
- Color mode toggle (select) synced via Yjs routeData
- i18n keys for color mode labels (en + de)
- Unit tests for segment boundary tracking (13 tests)
- E2E tests for enriched route response and color mode toggle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:15:55 +01:00

2.7 KiB

1. BRouter Data Pipeline

  • 1.1 Modify mergeGeoJsonSegments to preserve 3D coordinates (lon, lat, ele) and track segment boundary indices
  • 1.2 Add EnrichedRoute interface with coordinates, segmentBoundaries, surfaces, and stats
  • 1.3 Store enriched route data (including segment boundaries) in Yjs routeData map
  • 1.4 Write unit test for segment boundary tracking across multi-waypoint routes

2. Route Splitting (click-to-insert)

  • 2.1 Make the route polyline clickable — add click event handler to route Polyline in PlannerMap
  • 2.2 On click, find nearest point on route geometry and determine which waypoint segment it belongs to (using segment boundaries)
  • 2.3 Insert new waypoint at the clicked position using Y.Array.insert(segmentIndex + 1, [waypoint])
  • 2.4 Add wider invisible polyline behind the route for easier click targeting (hit area)

3. Drag-to-Reshape (midpoint handles)

  • 3.1 Create MidpointHandles component — renders a CircleMarker at the geographic midpoint of each route segment
  • 3.2 Compute geographic midpoint from actual route geometry (not straight-line between waypoints)
  • 3.3 On drag end, insert waypoint at dropped position between the two adjacent waypoints
  • 3.4 Hide midpoint handles below zoom level 12
  • 3.5 Style handles: semi-transparent by default, opaque on hover, match waypoint color scheme

4. Route Coloring

  • 4.1 Create ColoredRoute component — renders multiple short L.Polyline segments with per-point colors
  • 4.2 Implement elevation gradient: normalize elevation values to 0-1 range, map to green→yellow→red
  • 4.3 Implement surface coloring: map BRouter surface type strings to a fixed color palette
  • 4.4 Add color mode state to Yjs routeData map ("plain" | "elevation" | "surface")
  • 4.5 Add color mode toggle button to session header (icon or dropdown)
  • 4.6 Fall back to plain mode when surface data is unavailable
  • 4.7 Add i18n keys for color mode labels (en + de)

5. Integration

  • 5.1 Replace single Polyline in PlannerMap with ColoredRoute + click handler + MidpointHandles
  • 5.2 Ensure click-to-split and drag-to-reshape work alongside no-go area drawing mode (disable route interactions when drawing)
  • 5.3 Update ElevationChart hover sync to work with the new colored route

6. Verify

  • 6.1 E2E test: click on route inserts waypoint at correct position
  • 6.2 E2E test: color mode toggle switches between plain/elevation/surface
  • 6.3 Unit test: segment boundary computation with 2, 3, and 5 waypoints
  • 6.4 Verify midpoint handles reposition after route recomputation
  • 6.5 Verify all interactions sync correctly between two browser tabs