Files
maptool/TODO.adoc
T
randy 9c45e7275c
CI / check (push) Successful in 2m16s
CI / deploy (push) Successful in 11s
Add a Hiking trails overlay (Waymarked Trails, online only)
New Overlays panel toggle, same plain on/off shape as Contour lines —
raster tiles from waymarkedtrails.org, which already color each route
by its OSM colour tag (the KST/KČT paint-blaze colors used in
Slovakia/Czechia, plain red elsewhere), so no styling work needed here.

Online only for now; offline (baked into offline.pmtiles) needs a
custom Planetiler profile for route relations, deferred until there's
a route planner/router to pair it with.
2026-09-12 22:36:10 +02:00

12 KiB
Raw Blame History

TODO — implementation ideas

Ideas for offline use in a camper van. Implement incrementally, grouped by topic.

The local server has access to both the vehicle’s hardware and offline data — the vision is to grow it into a complete offline control center: resources, data, and independence from connectivity.

Offline data and cartography

  • ✓ Offline vector tiles (PMTiles/MBTiles) for Europe/world via Planetiler or MapTiler — Geofabrik per-country extracts, osmium merge, Planetiler’s default OpenMapTiles profile straight to PMTiles (lib/maptool/pmtiles_builder.rb); offline now shares the exact same style/palette as online (ONLINE_STYLE_PATCH) instead of a separate protomaps-schema theme

  • ✓ Shaded relief / DEM layer — hillshade toggle in the sidebar, sourced from public Terrarium tiles online; reads data/terrain.pmtiles for offline if one’s been generated (see docs/development.adoc), otherwise the toggle is online-only for now

    • ❏ Terrain slope readout for parking (numeric, not just visual shading)

  • ❏ Contour lines from OSM for hikes and mountain passes

  • ✓ Hiking trail overlay — Waymarked Trails raster tiles (public/js/hiking_trails.js), colored per-route by the OSM colour tag they already render (the KST/KČT paint-blaze colors in Slovakia/Czechia, plain red elsewhere), so no styling logic needed here. Online only for now — an offline copy (baked into offline.pmtiles, needing a custom Planetiler profile for route relations) is deferred until there’s a route planner/router to pair it with

  • ✓ Overpass/OSM scripts to extract POIs (drinking water, dump stations, LPG, public toilets, laundromats, shops, springs) — rake overpass:pois, see docs/development.adoc; writes a .geojson to drop in data/gpx/ or upload. Also runnable from inside the app itself now, see the import plugins entry below (plugins/overpass-pois wraps this same query). Each category now carries a real POI_ICONS glyph and color (not p4n2gpx’s plain red marker) plus a popup description built from opening_hours/operator/website tags

  • ✓ Import plugins: a pluggable way to add more data sources (Park4Night, iOverlander, Freecampsites, …​) without their scrapers necessarily living in this (public) repo — sidebar icon (logged in only) lists whatever’s under plugins/, "Run for this area" uses the current map viewport as the bbox, no separate area-picker needed. Contract: a plugin.json manifest + a script that reads --south/--west/--north/--east and prints a GeoJSON FeatureCollection to stdout (lib/maptool/plugins.rb, GET /api/plugins, POST /api/plugins/:name/run) — output saved the same way an upload would be. plugins/overpass-pois ships as the reference example; a private/ToS-sensitive scraper just drops its own directory in locally and is never `git add`ed

    • ✓ Park4Night — private plugin (data/plugins/p4n2gpx/, outside this repo per the "ToS-sensitive scraper" note above); iOverlander/Freecampsites still open, same story

    • ✓ A private plugin’s own dependencies now have somewhere to live too: data/plugins/ is under the persistent data/ bind mount (survives a redeploy, unlike build/), and docs/deployment.adoc documents the convention

  • ✓ Kiwix/ZIM offline Wikipedia linked to POI GPS coordinates — proxied through this app (GET /kiwix/* in app.rb) rather than a direct link to kiwix-serve — production sits behind a reverse proxy that only forwards to this app, so no address exists for a browser to reach kiwix-serve at directly; kiwix-serve runs with --urlRootLocation=/kiwix so its own emitted links already match. KIWIX_URL + GET /api/kiwix reachability check, same optional-integration pattern as offline.pmtiles/terrain.pmtiles; docker-compose.yaml now runs a kiwix service, ZIM not included (see docs/development.adoc for where to get one)

    • ✓ Replaced the old per-popup "Nearby on Wikipedia" link (one POI at a time, easy to miss) with a standalone "Wikipedia" layer under Tracks & Points — a live GET /api/kiwix/nearby refetch on every pan/zoom, not a saved file. kiwix-serve’s own geo search never echoes back a result’s coordinates, so Maptool::Kiwix.nearby fetches each matching article’s own page too and reads its <meta name="geo.position"> tag — verified against the real production ZIM (~1.6s for a 30-result page; tried parallelizing those fetches with threads, no measured gain, kept sequential)

  • ✓ Cache weather forecast when temporarily connected — Open-Meteo 3-day forecast in the Radar flyout, last successful fetch cached in localStorage as a fallback when offline

    • ✓ Cache the radar tile images too — public/sw.js, network-falling-back-to-cache for RainViewer tile requests, registered from layout.erb

NPS visual style

  • ✓ Map Park4Night/OSM place types to NPS pictograms (campground, primitive camp, drinking water, dump station, viewpoint, picnic table) for instant recognition without reading text — verified against real p4n2gpx exports (data/gpx/p4n_*.gpx, ~5000 waypoints, 15 distinct <type> values): every one already resolves to a registered POI_ICONS key, 0 waypoints fall back iconless. Drinking water/dump station aren’t standalone p4n place types (they’re description tags on a camping spot, already shown via PARK4NIGHT_TAGS); viewpoint doesn’t appear in these exports but has an icon (tourism_viewpoint) ready if it ever does

  • ❏ Restyle popovers, side panels, and point detail views after the NPS Unigrid layout system (Massimo Vignelli) with Frutiger/Rawlinson Roadside-style typography

    • ✓ Top black banner (full width): "MAPTOOL" on the left, live map-center coordinates in the center, offline-data status dot on the right, white sans-serif type — DEM elevation and a hamburger menu skipped (no DEM layer yet; sidebar isn’t mobile-collapsed, so nothing for a hamburger to reveal)

    • ❏ Point detail/sidepanel: black header banner with white location name and an NPS pictogram in the corner; amenities (water, waste, power, slope) shown as a pictogram grid, no extra text; action buttons for "route here" (Valhalla), "start leveling", "save offline"

    • ✓ Filter panel as a "Unigrid Matrix" — an icon grid to toggle categories on/off, styled like the legend on an official NPS paper map, instead of plain dropdowns

  • ❏ Custom vector style (MVT/MapLibre) using the NPS color palette — muted natural tones for forests, water, and contours — so POIs and routes stand out at high zoom

    • ❏ Landuse & protections: distinct styling for national parks, nature reserves (translucent green/gray-green), military zones, and private land (important for wild camping)

    • ❏ OpenTopoMap-style fill-pattern texture for forest (tree icons) and meadow/pasture (grass texture) landcover, instead of flat fill colors — Liberty’s own sprite (public/vendor/liberty-sprite/) only has a wetland dot pattern, no tree/grass, so this needs custom pattern images added to the sprite sheet; works offline and online alike since it’s just a style/sprite change, unlike pulling in OpenTopoMap’s own raster tiles (online-only, restrictive tile-usage policy, wouldn’t match the NPS palette)

    • ✓ Elevation-tinted terrain — a color-relief layer (hypsometric tint, this app’s own green→brown→gray palette) under the hillshade layer, same "Terrain shading" toggle

    • ✓ Road hierarchy: clearly distinguish paved roads from unpaved/gravel/track — critical for knowing if the camper can get there

Main menu reorganization (4 modules)

  • ❏ Explorer: place filters (Park4Night + OSM layers: water, waste, LPG, showers); map layers (contours, hillshade, satellite cache)

  • ❏ Navigation & route: offline router (Valhalla) with vehicle dimensions (height, weight, width); route elevation profile and isochrones

  • ❏ Offline hub: manager for downloaded PMTiles (country vector maps); downloaded Wikipedia archives; cached radar and weather

  • ❏ Camper & HW: level gauge (wheel-chock leveling); solar calculator (sun path on the map); telemetry (Victron / Home Assistant)

Custom layers & data

  • ✓ GPX/GeoJSON drag-and-drop import (Wikiloc, Komoot, own GPX tracks — also FIT), auto-styled by category with a generated elevation profile — KML not supported (only GPX/FIT/GeoJSON/.zip)

  • ✓ User overlay: offline drawing of custom points with notes (e.g. "turning space for a long vehicle", "narrow gate", "good swimming spot") — one click on the map, pick or name a .geojson layer, saved into the same GpxStore the Tracks panel already reads (so visibility/popup come for free)

    • ✓ Save a distance/area shape as a note too — Measure already draws these by hand, so a "Save" button there (not a second click-to-draw UI in the notes tool) reuses that instead of duplicating it; both share one NoteSaveForm (notes.js). gpx.js’s `_addLayers now renders Polygon and note-flagged LineString features (fill/outline, dashed line), not just points

    • ✓ Edit/delete individual notes from their popup (logged-in only) — targets a feature by a client-generated properties.id (GpxStore#update_feature/#delete_feature), not array position

    • ✓ Measure’s vertices are draggable (mousedown + move, event.preventDefault() to stop the map’s own drag-pan) and deletable (click to select — shown in yellow — then Delete/Backspace)

    • ✓ Fixed: a note saved before properties.id existed (the earliest test notes) had no Edit/Delete-able target — the popup no longer offers them without an id, and rake gpx:backfill_note_ids assigns one to any pre-existing Note feature missing it

    • ✓ Title + body split (name in the black header, body in a separate field) with light self-authored markdown (bold, italic, auto-linked URLs) in the body — a new, separate formatNoteBody (not formatDescription, which stays plain/untrusted-safe for uploaded GPX/park4night content per docs/nps-resources.adoc’s earlier markdown-rendering call)

    • ✓ Gated behind login: NotesControl isn’t added to the map at all when logged out, Measure’s "Save as note" button is hidden (Measure itself stays usable either way)

    • ✓ The clicked point stays marked on the map while the note form is open (a plain Marker, removed on save/cancel/deactivate) — it was disappearing back into the flat map with nothing showing where the note would land

    • ✓ Icon picker for point notes (a grid in the save form) — extends POI_ICONS with more of the symbols PARK4NIGHT_TAGS already vendors (water, dump station, toilets, playground, viewpoint, swimming, fishing, climbing, hiking, …), reusable as real marker-badge glyphs, not just inline tag icons. Hidden for a Measure-drawn line/polygon note — no single spot for a badge to sit at

    • ✓ Fixed: the Save button’s own blue background was losing to .notes-panelactions button’s gray — same class-vs-class+element specificity trap as `.gpx-panelaction[hidden] already has a comment about elsewhere in this file, just not yet applied here

    • ✓ Fixed: the Unigrid Matrix category filter only re-sliced the points source (_applyCategoryFilter) — toggling the "Note" category off hid point notes but not polygon/line ones sharing that category. _linesByPath now tracks those alongside _pointsByPath, re-sliced/scanned the same way

  • ❏ Offline satellite tile caching (e.g. ESRI) for a selected route area — key for judging surface quality and obstacles when wild camping

Nice to have (later)

Deprioritized for now — revisit after the sections above land.

Vanlife features

  • ❏ Offline routing (Valhalla/OSRM) with vehicle parameters (height, weight, width)

  • ❏ Solar calculator — sun path for location/date, shadows from surroundings, camper orientation

HW integration

  • ❏ Level gauge from IMU (ESP32/RPi) — camper tilt, wheel-chock leveling calculation

  • ❏ Victron/Home Assistant via MQTT or WebSocket — battery SoC, tank levels, temperatures

  • ❏ Plot GPS track with historical battery/speed data

Admin / ops tooling

  • ❏ Offline build log readability — a failed pmtiles/terrain build currently surfaces as one ~500k-character line; format it for the web UI instead (e.g. per-country/state name + status, not the raw combined stdout/stderr dump)

  • ❏ Expose the build log via an API endpoint, not just embedded in the admin page

  • ❏ Document all API endpoints somewhere and make them easy to browse (status of each) — maybe a status page, login-gated