Offline tiles were built from Protomaps' own basemap schema, needing a completely separate hand-tuned theme (protomaps-themes-base + OFFLINE_THEME) from the online Liberty style's ONLINE_STYLE_PATCH — the two could never be made to match exactly no matter how much either side got tuned (today's session found and fixed several mismatches: building opacity, park boundaries, road casings, road widths). Offline.pmtiles is now built with Planetiler's default OpenMapTiles profile against Geofabrik per-country OSM extracts (osmium-merged when more than one country is selected), the same vector schema Liberty already expects. offlineStyle() now clones the same Liberty JSON (vendored as a local snapshot for reliability with no internet) and applies the identical ONLINE_STYLE_PATCH, just repointed at local PMTiles/glyphs/sprite — one palette instead of two, correct on both sides by construction. Also vendors Liberty's icon sprite for the first time (offline had none before), adds Java/osmium-tool/planetiler.jar to the Docker image, and removes the now-unused protomaps-themes-base dependency and the theme-comparison debug page that found today's bugs.
73 lines
11 KiB
Plaintext
73 lines
11 KiB
Plaintext
= 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
|
|
|
|
* [x] 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
|
|
* [x] 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
|
|
* [x] 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
|
|
* [x] 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
|
|
** [x] Park4Night — private plugin (`data/plugins/p4n2gpx/`, outside this repo per the "ToS-sensitive scraper" note above); iOverlander/Freecampsites still open, same story
|
|
** [x] 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
|
|
* [x] 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)
|
|
** [x] 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)
|
|
* [x] 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
|
|
** [x] 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
|
|
|
|
* [x] 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
|
|
** [x] 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"
|
|
** [x] 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)
|
|
** [x] 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
|
|
** [x] 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
|
|
|
|
* [x] 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)
|
|
* [x] 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)
|
|
** [x] 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
|
|
** [x] 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
|
|
** [x] 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)
|
|
** [x] 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
|
|
** [x] 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)
|
|
** [x] 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)
|
|
** [x] 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
|
|
** [x] 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
|
|
** [x] Fixed: the Save button's own blue background was losing to `.notes-panel__actions button`'s gray — same class-vs-class+element specificity trap as `.gpx-panel__action[hidden]` already has a comment about elsewhere in this file, just not yet applied here
|
|
** [x] 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
|