Files
maptool/docs/nps-resources.adoc
T
randy 43785a074b
CI / check (push) Successful in 38s
CI / deploy (push) Successful in 12s
Note the NPS arrowhead logo's official Pantone/RAL colors
Unrelated to anything the app renders, but the doc already collects
NPS-ecosystem color facts and this came up while sourcing colors
for a 3D print of the shield.
2026-09-21 18:08:35 +02:00

404 lines
18 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
= National Park Service mapping resources
:toc:
:toclevels: 2
A reference for what's out there in the National Park Service's mapping
ecosystem: what this app has actually adopted, what was investigated and
deliberately skipped, and the licensing/provenance details behind each.
Kept as a knowledge base since NPS's tooling has repeatedly turned out to
be a better source than reinventing something from scratch — worth
checking here before searching from zero next time.
== What this app actually uses
[cols="1,2,1"]
|===
| What | Where | License
| `symbol-library` (map category icons, POI badge glyphs)
| `public/js/icons.js`'s `POI_ICONS`/`PARK4NIGHT_TAGS`
| CC0 (public domain)
| `home-button` (the "Home" map control)
| `public/vendor/npmap-home-button/`
| MIT (per `package.json`); the whole `npmap5-plugins` repo is separately
public domain as a US government work
| Park Tiles color palette (shared offline + online basemap theme)
| `public/js/map.js`'s `ONLINE_STYLE_PATCH`
| Colors only — see <<park-tiles>> for why the actual tile service isn't used
| `overview` (top-right minimap/inset control)
| `public/vendor/npmap-overview/`
| MIT (per that branch's `package.json`); same public-domain repo as above
|===
See `docs/third-party-notices.adoc` for the formal vendored-library
notice and `docs/architecture.adoc` for how each is wired in.
== npmap5-plugins
https://github.com/nationalparkservice/npmap5-plugins — a monorepo of
MapLibre GL JS plugins built for NPS's current (v5) map stack. Live
demos: https://nationalparkservice.github.io/npmap5-plugins. More
examples/screenshots: issue
https://github.com/nationalparkservice/npmap5-plugins/issues/7[#7].
=== On `main` (stable, what we've pulled from)
[cols="1,3"]
|===
| Plugin | What it is
| `symbol-library`
| The icon set — see above. Confirmed by the maintainer
(issue https://github.com/nationalparkservice/npmap5-plugins/issues/4[#4])
to be the designated replacement for the older standalone
`nationalparkservice/symbol-library` repo, with a much larger
vocabulary (300+ icons vs. the ~200 in the old repo).
| `home-button`
| Adopted, see above.
| `svg-icons`
| *Considered, not adopted.* Solves the same "recolor an icon at
render time" problem we hit and fixed ourselves this session (see
`docs/architecture.adoc`'s note on `_registerCategoryGlyphs` — SDF
images need an actual distance field, not a plain antialiased
raster, or edges blur). Its approach is more general (lazy,
on-demand recoloring via a `styleimagemissing` listener and a
query-string-encoded `icon-image` id, vs. our upfront
per-distinct-color registration) but swapping in ~800 lines of
unfamiliar third-party logic for something already working and
understood wasn't a clear win — no bug it would fix, no capability
we're missing.
| `interactivity`
| Not investigated in depth — "makes interactivity easier with
MapLibre GL JS". Our own click/hover handling (`gpx.js`) is already
small and specific to this app's needs.
| `maplibre-gl-vector-text-protocol`
| Loads KML/GPX/TopoJSON/OSM directly into MapLibre client-side. Not
a fit: our GPX/FIT handling is server-side
(`lib/maptool/gpx.rb`/`fit.rb`) specifically so we can compute
track stats, POI category styling, clustering, etc. — a generic
client-side loader wouldn't give us any of that.
| `markdown-handlebars`
| *Considered, not adopted.* Renders Markdown-with-`{{handlebars}}`
as HTML. Our waypoint popup content isn't Markdown — it's
park4night's own semi-structured text format (`formatDescription`
in `gpx.js` parses `Label: value` lines and turns Services/
Activities into icon tags) — a generic templater would replace the
wrong layer of that logic, and would mean trusting a new,
unaudited HTML-rendering path for untrusted (uploaded-file) content
in place of our already-reviewed escaping.
| `source-arcgis-rest`, `source-wms`
| Add ArcGIS REST / WMS raster layers as MapLibre sources. No current
need — we don't have an ArcGIS or WMS data source to point at. `wms`
explicitly noted by the user as maybe useful in the future.
|===
=== On unmerged feature branches (less vetted — not on `main` yet)
`overview` (branch `maplibre-gl-overview`) has since been adopted —
see "What this app actually uses" above and
`docs/architecture.adoc`'s control-stack section. Live demo (as
upstream ships it, unpatched):
https://raw.githack.com/nationalparkservice/npmap5-plugins/maplibre-gl-overview/examples/index.html.
Note: MapLibre GL JS has no first-party minimap of its own — this
isn't more "official" than any other third-party minimap plugin, just
NPS-flavored.
[cols="1,3"]
|===
| Plugin | What it is
| `carto` (branch `maplibre-gl-carto-source`)
| Adds a vector-tile source backed by Carto.com-hosted data. Only
useful if we actually have a Carto-hosted dataset to point at — we
don't right now.
| `wms` (branch `maplibre-gl-wms-source`)
| WMS raster layer source. Noted by the user as possibly handy later;
no current use case.
|===
=== Pending upstream: symbol artwork revisions
https://github.com/nationalparkservice/symbol-library/pull/226 ("npmap-hfc
standardization 2024") — a large (169-file), still-*open*/unmerged artwork
revision pass on the *old* standalone repo, open since January 2024. Of the
icons this app actually uses, three have revised artwork proposed there:
* `bicycle-trail` (our `sport_cycling`/`vtt`)
* `campground` (our `tourism_camp_site`)
* `pets-on-leash` (our `animaux`)
Plus filename-only renames (e.g. `motor-bike-trail` → `motorbike-trail`,
`sea-plane` → `seaplane`) and a handful of new icons not relevant to our
current `PARK4NIGHT_TAGS` mapping (`e-bike`, `foraging-gathering`,
`seaplane`, `toilet`, `windmill`). Deliberately *not* pulled in — it's an
unmerged draft, could still change. Worth revisiting once it lands on
`main` in whichever repo ends up canonical.
[[park-tiles]]
== Park Tiles (the NPS basemap theme)
https://www.nps.gov/maps/web/tools/park-tiles/ — the data and cartography
system behind NPS's own web maps. Documentation:
https://www.nps.gov/maps/web/tools/npmapjs/index.html (the wider NPMap
code library docs), legend:
https://www.nps.gov/maps/web/tools/park-tiles/legend/index.html, symbols:
https://www.nps.gov/maps/web/tools/park-tiles/pictographic-symbols/index.html.
=== Design lineage
Explicitly traces back to the National Park Service's iconic print
brochure maps produced at the Harpers Ferry Center — the Park Tiles team
consulted HFC cartographers directly, adapting the same visual language
for digital display. This is also the design lineage behind the
`Unigrid` system (Massimo Vignelli's 1970s NPS brochure/signage
template), one of the most respected government design programs.
=== The four style variants
* *Standard* — the default; used in the NPS mobile app and most of
nps.gov.
* *Aerial* — integrates an imagery underlay.
* *Slate* — dark grey, lets overlay data stand out; also deliberately
chosen to work well for low-vision users with inverted browser color
settings.
* *Light* — another neutral choice for data-overlay contexts.
=== Why we can't use the actual tile service
Their basemap data pipeline blends NPS's own enterprise GIS data
(roads/trails/buildings/parking/POIs/boundaries) with USGS/Census federal
data and, for context outside park boundaries (streets, coastlines,
buildings, terrain/hillshade), **OpenStreetMap data pre-processed by
Mapbox as part of their commercial Atlas service** — a paid,
non-sublicensable data license scoped to NPS's own use. Separately, the
cartography is explicitly designed for park visitors (trailhead/park-unit
labeling prioritized), not general-purpose worldwide mapping. Both are
why this app uses OpenFreeMap Liberty as its actual basemap, not Park
Tiles — see `docs/architecture.adoc`'s "Offline maps" section.
Recreating the *color choices* is a different matter — not the kind of
thing a data license restricts — and is what `ONLINE_STYLE_PATCH` in
`public/js/map.js` actually does (see `docs/architecture.adoc`).
=== Public style JSON (source for the real colors we did pull)
Of Park Tiles' four variants, only *Imagery* is served from a plain,
unauthenticated URL:
https://www.nps.gov/lib/npmap.js/style/ck72fwp2642dv07o7tbqinvz4.json
("Park Tiles 4 Imagery", 129 layers — a genuine Mapbox/MapLibre style
spec, found via `npmap.js`'s own bundled `baselayers.json` config.)
*Standard*, *Slate*, and *Light* resolve through Mapbox Studio's private
Styles API using an access token instead (`style_id`s below) — visible in
`npmap.js`'s own bundle, but not something to fetch using someone else's
embedded credentials, even when technically reachable:
[cols="1,1"]
|===
| Variant | Mapbox Studio `style_id`
| Standard
| `ck58pyquo009v01p99xebegr9`
| Slate
| `ck5cpvc2e0avf01p9zaw4co8o`
| Light
| `ck5cpia2u0auf01p9vbugvcpv`
|===
Colors actually pulled from the Imagery style JSON and used in
`ONLINE_STYLE_PATCH`: background (`hsl(40, 37%, 97%)`, a warm cream), the
park/protected-area green (`#b3e378`), the two road-importance tiers
(`#fdefbe`/`#fef7dd`), and the park-boundary line color (`#546619`, dark
olive). The rest of `ONLINE_STYLE_PATCH` extends that same warm/olive
family by eye rather than from a sourced value.
=== Legend / cartographic hierarchy
The legend page documents NPS's own road/trail classification standard
(primary/secondary/local/4WD/private/service roads; conventional/paved/
boardwalk trails; public/private buildings), each shown across all four
variants. Keyed to NPS's internal "NPS geospatial data standard for
roads," not OSM's `highway=*` tagging scheme — informative as design
reference, not directly portable onto our OSM-derived data without
reinterpreting the mapping ourselves.
== Typography & editorial standards
Part of the NPS graphic identity, alongside Park Tiles — noted for
completeness, but not adoptable and not directly relevant to this app's
own work (a map viewer, not a publisher of NPS-branded content):
* *Typefaces*: the standards specify two — *NPS Rawlinson* (licensed to
NPS by its creator, Terminal Design) and *Frutiger* (licensed from
Adobe Systems). Both proprietary/commercially licensed, unlike the
fonts this app already vendors (Noto Sans, SIL OFL — see
`docs/third-party-notices.adoc`) — not something to pull in.
* *A genuinely open alternative*: https://github.com/national-park-service/fonts
— despite the org name, its own `DISCLAIMER.md` is explicit that this
is an **independent, unofficial** project, "not affiliated with,
endorsed by, or sponsored by" NPS, and that its six typefaces (NPS
2026, Redwood Serif, Campmate Script, NPS Symbols, Sequoia Sans,
Switchback) are original works "inspired by" public-lands signage —
explicitly *not* reproductions of Rawlinson or anything NPS actually
owns. SIL OFL 1.1 licensed, same family of license as the fonts this
app already vendors. Unlike Rawlinson/Frutiger above, this one's
actually usable if the NPS-inspired look is ever wanted in this app's
own UI chrome (currently plain system fonts, `public/css/style.css`) —
no current use case, but no licensing blocker either, worth
remembering if that comes up.
* *Another open alternative, for display use*: https://nationalparktypeface.com[National Park]
— a separate, unrelated project (Ben Hoepner, Andrea Herstowski, Jeremy
Shellhorn / DO Studio), also SIL OFL licensed, also original ("inspired
by" park signage, not a Rawlinson reproduction). Ships as variable
`.ttf`, `.woff`/`.woff2`, and `.otf` — self-hostable via `@font-face`
the same way. Where it differs from Sequoia Sans above: it's a
router-carved-signage *display* face (the chunky all-caps look of
actual trailhead signs), not a general body/UI sans — best fit would be
a wordmark/heading use (e.g. the topbar's "MAPTOOL" text) alongside a
more legible sans for body copy, not a full typeface swap. Now used for
exactly that: `.topbar__brand` only (`public/css/style.css`), Bold
weight vendored under `public/vendor/national-park-typeface/` — see
`docs/third-party-notices.adoc`. Body copy elsewhere still plain system
fonts, unchanged.
* *Hawaiian typography*: NPS Rawlinson includes vowels with Hawaiian
macrons (ā, ē, ī, ō, ū) and the okina (ʻ); the regular weight of
Frutiger doesn't, so NPS uses a separate "HFrutiger" weight for
Hawaiian-language text in official materials.
* *Editorial style guide*:
https://www.nps.gov/subjects/hfc/hfc-editorial-style-guide.htm — HFC's
writing/terminology conventions (capitalization, place names,
Spanish-language guidance, disability language, etc.), built on top of
the Chicago Manual of Style, AP Stylebook, and GPO Style Manual. A
content style guide for NPS's own written materials, not a design/code
resource — included here only because it was shared alongside the
typography notes above.
== Arrowhead (shield) logo colors
Unrelated to anything this app renders — noted here only because it came up
in conversation (wanting exact colors to 3D-print the NPS arrowhead) and
this doc is already the dumping ground for NPS-ecosystem color/graphic-identity
facts. Per NPS's own graphic identity standards (Harpers Ferry Center), the
arrowhead uses three official Pantone spot colors plus white:
[cols="2,2,1,1"]
|===
| Element | Pantone | Hex (converted) | Nearest RAL Classic
| Mountain
| Dark Rust, PMS 1615 C
| `#8b4720`
| RAL 2013 Pearl orange (`#923E25`)
| Sky
| Medium Rust, PMS 1605 C
| `#a65523`
| RAL 8023 Orange brown (`#A45729`)
| Trees / grass
| Dark Green, PMS 553 C
| `#284734`
| RAL 6012 Black green (`#2F3D3A`)
| Bison, lake, snowfield, type
| White
| `#ffffff`
| RAL 9016 Traffic white (`#F1F1EA`) — RAL has no pure white
|===
Hex values are third-party Pantone→RGB conversions, not something NPS
publishes directly (their style guide only specifies PMS codes). RAL codes
are the closest match by RGB distance against the RAL Classic chart — same
caveat, not an official NPS-endorsed mapping, just the nearest available
code for filament/paint shopping. Source: NPS Graphic Identity and Style
Guides (https://www.nps.gov/subjects/hfc/nps-graphic-identity-and-style-guides.htm),
FAQs About Arrowhead Artwork
(https://www.nps.gov/subjects/hfc/faqs-about-arrowhead-artwork.htm). Use of
the arrowhead symbol itself is controlled by law/regulation/policy — see
the FAQ page before printing/distributing anything bearing it.
== NPMap4 (the older, Leaflet-based generation)
https://www.nps.gov/lib/npmap.js/4.2.1/ — predecessor to npmap5,
Leaflet-based, MIT-licensed. Superseded but still live, and currently
*more feature-complete* than npmap5: v4 is one large, mature framework
(~87k lines, years of accumulated features — baselayer presets, a
geocoder, popups, etc. all in one package), while npmap5 is a
still-in-progress rewrite split into small, independently-versioned
plugins (several still at `0.0.1-x`, pre-1.0), a few of which (`overview`,
`carto`, `wms`) aren't even merged to `main` yet — see above. v5 is the
direction NPS is migrating to, not (yet) a feature-for-feature
replacement; expect this gap to close over time, not to stay this way.
Three things worth noting from v4:
* *`infoboxControl`* — example:
https://www.nps.gov/lib/npmap.js/4.2.1/examples/basic/infobox.html. A
generic "click anything, show every raw property in a table" debug
view, kept separate from a dataset's own curated popup. *Adopted* — not
the code (Leaflet, not portable) but the concept: this app now has the
same thing as an Alt+click handler (see `docs/architecture.adoc`'s
"Debug inspector" section), showing `queryRenderedFeatures` results —
base map OSM tags included, not just this app's own layers.
* *Geocoder control* — example:
https://www.nps.gov/lib/npmap.js/4.2.1/examples/controls/geocoder-control.html.
Config is `geocoderControl: { searchPlaces: true }`: a search box that
resolves NPS park units by name/unit code, or a street address, or
raw coordinates, and jumps the map there. The concept (type a
place/address/coordinates, jump to it) is genuinely transferable and
not NPS-specific — could be built for this app with any geocoder (e.g.
OSM's free Nominatim), independent of anything NPS. Not implemented;
noted as a candidate feature if wanted later.
* Confirmed *not* a source for basemap tiles we could use — same
`nps-parkTiles*` naming and same underlying Mapbox Atlas-licensed data
pipeline as npmap5's Park Tiles (see <<park-tiles>>).
== Data tooling (not adopted)
https://github.com/nationalparkservice/national-dataset-query — a
Node.js *CLI tool*, not a browser library (different category from
everything else in this doc): pulls data from ArcGIS/ESRI REST endpoints
and converts it to GeoJSON/GeoJSONSeq/GeoPackage. Would only be relevant
if we ever wanted to bake a specific ArcGIS-hosted dataset into an
offline extract — the same role `data/offline.pmtiles` already plays for
OSM-derived data, just a different source. No current need, and unlike
everything else in this doc (CC0, BSD, MIT, public domain) this repo has
**no `LICENSE` file at all** — its terms are genuinely unclear, so treat
that as a blocker too, not just "no use case yet."
=== NPS Data API (developer.nps.gov)
A separate thing from the tile/Park Tiles service above — a general
government open-data API (parks, alerts, campgrounds, places, ... —
official docs: https://www.nps.gov/subjects/developer/api-documentation.htm,
a JS-rendered Swagger UI that doesn't render via a plain fetch; a free
API key from that same page is required to call it). No current use
case (this app isn't NPS-park-specific — park4night POIs and personal
GPX/FIT tracks, not NPS units), but it's the legitimate, non-Mapbox-Atlas
government data source behind it, worth remembering if a "show nearby
NPS park info/alerts" feature ever comes up — the `wms`/`source-arcgis-rest`
npmap5-plugins entries above would be the MapLibre-side plumbing for it.
Two hobby projects (both MIT, not NPS-affiliated, not directly reusable
as libraries — noted only as real-world examples of consuming this API)
turned up while looking at this:
* https://github.com/carlknutson/nps-changes-site — a React/Leaflet
explorer for all NPS sites, most fields sourced from this API
(supplemented by manual/AI-assisted research for fields the API
doesn't have), data refreshed daily via GitHub Actions rather than
called live.
* https://github.com/seankelliher/us-national-parks-alerts — a
Vue + Express directory of park alerts, pulled live through this API.