maplibre-gl-national-map 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +298 -0
- package/dist/NationalMapControl-CES8icAA.cjs +1362 -0
- package/dist/NationalMapControl-CES8icAA.cjs.map +1 -0
- package/dist/NationalMapControl-LZeTBvuV.js +1243 -0
- package/dist/NationalMapControl-LZeTBvuV.js.map +1 -0
- package/dist/index.cjs +22 -0
- package/dist/index.mjs +2 -0
- package/dist/maplibre-gl-national-map.css +518 -0
- package/dist/react.cjs +151 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.mjs +149 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types/index.d.cts +678 -0
- package/dist/types/index.d.ts +678 -0
- package/dist/types/react.d.cts +251 -0
- package/dist/types/react.d.ts +251 -0
- package/package.json +111 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Qiusheng Wu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# MapLibre GL National Map
|
|
2
|
+
|
|
3
|
+
A [MapLibre GL JS](https://maplibre.org) plugin for searching and adding [USGS National Map web services](https://apps.nationalmap.gov/services/) to a map. It ships as a standard MapLibre `IControl` with a React wrapper, and also builds as a GeoLibre Desktop plugin bundle.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/maplibre-gl-national-map)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://codesandbox.io/p/github/opengeos/maplibre-gl-national-map)
|
|
8
|
+
[](https://stackblitz.com/github/opengeos/maplibre-gl-national-map)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Service Catalog** - Browse 20+ USGS National Map services grouped by collapsible categories (Basemaps, Hydrography, Elevation, Cartography, Indexes)
|
|
13
|
+
- **Search** - Filter services by name, title, description, or category; matching categories expand automatically
|
|
14
|
+
- **Layer Insertion Point** - An "Insert before" selector in the panel (or the `beforeId` option) inserts added layers beneath an existing layer (e.g. labels); changing it re-anchors layers already added
|
|
15
|
+
- **Resizable Panel** - Drag the panel edge to resize; works from left and right corner placements
|
|
16
|
+
- **Live Catalog Refresh** - Fetches the latest service listings from the National Map ArcGIS REST endpoints at runtime, with a built-in static catalog as an instant-render fallback (works offline)
|
|
17
|
+
- **Layer Management** - Toggle visibility, adjust opacity, and remove added layers from an "Active layers" section
|
|
18
|
+
- **Light/Dark Theme** - Follows `prefers-color-scheme` by default, with a `theme` option to force light or dark
|
|
19
|
+
- **Small-Screen Friendly** - The panel constrains itself to the map height and scrolls vertically
|
|
20
|
+
- **Collapsible Control** - 29x29 toggle button matching MapLibre's navigation control, with a floating panel
|
|
21
|
+
- **TypeScript Support** - All public types exported from the package root
|
|
22
|
+
- **React Integration** - React wrapper component and custom hook
|
|
23
|
+
- **GeoLibre Bundle Output** - Builds a zip with root `plugin.json`, bundled ESM, and CSS for GeoLibre Desktop
|
|
24
|
+
|
|
25
|
+
## Supported Services
|
|
26
|
+
|
|
27
|
+
The catalog mirrors the map services listed at [apps.nationalmap.gov/services](https://apps.nationalmap.gov/services/). All endpoints are CORS-enabled ArcGIS REST services and need no API key:
|
|
28
|
+
|
|
29
|
+
| Category | Services | Rendering |
|
|
30
|
+
| ----------- | ----------------------------------------------------------------------------------------------------- | -------------------------- |
|
|
31
|
+
| Basemaps | USGS Topo, Imagery Only, Imagery Topo, Shaded Relief, Hydro Cached | Cached XYZ tiles |
|
|
32
|
+
| Hydrography | 3DHP, NHD, NHDPlus HR, Watershed Boundary Dataset | Dynamic map export |
|
|
33
|
+
| Elevation | 3DEP Elevation (hillshade) | ImageServer export |
|
|
34
|
+
| Imagery | NAIP Plus, NAIP False Color Imagery, NAIP NDVI | ImageServer export |
|
|
35
|
+
| Cartography | Contours, Geographic Names, Governmental Units, Map Indices, Selectable Polygons, Structures, Transportation, USGS Trails | Dynamic map export |
|
|
36
|
+
| Hazards | FEMA National Flood Hazard Layer | Dynamic map export |
|
|
37
|
+
| Other Data | Scanned USA Topo Maps, BLM PLSS, FWS National Wetlands Inventory | Cached tiles / map export |
|
|
38
|
+
| Indexes | 3DEP Elevation Index, NHDPlus HR Index, Seamless 1m DEM Index, NAIP Imagery Index, US Topo Availability, Special Edition 250K Maps, 3DEP Acquisition Grid | Dynamic map export |
|
|
39
|
+
|
|
40
|
+
A few services from the page are intentionally excluded: WFS/WCS endpoints and FeatureServers (not raster-displayable), NLCD land cover (WMS landing page only), and partner endpoints that were unreachable at testing time (ScienceBase geology, USGS ecosystems, GAP land cover, earthquake faults, mine symbols, NPS boundaries).
|
|
41
|
+
|
|
42
|
+
Note: layers added later render on top of earlier ones (or beneath the `beforeId` layer when configured). Remove and re-add layers to change stacking.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install maplibre-gl-national-map
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Vanilla JavaScript/TypeScript
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import maplibregl from "maplibre-gl";
|
|
56
|
+
import { NationalMapControl } from "maplibre-gl-national-map";
|
|
57
|
+
import "maplibre-gl-national-map/style.css";
|
|
58
|
+
|
|
59
|
+
const map = new maplibregl.Map({
|
|
60
|
+
container: "map",
|
|
61
|
+
style: "https://tiles.openfreemap.org/styles/positron",
|
|
62
|
+
center: [-98.5, 39.8],
|
|
63
|
+
zoom: 4,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
map.on("load", () => {
|
|
67
|
+
const control = new NationalMapControl({
|
|
68
|
+
title: "USGS National Map",
|
|
69
|
+
collapsed: false,
|
|
70
|
+
theme: "auto",
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
map.addControl(control, "top-right");
|
|
74
|
+
|
|
75
|
+
// Programmatic layer management
|
|
76
|
+
control.addService("basemap/USGSTopo");
|
|
77
|
+
console.log(control.getActiveLayers());
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### React
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { useEffect, useRef, useState } from "react";
|
|
85
|
+
import maplibregl, { Map } from "maplibre-gl";
|
|
86
|
+
import {
|
|
87
|
+
NationalMapControlReact,
|
|
88
|
+
useNationalMapState,
|
|
89
|
+
} from "maplibre-gl-national-map/react";
|
|
90
|
+
import "maplibre-gl-national-map/style.css";
|
|
91
|
+
|
|
92
|
+
function App() {
|
|
93
|
+
const mapContainer = useRef<HTMLDivElement>(null);
|
|
94
|
+
const [map, setMap] = useState<Map | null>(null);
|
|
95
|
+
const { state, toggle } = useNationalMapState();
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!mapContainer.current) return;
|
|
99
|
+
|
|
100
|
+
const mapInstance = new maplibregl.Map({
|
|
101
|
+
container: mapContainer.current,
|
|
102
|
+
style: "https://tiles.openfreemap.org/styles/positron",
|
|
103
|
+
center: [-98.5, 39.8],
|
|
104
|
+
zoom: 4,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
mapInstance.on("load", () => setMap(mapInstance));
|
|
108
|
+
|
|
109
|
+
return () => mapInstance.remove();
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div style={{ width: "100%", height: "100vh" }}>
|
|
114
|
+
<div ref={mapContainer} style={{ width: "100%", height: "100%" }} />
|
|
115
|
+
{map && (
|
|
116
|
+
<NationalMapControlReact
|
|
117
|
+
map={map}
|
|
118
|
+
title="National Map"
|
|
119
|
+
collapsed={state.collapsed}
|
|
120
|
+
theme="auto"
|
|
121
|
+
onStateChange={(newState) => console.log(newState)}
|
|
122
|
+
/>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## API
|
|
130
|
+
|
|
131
|
+
### NationalMapControl
|
|
132
|
+
|
|
133
|
+
The main control class implementing MapLibre's `IControl` interface.
|
|
134
|
+
|
|
135
|
+
#### Constructor Options
|
|
136
|
+
|
|
137
|
+
| Option | Type | Default | Description |
|
|
138
|
+
| ------------ | --------- | ---------------- | -------------------------------------------------------------------------- |
|
|
139
|
+
| `collapsed` | `boolean` | `true` | Whether the panel starts collapsed (showing only the 29x29 toggle button) |
|
|
140
|
+
| `position` | `string` | `'top-right'` | Control position on the map |
|
|
141
|
+
| `title` | `string` | `'USGS National Map'` | Title displayed in the header |
|
|
142
|
+
| `panelWidth` | `number` | `320` | Initial width of the dropdown panel in pixels (user-resizable by dragging the panel edge) |
|
|
143
|
+
| `className` | `string` | `''` | Custom CSS class name |
|
|
144
|
+
| `theme` | `string` | `'auto'` | Color theme: `'light'`, `'dark'`, or `'auto'` (follows `prefers-color-scheme`) |
|
|
145
|
+
| `beforeId` | `string` | `undefined` | Existing layer id to insert added layers before, so services render underneath it (ignored if the layer does not exist). Also adjustable at runtime via the panel's "Insert before" selector |
|
|
146
|
+
|
|
147
|
+
#### Methods
|
|
148
|
+
|
|
149
|
+
- `toggle()` - Toggle the collapsed state
|
|
150
|
+
- `expand()` - Expand the panel
|
|
151
|
+
- `collapse()` - Collapse the panel
|
|
152
|
+
- `getState()` - Get the current state (includes `activeLayerIds`)
|
|
153
|
+
- `setState(state)` - Update the state
|
|
154
|
+
- `addService(serviceId)` - Add a catalog service to the map (e.g. `"basemap/USGSTopo"`)
|
|
155
|
+
- `removeService(serviceId)` - Remove a previously added service
|
|
156
|
+
- `getActiveLayers()` - Get the services currently added to the map
|
|
157
|
+
- `setTheme(theme)` - Change the theme at runtime
|
|
158
|
+
- `on(event, handler)` - Register an event handler
|
|
159
|
+
- `off(event, handler)` - Remove an event handler
|
|
160
|
+
- `getMap()` - Get the map instance
|
|
161
|
+
- `getContainer()` - Get the container element
|
|
162
|
+
|
|
163
|
+
#### Events
|
|
164
|
+
|
|
165
|
+
- `collapse` - Fired when the panel is collapsed
|
|
166
|
+
- `expand` - Fired when the panel is expanded
|
|
167
|
+
- `statechange` - Fired when the state changes
|
|
168
|
+
- `layeradd` - Fired when a service is added to the map (`event.service` is the service)
|
|
169
|
+
- `layerremove` - Fired when a service is removed from the map
|
|
170
|
+
|
|
171
|
+
### NationalMapControlReact
|
|
172
|
+
|
|
173
|
+
React wrapper component for `NationalMapControl`.
|
|
174
|
+
|
|
175
|
+
#### Props
|
|
176
|
+
|
|
177
|
+
All `NationalMapControl` options plus:
|
|
178
|
+
|
|
179
|
+
| Prop | Type | Description |
|
|
180
|
+
| --------------- | ---------- | ----------------------------------- |
|
|
181
|
+
| `map` | `Map` | MapLibre GL map instance (required) |
|
|
182
|
+
| `onStateChange` | `function` | Callback fired when state changes |
|
|
183
|
+
|
|
184
|
+
### useNationalMapState
|
|
185
|
+
|
|
186
|
+
Custom React hook for managing control state.
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const {
|
|
190
|
+
state, // Current state
|
|
191
|
+
setState, // Replace the state
|
|
192
|
+
setCollapsed, // Set collapsed state
|
|
193
|
+
setPanelWidth, // Set panel width
|
|
194
|
+
setData, // Merge custom data
|
|
195
|
+
reset, // Reset to defaults
|
|
196
|
+
toggle, // Toggle collapsed
|
|
197
|
+
} = useNationalMapState({ collapsed: false });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Data Layer
|
|
201
|
+
|
|
202
|
+
The catalog and spec builders are exported for advanced use without the UI control:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import {
|
|
206
|
+
STATIC_CATALOG, // Built-in service catalog
|
|
207
|
+
fetchCatalog, // Live catalog fetch with static fallback
|
|
208
|
+
buildLayerSpec, // NationalMapService -> MapLibre source/layer specs
|
|
209
|
+
filterServices, // Search the catalog
|
|
210
|
+
groupByCategory, // Group services for display
|
|
211
|
+
LayerManager, // Add/remove/visibility/opacity on a map
|
|
212
|
+
} from "maplibre-gl-national-map";
|
|
213
|
+
|
|
214
|
+
const spec = buildLayerSpec(STATIC_CATALOG[0]);
|
|
215
|
+
map.addSource(spec.sourceId, spec.source);
|
|
216
|
+
map.addLayer(spec.layer);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Exported types include `NationalMapService`, `NationalMapControlOptions`, `NationalMapState`, `NationalMapTheme`, `NationalMapHost`, `NationalMapCategory`, `ServiceType`, `ServiceRenderMode`, `ActiveLayer`, `LayerSpec`, and `CategoryGroup`.
|
|
220
|
+
|
|
221
|
+
## Theming
|
|
222
|
+
|
|
223
|
+
The control uses CSS custom properties scoped to `.national-map` and `.national-map-panel`. With `theme: 'auto'` (default), dark colors apply when the OS is in dark mode. Use `theme: 'light'` or `theme: 'dark'` to force a theme, or override the `--nm-*` variables in your own CSS:
|
|
224
|
+
|
|
225
|
+
```css
|
|
226
|
+
.national-map-panel {
|
|
227
|
+
--nm-accent: #2e7d32;
|
|
228
|
+
--nm-accent-hover: #1b5e20;
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Examples
|
|
233
|
+
|
|
234
|
+
Run locally:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
npm install
|
|
238
|
+
npm run dev
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
- Basic: http://localhost:5173/examples/basic/
|
|
242
|
+
- React (with theme switcher): http://localhost:5173/examples/react/
|
|
243
|
+
|
|
244
|
+
## Build a GeoLibre plugin zip
|
|
245
|
+
|
|
246
|
+
GeoLibre Desktop loads external plugins from an app data `plugins/` directory. The zip must contain `plugin.json` at the root, plus a bundled ESM entry and optional CSS file.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm install
|
|
250
|
+
npm run package:geolibre
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This creates:
|
|
254
|
+
|
|
255
|
+
```text
|
|
256
|
+
geolibre-plugin/maplibre-gl-national-map-0.1.0.zip
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Copy the zip into GeoLibre Desktop's app data `plugins/` directory and restart GeoLibre. On Linux with the default app identifier, that directory is usually:
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
~/.local/share/org.geolibre.desktop/plugins/
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
For the GeoLibre web app, serve the unpacked plugin with CORS enabled:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
npm run package:geolibre
|
|
269
|
+
npm run serve:geolibre -- 8000
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Then add this manifest URL in GeoLibre Settings > Plugins:
|
|
273
|
+
|
|
274
|
+
```text
|
|
275
|
+
http://localhost:8000/plugin.json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Development
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm install # Install dependencies
|
|
282
|
+
npm run dev # Start the dev server
|
|
283
|
+
npm test # Run the test suite
|
|
284
|
+
npm run lint # Lint
|
|
285
|
+
npm run build # Build the library and GeoLibre bundle
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Docker
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
docker build -t maplibre-gl-national-map .
|
|
292
|
+
docker run -p 8080:80 maplibre-gl-national-map
|
|
293
|
+
# Open http://localhost:8080/maplibre-gl-national-map/
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## License
|
|
297
|
+
|
|
298
|
+
MIT
|