@gisfun/maplibre-gl-components 0.15.0-alpha.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 +1960 -0
- package/dist/ControlGrid-DN5md8hp.cjs +19636 -0
- package/dist/ControlGrid-rVNG7B9O.js +170422 -0
- package/dist/DuckDBConverter-B98M0DFs.cjs +23 -0
- package/dist/DuckDBConverter-RPq48-t0.js +434 -0
- package/dist/ShapefileConverter-AjbEjEyq.cjs +1 -0
- package/dist/ShapefileConverter-trvt8J3z.js +125 -0
- package/dist/decoder-CLokFc0V.js +8 -0
- package/dist/decoder-D9LU4bUo.cjs +1 -0
- package/dist/deflate-BA1jZeSX.js +10 -0
- package/dist/deflate-DEdCz12a.cjs +1 -0
- package/dist/geojson-BQSVgKFt.cjs +1 -0
- package/dist/geojson-BSUuDj5k.js +2551 -0
- package/dist/geotiff-De1w1lBy.cjs +8 -0
- package/dist/geotiff-o_Fq1Na4.js +3108 -0
- package/dist/index-8ZZtuDTp.js +705 -0
- package/dist/index-B-Nr9y7J.cjs +84 -0
- package/dist/index-B5NoFrpY.js +8892 -0
- package/dist/index-Bi1MMPUx.js +4163 -0
- package/dist/index-C9fk_HKR.js +167 -0
- package/dist/index-CBBRBJvR.cjs +274 -0
- package/dist/index-CZxPF1qt.js +4 -0
- package/dist/index-CiDPSJ9T.cjs +1 -0
- package/dist/index-CjM_nbxd.cjs +107 -0
- package/dist/index-DQXdX5y1.js +4666 -0
- package/dist/index-Dh1kpCb6.cjs +1 -0
- package/dist/index-IrsIiQNM.cjs +4 -0
- package/dist/index.cjs +3819 -0
- package/dist/index.mjs +19580 -0
- package/dist/jpeg-CF9OGQg_.js +533 -0
- package/dist/jpeg-JSQOxGHy.cjs +1 -0
- package/dist/lerc-7LlQoT6u.js +1032 -0
- package/dist/lerc-BIsodce9.cjs +1 -0
- package/dist/lzw-BZniWIYG.js +84 -0
- package/dist/lzw-BhML-BvT.cjs +1 -0
- package/dist/main-dist-Bymiy5aM.cjs +2 -0
- package/dist/main-dist-Cv8AKwrY.js +629 -0
- package/dist/maplibre-geoman.es-Bxdg-2EU.cjs +129 -0
- package/dist/maplibre-geoman.es-CFgM2ajb.js +22827 -0
- package/dist/maplibre-gl-components.css +1 -0
- package/dist/packbits-B9b7gX2c.cjs +1 -0
- package/dist/packbits-DWY5O-FG.js +24 -0
- package/dist/pako.esm-Bx5X36Wo.js +1074 -0
- package/dist/pako.esm-DZC2QrbJ.cjs +1 -0
- package/dist/raw-C3ARbSFo.cjs +1 -0
- package/dist/raw-DUslI1gr.js +9 -0
- package/dist/react.cjs +1 -0
- package/dist/react.mjs +1306 -0
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/adapters/AddVectorAdapter.d.ts +66 -0
- package/dist/types/lib/adapters/AddVectorAdapter.d.ts.map +1 -0
- package/dist/types/lib/adapters/CogLayerAdapter.d.ts +126 -0
- package/dist/types/lib/adapters/CogLayerAdapter.d.ts.map +1 -0
- package/dist/types/lib/adapters/PMTilesLayerAdapter.d.ts +78 -0
- package/dist/types/lib/adapters/PMTilesLayerAdapter.d.ts.map +1 -0
- package/dist/types/lib/adapters/StacLayerAdapter.d.ts +71 -0
- package/dist/types/lib/adapters/StacLayerAdapter.d.ts.map +1 -0
- package/dist/types/lib/adapters/ZarrLayerAdapter.d.ts +72 -0
- package/dist/types/lib/adapters/ZarrLayerAdapter.d.ts.map +1 -0
- package/dist/types/lib/adapters/index.d.ts +7 -0
- package/dist/types/lib/adapters/index.d.ts.map +1 -0
- package/dist/types/lib/addControlGrid.d.ts +80 -0
- package/dist/types/lib/addControlGrid.d.ts.map +1 -0
- package/dist/types/lib/colormaps/diverging.d.ts +30 -0
- package/dist/types/lib/colormaps/diverging.d.ts.map +1 -0
- package/dist/types/lib/colormaps/index.d.ts +32 -0
- package/dist/types/lib/colormaps/index.d.ts.map +1 -0
- package/dist/types/lib/colormaps/misc.d.ts +38 -0
- package/dist/types/lib/colormaps/misc.d.ts.map +1 -0
- package/dist/types/lib/colormaps/sequential.d.ts +22 -0
- package/dist/types/lib/colormaps/sequential.d.ts.map +1 -0
- package/dist/types/lib/converters/DuckDBConverter.d.ts +112 -0
- package/dist/types/lib/converters/DuckDBConverter.d.ts.map +1 -0
- package/dist/types/lib/converters/ShapefileConverter.d.ts +56 -0
- package/dist/types/lib/converters/ShapefileConverter.d.ts.map +1 -0
- package/dist/types/lib/converters/index.d.ts +8 -0
- package/dist/types/lib/converters/index.d.ts.map +1 -0
- package/dist/types/lib/converters/types.d.ts +75 -0
- package/dist/types/lib/converters/types.d.ts.map +1 -0
- package/dist/types/lib/core/AddVector.d.ts +116 -0
- package/dist/types/lib/core/AddVector.d.ts.map +1 -0
- package/dist/types/lib/core/Basemap.d.ts +206 -0
- package/dist/types/lib/core/Basemap.d.ts.map +1 -0
- package/dist/types/lib/core/BasemapReact.d.ts +32 -0
- package/dist/types/lib/core/BasemapReact.d.ts.map +1 -0
- package/dist/types/lib/core/BookmarkControl.d.ts +180 -0
- package/dist/types/lib/core/BookmarkControl.d.ts.map +1 -0
- package/dist/types/lib/core/ChoroplethControl.d.ts +105 -0
- package/dist/types/lib/core/ChoroplethControl.d.ts.map +1 -0
- package/dist/types/lib/core/CogLayer.d.ts +139 -0
- package/dist/types/lib/core/CogLayer.d.ts.map +1 -0
- package/dist/types/lib/core/CogLayerReact.d.ts +32 -0
- package/dist/types/lib/core/CogLayerReact.d.ts.map +1 -0
- package/dist/types/lib/core/Colorbar.d.ts +133 -0
- package/dist/types/lib/core/Colorbar.d.ts.map +1 -0
- package/dist/types/lib/core/ColorbarGuiControl.d.ts +79 -0
- package/dist/types/lib/core/ColorbarGuiControl.d.ts.map +1 -0
- package/dist/types/lib/core/ColorbarReact.d.ts +34 -0
- package/dist/types/lib/core/ColorbarReact.d.ts.map +1 -0
- package/dist/types/lib/core/ControlGrid.d.ts +125 -0
- package/dist/types/lib/core/ControlGrid.d.ts.map +1 -0
- package/dist/types/lib/core/ControlGridReact.d.ts +32 -0
- package/dist/types/lib/core/ControlGridReact.d.ts.map +1 -0
- package/dist/types/lib/core/HtmlControl.d.ts +140 -0
- package/dist/types/lib/core/HtmlControl.d.ts.map +1 -0
- package/dist/types/lib/core/HtmlControlReact.d.ts +32 -0
- package/dist/types/lib/core/HtmlControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/HtmlGuiControl.d.ts +68 -0
- package/dist/types/lib/core/HtmlGuiControl.d.ts.map +1 -0
- package/dist/types/lib/core/InspectControl.d.ts +202 -0
- package/dist/types/lib/core/InspectControl.d.ts.map +1 -0
- package/dist/types/lib/core/InspectControlReact.d.ts +32 -0
- package/dist/types/lib/core/InspectControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/Legend.d.ts +142 -0
- package/dist/types/lib/core/Legend.d.ts.map +1 -0
- package/dist/types/lib/core/LegendGuiControl.d.ts +69 -0
- package/dist/types/lib/core/LegendGuiControl.d.ts.map +1 -0
- package/dist/types/lib/core/LegendReact.d.ts +34 -0
- package/dist/types/lib/core/LegendReact.d.ts.map +1 -0
- package/dist/types/lib/core/MeasureControl.d.ts +211 -0
- package/dist/types/lib/core/MeasureControl.d.ts.map +1 -0
- package/dist/types/lib/core/MinimapControl.d.ts +77 -0
- package/dist/types/lib/core/MinimapControl.d.ts.map +1 -0
- package/dist/types/lib/core/MinimapControlReact.d.ts +32 -0
- package/dist/types/lib/core/MinimapControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/PMTilesLayer.d.ts +119 -0
- package/dist/types/lib/core/PMTilesLayer.d.ts.map +1 -0
- package/dist/types/lib/core/PrintControl.d.ts +226 -0
- package/dist/types/lib/core/PrintControl.d.ts.map +1 -0
- package/dist/types/lib/core/SearchControl.d.ts +172 -0
- package/dist/types/lib/core/SearchControl.d.ts.map +1 -0
- package/dist/types/lib/core/SearchControlReact.d.ts +32 -0
- package/dist/types/lib/core/SearchControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/StacLayer.d.ts +107 -0
- package/dist/types/lib/core/StacLayer.d.ts.map +1 -0
- package/dist/types/lib/core/StacSearch.d.ts +109 -0
- package/dist/types/lib/core/StacSearch.d.ts.map +1 -0
- package/dist/types/lib/core/Terrain.d.ts +165 -0
- package/dist/types/lib/core/Terrain.d.ts.map +1 -0
- package/dist/types/lib/core/TerrainReact.d.ts +32 -0
- package/dist/types/lib/core/TerrainReact.d.ts.map +1 -0
- package/dist/types/lib/core/VectorDataset.d.ts +228 -0
- package/dist/types/lib/core/VectorDataset.d.ts.map +1 -0
- package/dist/types/lib/core/VectorDatasetReact.d.ts +31 -0
- package/dist/types/lib/core/VectorDatasetReact.d.ts.map +1 -0
- package/dist/types/lib/core/ViewStateControl.d.ts +205 -0
- package/dist/types/lib/core/ViewStateControl.d.ts.map +1 -0
- package/dist/types/lib/core/ViewStateControlReact.d.ts +32 -0
- package/dist/types/lib/core/ViewStateControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/ZarrLayer.d.ts +110 -0
- package/dist/types/lib/core/ZarrLayer.d.ts.map +1 -0
- package/dist/types/lib/core/types.d.ts +2793 -0
- package/dist/types/lib/core/types.d.ts.map +1 -0
- package/dist/types/lib/hooks/index.d.ts +13 -0
- package/dist/types/lib/hooks/index.d.ts.map +1 -0
- package/dist/types/lib/hooks/useBasemap.d.ts +43 -0
- package/dist/types/lib/hooks/useBasemap.d.ts.map +1 -0
- package/dist/types/lib/hooks/useCogLayer.d.ts +44 -0
- package/dist/types/lib/hooks/useCogLayer.d.ts.map +1 -0
- package/dist/types/lib/hooks/useColorbar.d.ts +36 -0
- package/dist/types/lib/hooks/useColorbar.d.ts.map +1 -0
- package/dist/types/lib/hooks/useControlGrid.d.ts +41 -0
- package/dist/types/lib/hooks/useControlGrid.d.ts.map +1 -0
- package/dist/types/lib/hooks/useHtmlControl.d.ts +39 -0
- package/dist/types/lib/hooks/useHtmlControl.d.ts.map +1 -0
- package/dist/types/lib/hooks/useInspectControl.d.ts +49 -0
- package/dist/types/lib/hooks/useInspectControl.d.ts.map +1 -0
- package/dist/types/lib/hooks/useLegend.d.ts +41 -0
- package/dist/types/lib/hooks/useLegend.d.ts.map +1 -0
- package/dist/types/lib/hooks/useMinimapControl.d.ts +35 -0
- package/dist/types/lib/hooks/useMinimapControl.d.ts.map +1 -0
- package/dist/types/lib/hooks/useSearchControl.d.ts +43 -0
- package/dist/types/lib/hooks/useSearchControl.d.ts.map +1 -0
- package/dist/types/lib/hooks/useTerrain.d.ts +43 -0
- package/dist/types/lib/hooks/useTerrain.d.ts.map +1 -0
- package/dist/types/lib/hooks/useVectorDataset.d.ts +35 -0
- package/dist/types/lib/hooks/useVectorDataset.d.ts.map +1 -0
- package/dist/types/lib/hooks/useViewState.d.ts +43 -0
- package/dist/types/lib/hooks/useViewState.d.ts.map +1 -0
- package/dist/types/lib/utils/color.d.ts +47 -0
- package/dist/types/lib/utils/color.d.ts.map +1 -0
- package/dist/types/lib/utils/fileHelpers.d.ts +207 -0
- package/dist/types/lib/utils/fileHelpers.d.ts.map +1 -0
- package/dist/types/lib/utils/helpers.d.ts +48 -0
- package/dist/types/lib/utils/helpers.d.ts.map +1 -0
- package/dist/types/lib/utils/index.d.ts +4 -0
- package/dist/types/lib/utils/index.d.ts.map +1 -0
- package/dist/types/lib/utils/providers.d.ts +46 -0
- package/dist/types/lib/utils/providers.d.ts.map +1 -0
- package/dist/types/react.d.ts +15 -0
- package/dist/types/react.d.ts.map +1 -0
- package/dist/webimage-CBRffWZD.cjs +1 -0
- package/dist/webimage-ibSPOLHJ.js +19 -0
- package/package.json +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,1960 @@
|
|
|
1
|
+
# maplibre-gl-components
|
|
2
|
+
|
|
3
|
+
Legend, colorbar, basemap switcher, terrain toggle, search, vector data loader, feature inspector, measurement tools, coordinate display, bookmarks, minimap, and more for MapLibre GL JS maps.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/maplibre-gl-components)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://codesandbox.io/p/github/opengeos/maplibre-gl-components)
|
|
8
|
+
[](https://stackblitz.com/github/opengeos/maplibre-gl-components)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Colorbar** - Continuous gradient legends with built-in matplotlib colormaps
|
|
13
|
+
- **Legend** - Categorical legends with color swatches and labels
|
|
14
|
+
- **BasemapControl** - Interactive basemap switcher with 100+ providers from xyzservices
|
|
15
|
+
- **TerrainControl** - Toggle 3D terrain on/off using free AWS Terrarium elevation tiles
|
|
16
|
+
- **SearchControl** - Collapsible place search with geocoding and fly-to functionality
|
|
17
|
+
- **VectorDatasetControl** - Load GeoJSON files via file upload or drag-and-drop
|
|
18
|
+
- **AddVectorControl** - Load vector data from URLs (GeoJSON, GeoParquet, FlatGeobuf) with styling options
|
|
19
|
+
- **InspectControl** - Click on features to view their properties/attributes
|
|
20
|
+
- **ViewStateControl** - Display live map state (center, bounds, zoom, pitch, bearing) with optional bbox drawing
|
|
21
|
+
- **HtmlControl** - Flexible HTML content control for custom info panels
|
|
22
|
+
- **CogLayerControl** - Load and visualize Cloud Optimized GeoTIFF (COG) files with colormaps
|
|
23
|
+
- **ZarrLayerControl** - Load and visualize multi-dimensional Zarr arrays with colormaps
|
|
24
|
+
- **StacLayerControl** - Load COG layers from STAC (SpatioTemporal Asset Catalog) items
|
|
25
|
+
- **StacSearchControl** - Search and visualize STAC items from public catalogs (Earth Search, Planetary Computer)
|
|
26
|
+
- **MeasureControl** - Measure distances and areas on the map with multiple unit options
|
|
27
|
+
- **BookmarkControl** - Save and restore map views with localStorage persistence
|
|
28
|
+
- **PrintControl** - Export the map as PNG, JPEG, or PDF with optional title overlay
|
|
29
|
+
- **MinimapControl** - Inset overview map showing the current viewport extent with optional click-to-navigate
|
|
30
|
+
- **ControlGrid** - Collapsible toolbar grid that hosts any combination of built-in and plugin controls
|
|
31
|
+
- **addControlGrid** - One-call convenience function to add all default controls with customization
|
|
32
|
+
- **Three.js Integration** - Re-exported helpers (`MapScene`, `SceneTransform`, `Sun`, `Creator`) from `@dvt3d/maplibre-three-plugin`
|
|
33
|
+
- **Zoom-based Visibility** - Show/hide components at specific zoom levels with `minzoom`/`maxzoom`
|
|
34
|
+
- **React Support** - First-class React components and hooks
|
|
35
|
+
- **TypeScript** - Full type definitions included
|
|
36
|
+
- **20+ Built-in Colormaps** - viridis, plasma, terrain, jet, and more
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install maplibre-gl-components
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
### Vanilla JavaScript/TypeScript
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import maplibregl from "maplibre-gl";
|
|
50
|
+
import {
|
|
51
|
+
Colorbar,
|
|
52
|
+
Legend,
|
|
53
|
+
HtmlControl,
|
|
54
|
+
BasemapControl,
|
|
55
|
+
TerrainControl,
|
|
56
|
+
SearchControl,
|
|
57
|
+
VectorDatasetControl,
|
|
58
|
+
AddVectorControl,
|
|
59
|
+
ViewStateControl,
|
|
60
|
+
CogLayerControl,
|
|
61
|
+
ZarrLayerControl,
|
|
62
|
+
StacLayerControl,
|
|
63
|
+
MinimapControl,
|
|
64
|
+
} from "maplibre-gl-components";
|
|
65
|
+
import "maplibre-gl-components/style.css";
|
|
66
|
+
|
|
67
|
+
const map = new maplibregl.Map({
|
|
68
|
+
container: "map",
|
|
69
|
+
style: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
70
|
+
center: [-98, 38.5],
|
|
71
|
+
zoom: 4,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Add a terrain toggle control
|
|
75
|
+
const terrainControl = new TerrainControl({
|
|
76
|
+
exaggeration: 1.5,
|
|
77
|
+
hillshade: true,
|
|
78
|
+
});
|
|
79
|
+
map.addControl(terrainControl, "top-right");
|
|
80
|
+
|
|
81
|
+
// Add a search control
|
|
82
|
+
const searchControl = new SearchControl({
|
|
83
|
+
placeholder: "Search for a place...",
|
|
84
|
+
flyToZoom: 14,
|
|
85
|
+
showMarker: true,
|
|
86
|
+
});
|
|
87
|
+
map.addControl(searchControl, "top-right");
|
|
88
|
+
|
|
89
|
+
// Add a vector dataset loader (file upload and drag-drop)
|
|
90
|
+
const vectorControl = new VectorDatasetControl({
|
|
91
|
+
fitBounds: true,
|
|
92
|
+
});
|
|
93
|
+
map.addControl(vectorControl, "top-left");
|
|
94
|
+
|
|
95
|
+
vectorControl.on("load", (event) => {
|
|
96
|
+
console.log("Loaded:", event.dataset?.filename);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Add a view state control
|
|
100
|
+
const viewStateControl = new ViewStateControl({
|
|
101
|
+
collapsed: false,
|
|
102
|
+
enableBBox: true,
|
|
103
|
+
precision: 4,
|
|
104
|
+
});
|
|
105
|
+
map.addControl(viewStateControl, "bottom-left");
|
|
106
|
+
|
|
107
|
+
viewStateControl.on("bboxdraw", (event) => {
|
|
108
|
+
console.log("Drawn bbox:", event.bbox);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Add a basemap switcher
|
|
112
|
+
const basemapControl = new BasemapControl({
|
|
113
|
+
defaultBasemap: "OpenStreetMap.Mapnik",
|
|
114
|
+
showSearch: true,
|
|
115
|
+
filterGroups: ["OpenStreetMap", "CartoDB", "Stadia", "Esri"],
|
|
116
|
+
});
|
|
117
|
+
map.addControl(basemapControl, "top-left");
|
|
118
|
+
|
|
119
|
+
// Add a colorbar
|
|
120
|
+
const colorbar = new Colorbar({
|
|
121
|
+
colormap: "viridis",
|
|
122
|
+
vmin: 0,
|
|
123
|
+
vmax: 100,
|
|
124
|
+
label: "Temperature",
|
|
125
|
+
units: "°C",
|
|
126
|
+
orientation: "vertical",
|
|
127
|
+
});
|
|
128
|
+
map.addControl(colorbar, "bottom-right");
|
|
129
|
+
|
|
130
|
+
// Add a legend
|
|
131
|
+
const legend = new Legend({
|
|
132
|
+
title: "Land Cover",
|
|
133
|
+
items: [
|
|
134
|
+
{ label: "Forest", color: "#228B22" },
|
|
135
|
+
{ label: "Water", color: "#4169E1" },
|
|
136
|
+
{ label: "Urban", color: "#808080" },
|
|
137
|
+
],
|
|
138
|
+
collapsible: true,
|
|
139
|
+
});
|
|
140
|
+
map.addControl(legend, "bottom-left");
|
|
141
|
+
|
|
142
|
+
// Add an HTML control
|
|
143
|
+
const htmlControl = new HtmlControl({
|
|
144
|
+
html: "<div><strong>Stats:</strong> 1,234 features</div>",
|
|
145
|
+
});
|
|
146
|
+
map.addControl(htmlControl, "top-left");
|
|
147
|
+
|
|
148
|
+
// Update HTML dynamically
|
|
149
|
+
htmlControl.setHtml("<div><strong>Stats:</strong> 5,678 features</div>");
|
|
150
|
+
|
|
151
|
+
// Add a COG layer control (auto-loads the layer)
|
|
152
|
+
const cogControl = new CogLayerControl({
|
|
153
|
+
defaultUrl: "https://example.com/dem.tif",
|
|
154
|
+
defaultColormap: "terrain",
|
|
155
|
+
defaultRescaleMin: 0,
|
|
156
|
+
defaultRescaleMax: 4000,
|
|
157
|
+
loadDefaultUrl: true, // Auto-load the layer when control is added
|
|
158
|
+
});
|
|
159
|
+
map.addControl(cogControl, "top-right");
|
|
160
|
+
|
|
161
|
+
cogControl.on("layeradd", (event) => {
|
|
162
|
+
console.log("COG layer added:", event.url);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Add a Zarr layer control (auto-loads the layer)
|
|
166
|
+
const zarrControl = new ZarrLayerControl({
|
|
167
|
+
defaultUrl: "https://example.com/climate.zarr",
|
|
168
|
+
defaultVariable: "temperature",
|
|
169
|
+
defaultColormap: ["#440154", "#21918c", "#fde725"],
|
|
170
|
+
defaultClim: [0, 30],
|
|
171
|
+
loadDefaultUrl: true, // Auto-load the layer when control is added
|
|
172
|
+
});
|
|
173
|
+
map.addControl(zarrControl, "top-right");
|
|
174
|
+
|
|
175
|
+
zarrControl.on("layeradd", (event) => {
|
|
176
|
+
console.log("Zarr layer added:", event.url);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Add a STAC layer control (loads COG from STAC items)
|
|
180
|
+
const stacControl = new StacLayerControl({
|
|
181
|
+
defaultUrl: "https://example.com/stac-item.json",
|
|
182
|
+
loadDefaultUrl: true,
|
|
183
|
+
defaultColormap: "viridis",
|
|
184
|
+
defaultRescaleMin: 0,
|
|
185
|
+
defaultRescaleMax: 255,
|
|
186
|
+
});
|
|
187
|
+
map.addControl(stacControl, "top-right");
|
|
188
|
+
|
|
189
|
+
stacControl.on("stacload", (event) => {
|
|
190
|
+
console.log("STAC item loaded:", event.url);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
stacControl.on("layeradd", (event) => {
|
|
194
|
+
console.log("STAC layer added:", event.assetKey);
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### React
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { useState, useEffect, useRef } from "react";
|
|
202
|
+
import maplibregl from "maplibre-gl";
|
|
203
|
+
import {
|
|
204
|
+
ColorbarReact,
|
|
205
|
+
LegendReact,
|
|
206
|
+
HtmlControlReact,
|
|
207
|
+
BasemapReact,
|
|
208
|
+
TerrainReact,
|
|
209
|
+
SearchControlReact,
|
|
210
|
+
VectorDatasetReact,
|
|
211
|
+
ViewStateControlReact,
|
|
212
|
+
} from "maplibre-gl-components/react";
|
|
213
|
+
import "maplibre-gl-components/style.css";
|
|
214
|
+
|
|
215
|
+
function MyMap() {
|
|
216
|
+
const mapContainer = useRef<HTMLDivElement>(null);
|
|
217
|
+
const [map, setMap] = useState<maplibregl.Map | null>(null);
|
|
218
|
+
const [stats, setStats] = useState("Loading...");
|
|
219
|
+
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (!mapContainer.current) return;
|
|
222
|
+
|
|
223
|
+
const mapInstance = new maplibregl.Map({
|
|
224
|
+
container: mapContainer.current,
|
|
225
|
+
style: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
226
|
+
center: [-98, 38.5],
|
|
227
|
+
zoom: 4,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
mapInstance.on("load", () => setMap(mapInstance));
|
|
231
|
+
|
|
232
|
+
return () => mapInstance.remove();
|
|
233
|
+
}, []);
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<div style={{ width: "100%", height: "100vh" }}>
|
|
237
|
+
<div ref={mapContainer} style={{ width: "100%", height: "100%" }} />
|
|
238
|
+
|
|
239
|
+
{map && (
|
|
240
|
+
<>
|
|
241
|
+
<VectorDatasetReact
|
|
242
|
+
map={map}
|
|
243
|
+
fitBounds
|
|
244
|
+
position="top-left"
|
|
245
|
+
onDatasetLoad={(dataset) =>
|
|
246
|
+
console.log("Loaded:", dataset.filename)
|
|
247
|
+
}
|
|
248
|
+
/>
|
|
249
|
+
|
|
250
|
+
<ViewStateControlReact
|
|
251
|
+
map={map}
|
|
252
|
+
collapsed={false}
|
|
253
|
+
enableBBox
|
|
254
|
+
precision={4}
|
|
255
|
+
position="bottom-left"
|
|
256
|
+
onBBoxDraw={(bbox) => console.log("Drawn bbox:", bbox)}
|
|
257
|
+
/>
|
|
258
|
+
|
|
259
|
+
<SearchControlReact
|
|
260
|
+
map={map}
|
|
261
|
+
placeholder="Search for a place..."
|
|
262
|
+
flyToZoom={14}
|
|
263
|
+
showMarker
|
|
264
|
+
position="top-right"
|
|
265
|
+
onResultSelect={(result) => console.log("Selected:", result.name)}
|
|
266
|
+
/>
|
|
267
|
+
|
|
268
|
+
<TerrainReact
|
|
269
|
+
map={map}
|
|
270
|
+
exaggeration={1.5}
|
|
271
|
+
hillshade
|
|
272
|
+
position="top-right"
|
|
273
|
+
onTerrainChange={(enabled) => console.log("Terrain:", enabled)}
|
|
274
|
+
/>
|
|
275
|
+
|
|
276
|
+
<BasemapReact
|
|
277
|
+
map={map}
|
|
278
|
+
defaultBasemap="OpenStreetMap.Mapnik"
|
|
279
|
+
showSearch
|
|
280
|
+
filterGroups={["OpenStreetMap", "CartoDB", "Stadia"]}
|
|
281
|
+
position="top-left"
|
|
282
|
+
/>
|
|
283
|
+
|
|
284
|
+
<ColorbarReact
|
|
285
|
+
map={map}
|
|
286
|
+
colormap="viridis"
|
|
287
|
+
vmin={0}
|
|
288
|
+
vmax={100}
|
|
289
|
+
label="Temperature"
|
|
290
|
+
units="°C"
|
|
291
|
+
position="bottom-right"
|
|
292
|
+
/>
|
|
293
|
+
|
|
294
|
+
<LegendReact
|
|
295
|
+
map={map}
|
|
296
|
+
title="Categories"
|
|
297
|
+
items={[
|
|
298
|
+
{ label: "Low", color: "#2166ac" },
|
|
299
|
+
{ label: "High", color: "#b2182b" },
|
|
300
|
+
]}
|
|
301
|
+
position="bottom-left"
|
|
302
|
+
collapsible
|
|
303
|
+
/>
|
|
304
|
+
|
|
305
|
+
<HtmlControlReact
|
|
306
|
+
map={map}
|
|
307
|
+
html={`<div><strong>Stats:</strong> ${stats}</div>`}
|
|
308
|
+
position="top-left"
|
|
309
|
+
/>
|
|
310
|
+
</>
|
|
311
|
+
)}
|
|
312
|
+
</div>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## API Reference
|
|
318
|
+
|
|
319
|
+
### Colorbar
|
|
320
|
+
|
|
321
|
+
A continuous gradient colorbar control.
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
interface ColorbarOptions {
|
|
325
|
+
colormap?: ColormapName | string[]; // Colormap name or custom colors
|
|
326
|
+
colorStops?: ColorStop[]; // Fine-grained color control
|
|
327
|
+
vmin?: number; // Minimum value (default: 0)
|
|
328
|
+
vmax?: number; // Maximum value (default: 1)
|
|
329
|
+
label?: string; // Title/label
|
|
330
|
+
units?: string; // Units suffix
|
|
331
|
+
orientation?: "horizontal" | "vertical";
|
|
332
|
+
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
333
|
+
barThickness?: number; // Bar width/height in pixels
|
|
334
|
+
barLength?: number; // Bar length in pixels
|
|
335
|
+
ticks?: { count?: number; values?: number[]; format?: (v: number) => string };
|
|
336
|
+
visible?: boolean;
|
|
337
|
+
backgroundColor?: string;
|
|
338
|
+
opacity?: number;
|
|
339
|
+
fontSize?: number;
|
|
340
|
+
fontColor?: string;
|
|
341
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
342
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Methods
|
|
346
|
+
colorbar.show();
|
|
347
|
+
colorbar.hide();
|
|
348
|
+
colorbar.update(options);
|
|
349
|
+
colorbar.getState();
|
|
350
|
+
colorbar.on(event, handler);
|
|
351
|
+
colorbar.off(event, handler);
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Legend
|
|
355
|
+
|
|
356
|
+
A categorical legend control.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
interface LegendOptions {
|
|
360
|
+
title?: string;
|
|
361
|
+
items?: LegendItem[]; // { label, color, shape?, icon? }
|
|
362
|
+
position?: ControlPosition;
|
|
363
|
+
visible?: boolean;
|
|
364
|
+
collapsible?: boolean;
|
|
365
|
+
collapsed?: boolean;
|
|
366
|
+
width?: number;
|
|
367
|
+
maxHeight?: number;
|
|
368
|
+
swatchSize?: number;
|
|
369
|
+
backgroundColor?: string;
|
|
370
|
+
opacity?: number;
|
|
371
|
+
fontSize?: number;
|
|
372
|
+
fontColor?: string;
|
|
373
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
374
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
interface LegendItem {
|
|
378
|
+
label: string;
|
|
379
|
+
color: string;
|
|
380
|
+
shape?: "square" | "circle" | "line";
|
|
381
|
+
strokeColor?: string;
|
|
382
|
+
icon?: string; // URL to icon image
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Methods
|
|
386
|
+
legend.show();
|
|
387
|
+
legend.hide();
|
|
388
|
+
legend.expand();
|
|
389
|
+
legend.collapse();
|
|
390
|
+
legend.toggle();
|
|
391
|
+
legend.setItems(items);
|
|
392
|
+
legend.addItem(item);
|
|
393
|
+
legend.removeItem(label);
|
|
394
|
+
legend.update(options);
|
|
395
|
+
legend.getState();
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### HtmlControl
|
|
399
|
+
|
|
400
|
+
A flexible HTML content control.
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
interface HtmlControlOptions {
|
|
404
|
+
html?: string; // HTML content
|
|
405
|
+
element?: HTMLElement; // Or provide a DOM element
|
|
406
|
+
position?: ControlPosition;
|
|
407
|
+
visible?: boolean;
|
|
408
|
+
backgroundColor?: string;
|
|
409
|
+
padding?: number;
|
|
410
|
+
borderRadius?: number;
|
|
411
|
+
opacity?: number;
|
|
412
|
+
maxWidth?: number;
|
|
413
|
+
maxHeight?: number;
|
|
414
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
415
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Methods
|
|
419
|
+
htmlControl.show();
|
|
420
|
+
htmlControl.hide();
|
|
421
|
+
htmlControl.setHtml(html); // Update HTML content
|
|
422
|
+
htmlControl.setElement(element); // Set DOM element
|
|
423
|
+
htmlControl.getElement(); // Get content container
|
|
424
|
+
htmlControl.update(options);
|
|
425
|
+
htmlControl.getState();
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### BasemapControl
|
|
429
|
+
|
|
430
|
+
An interactive basemap switcher that loads providers from [xyzservices](https://github.com/geopandas/xyzservices).
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
interface BasemapControlOptions {
|
|
434
|
+
basemaps?: BasemapItem[]; // Custom basemaps array
|
|
435
|
+
providersUrl?: string; // URL to fetch providers.json (defaults to xyzservices)
|
|
436
|
+
defaultBasemap?: string; // Initial basemap ID (e.g., 'OpenStreetMap.Mapnik')
|
|
437
|
+
position?: ControlPosition;
|
|
438
|
+
visible?: boolean;
|
|
439
|
+
collapsible?: boolean; // Whether control is collapsible (default: true)
|
|
440
|
+
collapsed?: boolean; // Whether control starts collapsed (default: true)
|
|
441
|
+
displayMode?: "dropdown" | "gallery" | "list"; // UI mode (default: 'dropdown')
|
|
442
|
+
showSearch?: boolean; // Show search input (default: true)
|
|
443
|
+
filterGroups?: string[]; // Only include these provider groups
|
|
444
|
+
excludeGroups?: string[]; // Exclude these provider groups
|
|
445
|
+
excludeBroken?: boolean; // Exclude broken providers (default: true)
|
|
446
|
+
backgroundColor?: string;
|
|
447
|
+
maxWidth?: number;
|
|
448
|
+
maxHeight?: number;
|
|
449
|
+
fontSize?: number;
|
|
450
|
+
fontColor?: string;
|
|
451
|
+
minzoom?: number;
|
|
452
|
+
maxzoom?: number;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
interface BasemapItem {
|
|
456
|
+
id: string; // Unique identifier
|
|
457
|
+
name: string; // Display name
|
|
458
|
+
group?: string; // Provider group (e.g., 'OpenStreetMap')
|
|
459
|
+
url?: string; // XYZ tile URL template
|
|
460
|
+
style?: string; // MapLibre style URL
|
|
461
|
+
attribution?: string;
|
|
462
|
+
thumbnail?: string; // Preview image URL
|
|
463
|
+
maxZoom?: number;
|
|
464
|
+
minZoom?: number;
|
|
465
|
+
requiresApiKey?: boolean;
|
|
466
|
+
apiKey?: string;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Methods
|
|
470
|
+
basemapControl.show();
|
|
471
|
+
basemapControl.hide();
|
|
472
|
+
basemapControl.expand();
|
|
473
|
+
basemapControl.collapse();
|
|
474
|
+
basemapControl.toggle();
|
|
475
|
+
basemapControl.setBasemap(basemapId); // Switch to a basemap
|
|
476
|
+
basemapControl.getBasemaps(); // Get available basemaps
|
|
477
|
+
basemapControl.addBasemap(basemap); // Add a custom basemap
|
|
478
|
+
basemapControl.removeBasemap(id); // Remove a basemap
|
|
479
|
+
basemapControl.setApiKey(id, key); // Set API key for a basemap
|
|
480
|
+
basemapControl.getSelectedBasemap(); // Get currently selected basemap
|
|
481
|
+
basemapControl.update(options);
|
|
482
|
+
basemapControl.getState();
|
|
483
|
+
basemapControl.on("basemapchange", handler); // Listen for basemap changes
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
**Available Provider Groups:**
|
|
487
|
+
|
|
488
|
+
- OpenStreetMap, CartoDB, Stadia, Esri, OpenTopoMap
|
|
489
|
+
- Thunderforest, MapBox, MapTiler (require API keys)
|
|
490
|
+
- NASAGIBS, OpenSeaMap, and 20+ more
|
|
491
|
+
|
|
492
|
+
### SearchControl
|
|
493
|
+
|
|
494
|
+
A collapsible place search control with geocoding support.
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
interface SearchControlOptions {
|
|
498
|
+
position?: ControlPosition;
|
|
499
|
+
visible?: boolean; // Default: true
|
|
500
|
+
collapsed?: boolean; // Start collapsed (icon only). Default: true
|
|
501
|
+
placeholder?: string; // Search input placeholder. Default: 'Search places...'
|
|
502
|
+
geocoderUrl?: string; // Geocoding API URL. Default: Nominatim
|
|
503
|
+
maxResults?: number; // Max results to show. Default: 5
|
|
504
|
+
debounceMs?: number; // Debounce delay in ms. Default: 300
|
|
505
|
+
flyToZoom?: number; // Zoom level when selecting result. Default: 14
|
|
506
|
+
showMarker?: boolean; // Show marker at selected location. Default: true
|
|
507
|
+
markerColor?: string; // Marker color. Default: '#4264fb'
|
|
508
|
+
collapseOnSelect?: boolean; // Collapse after selecting. Default: true
|
|
509
|
+
clearOnSelect?: boolean; // Clear results after selecting. Default: true
|
|
510
|
+
geocoder?: (query: string) => Promise<SearchResult[]>; // Custom geocoder function
|
|
511
|
+
backgroundColor?: string;
|
|
512
|
+
borderRadius?: number;
|
|
513
|
+
opacity?: number;
|
|
514
|
+
width?: number; // Expanded width in pixels. Default: 280
|
|
515
|
+
fontSize?: number;
|
|
516
|
+
fontColor?: string;
|
|
517
|
+
minzoom?: number;
|
|
518
|
+
maxzoom?: number;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
interface SearchResult {
|
|
522
|
+
id: string; // Unique identifier
|
|
523
|
+
name: string; // Place name
|
|
524
|
+
displayName: string; // Full display name with address
|
|
525
|
+
lng: number; // Longitude
|
|
526
|
+
lat: number; // Latitude
|
|
527
|
+
bbox?: [number, number, number, number]; // Bounding box [west, south, east, north]
|
|
528
|
+
type?: string; // Place type (city, street, etc.)
|
|
529
|
+
importance?: number; // Relevance score
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Methods
|
|
533
|
+
searchControl.show();
|
|
534
|
+
searchControl.hide();
|
|
535
|
+
searchControl.expand(); // Expand to show input
|
|
536
|
+
searchControl.collapse(); // Collapse to icon only
|
|
537
|
+
searchControl.toggle(); // Toggle expanded/collapsed
|
|
538
|
+
searchControl.search(query); // Perform a search
|
|
539
|
+
searchControl.selectResult(result); // Select a result and fly to it
|
|
540
|
+
searchControl.clear(); // Clear search and marker
|
|
541
|
+
searchControl.update(options);
|
|
542
|
+
searchControl.getState();
|
|
543
|
+
searchControl.on("resultselect", handler); // Listen for result selection
|
|
544
|
+
searchControl.on("search", handler); // Listen for search completion
|
|
545
|
+
searchControl.on("clear", handler); // Listen for clear events
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Geocoding:**
|
|
549
|
+
By default, SearchControl uses [Nominatim](https://nominatim.openstreetmap.org/) (OpenStreetMap) for geocoding, which is free and requires no API key. You can also provide a custom geocoder function for other services.
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
// Using custom geocoder
|
|
553
|
+
const searchControl = new SearchControl({
|
|
554
|
+
geocoder: async (query) => {
|
|
555
|
+
const response = await fetch(`https://my-geocoder.com/search?q=${query}`);
|
|
556
|
+
const data = await response.json();
|
|
557
|
+
return data.map((item) => ({
|
|
558
|
+
id: item.id,
|
|
559
|
+
name: item.name,
|
|
560
|
+
displayName: item.address,
|
|
561
|
+
lng: item.longitude,
|
|
562
|
+
lat: item.latitude,
|
|
563
|
+
}));
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### VectorDatasetControl
|
|
569
|
+
|
|
570
|
+
A control for loading GeoJSON files via file upload button or drag-and-drop.
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
interface VectorDatasetControlOptions {
|
|
574
|
+
position?: ControlPosition;
|
|
575
|
+
visible?: boolean; // Default: true
|
|
576
|
+
showDropZone?: boolean; // Show overlay when dragging. Default: true
|
|
577
|
+
acceptedExtensions?: string[]; // File extensions. Default: ['.geojson', '.json']
|
|
578
|
+
multiple?: boolean; // Allow multiple files. Default: true
|
|
579
|
+
defaultStyle?: VectorLayerStyle; // Default styling for loaded layers
|
|
580
|
+
fitBounds?: boolean; // Fit map to loaded data. Default: true
|
|
581
|
+
fitBoundsPadding?: number; // Padding for fitBounds. Default: 50
|
|
582
|
+
maxFileSize?: number; // Max file size in bytes. Default: 50MB
|
|
583
|
+
backgroundColor?: string;
|
|
584
|
+
borderRadius?: number;
|
|
585
|
+
opacity?: number;
|
|
586
|
+
minzoom?: number;
|
|
587
|
+
maxzoom?: number;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
interface VectorLayerStyle {
|
|
591
|
+
fillColor?: string; // Polygon fill. Default: '#3388ff'
|
|
592
|
+
fillOpacity?: number; // Polygon fill opacity. Default: 0.3
|
|
593
|
+
strokeColor?: string; // Line/outline color. Default: '#3388ff'
|
|
594
|
+
strokeWidth?: number; // Line width. Default: 2
|
|
595
|
+
strokeOpacity?: number; // Line opacity. Default: 1
|
|
596
|
+
circleRadius?: number; // Point radius. Default: 6
|
|
597
|
+
circleColor?: string; // Point color. Default: '#3388ff'
|
|
598
|
+
circleStrokeColor?: string; // Point outline. Default: '#ffffff'
|
|
599
|
+
circleStrokeWidth?: number; // Point outline width. Default: 2
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
interface LoadedDataset {
|
|
603
|
+
id: string; // Unique ID
|
|
604
|
+
filename: string; // Original filename
|
|
605
|
+
sourceId: string; // MapLibre source ID
|
|
606
|
+
layerIds: string[]; // MapLibre layer IDs
|
|
607
|
+
featureCount: number; // Number of features
|
|
608
|
+
geometryTypes: string[]; // Geometry types present
|
|
609
|
+
loadedAt: Date; // When loaded
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Methods
|
|
613
|
+
vectorControl.show();
|
|
614
|
+
vectorControl.hide();
|
|
615
|
+
vectorControl.getLoadedDatasets(); // Get all loaded datasets
|
|
616
|
+
vectorControl.removeDataset(id); // Remove a dataset by ID
|
|
617
|
+
vectorControl.removeAllDatasets(); // Remove all datasets
|
|
618
|
+
vectorControl.loadGeoJSON(geojson, filename); // Programmatically load GeoJSON
|
|
619
|
+
vectorControl.update(options);
|
|
620
|
+
vectorControl.getState();
|
|
621
|
+
vectorControl.on("load", handler); // Fired when a dataset is loaded
|
|
622
|
+
vectorControl.on("error", handler); // Fired when an error occurs
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
**Loading Methods:**
|
|
626
|
+
|
|
627
|
+
- Click the upload button to open a file picker
|
|
628
|
+
- Drag and drop GeoJSON files directly onto the map
|
|
629
|
+
|
|
630
|
+
**Supported Formats:**
|
|
631
|
+
|
|
632
|
+
- GeoJSON (.geojson, .json)
|
|
633
|
+
- FeatureCollection, Feature, or raw Geometry objects
|
|
634
|
+
|
|
635
|
+
### AddVectorControl
|
|
636
|
+
|
|
637
|
+
A control for loading vector data from URLs with support for multiple formats and styling options.
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
interface AddVectorControlOptions {
|
|
641
|
+
position?: ControlPosition; // Control position (default: 'top-right')
|
|
642
|
+
className?: string; // Custom CSS class
|
|
643
|
+
visible?: boolean; // Initial visibility (default: true)
|
|
644
|
+
collapsed?: boolean; // Start collapsed (default: true)
|
|
645
|
+
beforeId?: string; // Layer ID to insert before
|
|
646
|
+
defaultUrl?: string; // Pre-filled URL
|
|
647
|
+
defaultLayerName?: string; // Pre-filled layer name
|
|
648
|
+
loadDefaultUrl?: boolean; // Auto-load defaultUrl on init (default: false)
|
|
649
|
+
defaultFormat?: "auto" | "geojson" | "geoparquet" | "flatgeobuf"; // Default format (default: 'auto')
|
|
650
|
+
defaultOpacity?: number; // Default opacity 0-1 (default: 1)
|
|
651
|
+
defaultFillColor?: string; // Default fill color (default: '#3388ff')
|
|
652
|
+
defaultStrokeColor?: string; // Default stroke color (default: '#3388ff')
|
|
653
|
+
defaultCircleColor?: string; // Default point color (default: '#3388ff')
|
|
654
|
+
defaultPickable?: boolean; // Enable click popups (default: true)
|
|
655
|
+
corsProxy?: string; // CORS proxy URL for cross-origin files
|
|
656
|
+
fitBounds?: boolean; // Fit to data bounds (default: true)
|
|
657
|
+
fitBoundsPadding?: number; // Padding for fitBounds (default: 50)
|
|
658
|
+
panelWidth?: number; // Panel width in pixels (default: 300)
|
|
659
|
+
backgroundColor?: string;
|
|
660
|
+
borderRadius?: number;
|
|
661
|
+
opacity?: number;
|
|
662
|
+
fontSize?: number;
|
|
663
|
+
fontColor?: string;
|
|
664
|
+
minzoom?: number;
|
|
665
|
+
maxzoom?: number;
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Usage:**
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
import { AddVectorControl } from "maplibre-gl-components";
|
|
673
|
+
|
|
674
|
+
// Basic usage
|
|
675
|
+
const addVectorControl = new AddVectorControl({
|
|
676
|
+
position: "top-right",
|
|
677
|
+
collapsed: false,
|
|
678
|
+
});
|
|
679
|
+
map.addControl(addVectorControl);
|
|
680
|
+
|
|
681
|
+
// With pre-filled URL that auto-loads
|
|
682
|
+
const addVectorControl = new AddVectorControl({
|
|
683
|
+
defaultUrl: "https://example.com/data.geojson",
|
|
684
|
+
loadDefaultUrl: true,
|
|
685
|
+
defaultOpacity: 0.8,
|
|
686
|
+
defaultFillColor: "#ff6600",
|
|
687
|
+
fitBounds: true,
|
|
688
|
+
});
|
|
689
|
+
map.addControl(addVectorControl);
|
|
690
|
+
|
|
691
|
+
// Listen for events
|
|
692
|
+
addVectorControl.on("layeradd", (event) => {
|
|
693
|
+
console.log("Layer added:", event.layerId, event.url);
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
addVectorControl.on("layerremove", (event) => {
|
|
697
|
+
console.log("Layer removed:", event.layerId);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
addVectorControl.on("error", (event) => {
|
|
701
|
+
console.error("Error:", event.error);
|
|
702
|
+
});
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Methods:**
|
|
706
|
+
|
|
707
|
+
```typescript
|
|
708
|
+
addVectorControl.expand()
|
|
709
|
+
addVectorControl.collapse()
|
|
710
|
+
addVectorControl.toggle()
|
|
711
|
+
addVectorControl.show()
|
|
712
|
+
addVectorControl.hide()
|
|
713
|
+
addVectorControl.getState()
|
|
714
|
+
addVectorControl.update(options)
|
|
715
|
+
addVectorControl.loadUrl(url, format?) // Programmatically load a URL
|
|
716
|
+
addVectorControl.getOpacity(layerId) // Get layer opacity
|
|
717
|
+
addVectorControl.setOpacity(layerId, value) // Set layer opacity
|
|
718
|
+
addVectorControl.getVisibility(layerId) // Get layer visibility
|
|
719
|
+
addVectorControl.setVisibility(layerId, visible) // Set layer visibility
|
|
720
|
+
addVectorControl.removeLayer(layerId) // Remove a layer
|
|
721
|
+
addVectorControl.removeAllLayers() // Remove all layers
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
**Supported Formats:**
|
|
725
|
+
|
|
726
|
+
- GeoJSON (.geojson, .json)
|
|
727
|
+
- GeoParquet (.parquet, .geoparquet)
|
|
728
|
+
- FlatGeobuf (.fgb)
|
|
729
|
+
|
|
730
|
+
**Features:**
|
|
731
|
+
|
|
732
|
+
- Auto-detect format from URL extension
|
|
733
|
+
- Customizable fill, stroke, and point colors
|
|
734
|
+
- Opacity slider with real-time updates
|
|
735
|
+
- Pickable layers with feature info popups on click
|
|
736
|
+
- Layer name and beforeId for layer ordering
|
|
737
|
+
- Fit map bounds to loaded data
|
|
738
|
+
|
|
739
|
+
### TerrainControl
|
|
740
|
+
|
|
741
|
+
A toggle control for 3D terrain rendering using free AWS Terrarium elevation tiles.
|
|
742
|
+
|
|
743
|
+
```typescript
|
|
744
|
+
interface TerrainControlOptions {
|
|
745
|
+
sourceUrl?: string; // Terrain tile URL (default: AWS Terrarium)
|
|
746
|
+
encoding?: "terrarium" | "mapbox"; // Terrain encoding (default: 'terrarium')
|
|
747
|
+
exaggeration?: number; // Vertical scale factor (default: 1.0)
|
|
748
|
+
enabled?: boolean; // Initial terrain state (default: false)
|
|
749
|
+
hillshade?: boolean; // Add hillshade layer (default: true)
|
|
750
|
+
hillshadeExaggeration?: number; // Hillshade intensity (default: 0.5)
|
|
751
|
+
position?: ControlPosition;
|
|
752
|
+
visible?: boolean;
|
|
753
|
+
backgroundColor?: string;
|
|
754
|
+
borderRadius?: number;
|
|
755
|
+
opacity?: number;
|
|
756
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
757
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// Methods
|
|
761
|
+
terrainControl.show();
|
|
762
|
+
terrainControl.hide();
|
|
763
|
+
terrainControl.enable(); // Enable terrain
|
|
764
|
+
terrainControl.disable(); // Disable terrain
|
|
765
|
+
terrainControl.toggle(); // Toggle terrain on/off
|
|
766
|
+
terrainControl.isEnabled(); // Check if terrain is enabled
|
|
767
|
+
terrainControl.setExaggeration(value); // Set vertical exaggeration (0.1 - 10.0)
|
|
768
|
+
terrainControl.getExaggeration(); // Get current exaggeration
|
|
769
|
+
terrainControl.enableHillshade(); // Enable hillshade layer
|
|
770
|
+
terrainControl.disableHillshade(); // Disable hillshade layer
|
|
771
|
+
terrainControl.toggleHillshade(); // Toggle hillshade layer
|
|
772
|
+
terrainControl.update(options);
|
|
773
|
+
terrainControl.getState();
|
|
774
|
+
terrainControl.on("terrainchange", handler); // Listen for terrain toggle
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
**Terrain Source:**
|
|
778
|
+
The control uses free terrain tiles from AWS:
|
|
779
|
+
|
|
780
|
+
- URL: `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png`
|
|
781
|
+
- Encoding: Terrarium RGB-encoded elevation data
|
|
782
|
+
- No API key required
|
|
783
|
+
|
|
784
|
+
### InspectControl
|
|
785
|
+
|
|
786
|
+
A control for inspecting vector features on the map. Click on features to view their properties/attributes in a popup.
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
interface InspectControlOptions {
|
|
790
|
+
position?: ControlPosition;
|
|
791
|
+
visible?: boolean; // Default: true
|
|
792
|
+
enabled?: boolean; // Start with inspect mode on. Default: false
|
|
793
|
+
maxFeatures?: number; // Max features at click point. Default: 10
|
|
794
|
+
includeLayers?: string[]; // Only inspect these layers
|
|
795
|
+
excludeLayers?: string[]; // Skip these layers
|
|
796
|
+
highlightStyle?: InspectHighlightStyle; // Style for selected feature
|
|
797
|
+
excludeProperties?: string[]; // Properties to hide (e.g., internal IDs)
|
|
798
|
+
showGeometryType?: boolean; // Show geometry type badge. Default: true
|
|
799
|
+
showLayerName?: boolean; // Show layer name. Default: true
|
|
800
|
+
maxWidth?: number; // Popup max width. Default: 320
|
|
801
|
+
maxHeight?: number; // Popup content max height. Default: 300
|
|
802
|
+
backgroundColor?: string;
|
|
803
|
+
borderRadius?: number;
|
|
804
|
+
opacity?: number;
|
|
805
|
+
fontSize?: number;
|
|
806
|
+
fontColor?: string;
|
|
807
|
+
minzoom?: number;
|
|
808
|
+
maxzoom?: number;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
interface InspectHighlightStyle {
|
|
812
|
+
fillColor?: string; // Polygon fill. Default: '#ffff00'
|
|
813
|
+
fillOpacity?: number; // Polygon fill opacity. Default: 0.3
|
|
814
|
+
strokeColor?: string; // Line/outline color. Default: '#ffff00'
|
|
815
|
+
strokeWidth?: number; // Line width. Default: 3
|
|
816
|
+
circleRadius?: number; // Point radius. Default: 10
|
|
817
|
+
circleStrokeWidth?: number; // Point outline. Default: 3
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
interface InspectedFeature {
|
|
821
|
+
id: string; // Unique inspection ID
|
|
822
|
+
feature: GeoJSON.Feature; // The GeoJSON feature
|
|
823
|
+
layerId: string; // MapLibre layer ID
|
|
824
|
+
sourceId: string; // MapLibre source ID
|
|
825
|
+
lngLat: [number, number]; // Click coordinates
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Methods
|
|
829
|
+
inspectControl.show();
|
|
830
|
+
inspectControl.hide();
|
|
831
|
+
inspectControl.enable(); // Enable inspect mode
|
|
832
|
+
inspectControl.disable(); // Disable inspect mode
|
|
833
|
+
inspectControl.toggle(); // Toggle inspect mode on/off
|
|
834
|
+
inspectControl.isEnabled(); // Check if inspect mode is enabled
|
|
835
|
+
inspectControl.clear(); // Clear current inspection
|
|
836
|
+
inspectControl.getInspectedFeatures(); // Get all features at click point
|
|
837
|
+
inspectControl.getSelectedFeature(); // Get currently selected feature
|
|
838
|
+
inspectControl.selectFeature(index); // Select feature by index
|
|
839
|
+
inspectControl.nextFeature(); // Navigate to next feature
|
|
840
|
+
inspectControl.previousFeature(); // Navigate to previous feature
|
|
841
|
+
inspectControl.update(options);
|
|
842
|
+
inspectControl.getState();
|
|
843
|
+
inspectControl.on("enable", handler); // Fired when inspect mode is enabled
|
|
844
|
+
inspectControl.on("disable", handler); // Fired when inspect mode is disabled
|
|
845
|
+
inspectControl.on("featureselect", handler); // Fired when a feature is selected
|
|
846
|
+
inspectControl.on("clear", handler); // Fired when inspection is cleared
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Usage:**
|
|
850
|
+
|
|
851
|
+
1. Click the info button to enable inspect mode
|
|
852
|
+
2. Click on any vector feature on the map
|
|
853
|
+
3. View properties in the popup
|
|
854
|
+
4. Use < > buttons to navigate when multiple features are at the same location
|
|
855
|
+
5. Click elsewhere or the button again to disable
|
|
856
|
+
|
|
857
|
+
### ViewStateControl
|
|
858
|
+
|
|
859
|
+
A control that displays live map view state (center, bounds, zoom, pitch, bearing) with optional bounding box drawing.
|
|
860
|
+
|
|
861
|
+
```typescript
|
|
862
|
+
interface ViewStateControlOptions {
|
|
863
|
+
position?: ControlPosition;
|
|
864
|
+
className?: string; // Custom CSS class
|
|
865
|
+
visible?: boolean; // Default: true
|
|
866
|
+
collapsed?: boolean; // Start collapsed (button only). Default: true
|
|
867
|
+
precision?: number; // Decimal precision for coordinates. Default: 4
|
|
868
|
+
showCenter?: boolean; // Show center coordinates. Default: true
|
|
869
|
+
showBounds?: boolean; // Show map bounds. Default: true
|
|
870
|
+
showZoom?: boolean; // Show zoom level. Default: true
|
|
871
|
+
showPitch?: boolean; // Show pitch value. Default: true
|
|
872
|
+
showBearing?: boolean; // Show bearing value. Default: true
|
|
873
|
+
enableBBox?: boolean; // Enable bounding box drawing. Default: false
|
|
874
|
+
bboxFillColor?: string; // BBox fill color. Default: 'rgba(0, 120, 215, 0.1)'
|
|
875
|
+
bboxStrokeColor?: string; // BBox stroke color. Default: '#0078d7'
|
|
876
|
+
bboxStrokeWidth?: number; // BBox stroke width. Default: 2
|
|
877
|
+
panelWidth?: number; // Panel width in pixels. Default: 280
|
|
878
|
+
backgroundColor?: string;
|
|
879
|
+
borderRadius?: number;
|
|
880
|
+
opacity?: number;
|
|
881
|
+
fontSize?: number;
|
|
882
|
+
fontColor?: string;
|
|
883
|
+
minzoom?: number;
|
|
884
|
+
maxzoom?: number;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
interface ViewStateControlState {
|
|
888
|
+
visible: boolean;
|
|
889
|
+
collapsed: boolean;
|
|
890
|
+
center: [number, number]; // [lng, lat]
|
|
891
|
+
bounds: [number, number, number, number]; // [west, south, east, north]
|
|
892
|
+
zoom: number;
|
|
893
|
+
pitch: number; // Degrees
|
|
894
|
+
bearing: number; // Degrees
|
|
895
|
+
drawingBBox: boolean; // Whether bbox drawing is active
|
|
896
|
+
drawnBBox: [number, number, number, number] | null; // Drawn bbox or null
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// Methods
|
|
900
|
+
viewStateControl.show();
|
|
901
|
+
viewStateControl.hide();
|
|
902
|
+
viewStateControl.expand(); // Expand the panel
|
|
903
|
+
viewStateControl.collapse(); // Collapse to button only
|
|
904
|
+
viewStateControl.toggle(); // Toggle expanded/collapsed
|
|
905
|
+
viewStateControl.isCollapsed(); // Check if collapsed
|
|
906
|
+
viewStateControl.startBBoxDraw(); // Start bounding box drawing mode
|
|
907
|
+
viewStateControl.stopBBoxDraw(); // Stop bounding box drawing mode
|
|
908
|
+
viewStateControl.clearBBox(); // Clear the drawn bounding box
|
|
909
|
+
viewStateControl.update(options);
|
|
910
|
+
viewStateControl.getState();
|
|
911
|
+
viewStateControl.on("viewchange", handler); // Fired when map view changes
|
|
912
|
+
viewStateControl.on("bboxdraw", handler); // Fired when bbox is drawn
|
|
913
|
+
viewStateControl.on("bboxclear", handler); // Fired when bbox is cleared
|
|
914
|
+
viewStateControl.on("drawstart", handler); // Fired when drawing mode starts
|
|
915
|
+
viewStateControl.on("drawend", handler); // Fired when drawing mode ends
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
**Usage:**
|
|
919
|
+
|
|
920
|
+
1. Click the target button to expand/collapse the panel
|
|
921
|
+
2. Pan, zoom, or tilt the map to see live updates
|
|
922
|
+
3. Click "Draw BBox" to enter drawing mode
|
|
923
|
+
4. Click and drag on the map to draw a bounding box
|
|
924
|
+
5. Copy coordinates using the copy button next to each value
|
|
925
|
+
|
|
926
|
+
### CogLayerControl
|
|
927
|
+
|
|
928
|
+
A control for adding Cloud Optimized GeoTIFF (COG) layers to the map. Uses deck.gl's COGLayer for efficient streaming and rendering.
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
interface CogLayerControlOptions {
|
|
932
|
+
position?: ControlPosition;
|
|
933
|
+
className?: string; // Custom CSS class
|
|
934
|
+
visible?: boolean; // Default: true
|
|
935
|
+
collapsed?: boolean; // Start collapsed. Default: true
|
|
936
|
+
beforeId?: string; // Layer ID to insert before (for ordering)
|
|
937
|
+
defaultUrl?: string; // Initial COG URL
|
|
938
|
+
loadDefaultUrl?: boolean; // Auto-load defaultUrl on add. Default: false
|
|
939
|
+
defaultBands?: string; // Band selection (e.g., "1" or "1,2,3"). Default: "1"
|
|
940
|
+
defaultColormap?: ColormapName | 'none'; // Colormap name. Default: 'none'
|
|
941
|
+
defaultRescaleMin?: number; // Min value for rescaling. Default: 0
|
|
942
|
+
defaultRescaleMax?: number; // Max value for rescaling. Default: 255
|
|
943
|
+
defaultNodata?: number; // Nodata value to mask
|
|
944
|
+
defaultOpacity?: number; // Layer opacity. Default: 1
|
|
945
|
+
panelWidth?: number; // Panel width in pixels. Default: 300
|
|
946
|
+
backgroundColor?: string;
|
|
947
|
+
borderRadius?: number;
|
|
948
|
+
opacity?: number;
|
|
949
|
+
fontSize?: number;
|
|
950
|
+
fontColor?: string;
|
|
951
|
+
minzoom?: number;
|
|
952
|
+
maxzoom?: number;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// Methods
|
|
956
|
+
cogControl.show()
|
|
957
|
+
cogControl.hide()
|
|
958
|
+
cogControl.expand()
|
|
959
|
+
cogControl.collapse()
|
|
960
|
+
cogControl.toggle()
|
|
961
|
+
cogControl.getState()
|
|
962
|
+
cogControl.update(options)
|
|
963
|
+
cogControl.addLayer(url?) // Add a COG layer
|
|
964
|
+
cogControl.removeLayer(id?) // Remove layer by ID or all
|
|
965
|
+
cogControl.getLayerIds() // Get all layer IDs
|
|
966
|
+
cogControl.getLayerOpacity(id) // Get layer opacity
|
|
967
|
+
cogControl.setLayerOpacity(id, opacity) // Set layer opacity
|
|
968
|
+
cogControl.getLayerVisibility(id) // Check if layer is visible
|
|
969
|
+
cogControl.setLayerVisibility(id, visible) // Show/hide layer
|
|
970
|
+
cogControl.getLayerUrl(id) // Get COG URL for a layer
|
|
971
|
+
cogControl.on('layeradd', handler) // Fired when layer is added
|
|
972
|
+
cogControl.on('layerremove', handler) // Fired when layer is removed
|
|
973
|
+
cogControl.on('error', handler) // Fired on error
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
**Features:**
|
|
977
|
+
|
|
978
|
+
- Supports single-band and multi-band GeoTIFFs
|
|
979
|
+
- Automatic float/integer data type detection
|
|
980
|
+
- 21 built-in colormaps with live preview
|
|
981
|
+
- Rescale values for visualization
|
|
982
|
+
- Nodata value masking
|
|
983
|
+
- Opacity control
|
|
984
|
+
- Layer ordering with `beforeId`
|
|
985
|
+
- Multiple COG layers support
|
|
986
|
+
|
|
987
|
+
### ZarrLayerControl
|
|
988
|
+
|
|
989
|
+
A control for adding Zarr layers to the map. Uses @carbonplan/zarr-layer for rendering multi-dimensional Zarr data.
|
|
990
|
+
|
|
991
|
+
```typescript
|
|
992
|
+
interface ZarrLayerControlOptions {
|
|
993
|
+
position?: ControlPosition;
|
|
994
|
+
className?: string; // Custom CSS class
|
|
995
|
+
visible?: boolean; // Default: true
|
|
996
|
+
collapsed?: boolean; // Start collapsed. Default: true
|
|
997
|
+
beforeId?: string; // Layer ID to insert before (for ordering)
|
|
998
|
+
defaultUrl?: string; // Initial Zarr store URL
|
|
999
|
+
loadDefaultUrl?: boolean; // Auto-load defaultUrl on add. Default: false
|
|
1000
|
+
defaultVariable?: string; // Variable/array name to visualize
|
|
1001
|
+
defaultColormap?: string[]; // Array of hex colors. Default: viridis
|
|
1002
|
+
defaultClim?: [number, number]; // Color limits [min, max]. Default: [0, 1]
|
|
1003
|
+
defaultSelector?: Record<string, number | string>; // Dimension selectors
|
|
1004
|
+
defaultOpacity?: number; // Layer opacity. Default: 1
|
|
1005
|
+
panelWidth?: number; // Panel width in pixels. Default: 300
|
|
1006
|
+
backgroundColor?: string;
|
|
1007
|
+
borderRadius?: number;
|
|
1008
|
+
opacity?: number;
|
|
1009
|
+
fontSize?: number;
|
|
1010
|
+
fontColor?: string;
|
|
1011
|
+
minzoom?: number;
|
|
1012
|
+
maxzoom?: number;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Methods
|
|
1016
|
+
zarrControl.show()
|
|
1017
|
+
zarrControl.hide()
|
|
1018
|
+
zarrControl.expand()
|
|
1019
|
+
zarrControl.collapse()
|
|
1020
|
+
zarrControl.toggle()
|
|
1021
|
+
zarrControl.getState()
|
|
1022
|
+
zarrControl.update(options)
|
|
1023
|
+
zarrControl.addLayer(url?, variable?) // Add a Zarr layer
|
|
1024
|
+
zarrControl.removeLayer(id?) // Remove layer by ID or all
|
|
1025
|
+
zarrControl.getLayerIds() // Get all layer IDs
|
|
1026
|
+
zarrControl.getLayerOpacity(id) // Get layer opacity
|
|
1027
|
+
zarrControl.setLayerOpacity(id, opacity) // Set layer opacity
|
|
1028
|
+
zarrControl.getLayerVisibility(id) // Check if layer is visible
|
|
1029
|
+
zarrControl.setLayerVisibility(id, visible) // Show/hide layer
|
|
1030
|
+
zarrControl.getLayerUrl(id) // Get Zarr URL for a layer
|
|
1031
|
+
zarrControl.fetchVariables() // Fetch available variables from store
|
|
1032
|
+
zarrControl.on('layeradd', handler) // Fired when layer is added
|
|
1033
|
+
zarrControl.on('layerremove', handler) // Fired when layer is removed
|
|
1034
|
+
zarrControl.on('error', handler) // Fired on error
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
**Features:**
|
|
1038
|
+
|
|
1039
|
+
- Multi-dimensional array support (time, band, etc.)
|
|
1040
|
+
- Automatic variable discovery from Zarr metadata
|
|
1041
|
+
- 21 built-in colormaps with live preview
|
|
1042
|
+
- Custom colormap support (array of hex colors)
|
|
1043
|
+
- Dimension selectors for slicing data
|
|
1044
|
+
- Smooth opacity control
|
|
1045
|
+
- Layer ordering with `beforeId`
|
|
1046
|
+
- Multiple Zarr layers support
|
|
1047
|
+
|
|
1048
|
+
**Example with dimension selector:**
|
|
1049
|
+
|
|
1050
|
+
```typescript
|
|
1051
|
+
const zarrControl = new ZarrLayerControl({
|
|
1052
|
+
defaultUrl: "https://example.com/climate.zarr",
|
|
1053
|
+
defaultVariable: "temperature",
|
|
1054
|
+
defaultColormap: ["#0000ff", "#ffffff", "#ff0000"], // Custom blue-white-red
|
|
1055
|
+
defaultClim: [-20, 40],
|
|
1056
|
+
defaultSelector: { time: 0, month: "January" }, // Select first time step, January
|
|
1057
|
+
});
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
### StacLayerControl
|
|
1061
|
+
|
|
1062
|
+
A control for loading Cloud Optimized GeoTIFF (COG) layers from STAC (SpatioTemporal Asset Catalog) items. Fetches STAC item metadata and displays available COG assets for visualization.
|
|
1063
|
+
|
|
1064
|
+
```typescript
|
|
1065
|
+
interface StacLayerControlOptions {
|
|
1066
|
+
position?: ControlPosition;
|
|
1067
|
+
className?: string; // Custom CSS class
|
|
1068
|
+
visible?: boolean; // Default: true
|
|
1069
|
+
collapsed?: boolean; // Start collapsed. Default: true
|
|
1070
|
+
beforeId?: string; // Layer ID to insert before (for ordering)
|
|
1071
|
+
defaultUrl?: string; // Initial STAC item URL
|
|
1072
|
+
loadDefaultUrl?: boolean; // Auto-load defaultUrl on add. Default: false
|
|
1073
|
+
defaultColormap?: ColormapName | "none"; // Colormap name. Default: 'none'
|
|
1074
|
+
defaultRescaleMin?: number; // Min value for rescaling. Default: 0
|
|
1075
|
+
defaultRescaleMax?: number; // Max value for rescaling. Default: 255
|
|
1076
|
+
defaultOpacity?: number; // Layer opacity. Default: 1
|
|
1077
|
+
defaultPickable?: boolean; // Enable click popups. Default: true
|
|
1078
|
+
panelWidth?: number; // Panel width in pixels. Default: 320
|
|
1079
|
+
backgroundColor?: string;
|
|
1080
|
+
borderRadius?: number;
|
|
1081
|
+
opacity?: number;
|
|
1082
|
+
fontSize?: number;
|
|
1083
|
+
fontColor?: string;
|
|
1084
|
+
minzoom?: number;
|
|
1085
|
+
maxzoom?: number;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// Methods
|
|
1089
|
+
stacControl.show();
|
|
1090
|
+
stacControl.hide();
|
|
1091
|
+
stacControl.expand();
|
|
1092
|
+
stacControl.collapse();
|
|
1093
|
+
stacControl.toggle();
|
|
1094
|
+
stacControl.getState();
|
|
1095
|
+
stacControl.update(options);
|
|
1096
|
+
stacControl.loadStacUrl(url); // Fetch and parse a STAC item
|
|
1097
|
+
stacControl.on("stacload", handler); // Fired when STAC item is loaded
|
|
1098
|
+
stacControl.on("layeradd", handler); // Fired when layer is added
|
|
1099
|
+
stacControl.on("layerremove", handler); // Fired when layer is removed
|
|
1100
|
+
stacControl.on("error", handler); // Fired on error
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
**Usage:**
|
|
1104
|
+
|
|
1105
|
+
```typescript
|
|
1106
|
+
import { StacLayerControl } from "maplibre-gl-components";
|
|
1107
|
+
|
|
1108
|
+
// Basic usage with STAC item URL
|
|
1109
|
+
const stacControl = new StacLayerControl({
|
|
1110
|
+
defaultUrl:
|
|
1111
|
+
"https://canada-spot-ortho.s3.amazonaws.com/.../S5_11055_6057_20070622.json",
|
|
1112
|
+
loadDefaultUrl: true,
|
|
1113
|
+
defaultColormap: "viridis",
|
|
1114
|
+
defaultRescaleMin: 0,
|
|
1115
|
+
defaultRescaleMax: 255,
|
|
1116
|
+
});
|
|
1117
|
+
map.addControl(stacControl, "top-right");
|
|
1118
|
+
|
|
1119
|
+
// Listen for events
|
|
1120
|
+
stacControl.on("stacload", (event) => {
|
|
1121
|
+
console.log("STAC loaded:", event.url);
|
|
1122
|
+
console.log("Available assets:", event.state.assets);
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1125
|
+
stacControl.on("layeradd", (event) => {
|
|
1126
|
+
console.log("Layer added:", event.assetKey, event.layerId);
|
|
1127
|
+
});
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
**Features:**
|
|
1131
|
+
|
|
1132
|
+
- Fetches and parses STAC item JSON
|
|
1133
|
+
- Lists available COG assets (GeoTIFF files)
|
|
1134
|
+
- Asset selector dropdown
|
|
1135
|
+
- 21 built-in colormaps with live preview
|
|
1136
|
+
- Rescale values for visualization
|
|
1137
|
+
- Opacity control
|
|
1138
|
+
- Pickable layers with info popup on click
|
|
1139
|
+
- Auto-fits map to STAC item bounding box
|
|
1140
|
+
- Multiple layer support
|
|
1141
|
+
|
|
1142
|
+
**Workflow:**
|
|
1143
|
+
|
|
1144
|
+
1. Enter a STAC item URL and click "Fetch STAC"
|
|
1145
|
+
2. Select a COG asset from the dropdown
|
|
1146
|
+
3. Configure colormap, rescale range, and opacity
|
|
1147
|
+
4. Click "Add Layer" to visualize
|
|
1148
|
+
5. Click on the layer to view info (if pickable)
|
|
1149
|
+
|
|
1150
|
+
### StacSearchControl
|
|
1151
|
+
|
|
1152
|
+
A control for searching and visualizing STAC items from public STAC API catalogs. Search within the current map viewport, browse results, and display imagery with customizable band combinations and colormaps.
|
|
1153
|
+
|
|
1154
|
+
```typescript
|
|
1155
|
+
interface StacSearchControlOptions {
|
|
1156
|
+
position?: ControlPosition;
|
|
1157
|
+
className?: string; // Custom CSS class
|
|
1158
|
+
visible?: boolean; // Default: true
|
|
1159
|
+
collapsed?: boolean; // Start collapsed. Default: true
|
|
1160
|
+
panelWidth?: number; // Panel width in pixels. Default: 360
|
|
1161
|
+
maxHeight?: number; // Max panel height in pixels. Default: none
|
|
1162
|
+
catalogs?: StacCatalog[]; // Predefined STAC catalogs
|
|
1163
|
+
maxItems?: number; // Max search results. Default: 20
|
|
1164
|
+
defaultRescaleMin?: number; // Min rescale value. Default: 0
|
|
1165
|
+
defaultRescaleMax?: number; // Max rescale value. Default: 10000
|
|
1166
|
+
defaultColormap?: string; // Colormap for single band. Default: 'viridis'
|
|
1167
|
+
defaultRgbMode?: boolean; // Start in RGB mode. Default: true
|
|
1168
|
+
showFootprints?: boolean; // Show item footprints on map. Default: true
|
|
1169
|
+
backgroundColor?: string;
|
|
1170
|
+
borderRadius?: number;
|
|
1171
|
+
opacity?: number;
|
|
1172
|
+
fontSize?: number;
|
|
1173
|
+
fontColor?: string;
|
|
1174
|
+
minzoom?: number;
|
|
1175
|
+
maxzoom?: number;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
interface StacCatalog {
|
|
1179
|
+
name: string; // Display name
|
|
1180
|
+
url: string; // STAC API URL
|
|
1181
|
+
}
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
**Usage:**
|
|
1185
|
+
|
|
1186
|
+
```typescript
|
|
1187
|
+
import { StacSearchControl } from "maplibre-gl-components";
|
|
1188
|
+
|
|
1189
|
+
// Basic usage with default catalogs
|
|
1190
|
+
const stacSearch = new StacSearchControl({
|
|
1191
|
+
collapsed: false,
|
|
1192
|
+
maxItems: 20,
|
|
1193
|
+
showFootprints: true,
|
|
1194
|
+
});
|
|
1195
|
+
map.addControl(stacSearch, "top-right");
|
|
1196
|
+
|
|
1197
|
+
// With custom catalogs
|
|
1198
|
+
const stacSearch = new StacSearchControl({
|
|
1199
|
+
catalogs: [
|
|
1200
|
+
{
|
|
1201
|
+
name: "Element84 Earth Search",
|
|
1202
|
+
url: "https://earth-search.aws.element84.com/v1",
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
name: "Microsoft Planetary Computer",
|
|
1206
|
+
url: "https://planetarycomputer.microsoft.com/api/stac/v1",
|
|
1207
|
+
},
|
|
1208
|
+
],
|
|
1209
|
+
defaultRgbMode: true,
|
|
1210
|
+
defaultRescaleMin: 0,
|
|
1211
|
+
defaultRescaleMax: 3000,
|
|
1212
|
+
maxHeight: 500,
|
|
1213
|
+
});
|
|
1214
|
+
map.addControl(stacSearch, "top-right");
|
|
1215
|
+
|
|
1216
|
+
// Listen for events
|
|
1217
|
+
stacSearch.on("catalogselect", (event) => {
|
|
1218
|
+
console.log("Catalog selected:", event.catalog?.name);
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
stacSearch.on("collectionsload", (event) => {
|
|
1222
|
+
console.log("Collections loaded:", event.state.collections.length);
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
stacSearch.on("collectionselect", (event) => {
|
|
1226
|
+
console.log("Collection selected:", event.collection?.id);
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
stacSearch.on("search", (event) => {
|
|
1230
|
+
console.log("Search completed:", event.state.items.length, "items found");
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
stacSearch.on("itemselect", (event) => {
|
|
1234
|
+
console.log("Item selected:", event.item?.id);
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
stacSearch.on("display", (event) => {
|
|
1238
|
+
console.log("Item displayed:", event.item?.id);
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
stacSearch.on("error", (event) => {
|
|
1242
|
+
console.error("Error:", event.error);
|
|
1243
|
+
});
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
**Methods:**
|
|
1247
|
+
|
|
1248
|
+
```typescript
|
|
1249
|
+
stacSearch.show();
|
|
1250
|
+
stacSearch.hide();
|
|
1251
|
+
stacSearch.expand();
|
|
1252
|
+
stacSearch.collapse();
|
|
1253
|
+
stacSearch.toggle();
|
|
1254
|
+
stacSearch.getState();
|
|
1255
|
+
stacSearch.update(options);
|
|
1256
|
+
stacSearch.getSelectedCatalog(); // Get current catalog
|
|
1257
|
+
stacSearch.getSelectedCollection(); // Get current collection
|
|
1258
|
+
stacSearch.getSelectedItem(); // Get current item
|
|
1259
|
+
stacSearch.on(event, handler); // Subscribe to events
|
|
1260
|
+
stacSearch.off(event, handler); // Unsubscribe from events
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
**Default Catalogs:**
|
|
1264
|
+
|
|
1265
|
+
- **Element84 Earth Search** - Sentinel-2, Landsat, NAIP, Copernicus DEM
|
|
1266
|
+
- **Microsoft Planetary Computer** - Extensive collection with tile server
|
|
1267
|
+
|
|
1268
|
+
**Features:**
|
|
1269
|
+
|
|
1270
|
+
- Search STAC items within current map viewport
|
|
1271
|
+
- Date range filtering
|
|
1272
|
+
- Query filter support (e.g., cloud cover)
|
|
1273
|
+
- Footprint visualization on map
|
|
1274
|
+
- **Visualization modes:**
|
|
1275
|
+
- **RGB Composite** - Select R, G, B bands for true/false color composites
|
|
1276
|
+
- **Single Band** - Select one band with colormap
|
|
1277
|
+
- 21 built-in colormaps for single band visualization
|
|
1278
|
+
- Rescale range adjustment
|
|
1279
|
+
- Auto-detects available bands/assets from STAC items
|
|
1280
|
+
- Custom catalog URL support
|
|
1281
|
+
|
|
1282
|
+
**Workflow:**
|
|
1283
|
+
|
|
1284
|
+
1. Select a catalog (or enter custom URL)
|
|
1285
|
+
2. Click "Collections" to load available collections
|
|
1286
|
+
3. Select a collection (e.g., sentinel-2-l2a)
|
|
1287
|
+
4. Optionally set date range and query filters
|
|
1288
|
+
5. Click "Search" to find items in current map viewport
|
|
1289
|
+
6. Select an item from the dropdown
|
|
1290
|
+
7. Choose visualization mode (RGB or Single Band)
|
|
1291
|
+
8. Select bands and adjust rescale range
|
|
1292
|
+
9. Click "Display Item" to visualize
|
|
1293
|
+
|
|
1294
|
+
### MeasureControl
|
|
1295
|
+
|
|
1296
|
+
A control for measuring distances and areas on the map.
|
|
1297
|
+
|
|
1298
|
+
See the [measure-control example](./examples/measure-control/) for a complete working example.
|
|
1299
|
+
|
|
1300
|
+
### BookmarkControl
|
|
1301
|
+
|
|
1302
|
+
A control for saving and restoring map views with localStorage persistence.
|
|
1303
|
+
|
|
1304
|
+
See the [bookmark-control example](./examples/bookmark-control/) for a complete working example.
|
|
1305
|
+
|
|
1306
|
+
### PrintControl
|
|
1307
|
+
|
|
1308
|
+
A control for exporting the current map view as PNG, JPEG, or PDF. Supports optional title overlays, custom filenames, quality settings, and custom export sizes. PDF export requires the optional `jspdf` peer dependency.
|
|
1309
|
+
|
|
1310
|
+
```typescript
|
|
1311
|
+
interface PrintControlOptions {
|
|
1312
|
+
position?: ControlPosition; // Control position (default: 'top-right')
|
|
1313
|
+
className?: string; // Custom CSS class
|
|
1314
|
+
visible?: boolean; // Initial visibility (default: true)
|
|
1315
|
+
collapsed?: boolean; // Start collapsed (default: true)
|
|
1316
|
+
format?: "png" | "jpeg" | "pdf"; // Default format (default: 'png')
|
|
1317
|
+
quality?: number; // JPEG quality 0-1 (default: 0.92)
|
|
1318
|
+
filename?: string; // Default filename without extension (default: 'map-export')
|
|
1319
|
+
title?: string; // Optional title rendered on the image
|
|
1320
|
+
includeNorthArrow?: boolean; // Include north arrow in export (default: false)
|
|
1321
|
+
includeScaleBar?: boolean; // Include scale bar in export (default: false)
|
|
1322
|
+
titleFontSize?: number; // Title font size in pixels (default: 24)
|
|
1323
|
+
titleFontColor?: string; // Title font color (default: '#333333')
|
|
1324
|
+
titleBackground?: string; // Title background (default: 'rgba(255,255,255,0.8)')
|
|
1325
|
+
showSizeOptions?: boolean; // Show current/custom size options (default: false)
|
|
1326
|
+
width?: number; // Width override in pixels
|
|
1327
|
+
height?: number; // Height override in pixels
|
|
1328
|
+
panelWidth?: number; // Panel width in pixels (default: 280)
|
|
1329
|
+
backgroundColor?: string;
|
|
1330
|
+
borderRadius?: number;
|
|
1331
|
+
opacity?: number;
|
|
1332
|
+
fontSize?: number;
|
|
1333
|
+
fontColor?: string;
|
|
1334
|
+
minzoom?: number;
|
|
1335
|
+
maxzoom?: number;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
// Methods
|
|
1339
|
+
printControl.show()
|
|
1340
|
+
printControl.hide()
|
|
1341
|
+
printControl.getState()
|
|
1342
|
+
printControl.setFormat(format) // Set format: 'png', 'jpeg', or 'pdf'
|
|
1343
|
+
printControl.setQuality(quality) // Set JPEG quality (0.1 - 1)
|
|
1344
|
+
printControl.setTitle(title) // Set title text
|
|
1345
|
+
printControl.exportMap(options?) // Programmatic export, returns data URL (empty string for PDF)
|
|
1346
|
+
printControl.on('export', handler) // Fired after successful export
|
|
1347
|
+
printControl.on('copy', handler) // Fired after clipboard copy
|
|
1348
|
+
printControl.on('error', handler) // Fired on error
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
**Usage:**
|
|
1352
|
+
|
|
1353
|
+
```typescript
|
|
1354
|
+
import { PrintControl } from "maplibre-gl-components";
|
|
1355
|
+
|
|
1356
|
+
const printControl = new PrintControl({
|
|
1357
|
+
filename: "my-map",
|
|
1358
|
+
format: "png",
|
|
1359
|
+
title: "My Map Title",
|
|
1360
|
+
includeNorthArrow: true,
|
|
1361
|
+
includeScaleBar: true,
|
|
1362
|
+
});
|
|
1363
|
+
map.addControl(printControl, "top-right");
|
|
1364
|
+
|
|
1365
|
+
// Listen for export events
|
|
1366
|
+
printControl.on("export", (event) => {
|
|
1367
|
+
console.log("Exported:", event.state.filename);
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1370
|
+
// Programmatic export
|
|
1371
|
+
const dataUrl = await printControl.exportMap({
|
|
1372
|
+
format: "jpeg",
|
|
1373
|
+
quality: 0.95,
|
|
1374
|
+
title: "Custom Title",
|
|
1375
|
+
includeNorthArrow: true,
|
|
1376
|
+
includeScaleBar: true,
|
|
1377
|
+
});
|
|
1378
|
+
|
|
1379
|
+
// Export as PDF (requires jspdf)
|
|
1380
|
+
await printControl.exportMap({ format: "pdf" });
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
**Features:**
|
|
1384
|
+
|
|
1385
|
+
- Export as PNG, JPEG, or PDF
|
|
1386
|
+
- Optional title overlay rendered on the exported image
|
|
1387
|
+
- Optional north arrow and scale bar overlays in exported output
|
|
1388
|
+
- Customizable filename, quality, and export size
|
|
1389
|
+
- Copy to clipboard (PNG/JPEG only)
|
|
1390
|
+
- PDF export with auto landscape/portrait detection, fitted to A4 page
|
|
1391
|
+
- Programmatic export API
|
|
1392
|
+
|
|
1393
|
+
**PDF Export:**
|
|
1394
|
+
|
|
1395
|
+
PDF export requires the optional [`jspdf`](https://www.npmjs.com/package/jspdf) package:
|
|
1396
|
+
|
|
1397
|
+
```bash
|
|
1398
|
+
npm install jspdf
|
|
1399
|
+
```
|
|
1400
|
+
|
|
1401
|
+
The library is dynamically imported only when PDF format is selected, keeping the main bundle lean.
|
|
1402
|
+
|
|
1403
|
+
### MinimapControl
|
|
1404
|
+
|
|
1405
|
+
An inset overview map that shows the current viewport extent on a smaller map. Supports click-to-navigate and customizable styling.
|
|
1406
|
+
|
|
1407
|
+
```typescript
|
|
1408
|
+
interface MinimapControlOptions {
|
|
1409
|
+
position?: ControlPosition; // Control position (default: 'bottom-left')
|
|
1410
|
+
className?: string; // Custom CSS class
|
|
1411
|
+
visible?: boolean; // Initial visibility (default: true)
|
|
1412
|
+
collapsed?: boolean; // Start collapsed (default: false)
|
|
1413
|
+
width?: number; // Minimap width in pixels (default: 250)
|
|
1414
|
+
height?: number; // Minimap height in pixels (default: 180)
|
|
1415
|
+
zoomOffset?: number; // Zoom offset from main map (default: -5)
|
|
1416
|
+
style?: string | object; // Map style URL or object
|
|
1417
|
+
viewportRectColor?: string; // Viewport rectangle color (default: '#0078d7')
|
|
1418
|
+
viewportRectOpacity?: number; // Viewport rectangle fill opacity (default: 0.2)
|
|
1419
|
+
toggleable?: boolean; // Whether minimap can be toggled (default: true)
|
|
1420
|
+
interactive?: boolean; // Click minimap to navigate main map (default: false)
|
|
1421
|
+
minzoom?: number;
|
|
1422
|
+
maxzoom?: number;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// Methods
|
|
1426
|
+
minimapControl.show()
|
|
1427
|
+
minimapControl.hide()
|
|
1428
|
+
minimapControl.expand() // Show the minimap panel
|
|
1429
|
+
minimapControl.collapse() // Hide the minimap panel
|
|
1430
|
+
minimapControl.toggle() // Toggle panel visibility
|
|
1431
|
+
minimapControl.getState()
|
|
1432
|
+
minimapControl.on(event, handler) // 'show' | 'hide' | 'expand' | 'collapse'
|
|
1433
|
+
minimapControl.off(event, handler)
|
|
1434
|
+
```
|
|
1435
|
+
|
|
1436
|
+
**Usage:**
|
|
1437
|
+
|
|
1438
|
+
```typescript
|
|
1439
|
+
import { MinimapControl } from "maplibre-gl-components";
|
|
1440
|
+
|
|
1441
|
+
const minimapControl = new MinimapControl({
|
|
1442
|
+
width: 250,
|
|
1443
|
+
height: 180,
|
|
1444
|
+
zoomOffset: -5,
|
|
1445
|
+
interactive: true,
|
|
1446
|
+
});
|
|
1447
|
+
map.addControl(minimapControl, "bottom-left");
|
|
1448
|
+
|
|
1449
|
+
minimapControl.on("expand", (event) => {
|
|
1450
|
+
console.log("Minimap expanded:", event.state);
|
|
1451
|
+
});
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
**Features:**
|
|
1455
|
+
|
|
1456
|
+
- Syncs center and zoom with the main map
|
|
1457
|
+
- Viewport rectangle overlay showing the visible area
|
|
1458
|
+
- Click anywhere on the minimap to fly the main map to that location
|
|
1459
|
+
- Drag on the minimap to pan the main map in real time
|
|
1460
|
+
- Toggleable panel with button
|
|
1461
|
+
- Customizable size, zoom offset, and style
|
|
1462
|
+
|
|
1463
|
+
See the [minimap-control example](./examples/minimap-control/) for a complete working example.
|
|
1464
|
+
|
|
1465
|
+
### ControlGrid
|
|
1466
|
+
|
|
1467
|
+
A collapsible toolbar grid that organizes multiple controls (built-in and plugin) in a configurable rows × columns layout.
|
|
1468
|
+
|
|
1469
|
+
```typescript
|
|
1470
|
+
interface ControlGridOptions {
|
|
1471
|
+
title?: string; // Header title
|
|
1472
|
+
position?: ControlPosition; // Control position (default: 'top-right')
|
|
1473
|
+
visible?: boolean; // Initial visibility (default: true)
|
|
1474
|
+
collapsible?: boolean; // Whether grid is collapsible (default: true)
|
|
1475
|
+
collapsed?: boolean; // Start collapsed (default: true)
|
|
1476
|
+
rows?: number; // Grid rows, 1-12 (default: 1)
|
|
1477
|
+
columns?: number; // Grid columns, 1-12 (default: 3)
|
|
1478
|
+
showRowColumnControls?: boolean; // Show row/column input fields (default: true)
|
|
1479
|
+
controls?: IControl[]; // Custom IControl instances
|
|
1480
|
+
defaultControls?: DefaultControlName[]; // Built-in control names (26 available)
|
|
1481
|
+
gap?: number; // Gap between cells in pixels (default: 6)
|
|
1482
|
+
basemapStyleUrl?: string; // Basemap style URL for SwipeControl
|
|
1483
|
+
excludeLayers?: string[]; // Layer patterns to exclude from SwipeControl
|
|
1484
|
+
streetViewOptions?: Partial<StreetViewControlOptions>; // Optional API keys and StreetView config overrides
|
|
1485
|
+
backgroundColor?: string;
|
|
1486
|
+
padding?: number;
|
|
1487
|
+
borderRadius?: number;
|
|
1488
|
+
opacity?: number;
|
|
1489
|
+
minzoom?: number;
|
|
1490
|
+
maxzoom?: number;
|
|
1491
|
+
}
|
|
1492
|
+
```
|
|
1493
|
+
|
|
1494
|
+
**Available default controls:** `fullscreen`, `globe`, `north`, `terrain`, `search`, `viewState`, `inspect`, `vectorDataset`, `basemap`, `cogLayer`, `minimap`, `measure`, `bookmark`, `print`, `zarrLayer`, `pmtilesLayer`, `stacLayer`, `stacSearch`, `addVector`, `geoEditor`, `lidar`, `planetaryComputer`, `gaussianSplat`, `streetView`, `swipe`, `usgsLidar`
|
|
1495
|
+
|
|
1496
|
+
**StreetView env setup (for `streetView` default control):**
|
|
1497
|
+
|
|
1498
|
+
```bash
|
|
1499
|
+
# .env
|
|
1500
|
+
VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key
|
|
1501
|
+
VITE_MAPILLARY_ACCESS_TOKEN=your_mapillary_access_token
|
|
1502
|
+
```
|
|
1503
|
+
|
|
1504
|
+
`ControlGrid` auto-reads these values for the built-in `streetView` control. You can also override explicitly with `streetViewOptions`.
|
|
1505
|
+
Mapillary viewer CSS is bundled by `maplibre-gl-components`, so no extra `mapillary-js` CSS import is needed.
|
|
1506
|
+
|
|
1507
|
+
```typescript
|
|
1508
|
+
// Methods
|
|
1509
|
+
controlGrid.addControl(control) // Add a control to the grid
|
|
1510
|
+
controlGrid.removeControl(control) // Remove a control from the grid
|
|
1511
|
+
controlGrid.getControls() // Get all controls in the grid
|
|
1512
|
+
controlGrid.getAdapters() // Get layer adapters for LayerControl integration
|
|
1513
|
+
controlGrid.show()
|
|
1514
|
+
controlGrid.hide()
|
|
1515
|
+
controlGrid.expand()
|
|
1516
|
+
controlGrid.collapse()
|
|
1517
|
+
controlGrid.toggle()
|
|
1518
|
+
controlGrid.setRows(n)
|
|
1519
|
+
controlGrid.setColumns(n)
|
|
1520
|
+
controlGrid.getState()
|
|
1521
|
+
controlGrid.on(event, handler) // 'show' | 'hide' | 'expand' | 'collapse' | 'controladd' | 'controlremove'
|
|
1522
|
+
controlGrid.off(event, handler)
|
|
1523
|
+
```
|
|
1524
|
+
|
|
1525
|
+
**Usage:**
|
|
1526
|
+
|
|
1527
|
+
```typescript
|
|
1528
|
+
import { ControlGrid } from "maplibre-gl-components";
|
|
1529
|
+
|
|
1530
|
+
const controlGrid = new ControlGrid({
|
|
1531
|
+
rows: 5,
|
|
1532
|
+
columns: 5,
|
|
1533
|
+
collapsible: true,
|
|
1534
|
+
collapsed: true,
|
|
1535
|
+
basemapStyleUrl: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
1536
|
+
streetViewOptions: {
|
|
1537
|
+
// Optional explicit override (otherwise auto-read from VITE_* env vars)
|
|
1538
|
+
googleApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
|
|
1539
|
+
mapillaryAccessToken: import.meta.env.VITE_MAPILLARY_ACCESS_TOKEN,
|
|
1540
|
+
},
|
|
1541
|
+
defaultControls: [
|
|
1542
|
+
"globe", "fullscreen", "north", "terrain", "search",
|
|
1543
|
+
"viewState", "inspect", "basemap", "measure", "bookmark",
|
|
1544
|
+
],
|
|
1545
|
+
});
|
|
1546
|
+
map.addControl(controlGrid, "top-right");
|
|
1547
|
+
```
|
|
1548
|
+
|
|
1549
|
+
See the [control-grid example](./examples/control-grid/) for a complete working example.
|
|
1550
|
+
|
|
1551
|
+
### addControlGrid
|
|
1552
|
+
|
|
1553
|
+
A convenience function that adds a ControlGrid with all 26 default controls in one call. Auto-calculates grid dimensions and sets sensible defaults.
|
|
1554
|
+
|
|
1555
|
+
```typescript
|
|
1556
|
+
import { addControlGrid } from "maplibre-gl-components";
|
|
1557
|
+
|
|
1558
|
+
// Add all 26 default controls
|
|
1559
|
+
const grid = addControlGrid(map);
|
|
1560
|
+
|
|
1561
|
+
// Or use as a Map method (auto-installed on import)
|
|
1562
|
+
const grid = map.addControlGrid();
|
|
1563
|
+
|
|
1564
|
+
// Exclude specific controls
|
|
1565
|
+
const grid = addControlGrid(map, {
|
|
1566
|
+
exclude: ["minimap", "streetView", "gaussianSplat"],
|
|
1567
|
+
});
|
|
1568
|
+
|
|
1569
|
+
// Only specific controls
|
|
1570
|
+
const grid = addControlGrid(map, {
|
|
1571
|
+
defaultControls: ["search", "basemap", "terrain", "fullscreen"],
|
|
1572
|
+
});
|
|
1573
|
+
|
|
1574
|
+
// With basemap style for SwipeControl layer grouping
|
|
1575
|
+
const grid = addControlGrid(map, {
|
|
1576
|
+
basemapStyleUrl: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
1577
|
+
});
|
|
1578
|
+
```
|
|
1579
|
+
|
|
1580
|
+
```typescript
|
|
1581
|
+
interface AddControlGridOptions extends ControlGridOptions {
|
|
1582
|
+
exclude?: DefaultControlName[]; // Controls to exclude (ignored if defaultControls is set)
|
|
1583
|
+
}
|
|
1584
|
+
```
|
|
1585
|
+
|
|
1586
|
+
**Defaults applied by `addControlGrid`:**
|
|
1587
|
+
|
|
1588
|
+
- All 26 controls included (unless filtered by `exclude` or `defaultControls`)
|
|
1589
|
+
- Grid dimensions auto-calculated as near-square layout
|
|
1590
|
+
- `collapsed: true`, `collapsible: true`, `showRowColumnControls: true`
|
|
1591
|
+
- `gap: 2`, `position: "top-right"`
|
|
1592
|
+
- `excludeLayers` set to default patterns for internal/helper layers
|
|
1593
|
+
|
|
1594
|
+
**With LayerControl integration:**
|
|
1595
|
+
|
|
1596
|
+
```typescript
|
|
1597
|
+
import { addControlGrid, DEFAULT_EXCLUDE_LAYERS } from "maplibre-gl-components";
|
|
1598
|
+
import { LayerControl } from "maplibre-gl-layer-control";
|
|
1599
|
+
|
|
1600
|
+
const layerControl = new LayerControl({ collapsed: true });
|
|
1601
|
+
map.addControl(layerControl, "top-right");
|
|
1602
|
+
|
|
1603
|
+
const grid = addControlGrid(map, { basemapStyleUrl: BASEMAP_STYLE });
|
|
1604
|
+
|
|
1605
|
+
for (const adapter of grid.getAdapters()) {
|
|
1606
|
+
layerControl.registerCustomAdapter(adapter);
|
|
1607
|
+
}
|
|
1608
|
+
```
|
|
1609
|
+
|
|
1610
|
+
See the [add-control-grid example](./examples/add-control-grid/) for a complete working example.
|
|
1611
|
+
|
|
1612
|
+
### Layer Control Adapters
|
|
1613
|
+
|
|
1614
|
+
To integrate COG and Zarr layers with [maplibre-gl-layer-control](https://github.com/AJPNorthwest/maplibre-gl-layer-control), use the included adapters:
|
|
1615
|
+
|
|
1616
|
+
```typescript
|
|
1617
|
+
import { LayerControl, CustomLayerAdapter } from "maplibre-gl-layer-control";
|
|
1618
|
+
import {
|
|
1619
|
+
CogLayerControl,
|
|
1620
|
+
ZarrLayerControl,
|
|
1621
|
+
CogLayerAdapter,
|
|
1622
|
+
ZarrLayerAdapter,
|
|
1623
|
+
} from "maplibre-gl-components";
|
|
1624
|
+
|
|
1625
|
+
// Create layer controls
|
|
1626
|
+
const cogControl = new CogLayerControl({ collapsed: true });
|
|
1627
|
+
const zarrControl = new ZarrLayerControl({ collapsed: true });
|
|
1628
|
+
|
|
1629
|
+
map.addControl(cogControl);
|
|
1630
|
+
map.addControl(zarrControl);
|
|
1631
|
+
|
|
1632
|
+
// Add layers
|
|
1633
|
+
await cogControl.addLayer("https://example.com/dem.tif");
|
|
1634
|
+
await zarrControl.addLayer("https://example.com/data.zarr", "temperature");
|
|
1635
|
+
|
|
1636
|
+
// Create layer control with adapters
|
|
1637
|
+
const layerControl = new LayerControl({
|
|
1638
|
+
customLayers: [
|
|
1639
|
+
new CogLayerAdapter(cogControl, { name: "Elevation DEM" }),
|
|
1640
|
+
new ZarrLayerAdapter(zarrControl, { name: "Temperature Data" }),
|
|
1641
|
+
],
|
|
1642
|
+
});
|
|
1643
|
+
map.addControl(layerControl);
|
|
1644
|
+
```
|
|
1645
|
+
|
|
1646
|
+
**Adapter Options:**
|
|
1647
|
+
|
|
1648
|
+
```typescript
|
|
1649
|
+
interface AdapterOptions {
|
|
1650
|
+
name?: string; // Display name in layer control
|
|
1651
|
+
defaultOpacity?: number; // Opacity when toggled on (default: 1)
|
|
1652
|
+
}
|
|
1653
|
+
```
|
|
1654
|
+
|
|
1655
|
+
## Built-in Colormaps
|
|
1656
|
+
|
|
1657
|
+
### Sequential
|
|
1658
|
+
|
|
1659
|
+
- `viridis` - Perceptually uniform, colorblind-friendly
|
|
1660
|
+
- `plasma` - Perceptually uniform
|
|
1661
|
+
- `inferno` - Perceptually uniform
|
|
1662
|
+
- `magma` - Perceptually uniform
|
|
1663
|
+
- `cividis` - Colorblind-friendly
|
|
1664
|
+
|
|
1665
|
+
### Diverging
|
|
1666
|
+
|
|
1667
|
+
- `coolwarm` - Blue to red through white
|
|
1668
|
+
- `bwr` - Blue-white-red
|
|
1669
|
+
- `seismic` - Blue to red
|
|
1670
|
+
- `RdBu` - Red to blue
|
|
1671
|
+
- `RdYlBu` - Red-yellow-blue
|
|
1672
|
+
- `RdYlGn` - Red-yellow-green
|
|
1673
|
+
- `spectral` - Rainbow-like diverging
|
|
1674
|
+
|
|
1675
|
+
### Miscellaneous
|
|
1676
|
+
|
|
1677
|
+
- `jet` - Classic rainbow
|
|
1678
|
+
- `rainbow` - Full spectrum
|
|
1679
|
+
- `turbo` - Improved rainbow
|
|
1680
|
+
- `terrain` - Elevation-like
|
|
1681
|
+
- `ocean` - Ocean depths
|
|
1682
|
+
- `hot` - Black-red-yellow-white
|
|
1683
|
+
- `cool` - Cyan to magenta
|
|
1684
|
+
- `gray` - Grayscale
|
|
1685
|
+
- `bone` - Blue-tinted grayscale
|
|
1686
|
+
|
|
1687
|
+
### Custom Colors
|
|
1688
|
+
|
|
1689
|
+
```typescript
|
|
1690
|
+
// Use an array of colors
|
|
1691
|
+
const colorbar = new Colorbar({
|
|
1692
|
+
colormap: ["#0000ff", "#00ff00", "#ffff00", "#ff0000"],
|
|
1693
|
+
vmin: 0,
|
|
1694
|
+
vmax: 100,
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1697
|
+
// Or use color stops for precise control
|
|
1698
|
+
const colorbar = new Colorbar({
|
|
1699
|
+
colorStops: [
|
|
1700
|
+
{ position: 0, color: "#0000ff" },
|
|
1701
|
+
{ position: 0.3, color: "#00ff00" },
|
|
1702
|
+
{ position: 0.7, color: "#ffff00" },
|
|
1703
|
+
{ position: 1, color: "#ff0000" },
|
|
1704
|
+
],
|
|
1705
|
+
vmin: 0,
|
|
1706
|
+
vmax: 100,
|
|
1707
|
+
});
|
|
1708
|
+
```
|
|
1709
|
+
|
|
1710
|
+
## Zoom-based Visibility
|
|
1711
|
+
|
|
1712
|
+
All components support `minzoom` and `maxzoom` options to control visibility based on the map's zoom level. This is useful for showing different legends at different zoom levels, similar to how map layers work.
|
|
1713
|
+
|
|
1714
|
+
```typescript
|
|
1715
|
+
// Show legend only when zoomed in (zoom >= 10)
|
|
1716
|
+
const detailLegend = new Legend({
|
|
1717
|
+
title: 'Detailed Features',
|
|
1718
|
+
items: [...],
|
|
1719
|
+
minzoom: 10, // Only visible at zoom 10 and above
|
|
1720
|
+
});
|
|
1721
|
+
|
|
1722
|
+
// Show legend only when zoomed out (zoom <= 8)
|
|
1723
|
+
const overviewLegend = new Legend({
|
|
1724
|
+
title: 'Overview',
|
|
1725
|
+
items: [...],
|
|
1726
|
+
maxzoom: 8, // Only visible at zoom 8 and below
|
|
1727
|
+
});
|
|
1728
|
+
|
|
1729
|
+
// Show colorbar only within a specific zoom range
|
|
1730
|
+
const colorbar = new Colorbar({
|
|
1731
|
+
colormap: 'viridis',
|
|
1732
|
+
vmin: 0,
|
|
1733
|
+
vmax: 100,
|
|
1734
|
+
minzoom: 5, // Visible from zoom 5...
|
|
1735
|
+
maxzoom: 15, // ...up to zoom 15
|
|
1736
|
+
});
|
|
1737
|
+
```
|
|
1738
|
+
|
|
1739
|
+
### React Example
|
|
1740
|
+
|
|
1741
|
+
```tsx
|
|
1742
|
+
<LegendReact
|
|
1743
|
+
map={map}
|
|
1744
|
+
title="Lidar Point Cloud"
|
|
1745
|
+
items={[
|
|
1746
|
+
{ label: "QL0 (Approx. <= 0.35m NPS)", color: "#003300" },
|
|
1747
|
+
{ label: "QL1 (Approx. 0.35m NPS)", color: "#006600" },
|
|
1748
|
+
{ label: "QL2 (Approx. 0.7m NPS)", color: "#00cc00" },
|
|
1749
|
+
{ label: "QL3 (Approx. 1.4m NPS)", color: "#ccff00" },
|
|
1750
|
+
{ label: "Other", color: "#99ccff" },
|
|
1751
|
+
]}
|
|
1752
|
+
minzoom={8}
|
|
1753
|
+
maxzoom={18}
|
|
1754
|
+
position="top-left"
|
|
1755
|
+
/>
|
|
1756
|
+
```
|
|
1757
|
+
|
|
1758
|
+
**Note:** The `visible` option takes precedence - if `visible` is `false`, the component will be hidden regardless of zoom level.
|
|
1759
|
+
|
|
1760
|
+
## React Hooks
|
|
1761
|
+
|
|
1762
|
+
```typescript
|
|
1763
|
+
import { useColorbar, useLegend, useHtmlControl, useBasemap, useTerrain, useSearchControl, useVectorDataset, useViewState } from 'maplibre-gl-components/react';
|
|
1764
|
+
|
|
1765
|
+
function MyComponent() {
|
|
1766
|
+
const colorbar = useColorbar({ colormap: 'viridis', vmin: 0, vmax: 100 });
|
|
1767
|
+
const legend = useLegend({ items: [...] });
|
|
1768
|
+
const htmlControl = useHtmlControl({ html: '...' });
|
|
1769
|
+
const basemap = useBasemap({ selectedBasemap: 'OpenStreetMap.Mapnik' });
|
|
1770
|
+
const terrain = useTerrain({ enabled: false, exaggeration: 1.5 });
|
|
1771
|
+
const search = useSearchControl({ collapsed: true });
|
|
1772
|
+
const vectorDataset = useVectorDataset();
|
|
1773
|
+
const viewState = useViewState({ collapsed: false, enableBBox: true });
|
|
1774
|
+
|
|
1775
|
+
return (
|
|
1776
|
+
<>
|
|
1777
|
+
<button onClick={() => colorbar.setColormap('plasma')}>
|
|
1778
|
+
Change Colormap
|
|
1779
|
+
</button>
|
|
1780
|
+
<button onClick={() => legend.toggle()}>
|
|
1781
|
+
Toggle Legend
|
|
1782
|
+
</button>
|
|
1783
|
+
<button onClick={() => basemap.setBasemap('CartoDB.Positron')}>
|
|
1784
|
+
Change Basemap
|
|
1785
|
+
</button>
|
|
1786
|
+
<button onClick={() => terrain.toggle()}>
|
|
1787
|
+
Toggle Terrain
|
|
1788
|
+
</button>
|
|
1789
|
+
<button onClick={() => search.toggle()}>
|
|
1790
|
+
Toggle Search
|
|
1791
|
+
</button>
|
|
1792
|
+
|
|
1793
|
+
<SearchControlReact
|
|
1794
|
+
map={map}
|
|
1795
|
+
collapsed={search.state.collapsed}
|
|
1796
|
+
onResultSelect={(result) => search.selectResult(result)}
|
|
1797
|
+
/>
|
|
1798
|
+
|
|
1799
|
+
<TerrainReact
|
|
1800
|
+
map={map}
|
|
1801
|
+
enabled={terrain.state.enabled}
|
|
1802
|
+
exaggeration={terrain.state.exaggeration}
|
|
1803
|
+
onTerrainChange={(enabled) => terrain.setEnabled(enabled)}
|
|
1804
|
+
/>
|
|
1805
|
+
|
|
1806
|
+
<BasemapReact
|
|
1807
|
+
map={map}
|
|
1808
|
+
defaultBasemap={basemap.state.selectedBasemap}
|
|
1809
|
+
onBasemapChange={(b) => basemap.setBasemap(b.id)}
|
|
1810
|
+
/>
|
|
1811
|
+
|
|
1812
|
+
<ColorbarReact
|
|
1813
|
+
map={map}
|
|
1814
|
+
{...colorbar.state}
|
|
1815
|
+
vmin={colorbar.state.vmin}
|
|
1816
|
+
vmax={colorbar.state.vmax}
|
|
1817
|
+
/>
|
|
1818
|
+
</>
|
|
1819
|
+
);
|
|
1820
|
+
}
|
|
1821
|
+
```
|
|
1822
|
+
|
|
1823
|
+
## Styling
|
|
1824
|
+
|
|
1825
|
+
The default styles can be customized using CSS:
|
|
1826
|
+
|
|
1827
|
+
```css
|
|
1828
|
+
/* Override colorbar styles */
|
|
1829
|
+
.maplibre-gl-colorbar {
|
|
1830
|
+
background: rgba(0, 0, 0, 0.8);
|
|
1831
|
+
color: white;
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
/* Override legend styles */
|
|
1835
|
+
.maplibre-gl-legend {
|
|
1836
|
+
font-size: 14px;
|
|
1837
|
+
border-radius: 8px;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
/* Override HTML control styles */
|
|
1841
|
+
.maplibre-gl-html-control {
|
|
1842
|
+
max-width: 400px;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
/* Override basemap control styles */
|
|
1846
|
+
.maplibre-gl-basemap {
|
|
1847
|
+
max-width: 300px;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
/* Override terrain control styles */
|
|
1851
|
+
.maplibre-gl-terrain-button {
|
|
1852
|
+
color: #0078d7;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/* Override search control styles */
|
|
1856
|
+
.maplibre-gl-search {
|
|
1857
|
+
background: rgba(255, 255, 255, 0.95);
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
.maplibre-gl-search-toggle:hover {
|
|
1861
|
+
color: #0078d7;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
/* Override vector dataset control styles */
|
|
1865
|
+
.maplibre-gl-vector-dataset-button:hover {
|
|
1866
|
+
color: #0078d7;
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
.maplibre-gl-vector-dataset-dropzone {
|
|
1870
|
+
background: rgba(0, 120, 215, 0.2);
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
/* Override view state control styles */
|
|
1874
|
+
.maplibre-gl-view-state-button:hover {
|
|
1875
|
+
color: #0078d7;
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
.maplibre-gl-view-state-panel {
|
|
1879
|
+
background: rgba(255, 255, 255, 0.95);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
.maplibre-gl-view-state-bbox-toggle--active {
|
|
1883
|
+
background: #0078d7;
|
|
1884
|
+
color: white;
|
|
1885
|
+
}
|
|
1886
|
+
```
|
|
1887
|
+
|
|
1888
|
+
## Examples
|
|
1889
|
+
|
|
1890
|
+
See the [examples](./examples/) directory for complete working examples:
|
|
1891
|
+
|
|
1892
|
+
- **Basic Example** - Vanilla TypeScript with all components
|
|
1893
|
+
- **React Example** - React with hooks and dynamic updates
|
|
1894
|
+
- **View State Example** - View state control with bounding box drawing
|
|
1895
|
+
- **COG Layer Example** - Cloud Optimized GeoTIFF visualization with colormaps
|
|
1896
|
+
- **Zarr Layer Example** - Multi-dimensional Zarr data visualization
|
|
1897
|
+
- **STAC Layer Example** - Load COG layers from STAC catalog items
|
|
1898
|
+
- **STAC Search Example** - Search and visualize STAC items from public catalogs
|
|
1899
|
+
- **Print Control Example** - Export map as PNG, JPEG, or PDF
|
|
1900
|
+
- **Minimap Control Example** - Inset overview map with viewport rectangle
|
|
1901
|
+
- **Control Grid Example** - ControlGrid with all built-in and plugin controls
|
|
1902
|
+
- **addControlGrid Example** - One-call convenience function with all default controls
|
|
1903
|
+
- **Three.js Plugin Example** - Integrate `MapScene` from maplibre-three-plugin with a rotating 3D object
|
|
1904
|
+
|
|
1905
|
+
## Development
|
|
1906
|
+
|
|
1907
|
+
```bash
|
|
1908
|
+
# Install dependencies
|
|
1909
|
+
npm install
|
|
1910
|
+
|
|
1911
|
+
# Start development server
|
|
1912
|
+
npm run dev
|
|
1913
|
+
|
|
1914
|
+
# Run tests
|
|
1915
|
+
npm test
|
|
1916
|
+
|
|
1917
|
+
# Build for production
|
|
1918
|
+
npm run build
|
|
1919
|
+
|
|
1920
|
+
# Build examples
|
|
1921
|
+
npm run build:examples
|
|
1922
|
+
```
|
|
1923
|
+
|
|
1924
|
+
## Docker
|
|
1925
|
+
|
|
1926
|
+
The examples can be run using Docker. The image is automatically built and published to GitHub Container Registry.
|
|
1927
|
+
|
|
1928
|
+
### Pull and Run
|
|
1929
|
+
|
|
1930
|
+
```bash
|
|
1931
|
+
# Pull the latest image
|
|
1932
|
+
docker pull ghcr.io/opengeos/maplibre-gl-components:latest
|
|
1933
|
+
|
|
1934
|
+
# Run the container
|
|
1935
|
+
docker run -p 8080:80 ghcr.io/opengeos/maplibre-gl-components:latest
|
|
1936
|
+
```
|
|
1937
|
+
|
|
1938
|
+
Then open http://localhost:8080/maplibre-gl-components/ in your browser to view the examples.
|
|
1939
|
+
|
|
1940
|
+
### Build Locally
|
|
1941
|
+
|
|
1942
|
+
```bash
|
|
1943
|
+
# Build the image
|
|
1944
|
+
docker build -t maplibre-gl-components .
|
|
1945
|
+
|
|
1946
|
+
# Run the container
|
|
1947
|
+
docker run -p 8080:80 maplibre-gl-components
|
|
1948
|
+
```
|
|
1949
|
+
|
|
1950
|
+
### Available Tags
|
|
1951
|
+
|
|
1952
|
+
| Tag | Description |
|
|
1953
|
+
| -------- | -------------------------------- |
|
|
1954
|
+
| `latest` | Latest release |
|
|
1955
|
+
| `x.y.z` | Specific version (e.g., `1.0.0`) |
|
|
1956
|
+
| `x.y` | Minor version (e.g., `1.0`) |
|
|
1957
|
+
|
|
1958
|
+
## License
|
|
1959
|
+
|
|
1960
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|