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.
This commit is contained in:
randy committed 2026-09-07 19:45:19 +02:00
1 parent 481233c232
commit 170af80cac
6 files changed
+235 -39

No files matched your search

+40 -29
View File
@@ -75,25 +75,25 @@ export const MAP_MARKER_ICON = `
// the categories park4night actually uses (see waypoint_style in
// lib/maptool/gpx.rb), not an exhaustive OsmAnd icon set.
//
// Six of these are the National Park Service's own map pictograms
// (github.com/nationalparkservice/symbol-library, src/standalone/*-black-22),
// not hand-drawn — a professional, widely-recognized icon set built for
// These are the National Park Service's own map pictograms, not
// hand-drawn — a professional, widely-recognized icon set built for
// exactly this job (small monochrome map markers) beats reinventing "fuel
// pump"/"picnic table" glyphs from scratch. Used under that repo's license:
// pump"/"picnic table" glyphs from scratch. Pulled from
// github.com/nationalparkservice/npmap5-plugins's bundled `symbol-library`
// (src/<name>-22.svg) — an actively-maintained monorepo that's the
// designated replacement for the same org's older standalone
// `symbol-library` repo (confirmed by its maintainer:
// github.com/nationalparkservice/npmap5-plugins/issues/4), with a much
// larger icon vocabulary. CC0-licensed (public domain) — no attribution
// required.
//
// BSD License. Copyright (c) 2013, Mapbox, LLC. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the copyright notice and
// this list of conditions are retained.
//
// `forest` has no NPS equivalent (that set covers facilities, not land
// cover) and stays hand-drawn. All filled shapes — these render at ~14px on
// the map, where a hairline stroke disappears — and rasterized/used as SDF
// map icons (see gpx.js), so only the alpha shape matters, not the actual
// `currentColor` value.
// All filled shapes — these render at ~14px on the map, where a hairline
// stroke disappears — and rasterized (non-SDF; a plain colored raster, not
// tinted at render time, see gpx.js's _registerCategoryGlyphs) so only the
// alpha shape matters, not the actual `currentColor` value.
// src/standalone/bicycle-trail-black-22.svg — pulled out to its own constant
// since it's also used unrasterized, inline, as PARK4NIGHT_TAGS.vtt below.
// src/bicycle-trail-22.svg — pulled out to its own constant since it's also
// used unrasterized, inline, as PARK4NIGHT_TAGS.vtt below.
const BICYCLE_TRAIL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<circle cx="13.9" cy="3" r="2"/>
@@ -107,12 +107,12 @@ const BICYCLE_TRAIL_ICON = `
</svg>`;
export const POI_ICONS = {
// src/standalone/parking-black-22.svg
// src/parking-22.svg
amenity_parking: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M11.9,11c1.8,0,3.5-1.8,3.5-3.6S13.7,4,11.9,4h-5v7H11.9z M12.1,0C16.2,0,20,3.3,20,7.5c0,4.1-3.9,7.5-8.1,7.5h-5v7H3V0
H12.1z"/></svg>`,
// src/standalone/campground-black-22.svg
// src/campground-22.svg
tourism_camp_site: `
<svg viewBox="0 0 22 22" fill="currentColor">
<path d="M17,21L9.4,5.8L2,21H0v1h19v-1H17z M5,21l4.5-8.5L14,21H5z"/>
@@ -120,18 +120,18 @@ export const POI_ICONS = {
<polygon points="15.5,0 14.7,1.7 22,16 22,13 "/>
</svg>`,
// src/standalone/picnic-area-black-22.svg
// src/picnic-area-22.svg
leisure_picnic_table: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M22,11h-6l-2-5h4V4H4v2h4l-2,5H0v2h5l-2,5h2l2-5h8l2,5h2l-2-5h5V11z M8,11l2-5h2l2,5H8z"/></svg>`,
// src/standalone/gas-station-black-22.svg
// src/gas-station-22.svg
amenity_fuel: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M19,14.4L19,14.4v-1.5V6.2c0-0.7-0.4-1.3-0.9-1.8L15,1.5c-0.2,0-0.8,0.4-0.8,0.4c0,0.2,1.5,1.8,1.5,1.8v2.6
c0,0.9,0.8,1.8,1.7,1.8L18,7.9v5v1.7l1,5.1c0,0.8-0.9,1.3-1.5,1.3C17,21,16,20.5,16,20v-8.9C16,10,15.4,9,14.4,9H12V1h-1V0H3v1H2
v21h10V10.4h2.4c0.4,0,0.6,0.3,0.6,0.7V20c0,1.2,1.2,2,2.5,2c1.2,0,2.5-0.8,2.5-2C20,19.7,19,14.4,19,14.4z M18,7h-1V5h1V7z
M10.5,5.8L9.6,6.6H4.4L3.5,5.8V2.2l0.9-0.9h5.2l0.9,0.9V5.8z"/></svg>`,
// src/standalone/lodging-black-22.svg
// src/lodging-22.svg
tourism_hotel: `
<svg viewBox="0 0 22 22" fill="currentColor">
<polygon points="0,4 2,4 2,12 22,12 22,17 20,17 20,14 2,14 2,17 0,17 "/>
@@ -139,13 +139,11 @@ export const POI_ICONS = {
<circle cx="4.5" cy="6.5" r="1.5"/>
</svg>`,
// src/wilderness-22.svg
forest: `
<svg viewBox="0 0 24 24">
<path d="M12 2 18 12 15 12 19 19 5 19 9 12 6 12Z" fill="currentColor"/>
<rect x="10.5" y="19" width="3" height="3" fill="currentColor"/>
</svg>`,
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="18,18 13,15 17,15 13,11 16,11 12,7 15,7 12,4 14,4 11,0 8,4 10,4 7,7 10,7 6,11 9,11 5,15 9,15 4,18 10,18 10,22 12,22 12,18 "/></svg>`,
// src/standalone/bicycle-trail-black-22.svg
// src/bicycle-trail-22.svg
sport_cycling: BICYCLE_TRAIL_ICON,
};
@@ -213,6 +211,19 @@ const GUIDED_TOURS_ICON = `
const WIND_SURFING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="21,20 19,19 18,19 16,20 15,20 13,19 12,19 10,20 9,20 8,20 8,19.5 7,19 6,19 4,20 3,20 1,19 1,21 3,22 4,22 6,21 7,21 9,22 10,22 12,21 13,21 15,22 16,22 18,21 19,21 21,22 22,22 22,20 "/><path d="M10.7,17.5l-2.5-2.4C8.1,15,7.9,15,7.7,15H5l-0.4-1H4v-1h0.2L4,12.4h1.4c0,0,0.3,0,0.4-0.1l2.3-1c0.2-0.1,0.3-0.3,0.3-0.5 c0-0.4-0.3-0.7-0.6-0.7c-0.1,0-0.2,0-0.2,0l-2.1,1h-3c-0.1,0-0.2,0-0.4,0.1V12h-1C1,12.1,1,12.2,1,12.4c0,0.1,0,0.2,0,0.3l1.4,3.2 c0.2,0.5,0.7,0.8,1.2,0.8h3.7l2.2,2.1c0.3,0.3,0.9,0.3,1.2,0C11.1,18.4,11.1,17.8,10.7,17.5z"/><path d="M7,0l7.1,18l7.9-4.9C21.5,5.7,13.4,0.8,7,0z M18,10c-1.5,0-6,0-6,0V9c0,0,4.5,0,6,0c1.8,0,3,2,3,2v1h-1C20,12,18.8,10,18,10 z"/><circle cx="1.5" cy="9.5" r="1.5"/></svg>`;
// These three have no equivalent in the older standalone symbol-library
// repo (see POI_ICONS above) — pulled from npmap5-plugins' bundled,
// actively-maintained symbol-library instead (CC0-licensed), which has a
// much larger vocabulary.
const WIFI_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><path d="M11,11.9c-1.9,0-3.6,0.8-4.8,2l1.6,1.6c0.8-0.8,1.9-1.3,3.1-1.3c1.2,0,2.3,0.5,3.1,1.3l1.6-1.6 C14.6,12.7,12.9,11.9,11,11.9z"/><path d="M11,7c-3.1,0-5.9,1.3-7.9,3.3l1.6,1.6c1.6-1.6,3.8-2.6,6.2-2.6c2.4,0,4.6,1,6.2,2.6l1.6-1.6C16.9,8.3,14.1,7,11,7z"/><path d="M11,4.5c3.7,0,7,1.5,9.4,3.9L22,6.7c-2.8-2.8-6.7-4.6-11-4.6c-4.3,0-8.2,1.7-11,4.6l1.6,1.6C4,6,7.3,4.5,11,4.5z"/><circle cx="11" cy="18.3" r="1.6"/></g></svg>`;
const CELLULAR_SIGNAL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M18.8,3.2l-1.4,1.4C19,6.3,20,8.5,20,11s-1,4.7-2.6,6.4l1.4,1.4c2-2,3.2-4.7,3.2-7.8C22,8,20.8,5.2,18.8,3.2 z"/><path d="M2,11c0-2.5,1-4.7,2.6-6.4L3.2,3.2C1.2,5.2,0,8,0,11c0,3,1.2,5.8,3.2,7.8l1.4-1.4C3,15.7,2,13.5,2,11z"/><path d="M6.1,15.9l1.4-1.4C6.6,13.6,6,12.4,6,11c0-1.4,0.6-2.6,1.5-3.5L6.1,6.1C4.8,7.3,4,9.1,4,11 S4.8,14.7,6.1,15.9z"/><path d="M16,11c0,1.4-0.6,2.6-1.5,3.5l1.4,1.4c1.3-1.3,2.1-3,2.1-4.9c0-1.9-0.8-3.7-2.1-4.9l-1.4,1.4 C15.4,8.4,16,9.6,16,11z"/><path d="M12,13.8c1.2-0.4,2-1.5,2-2.8c0-1.7-1.3-3-3-3s-3,1.3-3,3c0,1.3,0.8,2.4,2,2.8L8.9,20H8v2h0.6h1h2.9h1H14v-2 h-0.9L12,13.8z M9.9,20l1.1-6c0,0,0,0,0,0s0,0,0,0l1.1,6H9.9z"/></svg>`;
const WINTER_RECREATION_AREA_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M10.1,21.4v-2.9l-1.6,0.9l-0.8-0.5v-1l2.4-1.4v-1.9l-1.7,1.1v-2l-1.7,1v2.7L5.7,18l-0.8-0.5v-1.8l-2.5,1.4l-1.1-0.5v-1.2 L4,14l-1.7-0.8v-1.1l0.9-0.5L5.6,13l1.7-1l0,0l-1.7-1l1.6-1l-1.7-1l-2.4,1.4L2.3,10V9l1.6-0.9L1.3,6.7V5.5l1-0.5l2.5,1.5V4.6 l0.8-0.5l0.9,0.5l0,2.8l1.7,1l0-2l1.8,1V5.5L7.6,4.1v-1l0.8-0.5l1.6,0.9V0.6L11,0l0.9,0.6v2.9l1.7-0.9l0.8,0.6V4L12,5.5v1.9l1.7-1 v2.1l1.8-1v-3l0.8-0.4l0.9,0.4v1.9L19.8,5l0.9,0.6v1.1l-2.6,1.5l1.6,0.9v1l-0.8,0.5L16.5,9l-1.7,1.1l1.6,1l-1.7,1l1.7,0.9l2.5-1.4 l0.8,0.6v1L18.2,14l2.5,1.5v1.1l-1,0.5l-2.4-1.4v1.8L16.3,18l-0.8-0.5v-2.8l-1.8-1v1.9l-1.7-1v1.9l2.4,1.4V19l-0.8,0.4l-1.6-0.9v2.9 L11,22L10.1,21.4z M9.4,11.1l0.9,1.3h1.6l0.7-1.3l-0.8-1.4h-1.6L9.4,11.1z"/></svg>`;
// park4night's fixed vocabulary of Services/Activities codes (the ones
// p4n2gpx exports actually use — not necessarily park4night's entire API),
// each with a human label (always shown) and an icon where the NPS set has
@@ -223,8 +234,8 @@ export const PARK4NIGHT_TAGS = {
// Services
animaux: { icon: PETS_ON_LEASH_ICON, label: "Pets allowed" },
boulangerie: { label: "Bakery nearby" },
caravaneige: { label: "Winter/snow camping" },
donnees_mobile: { label: "Mobile data coverage" },
caravaneige: { icon: WINTER_RECREATION_AREA_ICON, label: "Winter/snow camping" },
donnees_mobile: { icon: CELLULAR_SIGNAL_ICON, label: "Mobile data coverage" },
douche: { icon: SHOWERS_ICON, label: "Showers" },
eau_noire: { icon: SANITARY_DISPOSAL_ICON, label: "Black water disposal" },
eau_usee: { icon: SANITARY_DISPOSAL_ICON, label: "Grey water disposal" },
@@ -237,7 +248,7 @@ export const PARK4NIGHT_TAGS = {
point_eau: { icon: DRINKING_WATER_ICON, label: "Drinking water" },
poubelle: { icon: TRASH_DUMPSTER_ICON, label: "Trash disposal" },
wc_public: { icon: RESTROOMS_ICON, label: "Public toilet" },
wifi: { label: "Wi-Fi" },
wifi: { icon: WIFI_ICON, label: "Wi-Fi" },
// Activities
baignade: { icon: SWIMMING_ICON, label: "Swimming" },
+8
View File
@@ -11,6 +11,7 @@ import { LiveTrackPanelControl } from "/js/livetrack.js";
import { TrackProfilePanel } from "/js/track_profile.js";
import { LAYERS_ICON } from "/js/icons.js";
import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
import HomeButton from "/vendor/npmap-home-button/home-button.esm.js";
const CENTER = [17.1077, 48.1486];
const ZOOM = 13;
@@ -133,6 +134,13 @@ map.addControl(
}),
"bottom-right",
);
// homePosition/zoom pinned to the app's own default rather than left to the
// button's own fallback (current center/zoom at construction) — now that
// the URL hash can restore any view on load (see the Hash option above),
// "current view" and "the default view" are no longer the same thing, and
// a home button that resets to wherever you happened to load the page
// wouldn't be a home button.
map.addControl(new HomeButton({ homePosition: CENTER, zoom: ZOOM }), "top-left");
const sidebar = document.getElementById("sidebar");