Commit Graph
12 Commits
Author SHA1 Message Date
randy ede21454a2 Draw offline hiking trails sharing a path as parallel lanes
CI / check (push) Successful in 22s
CI / deploy (push) Successful in 12s
Several marked routes running down one path drew as a single line, only
the topmost color visible. maplibre-gl-lanes puts each route in its own
lane; OSM relations already share exact vertices, which is all it needs.
One LaneLayer across every picked country; click hit-testing and the
highlight move to queryLane/setHighlight.
2026-10-09 21:46:05 +02:00
randy 619f2293df Move Docker base image to Debian trixie for Java 21
Planetiler 0.10.2 needs Java 21+; bookworm's default-jre-headless (and
its backports) only goes up to 17, causing a real build to fail with
UnsupportedClassVersionError. trixie's default-jre-headless is Java 21.
2026-09-11 22:13:30 +02:00
randy d08ed41185 Replace offline basemap pipeline with Planetiler, unify online/offline styling
CI / check (push) Successful in 18s
CI / deploy (push) Successful in 2m43s
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.
2026-09-11 20:52:11 +02:00
randy 9223410b40 Swap flag emoji for real (square, bordered) SVG flags
CI / check (push) Successful in 21s
CI / deploy (push) Successful in 16s
Emoji flags are font glyphs, not shapes — no way to resize, border, or
tone them down to fit this app's controlled, hand-drawn-icon look
(same reasoning the topbar readout already settled earlier this
session). Vendored flag-icons' pre-cropped square SVGs (MIT) instead,
framed in a small rounded-square badge — the same convention
icons.js's MAP_MARKER_ICON already uses for framing a glyph, not a new
visual language.
2026-09-11 13:31:36 +02:00
randy f89dea5805 Build terrain.pmtiles from Mapterhorn instead of fetching tiles ourselves
CI / check (push) Successful in 18s
CI / deploy (push) Successful in 1m52s
Mapterhorn (mapterhorn.com, Protomaps-affiliated) publishes pre-built
Terrarium-encoded terrain as PMTiles: a global planet.pmtiles (z0-12)
plus ~450 regional chunks (z13+). Same pmtiles extract --bbox=...
mechanism offline.pmtiles already uses, just against their files —
confirmed live against their real manifest and the documented
Interlaken example. Replaces fetching every individual tile ourselves
(even after this session's earlier concurrency fix, still tens of
minutes for a real region) with 1-3 extract calls plus a merge when
the bbox spans more than one chunk: seconds, not minutes.

Removes CONCURRENT_TILE_FETCHES, write_terrarium_mbtiles, tile_range,
lng/lat_to_tile_x/y, fetch_terrarium_tile, and the sqlite3 gem
entirely — none of it is needed once the tiles arrive pre-packaged.

dem.js's point-elevation lookup (shadow.js's terrain-shadow overlay)
hardcoded a 256px PNG tile assumption that Mapterhorn's 512px WebP
tiles would have silently broken — now reads the actually-decoded
tile's own size and mime type instead of assuming either.
2026-09-11 12:26:03 +02:00
randy d72f8a3c94 Bundle go-pmtiles into the Docker image
CI / check (push) Successful in 18s
CI / deploy (push) Successful in 2m23s
The "Regenerate for current view" build was failing in production with
"could not run 'pmtiles'" — go-pmtiles was never actually installed
anywhere, just documented as something a developer runs by hand
locally (docs/development.adoc). Installs the static Linux binary from
go-pmtiles' own GitHub releases, architecture-matched via dpkg rather
than hardcoded amd64.

Verified the exact download/extract/exec sequence end-to-end outside
Docker (no daemon available in this sandbox to run a real build).
2026-09-11 11:47:31 +02:00
randy fba8ca10a2 Add contour lines to the Overlays panel via maplibre-contour
CI / check (push) Successful in 18s
CI / deploy (push) Successful in 12s
5th Overlays item, generated client-side from the same online Terrarium
DEM tiles Terrain shading already fetches (no offline fallback — the
plugin's DemSource has no public hook to route through the pmtiles://
protocol the offline basemap uses, so this quietly renders nothing
without a network, same as Radar/the Wikipedia layer).

A plain vector source/layer under MapLibre's own tile lifecycle, no
manual refetch-on-move code needed. Thresholds are the plugin's own
generic starting point, not yet tuned against real terrain. Labels
skipped for now (font-name matching across the online/offline styles'
own glyph sets adds real risk for a nice-to-have, not the actual ask).
2026-09-11 00:12:32 +02:00
randy c8b6dd2fb1 Use the National Park typeface for the topbar wordmark
CI / check (push) Successful in 17s
CI / deploy (push) Successful in 12s
Self-hosted Bold woff2 only (the one weight .topbar__brand renders at)
under public/vendor/national-park-typeface/ — a router-carved-signage
display face for the "MAPTOOL" heading, matching the uppercase/
letter-spaced treatment it already had. Everything else stays on the
system font stack; this is a wordmark swap, not a body-text one.

docs/nps-resources.adoc/third-party-notices.adoc updated to record it.
2026-09-10 23:50:19 +02:00
randy 96065b1237 Home button fits all of Slovakia; add an overview map, top-right
CI / check (push) Successful in 1m33s
CI / deploy (push) Successful in 27s
Home now fitBounds()s a country-wide bbox instead of resetting to
CENTER/ZOOM's Bratislava point, since Home resetting into the same
city you'd already be looking at wasn't useful.

The overview map is NPS's own overview plugin (npmap5-plugins, still
on an unmerged branch), vendored and converted from its UMD dist
build to a plain ES module. Patched one MapLibre API break found while
verifying it: the plugin reads map.transform (public in the MapLibre
~2.4 it targets) to relax the inset's polar pan limit; MapLibre 6 (this
app's vendored version) no longer exposes .transform at all, so it
threw on load. Guarded to skip that cosmetic adjustment when absent
instead.
2026-09-07 22:30:56 +02:00
randy 170af80cac Add a Home button and fill icon gaps from NPS's newer symbol library
CI / check (push) Successful in 42s
CI / deploy (push) Successful in 18s
Two things pulled in from github.com/nationalparkservice/npmap5-plugins:

- A "Home" button (public/vendor/npmap-home-button/, NPS's own MapLibre
  control) pinned to the app's CENTER/ZOOM, sitting top-left on the map. Now
  that the URL hash permalink can open the map at any view, "current view"
  and "the default view" aren't the same thing anymore, so a quick way back
  to the default is worth having.

- npmap5-plugins bundles a newer, actively-maintained version of the same
  NPS symbol-library already used for POI_ICONS (confirmed by its
  maintainer to be the designated replacement for the older standalone
  repo: nationalparkservice/npmap5-plugins#4), with a much larger icon
  vocabulary and a simpler CC0 (public domain) license. All 25 icons
  already in use came back byte-identical from the new source, so this
  just repoints their attribution — but it also has icons the old repo
  didn't: `forest` (POI_ICONS) is now the official "wilderness" pictogram
  instead of hand-drawn, and three of the five previously icon-less
  Services/Activities tags (wifi, mobile data coverage, winter/snow
  camping) now have real icons too. Only bakery and vehicle wash still
  have no NPS equivalent.
2026-09-07 19:45:19 +02:00
randy 0887ccbfe7 Drop the OsmAnd-recolor map theme, add offline labels and a lighter palette nudge
Remove osmand-style.js (the per-layer color-patching approach) and its
docs entirely — back to the plain OpenFreeMap "liberty" style online,
and protomaps-themes-base's stock theme offline as the base.

Offline maps previously had no text labels at all: the
protomaps-themes-base layers() call never passed a lang option, which
is required to include its label layers. Fixed, backed by vendored
Noto Sans Regular/Italic/Medium glyph PBFs (ranges 0-255 and 256-511
only — Basic Latin + Latin-1 Supplement + Latin Extended-A, enough for
accented Central European place names; other scripts won't render
offline). Verified against the actual offline.pmtiles vector layer
schema that the name/name:en/script fields this expects are present.

Also nudge a handful of OFFLINE_THEME color roles (background, water,
wood, buildings, the two road-importance tiers) towards the online
style's actual palette (sampled from its style JSON) so switching
Online/Offline doesn't look like two different apps — deliberately
partial, not the removed full recolor.
2026-08-25 22:38:56 +02:00
randy 5afb130c45 Switch to vector maps (MapLibre GL JS + PMTiles) and add RainViewer radar
Replace Leaflet/raster tiles with MapLibre GL JS: an online OpenFreeMap
style and an offline style built from a local PMTiles archive via
pmtiles.js and protomaps-themes-base (no glyphs/labels offline by
design, see docs/architecture.adoc). Frontend libraries are vendored
locally rather than loaded from a CDN so the app keeps working with no
internet access.

Also add an animated RainViewer precipitation radar overlay (toggle,
play/pause, scrub slider), matching the default time window of the
weather-radar-card Home Assistant integration.
2026-08-25 01:18:36 +02:00