maplibre-gl-components 0.3.0 → 0.5.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/README.md +453 -6
- package/dist/InspectControl-BLalXkaR.cjs +5055 -0
- package/dist/InspectControl-BLalXkaR.cjs.map +1 -0
- package/dist/InspectControl-DXc8bOjy.js +5035 -0
- package/dist/InspectControl-DXc8bOjy.js.map +1 -0
- package/dist/index.cjs +48 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +40 -27
- package/dist/maplibre-gl-components.css +774 -0
- package/dist/react.cjs +806 -13
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +804 -11
- package/dist/react.mjs.map +1 -1
- package/dist/types/index.d.ts +7 -1
- package/dist/types/index.d.ts.map +1 -1
- 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/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/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/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 +197 -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/types.d.ts +557 -0
- package/dist/types/lib/core/types.d.ts.map +1 -1
- package/dist/types/lib/hooks/index.d.ts +5 -0
- package/dist/types/lib/hooks/index.d.ts.map +1 -1
- 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/useInspectControl.d.ts +49 -0
- package/dist/types/lib/hooks/useInspectControl.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/utils/index.d.ts +1 -0
- package/dist/types/lib/utils/index.d.ts.map +1 -1
- 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 +7 -2
- package/dist/types/react.d.ts.map +1 -1
- package/package.json +4 -1
- package/dist/HtmlControl-CxD6T9bG.js +0 -1380
- package/dist/HtmlControl-CxD6T9bG.js.map +0 -1
- package/dist/HtmlControl-CzXIBk1H.cjs +0 -1379
- package/dist/HtmlControl-CzXIBk1H.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# maplibre-gl-components
|
|
2
2
|
|
|
3
|
-
Legend, colorbar, and HTML control components for MapLibre GL JS maps.
|
|
3
|
+
Legend, colorbar, basemap switcher, terrain toggle, search, vector data loader, feature inspector, and HTML control components for MapLibre GL JS maps.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/maplibre-gl-components)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -9,6 +9,11 @@ Legend, colorbar, and HTML control components for MapLibre GL JS maps.
|
|
|
9
9
|
|
|
10
10
|
- **Colorbar** - Continuous gradient legends with built-in matplotlib colormaps
|
|
11
11
|
- **Legend** - Categorical legends with color swatches and labels
|
|
12
|
+
- **BasemapControl** - Interactive basemap switcher with 100+ providers from xyzservices
|
|
13
|
+
- **TerrainControl** - Toggle 3D terrain on/off using free AWS Terrarium elevation tiles
|
|
14
|
+
- **SearchControl** - Collapsible place search with geocoding and fly-to functionality
|
|
15
|
+
- **VectorDatasetControl** - Load GeoJSON files via file upload or drag-and-drop
|
|
16
|
+
- **InspectControl** - Click on features to view their properties/attributes
|
|
12
17
|
- **HtmlControl** - Flexible HTML content control for custom info panels
|
|
13
18
|
- **Zoom-based Visibility** - Show/hide components at specific zoom levels with `minzoom`/`maxzoom`
|
|
14
19
|
- **React Support** - First-class React components and hooks
|
|
@@ -27,7 +32,7 @@ npm install maplibre-gl-components
|
|
|
27
32
|
|
|
28
33
|
```typescript
|
|
29
34
|
import maplibregl from 'maplibre-gl';
|
|
30
|
-
import { Colorbar, Legend, HtmlControl } from 'maplibre-gl-components';
|
|
35
|
+
import { Colorbar, Legend, HtmlControl, BasemapControl, TerrainControl, SearchControl, VectorDatasetControl } from 'maplibre-gl-components';
|
|
31
36
|
import 'maplibre-gl-components/style.css';
|
|
32
37
|
|
|
33
38
|
const map = new maplibregl.Map({
|
|
@@ -37,6 +42,39 @@ const map = new maplibregl.Map({
|
|
|
37
42
|
zoom: 4,
|
|
38
43
|
});
|
|
39
44
|
|
|
45
|
+
// Add a terrain toggle control
|
|
46
|
+
const terrainControl = new TerrainControl({
|
|
47
|
+
exaggeration: 1.5,
|
|
48
|
+
hillshade: true,
|
|
49
|
+
});
|
|
50
|
+
map.addControl(terrainControl, 'top-right');
|
|
51
|
+
|
|
52
|
+
// Add a search control
|
|
53
|
+
const searchControl = new SearchControl({
|
|
54
|
+
placeholder: 'Search for a place...',
|
|
55
|
+
flyToZoom: 14,
|
|
56
|
+
showMarker: true,
|
|
57
|
+
});
|
|
58
|
+
map.addControl(searchControl, 'top-right');
|
|
59
|
+
|
|
60
|
+
// Add a vector dataset loader (file upload and drag-drop)
|
|
61
|
+
const vectorControl = new VectorDatasetControl({
|
|
62
|
+
fitBounds: true,
|
|
63
|
+
});
|
|
64
|
+
map.addControl(vectorControl, 'top-left');
|
|
65
|
+
|
|
66
|
+
vectorControl.on('load', (event) => {
|
|
67
|
+
console.log('Loaded:', event.dataset?.filename);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Add a basemap switcher
|
|
71
|
+
const basemapControl = new BasemapControl({
|
|
72
|
+
defaultBasemap: 'OpenStreetMap.Mapnik',
|
|
73
|
+
showSearch: true,
|
|
74
|
+
filterGroups: ['OpenStreetMap', 'CartoDB', 'Stadia', 'Esri'],
|
|
75
|
+
});
|
|
76
|
+
map.addControl(basemapControl, 'top-left');
|
|
77
|
+
|
|
40
78
|
// Add a colorbar
|
|
41
79
|
const colorbar = new Colorbar({
|
|
42
80
|
colormap: 'viridis',
|
|
@@ -75,7 +113,7 @@ htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');
|
|
|
75
113
|
```tsx
|
|
76
114
|
import { useState, useEffect, useRef } from 'react';
|
|
77
115
|
import maplibregl from 'maplibre-gl';
|
|
78
|
-
import { ColorbarReact, LegendReact, HtmlControlReact } from 'maplibre-gl-components/react';
|
|
116
|
+
import { ColorbarReact, LegendReact, HtmlControlReact, BasemapReact, TerrainReact, SearchControlReact, VectorDatasetReact } from 'maplibre-gl-components/react';
|
|
79
117
|
import 'maplibre-gl-components/style.css';
|
|
80
118
|
|
|
81
119
|
function MyMap() {
|
|
@@ -104,6 +142,38 @@ function MyMap() {
|
|
|
104
142
|
|
|
105
143
|
{map && (
|
|
106
144
|
<>
|
|
145
|
+
<VectorDatasetReact
|
|
146
|
+
map={map}
|
|
147
|
+
fitBounds
|
|
148
|
+
position="top-left"
|
|
149
|
+
onDatasetLoad={(dataset) => console.log('Loaded:', dataset.filename)}
|
|
150
|
+
/>
|
|
151
|
+
|
|
152
|
+
<SearchControlReact
|
|
153
|
+
map={map}
|
|
154
|
+
placeholder="Search for a place..."
|
|
155
|
+
flyToZoom={14}
|
|
156
|
+
showMarker
|
|
157
|
+
position="top-right"
|
|
158
|
+
onResultSelect={(result) => console.log('Selected:', result.name)}
|
|
159
|
+
/>
|
|
160
|
+
|
|
161
|
+
<TerrainReact
|
|
162
|
+
map={map}
|
|
163
|
+
exaggeration={1.5}
|
|
164
|
+
hillshade
|
|
165
|
+
position="top-right"
|
|
166
|
+
onTerrainChange={(enabled) => console.log('Terrain:', enabled)}
|
|
167
|
+
/>
|
|
168
|
+
|
|
169
|
+
<BasemapReact
|
|
170
|
+
map={map}
|
|
171
|
+
defaultBasemap="OpenStreetMap.Mapnik"
|
|
172
|
+
showSearch
|
|
173
|
+
filterGroups={['OpenStreetMap', 'CartoDB', 'Stadia']}
|
|
174
|
+
position="top-left"
|
|
175
|
+
/>
|
|
176
|
+
|
|
107
177
|
<ColorbarReact
|
|
108
178
|
map={map}
|
|
109
179
|
colormap="viridis"
|
|
@@ -248,6 +318,326 @@ htmlControl.update(options)
|
|
|
248
318
|
htmlControl.getState()
|
|
249
319
|
```
|
|
250
320
|
|
|
321
|
+
### BasemapControl
|
|
322
|
+
|
|
323
|
+
An interactive basemap switcher that loads providers from [xyzservices](https://github.com/geopandas/xyzservices).
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
interface BasemapControlOptions {
|
|
327
|
+
basemaps?: BasemapItem[]; // Custom basemaps array
|
|
328
|
+
providersUrl?: string; // URL to fetch providers.json (defaults to xyzservices)
|
|
329
|
+
defaultBasemap?: string; // Initial basemap ID (e.g., 'OpenStreetMap.Mapnik')
|
|
330
|
+
position?: ControlPosition;
|
|
331
|
+
visible?: boolean;
|
|
332
|
+
collapsible?: boolean; // Whether control is collapsible (default: true)
|
|
333
|
+
collapsed?: boolean; // Whether control starts collapsed (default: true)
|
|
334
|
+
displayMode?: 'dropdown' | 'gallery' | 'list'; // UI mode (default: 'dropdown')
|
|
335
|
+
showSearch?: boolean; // Show search input (default: true)
|
|
336
|
+
filterGroups?: string[]; // Only include these provider groups
|
|
337
|
+
excludeGroups?: string[]; // Exclude these provider groups
|
|
338
|
+
excludeBroken?: boolean; // Exclude broken providers (default: true)
|
|
339
|
+
backgroundColor?: string;
|
|
340
|
+
maxWidth?: number;
|
|
341
|
+
maxHeight?: number;
|
|
342
|
+
fontSize?: number;
|
|
343
|
+
fontColor?: string;
|
|
344
|
+
minzoom?: number;
|
|
345
|
+
maxzoom?: number;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
interface BasemapItem {
|
|
349
|
+
id: string; // Unique identifier
|
|
350
|
+
name: string; // Display name
|
|
351
|
+
group?: string; // Provider group (e.g., 'OpenStreetMap')
|
|
352
|
+
url?: string; // XYZ tile URL template
|
|
353
|
+
style?: string; // MapLibre style URL
|
|
354
|
+
attribution?: string;
|
|
355
|
+
thumbnail?: string; // Preview image URL
|
|
356
|
+
maxZoom?: number;
|
|
357
|
+
minZoom?: number;
|
|
358
|
+
requiresApiKey?: boolean;
|
|
359
|
+
apiKey?: string;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Methods
|
|
363
|
+
basemapControl.show()
|
|
364
|
+
basemapControl.hide()
|
|
365
|
+
basemapControl.expand()
|
|
366
|
+
basemapControl.collapse()
|
|
367
|
+
basemapControl.toggle()
|
|
368
|
+
basemapControl.setBasemap(basemapId) // Switch to a basemap
|
|
369
|
+
basemapControl.getBasemaps() // Get available basemaps
|
|
370
|
+
basemapControl.addBasemap(basemap) // Add a custom basemap
|
|
371
|
+
basemapControl.removeBasemap(id) // Remove a basemap
|
|
372
|
+
basemapControl.setApiKey(id, key) // Set API key for a basemap
|
|
373
|
+
basemapControl.getSelectedBasemap() // Get currently selected basemap
|
|
374
|
+
basemapControl.update(options)
|
|
375
|
+
basemapControl.getState()
|
|
376
|
+
basemapControl.on('basemapchange', handler) // Listen for basemap changes
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Available Provider Groups:**
|
|
380
|
+
- OpenStreetMap, CartoDB, Stadia, Esri, OpenTopoMap
|
|
381
|
+
- Thunderforest, MapBox, MapTiler (require API keys)
|
|
382
|
+
- NASAGIBS, OpenSeaMap, and 20+ more
|
|
383
|
+
|
|
384
|
+
### SearchControl
|
|
385
|
+
|
|
386
|
+
A collapsible place search control with geocoding support.
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
interface SearchControlOptions {
|
|
390
|
+
position?: ControlPosition;
|
|
391
|
+
visible?: boolean; // Default: true
|
|
392
|
+
collapsed?: boolean; // Start collapsed (icon only). Default: true
|
|
393
|
+
placeholder?: string; // Search input placeholder. Default: 'Search places...'
|
|
394
|
+
geocoderUrl?: string; // Geocoding API URL. Default: Nominatim
|
|
395
|
+
maxResults?: number; // Max results to show. Default: 5
|
|
396
|
+
debounceMs?: number; // Debounce delay in ms. Default: 300
|
|
397
|
+
flyToZoom?: number; // Zoom level when selecting result. Default: 14
|
|
398
|
+
showMarker?: boolean; // Show marker at selected location. Default: true
|
|
399
|
+
markerColor?: string; // Marker color. Default: '#4264fb'
|
|
400
|
+
collapseOnSelect?: boolean; // Collapse after selecting. Default: true
|
|
401
|
+
clearOnSelect?: boolean; // Clear results after selecting. Default: true
|
|
402
|
+
geocoder?: (query: string) => Promise<SearchResult[]>; // Custom geocoder function
|
|
403
|
+
backgroundColor?: string;
|
|
404
|
+
borderRadius?: number;
|
|
405
|
+
opacity?: number;
|
|
406
|
+
width?: number; // Expanded width in pixels. Default: 280
|
|
407
|
+
fontSize?: number;
|
|
408
|
+
fontColor?: string;
|
|
409
|
+
minzoom?: number;
|
|
410
|
+
maxzoom?: number;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
interface SearchResult {
|
|
414
|
+
id: string; // Unique identifier
|
|
415
|
+
name: string; // Place name
|
|
416
|
+
displayName: string; // Full display name with address
|
|
417
|
+
lng: number; // Longitude
|
|
418
|
+
lat: number; // Latitude
|
|
419
|
+
bbox?: [number, number, number, number]; // Bounding box [west, south, east, north]
|
|
420
|
+
type?: string; // Place type (city, street, etc.)
|
|
421
|
+
importance?: number; // Relevance score
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Methods
|
|
425
|
+
searchControl.show()
|
|
426
|
+
searchControl.hide()
|
|
427
|
+
searchControl.expand() // Expand to show input
|
|
428
|
+
searchControl.collapse() // Collapse to icon only
|
|
429
|
+
searchControl.toggle() // Toggle expanded/collapsed
|
|
430
|
+
searchControl.search(query) // Perform a search
|
|
431
|
+
searchControl.selectResult(result) // Select a result and fly to it
|
|
432
|
+
searchControl.clear() // Clear search and marker
|
|
433
|
+
searchControl.update(options)
|
|
434
|
+
searchControl.getState()
|
|
435
|
+
searchControl.on('resultselect', handler) // Listen for result selection
|
|
436
|
+
searchControl.on('search', handler) // Listen for search completion
|
|
437
|
+
searchControl.on('clear', handler) // Listen for clear events
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Geocoding:**
|
|
441
|
+
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.
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
// Using custom geocoder
|
|
445
|
+
const searchControl = new SearchControl({
|
|
446
|
+
geocoder: async (query) => {
|
|
447
|
+
const response = await fetch(`https://my-geocoder.com/search?q=${query}`);
|
|
448
|
+
const data = await response.json();
|
|
449
|
+
return data.map(item => ({
|
|
450
|
+
id: item.id,
|
|
451
|
+
name: item.name,
|
|
452
|
+
displayName: item.address,
|
|
453
|
+
lng: item.longitude,
|
|
454
|
+
lat: item.latitude,
|
|
455
|
+
}));
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### VectorDatasetControl
|
|
461
|
+
|
|
462
|
+
A control for loading GeoJSON files via file upload button or drag-and-drop.
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
interface VectorDatasetControlOptions {
|
|
466
|
+
position?: ControlPosition;
|
|
467
|
+
visible?: boolean; // Default: true
|
|
468
|
+
showDropZone?: boolean; // Show overlay when dragging. Default: true
|
|
469
|
+
acceptedExtensions?: string[]; // File extensions. Default: ['.geojson', '.json']
|
|
470
|
+
multiple?: boolean; // Allow multiple files. Default: true
|
|
471
|
+
defaultStyle?: VectorLayerStyle; // Default styling for loaded layers
|
|
472
|
+
fitBounds?: boolean; // Fit map to loaded data. Default: true
|
|
473
|
+
fitBoundsPadding?: number; // Padding for fitBounds. Default: 50
|
|
474
|
+
maxFileSize?: number; // Max file size in bytes. Default: 50MB
|
|
475
|
+
backgroundColor?: string;
|
|
476
|
+
borderRadius?: number;
|
|
477
|
+
opacity?: number;
|
|
478
|
+
minzoom?: number;
|
|
479
|
+
maxzoom?: number;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface VectorLayerStyle {
|
|
483
|
+
fillColor?: string; // Polygon fill. Default: '#3388ff'
|
|
484
|
+
fillOpacity?: number; // Polygon fill opacity. Default: 0.3
|
|
485
|
+
strokeColor?: string; // Line/outline color. Default: '#3388ff'
|
|
486
|
+
strokeWidth?: number; // Line width. Default: 2
|
|
487
|
+
strokeOpacity?: number; // Line opacity. Default: 1
|
|
488
|
+
circleRadius?: number; // Point radius. Default: 6
|
|
489
|
+
circleColor?: string; // Point color. Default: '#3388ff'
|
|
490
|
+
circleStrokeColor?: string; // Point outline. Default: '#ffffff'
|
|
491
|
+
circleStrokeWidth?: number; // Point outline width. Default: 2
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
interface LoadedDataset {
|
|
495
|
+
id: string; // Unique ID
|
|
496
|
+
filename: string; // Original filename
|
|
497
|
+
sourceId: string; // MapLibre source ID
|
|
498
|
+
layerIds: string[]; // MapLibre layer IDs
|
|
499
|
+
featureCount: number; // Number of features
|
|
500
|
+
geometryTypes: string[]; // Geometry types present
|
|
501
|
+
loadedAt: Date; // When loaded
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Methods
|
|
505
|
+
vectorControl.show()
|
|
506
|
+
vectorControl.hide()
|
|
507
|
+
vectorControl.getLoadedDatasets() // Get all loaded datasets
|
|
508
|
+
vectorControl.removeDataset(id) // Remove a dataset by ID
|
|
509
|
+
vectorControl.removeAllDatasets() // Remove all datasets
|
|
510
|
+
vectorControl.loadGeoJSON(geojson, filename) // Programmatically load GeoJSON
|
|
511
|
+
vectorControl.update(options)
|
|
512
|
+
vectorControl.getState()
|
|
513
|
+
vectorControl.on('load', handler) // Fired when a dataset is loaded
|
|
514
|
+
vectorControl.on('error', handler) // Fired when an error occurs
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Loading Methods:**
|
|
518
|
+
- Click the upload button to open a file picker
|
|
519
|
+
- Drag and drop GeoJSON files directly onto the map
|
|
520
|
+
|
|
521
|
+
**Supported Formats:**
|
|
522
|
+
- GeoJSON (.geojson, .json)
|
|
523
|
+
- FeatureCollection, Feature, or raw Geometry objects
|
|
524
|
+
|
|
525
|
+
### TerrainControl
|
|
526
|
+
|
|
527
|
+
A toggle control for 3D terrain rendering using free AWS Terrarium elevation tiles.
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
interface TerrainControlOptions {
|
|
531
|
+
sourceUrl?: string; // Terrain tile URL (default: AWS Terrarium)
|
|
532
|
+
encoding?: 'terrarium' | 'mapbox'; // Terrain encoding (default: 'terrarium')
|
|
533
|
+
exaggeration?: number; // Vertical scale factor (default: 1.0)
|
|
534
|
+
enabled?: boolean; // Initial terrain state (default: false)
|
|
535
|
+
hillshade?: boolean; // Add hillshade layer (default: true)
|
|
536
|
+
hillshadeExaggeration?: number; // Hillshade intensity (default: 0.5)
|
|
537
|
+
position?: ControlPosition;
|
|
538
|
+
visible?: boolean;
|
|
539
|
+
backgroundColor?: string;
|
|
540
|
+
borderRadius?: number;
|
|
541
|
+
opacity?: number;
|
|
542
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
543
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Methods
|
|
547
|
+
terrainControl.show()
|
|
548
|
+
terrainControl.hide()
|
|
549
|
+
terrainControl.enable() // Enable terrain
|
|
550
|
+
terrainControl.disable() // Disable terrain
|
|
551
|
+
terrainControl.toggle() // Toggle terrain on/off
|
|
552
|
+
terrainControl.isEnabled() // Check if terrain is enabled
|
|
553
|
+
terrainControl.setExaggeration(value) // Set vertical exaggeration (0.1 - 10.0)
|
|
554
|
+
terrainControl.getExaggeration() // Get current exaggeration
|
|
555
|
+
terrainControl.enableHillshade() // Enable hillshade layer
|
|
556
|
+
terrainControl.disableHillshade() // Disable hillshade layer
|
|
557
|
+
terrainControl.toggleHillshade() // Toggle hillshade layer
|
|
558
|
+
terrainControl.update(options)
|
|
559
|
+
terrainControl.getState()
|
|
560
|
+
terrainControl.on('terrainchange', handler) // Listen for terrain toggle
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**Terrain Source:**
|
|
564
|
+
The control uses free terrain tiles from AWS:
|
|
565
|
+
- URL: `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png`
|
|
566
|
+
- Encoding: Terrarium RGB-encoded elevation data
|
|
567
|
+
- No API key required
|
|
568
|
+
|
|
569
|
+
### InspectControl
|
|
570
|
+
|
|
571
|
+
A control for inspecting vector features on the map. Click on features to view their properties/attributes in a popup.
|
|
572
|
+
|
|
573
|
+
```typescript
|
|
574
|
+
interface InspectControlOptions {
|
|
575
|
+
position?: ControlPosition;
|
|
576
|
+
visible?: boolean; // Default: true
|
|
577
|
+
enabled?: boolean; // Start with inspect mode on. Default: false
|
|
578
|
+
maxFeatures?: number; // Max features at click point. Default: 10
|
|
579
|
+
includeLayers?: string[]; // Only inspect these layers
|
|
580
|
+
excludeLayers?: string[]; // Skip these layers
|
|
581
|
+
highlightStyle?: InspectHighlightStyle; // Style for selected feature
|
|
582
|
+
excludeProperties?: string[]; // Properties to hide (e.g., internal IDs)
|
|
583
|
+
showGeometryType?: boolean; // Show geometry type badge. Default: true
|
|
584
|
+
showLayerName?: boolean; // Show layer name. Default: true
|
|
585
|
+
maxWidth?: number; // Popup max width. Default: 320
|
|
586
|
+
maxHeight?: number; // Popup content max height. Default: 300
|
|
587
|
+
backgroundColor?: string;
|
|
588
|
+
borderRadius?: number;
|
|
589
|
+
opacity?: number;
|
|
590
|
+
fontSize?: number;
|
|
591
|
+
fontColor?: string;
|
|
592
|
+
minzoom?: number;
|
|
593
|
+
maxzoom?: number;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
interface InspectHighlightStyle {
|
|
597
|
+
fillColor?: string; // Polygon fill. Default: '#ffff00'
|
|
598
|
+
fillOpacity?: number; // Polygon fill opacity. Default: 0.3
|
|
599
|
+
strokeColor?: string; // Line/outline color. Default: '#ffff00'
|
|
600
|
+
strokeWidth?: number; // Line width. Default: 3
|
|
601
|
+
circleRadius?: number; // Point radius. Default: 10
|
|
602
|
+
circleStrokeWidth?: number; // Point outline. Default: 3
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
interface InspectedFeature {
|
|
606
|
+
id: string; // Unique inspection ID
|
|
607
|
+
feature: GeoJSON.Feature; // The GeoJSON feature
|
|
608
|
+
layerId: string; // MapLibre layer ID
|
|
609
|
+
sourceId: string; // MapLibre source ID
|
|
610
|
+
lngLat: [number, number]; // Click coordinates
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// Methods
|
|
614
|
+
inspectControl.show()
|
|
615
|
+
inspectControl.hide()
|
|
616
|
+
inspectControl.enable() // Enable inspect mode
|
|
617
|
+
inspectControl.disable() // Disable inspect mode
|
|
618
|
+
inspectControl.toggle() // Toggle inspect mode on/off
|
|
619
|
+
inspectControl.isEnabled() // Check if inspect mode is enabled
|
|
620
|
+
inspectControl.clear() // Clear current inspection
|
|
621
|
+
inspectControl.getInspectedFeatures() // Get all features at click point
|
|
622
|
+
inspectControl.getSelectedFeature() // Get currently selected feature
|
|
623
|
+
inspectControl.selectFeature(index) // Select feature by index
|
|
624
|
+
inspectControl.nextFeature() // Navigate to next feature
|
|
625
|
+
inspectControl.previousFeature() // Navigate to previous feature
|
|
626
|
+
inspectControl.update(options)
|
|
627
|
+
inspectControl.getState()
|
|
628
|
+
inspectControl.on('enable', handler) // Fired when inspect mode is enabled
|
|
629
|
+
inspectControl.on('disable', handler) // Fired when inspect mode is disabled
|
|
630
|
+
inspectControl.on('featureselect', handler) // Fired when a feature is selected
|
|
631
|
+
inspectControl.on('clear', handler) // Fired when inspection is cleared
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**Usage:**
|
|
635
|
+
1. Click the info button to enable inspect mode
|
|
636
|
+
2. Click on any vector feature on the map
|
|
637
|
+
3. View properties in the popup
|
|
638
|
+
4. Use < > buttons to navigate when multiple features are at the same location
|
|
639
|
+
5. Click elsewhere or the button again to disable
|
|
640
|
+
|
|
251
641
|
## Built-in Colormaps
|
|
252
642
|
|
|
253
643
|
### Sequential
|
|
@@ -353,12 +743,16 @@ const colorbar = new Colorbar({
|
|
|
353
743
|
## React Hooks
|
|
354
744
|
|
|
355
745
|
```typescript
|
|
356
|
-
import { useColorbar, useLegend, useHtmlControl } from 'maplibre-gl-components/react';
|
|
746
|
+
import { useColorbar, useLegend, useHtmlControl, useBasemap, useTerrain, useSearchControl, useVectorDataset } from 'maplibre-gl-components/react';
|
|
357
747
|
|
|
358
748
|
function MyComponent() {
|
|
359
749
|
const colorbar = useColorbar({ colormap: 'viridis', vmin: 0, vmax: 100 });
|
|
360
750
|
const legend = useLegend({ items: [...] });
|
|
361
751
|
const htmlControl = useHtmlControl({ html: '...' });
|
|
752
|
+
const basemap = useBasemap({ selectedBasemap: 'OpenStreetMap.Mapnik' });
|
|
753
|
+
const terrain = useTerrain({ enabled: false, exaggeration: 1.5 });
|
|
754
|
+
const search = useSearchControl({ collapsed: true });
|
|
755
|
+
const vectorDataset = useVectorDataset();
|
|
362
756
|
|
|
363
757
|
return (
|
|
364
758
|
<>
|
|
@@ -368,10 +762,35 @@ function MyComponent() {
|
|
|
368
762
|
<button onClick={() => legend.toggle()}>
|
|
369
763
|
Toggle Legend
|
|
370
764
|
</button>
|
|
371
|
-
<button onClick={() =>
|
|
372
|
-
|
|
765
|
+
<button onClick={() => basemap.setBasemap('CartoDB.Positron')}>
|
|
766
|
+
Change Basemap
|
|
767
|
+
</button>
|
|
768
|
+
<button onClick={() => terrain.toggle()}>
|
|
769
|
+
Toggle Terrain
|
|
770
|
+
</button>
|
|
771
|
+
<button onClick={() => search.toggle()}>
|
|
772
|
+
Toggle Search
|
|
373
773
|
</button>
|
|
374
774
|
|
|
775
|
+
<SearchControlReact
|
|
776
|
+
map={map}
|
|
777
|
+
collapsed={search.state.collapsed}
|
|
778
|
+
onResultSelect={(result) => search.selectResult(result)}
|
|
779
|
+
/>
|
|
780
|
+
|
|
781
|
+
<TerrainReact
|
|
782
|
+
map={map}
|
|
783
|
+
enabled={terrain.state.enabled}
|
|
784
|
+
exaggeration={terrain.state.exaggeration}
|
|
785
|
+
onTerrainChange={(enabled) => terrain.setEnabled(enabled)}
|
|
786
|
+
/>
|
|
787
|
+
|
|
788
|
+
<BasemapReact
|
|
789
|
+
map={map}
|
|
790
|
+
defaultBasemap={basemap.state.selectedBasemap}
|
|
791
|
+
onBasemapChange={(b) => basemap.setBasemap(b.id)}
|
|
792
|
+
/>
|
|
793
|
+
|
|
375
794
|
<ColorbarReact
|
|
376
795
|
map={map}
|
|
377
796
|
{...colorbar.state}
|
|
@@ -404,6 +823,34 @@ The default styles can be customized using CSS:
|
|
|
404
823
|
.maplibre-gl-html-control {
|
|
405
824
|
max-width: 400px;
|
|
406
825
|
}
|
|
826
|
+
|
|
827
|
+
/* Override basemap control styles */
|
|
828
|
+
.maplibre-gl-basemap {
|
|
829
|
+
max-width: 300px;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/* Override terrain control styles */
|
|
833
|
+
.maplibre-gl-terrain-button {
|
|
834
|
+
color: #0078d7;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/* Override search control styles */
|
|
838
|
+
.maplibre-gl-search {
|
|
839
|
+
background: rgba(255, 255, 255, 0.95);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.maplibre-gl-search-toggle:hover {
|
|
843
|
+
color: #0078d7;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/* Override vector dataset control styles */
|
|
847
|
+
.maplibre-gl-vector-dataset-button:hover {
|
|
848
|
+
color: #0078d7;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.maplibre-gl-vector-dataset-dropzone {
|
|
852
|
+
background: rgba(0, 120, 215, 0.2);
|
|
853
|
+
}
|
|
407
854
|
```
|
|
408
855
|
|
|
409
856
|
## Examples
|