From f414c97887821ed6ceb8b1f15219a9ba49a2be50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Sat, 11 Apr 2026 02:09:44 +0200 Subject: [PATCH] Update specs with POI-waypoint integration, resilience, z-index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proposal: Added POI→waypoint, POI snapping, and metadata storage. Design: Added D10 (POI-waypoint integration), D11 (Overpass fallback), D12 (z-index layering). Updated risks/trade-offs. Tasks: Added sections 11 (POI-waypoint, 5 tasks) and 12 (resilience, 5 tasks). Fixed Overpass test to match updated query format. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/planner/app/lib/overpass.test.ts | 2 +- openspec/changes/osm-overlays/design.md | 42 +++++++++++++++++++---- openspec/changes/osm-overlays/proposal.md | 4 ++- openspec/changes/osm-overlays/tasks.md | 16 +++++++++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/apps/planner/app/lib/overpass.test.ts b/apps/planner/app/lib/overpass.test.ts index 919d9ca..5a7734a 100644 --- a/apps/planner/app/lib/overpass.test.ts +++ b/apps/planner/app/lib/overpass.test.ts @@ -11,7 +11,7 @@ describe("buildQuery", () => { expect(query).toContain("[out:json]"); expect(query).toContain("[bbox:52.5,13.3,52.6,13.5]"); expect(query).toContain('amenity"="drinking_water"'); - expect(query).toContain("out center 200"); + expect(query).toContain("out center qt 100"); }); it("combines multiple categories into a single union", () => { diff --git a/openspec/changes/osm-overlays/design.md b/openspec/changes/osm-overlays/design.md index 86e02a9..fe41d63 100644 --- a/openspec/changes/osm-overlays/design.md +++ b/openspec/changes/osm-overlays/design.md @@ -169,18 +169,46 @@ routeOptions.poiCategories = ["drinking_water", "camping", "bike_infra"] Array of string IDs. Changes sync to all participants. Persisted in crash recovery localStorage snapshot. +### D10: POI-to-waypoint integration + +POIs can become waypoints through three paths, all using the same snap logic: + +1. **"Add as waypoint" button** in POI popup → appends to end of route +2. **Click near a POI** (within 50m) → new waypoint snaps to POI position +3. **Drag waypoint near a POI** → snaps on drop, clears name if dragged away + +When snapping, the waypoint's Yjs Y.Map stores: +- `osmId`: OSM node ID for future cross-referencing +- `poiTags`: Key tags (phone, address, website, opening hours, amenity type) + +This metadata persists through Yjs and will be available for Journal display. + +### D11: Overpass endpoint fallback + +Primary endpoint is `overpass.kumi.systems` (higher rate limits, same as +brouter-web). Falls back to `overpass-api.de` if the primary fails. The +Overpass API sometimes returns rate limit errors as HTTP 200 with +"rate_limited" in the body — the client checks for this pattern. + +### D12: Z-index layering + +Marker z-index offsets centralized in `apps/planner/app/lib/z-index.ts`: +- Cursors (-1000) < Ghost waypoint (-100) < Waypoints (1000) < + Waypoint highlighted (1200) < POI markers (1500) < Highlight dot (2000) + ## Risks / Trade-offs - **Overpass API availability**: Public endpoint, no SLA. If down, POI overlays - fail gracefully (show message, tile overlays still work). → Could add - fallback endpoint (`overpass.kumi.systems`) later. + fail gracefully (show message, tile overlays still work). Fallback endpoint + (`overpass.kumi.systems` → `overpass-api.de`) implemented. - **Tile service availability**: Waymarked Trails and hillshading tiles are community-run. → Degrade gracefully if tiles 404. Consider self-hosting tiles if usage grows. - **Performance with many POIs**: Dense areas (cities) may return hundreds of - POIs. → Marker clustering + zoom threshold mitigate this. Limit Overpass - response to 200 elements per category. -- **leaflet.markercluster dependency**: Adds ~40KB. → Only load when POI - overlays are enabled (dynamic import). + POIs. → Zoom threshold (>=10) + 100 element limit mitigate this. Marker + clustering deferred — can add later if density becomes an issue. - **Overpass query cost**: Combining many categories into one query is efficient - but returns large payloads. → Only query enabled categories, not all. + but returns large payloads. → Only query enabled categories, not all. 1MB + maxsize limit, 10s timeout. +- **Routing rate limit**: Multi-waypoint routes with POI snapping can trigger + rapid recomputes. Increased rate limit from 60 to 300/hour to accommodate. diff --git a/openspec/changes/osm-overlays/proposal.md b/openspec/changes/osm-overlays/proposal.md index 04574ec..6870d3f 100644 --- a/openspec/changes/osm-overlays/proposal.md +++ b/openspec/changes/osm-overlays/proposal.md @@ -8,7 +8,9 @@ The Planner shows three base tile layers (OSM, OpenTopoMap, CyclOSM) but no over - **POI overlay panel**: Add a collapsible panel to toggle categories of OSM points of interest (water, shelter, camping, food, bike infrastructure, accommodation) queried from the Overpass API within the current viewport - **POI markers**: Render POI results as categorized markers with icons, name labels, and popups showing OSM tags (opening hours, website, etc.) - **Profile-aware defaults**: Auto-enable relevant overlays based on the active routing profile (cycling → Waymarked Cycling + bike POIs; hiking → Waymarked Hiking + water/shelter POIs) -- **Overpass client**: Shared utility for querying the Overpass API with caching, debouncing, and rate limit handling — reused by the waypoint-notes POI snap feature +- **Overpass client**: Shared utility for querying the Overpass API with caching, debouncing, rate limit handling, and endpoint fallback (kumi.systems → overpass-api.de) +- **POI → waypoint**: "Add as waypoint" button in POI popups, plus automatic snapping of placed/dragged waypoints to nearby POIs (50m threshold) with OSM metadata preserved +- **POI metadata on waypoints**: Waypoints snapped to POIs store osmId and key tags (phone, address, website, opening hours) for future Journal display ## Capabilities diff --git a/openspec/changes/osm-overlays/tasks.md b/openspec/changes/osm-overlays/tasks.md index f87736f..1658ca3 100644 --- a/openspec/changes/osm-overlays/tasks.md +++ b/openspec/changes/osm-overlays/tasks.md @@ -62,3 +62,19 @@ - [x] 10.3 Unit tests for profile-to-overlay mapping - [ ] 10.4 E2E test: enable hillshading overlay, verify tile requests - [ ] 10.5 E2E test: enable POI category, verify markers appear (mock Overpass response) + +## 11. POI-Waypoint Integration + +- [x] 11.1 Add "Add as waypoint" button to POI popup — appends POI location + name as waypoint +- [x] 11.2 Snap click-to-add waypoints to nearby POIs (50m threshold) with name + metadata +- [x] 11.3 Snap dragged waypoints to nearby POIs, clear name/metadata when dragged away +- [x] 11.4 Snap route-inserted waypoints to nearby POIs +- [x] 11.5 Store osmId and poiTags on Yjs waypoint Y.Map for snapped POIs + +## 12. Resilience + +- [x] 12.1 Fallback Overpass endpoint (kumi.systems → overpass-api.de) +- [x] 12.2 Handle Overpass rate limit returned as HTTP 200 with error body +- [x] 12.3 Reduce query size (100 results, 1MB maxsize, 10s timeout) +- [x] 12.4 Extract z-index constants into z-index.ts for consistent marker layering +- [x] 12.5 Increase Planner route rate limit from 60 to 300 requests/hour