maplibre-gl-components 0.2.1 → 0.4.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.
Files changed (51) hide show
  1. package/README.md +231 -6
  2. package/dist/Terrain-1bxohZJX.cjs +2812 -0
  3. package/dist/Terrain-1bxohZJX.cjs.map +1 -0
  4. package/dist/Terrain-BbC-hVIs.js +2813 -0
  5. package/dist/Terrain-BbC-hVIs.js.map +1 -0
  6. package/dist/index.cjs +45 -35
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.mjs +37 -27
  9. package/dist/maplibre-gl-components.css +327 -0
  10. package/dist/react.cjs +308 -16
  11. package/dist/react.cjs.map +1 -1
  12. package/dist/react.mjs +306 -14
  13. package/dist/react.mjs.map +1 -1
  14. package/dist/types/index.d.ts +4 -1
  15. package/dist/types/index.d.ts.map +1 -1
  16. package/dist/types/lib/core/Basemap.d.ts +206 -0
  17. package/dist/types/lib/core/Basemap.d.ts.map +1 -0
  18. package/dist/types/lib/core/BasemapReact.d.ts +32 -0
  19. package/dist/types/lib/core/BasemapReact.d.ts.map +1 -0
  20. package/dist/types/lib/core/Colorbar.d.ts +12 -1
  21. package/dist/types/lib/core/Colorbar.d.ts.map +1 -1
  22. package/dist/types/lib/core/ColorbarReact.d.ts.map +1 -1
  23. package/dist/types/lib/core/HtmlControl.d.ts +12 -1
  24. package/dist/types/lib/core/HtmlControl.d.ts.map +1 -1
  25. package/dist/types/lib/core/HtmlControlReact.d.ts.map +1 -1
  26. package/dist/types/lib/core/Legend.d.ts +12 -1
  27. package/dist/types/lib/core/Legend.d.ts.map +1 -1
  28. package/dist/types/lib/core/LegendReact.d.ts.map +1 -1
  29. package/dist/types/lib/core/Terrain.d.ts +165 -0
  30. package/dist/types/lib/core/Terrain.d.ts.map +1 -0
  31. package/dist/types/lib/core/TerrainReact.d.ts +32 -0
  32. package/dist/types/lib/core/TerrainReact.d.ts.map +1 -0
  33. package/dist/types/lib/core/types.d.ts +214 -0
  34. package/dist/types/lib/core/types.d.ts.map +1 -1
  35. package/dist/types/lib/hooks/index.d.ts +2 -0
  36. package/dist/types/lib/hooks/index.d.ts.map +1 -1
  37. package/dist/types/lib/hooks/useBasemap.d.ts +43 -0
  38. package/dist/types/lib/hooks/useBasemap.d.ts.map +1 -0
  39. package/dist/types/lib/hooks/useTerrain.d.ts +43 -0
  40. package/dist/types/lib/hooks/useTerrain.d.ts.map +1 -0
  41. package/dist/types/lib/utils/index.d.ts +1 -0
  42. package/dist/types/lib/utils/index.d.ts.map +1 -1
  43. package/dist/types/lib/utils/providers.d.ts +46 -0
  44. package/dist/types/lib/utils/providers.d.ts.map +1 -0
  45. package/dist/types/react.d.ts +4 -2
  46. package/dist/types/react.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/dist/HtmlControl-mwWlMV6V.js +0 -1281
  49. package/dist/HtmlControl-mwWlMV6V.js.map +0 -1
  50. package/dist/HtmlControl-te5F3x7c.cjs +0 -1280
  51. package/dist/HtmlControl-te5F3x7c.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, and HTML control components for MapLibre GL JS maps.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/maplibre-gl-components.svg)](https://badge.fury.io/js/maplibre-gl-components)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -9,7 +9,10 @@ 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
12
14
  - **HtmlControl** - Flexible HTML content control for custom info panels
15
+ - **Zoom-based Visibility** - Show/hide components at specific zoom levels with `minzoom`/`maxzoom`
13
16
  - **React Support** - First-class React components and hooks
14
17
  - **TypeScript** - Full type definitions included
15
18
  - **20+ Built-in Colormaps** - viridis, plasma, terrain, jet, and more
@@ -26,7 +29,7 @@ npm install maplibre-gl-components
26
29
 
27
30
  ```typescript
28
31
  import maplibregl from 'maplibre-gl';
29
- import { Colorbar, Legend, HtmlControl } from 'maplibre-gl-components';
32
+ import { Colorbar, Legend, HtmlControl, BasemapControl, TerrainControl } from 'maplibre-gl-components';
30
33
  import 'maplibre-gl-components/style.css';
31
34
 
32
35
  const map = new maplibregl.Map({
@@ -36,6 +39,21 @@ const map = new maplibregl.Map({
36
39
  zoom: 4,
37
40
  });
38
41
 
42
+ // Add a terrain toggle control
43
+ const terrainControl = new TerrainControl({
44
+ exaggeration: 1.5,
45
+ hillshade: true,
46
+ });
47
+ map.addControl(terrainControl, 'top-right');
48
+
49
+ // Add a basemap switcher
50
+ const basemapControl = new BasemapControl({
51
+ defaultBasemap: 'OpenStreetMap.Mapnik',
52
+ showSearch: true,
53
+ filterGroups: ['OpenStreetMap', 'CartoDB', 'Stadia', 'Esri'],
54
+ });
55
+ map.addControl(basemapControl, 'top-left');
56
+
39
57
  // Add a colorbar
40
58
  const colorbar = new Colorbar({
41
59
  colormap: 'viridis',
@@ -74,7 +92,7 @@ htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');
74
92
  ```tsx
75
93
  import { useState, useEffect, useRef } from 'react';
76
94
  import maplibregl from 'maplibre-gl';
77
- import { ColorbarReact, LegendReact, HtmlControlReact } from 'maplibre-gl-components/react';
95
+ import { ColorbarReact, LegendReact, HtmlControlReact, BasemapReact, TerrainReact } from 'maplibre-gl-components/react';
78
96
  import 'maplibre-gl-components/style.css';
79
97
 
80
98
  function MyMap() {
@@ -103,6 +121,22 @@ function MyMap() {
103
121
 
104
122
  {map && (
105
123
  <>
124
+ <TerrainReact
125
+ map={map}
126
+ exaggeration={1.5}
127
+ hillshade
128
+ position="top-right"
129
+ onTerrainChange={(enabled) => console.log('Terrain:', enabled)}
130
+ />
131
+
132
+ <BasemapReact
133
+ map={map}
134
+ defaultBasemap="OpenStreetMap.Mapnik"
135
+ showSearch
136
+ filterGroups={['OpenStreetMap', 'CartoDB', 'Stadia']}
137
+ position="top-left"
138
+ />
139
+
106
140
  <ColorbarReact
107
141
  map={map}
108
142
  colormap="viridis"
@@ -160,6 +194,8 @@ interface ColorbarOptions {
160
194
  opacity?: number;
161
195
  fontSize?: number;
162
196
  fontColor?: string;
197
+ minzoom?: number; // Min zoom level to show (default: 0)
198
+ maxzoom?: number; // Max zoom level to show (default: 24)
163
199
  }
164
200
 
165
201
  // Methods
@@ -190,6 +226,8 @@ interface LegendOptions {
190
226
  opacity?: number;
191
227
  fontSize?: number;
192
228
  fontColor?: string;
229
+ minzoom?: number; // Min zoom level to show (default: 0)
230
+ maxzoom?: number; // Max zoom level to show (default: 24)
193
231
  }
194
232
 
195
233
  interface LegendItem {
@@ -229,6 +267,8 @@ interface HtmlControlOptions {
229
267
  opacity?: number;
230
268
  maxWidth?: number;
231
269
  maxHeight?: number;
270
+ minzoom?: number; // Min zoom level to show (default: 0)
271
+ maxzoom?: number; // Max zoom level to show (default: 24)
232
272
  }
233
273
 
234
274
  // Methods
@@ -241,6 +281,113 @@ htmlControl.update(options)
241
281
  htmlControl.getState()
242
282
  ```
243
283
 
284
+ ### BasemapControl
285
+
286
+ An interactive basemap switcher that loads providers from [xyzservices](https://github.com/geopandas/xyzservices).
287
+
288
+ ```typescript
289
+ interface BasemapControlOptions {
290
+ basemaps?: BasemapItem[]; // Custom basemaps array
291
+ providersUrl?: string; // URL to fetch providers.json (defaults to xyzservices)
292
+ defaultBasemap?: string; // Initial basemap ID (e.g., 'OpenStreetMap.Mapnik')
293
+ position?: ControlPosition;
294
+ visible?: boolean;
295
+ collapsible?: boolean; // Whether control is collapsible (default: true)
296
+ collapsed?: boolean; // Whether control starts collapsed (default: true)
297
+ displayMode?: 'dropdown' | 'gallery' | 'list'; // UI mode (default: 'dropdown')
298
+ showSearch?: boolean; // Show search input (default: true)
299
+ filterGroups?: string[]; // Only include these provider groups
300
+ excludeGroups?: string[]; // Exclude these provider groups
301
+ excludeBroken?: boolean; // Exclude broken providers (default: true)
302
+ backgroundColor?: string;
303
+ maxWidth?: number;
304
+ maxHeight?: number;
305
+ fontSize?: number;
306
+ fontColor?: string;
307
+ minzoom?: number;
308
+ maxzoom?: number;
309
+ }
310
+
311
+ interface BasemapItem {
312
+ id: string; // Unique identifier
313
+ name: string; // Display name
314
+ group?: string; // Provider group (e.g., 'OpenStreetMap')
315
+ url?: string; // XYZ tile URL template
316
+ style?: string; // MapLibre style URL
317
+ attribution?: string;
318
+ thumbnail?: string; // Preview image URL
319
+ maxZoom?: number;
320
+ minZoom?: number;
321
+ requiresApiKey?: boolean;
322
+ apiKey?: string;
323
+ }
324
+
325
+ // Methods
326
+ basemapControl.show()
327
+ basemapControl.hide()
328
+ basemapControl.expand()
329
+ basemapControl.collapse()
330
+ basemapControl.toggle()
331
+ basemapControl.setBasemap(basemapId) // Switch to a basemap
332
+ basemapControl.getBasemaps() // Get available basemaps
333
+ basemapControl.addBasemap(basemap) // Add a custom basemap
334
+ basemapControl.removeBasemap(id) // Remove a basemap
335
+ basemapControl.setApiKey(id, key) // Set API key for a basemap
336
+ basemapControl.getSelectedBasemap() // Get currently selected basemap
337
+ basemapControl.update(options)
338
+ basemapControl.getState()
339
+ basemapControl.on('basemapchange', handler) // Listen for basemap changes
340
+ ```
341
+
342
+ **Available Provider Groups:**
343
+ - OpenStreetMap, CartoDB, Stadia, Esri, OpenTopoMap
344
+ - Thunderforest, MapBox, MapTiler (require API keys)
345
+ - NASAGIBS, OpenSeaMap, and 20+ more
346
+
347
+ ### TerrainControl
348
+
349
+ A toggle control for 3D terrain rendering using free AWS Terrarium elevation tiles.
350
+
351
+ ```typescript
352
+ interface TerrainControlOptions {
353
+ sourceUrl?: string; // Terrain tile URL (default: AWS Terrarium)
354
+ encoding?: 'terrarium' | 'mapbox'; // Terrain encoding (default: 'terrarium')
355
+ exaggeration?: number; // Vertical scale factor (default: 1.0)
356
+ enabled?: boolean; // Initial terrain state (default: false)
357
+ hillshade?: boolean; // Add hillshade layer (default: true)
358
+ hillshadeExaggeration?: number; // Hillshade intensity (default: 0.5)
359
+ position?: ControlPosition;
360
+ visible?: boolean;
361
+ backgroundColor?: string;
362
+ borderRadius?: number;
363
+ opacity?: number;
364
+ minzoom?: number; // Min zoom level to show (default: 0)
365
+ maxzoom?: number; // Max zoom level to show (default: 24)
366
+ }
367
+
368
+ // Methods
369
+ terrainControl.show()
370
+ terrainControl.hide()
371
+ terrainControl.enable() // Enable terrain
372
+ terrainControl.disable() // Disable terrain
373
+ terrainControl.toggle() // Toggle terrain on/off
374
+ terrainControl.isEnabled() // Check if terrain is enabled
375
+ terrainControl.setExaggeration(value) // Set vertical exaggeration (0.1 - 10.0)
376
+ terrainControl.getExaggeration() // Get current exaggeration
377
+ terrainControl.enableHillshade() // Enable hillshade layer
378
+ terrainControl.disableHillshade() // Disable hillshade layer
379
+ terrainControl.toggleHillshade() // Toggle hillshade layer
380
+ terrainControl.update(options)
381
+ terrainControl.getState()
382
+ terrainControl.on('terrainchange', handler) // Listen for terrain toggle
383
+ ```
384
+
385
+ **Terrain Source:**
386
+ The control uses free terrain tiles from AWS:
387
+ - URL: `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png`
388
+ - Encoding: Terrarium RGB-encoded elevation data
389
+ - No API key required
390
+
244
391
  ## Built-in Colormaps
245
392
 
246
393
  ### Sequential
@@ -293,15 +440,67 @@ const colorbar = new Colorbar({
293
440
  });
294
441
  ```
295
442
 
443
+ ## Zoom-based Visibility
444
+
445
+ 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.
446
+
447
+ ```typescript
448
+ // Show legend only when zoomed in (zoom >= 10)
449
+ const detailLegend = new Legend({
450
+ title: 'Detailed Features',
451
+ items: [...],
452
+ minzoom: 10, // Only visible at zoom 10 and above
453
+ });
454
+
455
+ // Show legend only when zoomed out (zoom <= 8)
456
+ const overviewLegend = new Legend({
457
+ title: 'Overview',
458
+ items: [...],
459
+ maxzoom: 8, // Only visible at zoom 8 and below
460
+ });
461
+
462
+ // Show colorbar only within a specific zoom range
463
+ const colorbar = new Colorbar({
464
+ colormap: 'viridis',
465
+ vmin: 0,
466
+ vmax: 100,
467
+ minzoom: 5, // Visible from zoom 5...
468
+ maxzoom: 15, // ...up to zoom 15
469
+ });
470
+ ```
471
+
472
+ ### React Example
473
+
474
+ ```tsx
475
+ <LegendReact
476
+ map={map}
477
+ title="Lidar Point Cloud"
478
+ items={[
479
+ { label: 'QL0 (Approx. <= 0.35m NPS)', color: '#003300' },
480
+ { label: 'QL1 (Approx. 0.35m NPS)', color: '#006600' },
481
+ { label: 'QL2 (Approx. 0.7m NPS)', color: '#00cc00' },
482
+ { label: 'QL3 (Approx. 1.4m NPS)', color: '#ccff00' },
483
+ { label: 'Other', color: '#99ccff' },
484
+ ]}
485
+ minzoom={8}
486
+ maxzoom={18}
487
+ position="top-left"
488
+ />
489
+ ```
490
+
491
+ **Note:** The `visible` option takes precedence - if `visible` is `false`, the component will be hidden regardless of zoom level.
492
+
296
493
  ## React Hooks
297
494
 
298
495
  ```typescript
299
- import { useColorbar, useLegend, useHtmlControl } from 'maplibre-gl-components/react';
496
+ import { useColorbar, useLegend, useHtmlControl, useBasemap, useTerrain } from 'maplibre-gl-components/react';
300
497
 
301
498
  function MyComponent() {
302
499
  const colorbar = useColorbar({ colormap: 'viridis', vmin: 0, vmax: 100 });
303
500
  const legend = useLegend({ items: [...] });
304
501
  const htmlControl = useHtmlControl({ html: '...' });
502
+ const basemap = useBasemap({ selectedBasemap: 'OpenStreetMap.Mapnik' });
503
+ const terrain = useTerrain({ enabled: false, exaggeration: 1.5 });
305
504
 
306
505
  return (
307
506
  <>
@@ -311,9 +510,25 @@ function MyComponent() {
311
510
  <button onClick={() => legend.toggle()}>
312
511
  Toggle Legend
313
512
  </button>
314
- <button onClick={() => htmlControl.setHtml('<div>Updated!</div>')}>
315
- Update HTML
513
+ <button onClick={() => basemap.setBasemap('CartoDB.Positron')}>
514
+ Change Basemap
316
515
  </button>
516
+ <button onClick={() => terrain.toggle()}>
517
+ Toggle Terrain
518
+ </button>
519
+
520
+ <TerrainReact
521
+ map={map}
522
+ enabled={terrain.state.enabled}
523
+ exaggeration={terrain.state.exaggeration}
524
+ onTerrainChange={(enabled) => terrain.setEnabled(enabled)}
525
+ />
526
+
527
+ <BasemapReact
528
+ map={map}
529
+ defaultBasemap={basemap.state.selectedBasemap}
530
+ onBasemapChange={(b) => basemap.setBasemap(b.id)}
531
+ />
317
532
 
318
533
  <ColorbarReact
319
534
  map={map}
@@ -347,6 +562,16 @@ The default styles can be customized using CSS:
347
562
  .maplibre-gl-html-control {
348
563
  max-width: 400px;
349
564
  }
565
+
566
+ /* Override basemap control styles */
567
+ .maplibre-gl-basemap {
568
+ max-width: 300px;
569
+ }
570
+
571
+ /* Override terrain control styles */
572
+ .maplibre-gl-terrain-button {
573
+ color: #0078d7;
574
+ }
350
575
  ```
351
576
 
352
577
  ## Examples