Swap the pin marker for a rounded-square badge
CI / check (push) Successful in 43s
CI / deploy (push) Successful in 14s

The National Park Service frames its own map symbols (the icons already
vendored in for POI categories) in a rounded square, not a pin — pairing a
pin shape with NPS-style pictograms looked like two mismatched icon
conventions. Switched the marker to a rounded square to match.

This also simplifies the placement code: a pin has to anchor at its tip, so
the category glyph on top needed an offset computed from the pin/glyph
geometry to land in the pin's head. A square has no tip — both the badge and
the glyph layer just center directly on the coordinate with no offset math
at all.
This commit is contained in:
randy committed 2026-09-07 16:45:22 +02:00
1 parent 2a83bb10ca
commit 7de8428b05
3 files changed
+50 -64

No files matched your search

+22 -23
View File
@@ -219,38 +219,37 @@ the same local element name "icon" once REXML drops namespace
prefixes, so this specifically matches on namespace *URI*
(`https://osmand.net`), not local name, to avoid picking whichever
happens to come last in the file). Individual waypoints render as a
pin (`public/js/icons.js`'s `MAP_PIN_ICON`, the same path as the
existing `WAYPOINT_ICON` outline, filled instead of stroked) rather
rounded-square badge (`public/js/icons.js`'s `MAP_MARKER_ICON`) rather
than a plain circle — a flat colored dot turned out to look too much
like a base map style's own small circular POI icons, blending in
instead of reading as "your data"; a pin is a shape convention no base
map uses for its own points. It's colored via
`["coalesce", ["get", "color"], TRACK_COLOR]` (falling back to the
instead of reading as "your data". A rounded square rather than a
pin/teardrop: it matches how the National Park Service itself frames
these exact category symbols (below) on its own maps, so the two look
native together instead of like mismatched icon styles. It's colored
via `["coalesce", ["get", "color"], TRACK_COLOR]` (falling back to the
plain track color for a waypoint with no category, e.g. a hand-placed
GNSS pin) and anchored at its tip (`icon-anchor: "bottom"`, the
standard map-pin convention — the tip, not the shape's center, lands on
the actual coordinate). A small curated icon set
(`public/js/icons.js`'s `POI_ICONS`, covering the categories p4n2gpx
actually uses, not an exhaustive OsmAnd icon set) draws a white glyph
on top of the pin's head, in a symbol layer offset up from the shared
tip anchor by a size computed from the pin and glyph geometry
(`POI_ICON_OFFSET_Y` — both layers anchor to the same raster canvas
edge, so the offset is "how far above that shared anchor is the pin's
head-center, minus how far above it the glyph's own visual center
already sits at its own icon-size"), filtered to just the known keys
(anything else keeps the plain pin with no glyph, rather than a
GNSS pin) and — unlike a pin, which has to anchor at its tip — centered
directly on the coordinate with plain default anchoring, which also
means the category-glyph layer on top needs no offset math: both
layers just share the same center anchor at `[0, 0]`. A small curated
icon set (`public/js/icons.js`'s `POI_ICONS`, covering the categories
p4n2gpx actually uses, not an exhaustive OsmAnd icon set) draws a white
glyph on top of the badge for any waypoint whose `icon` matches a known
key (filtered out entirely for anything else, so an unrecognized icon
key just falls back to a plain colored badge rather than a
broken/missing image warning). Six of the seven glyphs are the
National Park Service's own map symbols
(`github.com/nationalparkservice/symbol-library`, BSD-licensed,
originally forked from Mapbox's Maki project) — a professional,
purpose-built icon set beats hand-drawing "fuel pump"/"picnic table"
glyphs from scratch; `forest` has no NPS equivalent (that set covers
facilities, not land cover) and stays hand-drawn. Both the pin and the
category glyphs are rasterized once per style load (`_registerPoiIcons`,
an SVG → `<img>` → `<canvas>` → `ImageData` round trip, since these
need to be real raster images for `map.addImage`) and registered as SDF
images — a single alpha shape MapLibre tints at render time via
`icon-color` rather than a fixed-color image. The points source itself
facilities, not land cover) and stays hand-drawn. Both the badge and
the category glyphs are rasterized once per style load
(`_registerPoiIcons`, an SVG → `<img>` → `<canvas>` → `ImageData` round
trip, since these need to be real raster images for `map.addImage`) and
registered as SDF images — a single alpha shape MapLibre tints at
render time via `icon-color` rather than a fixed-color image. The
points source itself
is created with
`cluster: true`; nearby points collapse into a stepped-radius,
sequential-blue circle sized by `point_count` below `clusterMaxZoom`,