maplibre-gl-basemap-control 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/dist/BasemapControl-C40PophU.js +1343 -0
- package/dist/BasemapControl-C40PophU.js.map +1 -0
- package/dist/BasemapControl-pnHGO378.cjs +1342 -0
- package/dist/BasemapControl-pnHGO378.cjs.map +1 -0
- package/dist/index.cjs +57 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +57 -0
- package/dist/index.mjs.map +1 -0
- package/dist/maplibre-gl-basemap-control.css +272 -0
- package/dist/react.cjs +126 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.mjs +126 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/core/BasemapControl.d.ts +57 -0
- package/dist/types/lib/core/BasemapControl.d.ts.map +1 -0
- package/dist/types/lib/core/BasemapControlReact.d.ts +3 -0
- package/dist/types/lib/core/BasemapControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/catalog.d.ts +14 -0
- package/dist/types/lib/core/catalog.d.ts.map +1 -0
- package/dist/types/lib/core/types.d.ts +85 -0
- package/dist/types/lib/core/types.d.ts.map +1 -0
- package/dist/types/lib/hooks/index.d.ts +2 -0
- package/dist/types/lib/hooks/index.d.ts.map +1 -0
- package/dist/types/lib/hooks/useBasemapState.d.ts +12 -0
- package/dist/types/lib/hooks/useBasemapState.d.ts.map +1 -0
- package/dist/types/lib/utils/helpers.d.ts +86 -0
- package/dist/types/lib/utils/helpers.d.ts.map +1 -0
- package/dist/types/lib/utils/index.d.ts +2 -0
- package/dist/types/lib/utils/index.d.ts.map +1 -0
- package/dist/types/react.d.ts +4 -0
- package/dist/types/react.d.ts.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,1343 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
const DEFAULT_BASEMAP_PROVIDERS = [
|
|
5
|
+
{ id: "openstreetmap", name: "OpenStreetMap", category: "Community" },
|
|
6
|
+
{ id: "google", name: "Google", category: "General" },
|
|
7
|
+
{ id: "carto", name: "Carto", category: "General" },
|
|
8
|
+
{ id: "cyclosm", name: "CyclOSM", category: "Cycling" },
|
|
9
|
+
{ id: "esri", name: "ESRI", category: "Imagery" },
|
|
10
|
+
{ id: "nasa-gibs", name: "NASA GIBS", category: "Imagery" },
|
|
11
|
+
{ id: "openrailwaymap", name: "OpenRailwayMap", category: "Transport" },
|
|
12
|
+
{ id: "opentopomap", name: "OpenTopoMap", category: "Terrain" },
|
|
13
|
+
{ id: "openfreemap", name: "OpenFreeMap", category: "Vector Styles" },
|
|
14
|
+
{ id: "swisstopo", name: "Swiss Federal Geoportal", category: "Regional" },
|
|
15
|
+
{ id: "topplusopen", name: "TopPlusOpen", category: "Regional" },
|
|
16
|
+
{ id: "usgs", name: "USGS", category: "United States" },
|
|
17
|
+
{ id: "waymarkedtrails", name: "Waymarked Trails", category: "Outdoor" },
|
|
18
|
+
{ id: "nlmaps", name: "nlmaps", category: "Regional" }
|
|
19
|
+
];
|
|
20
|
+
function rasterBasemap({
|
|
21
|
+
id,
|
|
22
|
+
name,
|
|
23
|
+
provider,
|
|
24
|
+
category,
|
|
25
|
+
description,
|
|
26
|
+
attribution,
|
|
27
|
+
tiles,
|
|
28
|
+
maxzoom = 19,
|
|
29
|
+
tags = []
|
|
30
|
+
}) {
|
|
31
|
+
return {
|
|
32
|
+
id,
|
|
33
|
+
name,
|
|
34
|
+
provider,
|
|
35
|
+
type: "raster",
|
|
36
|
+
category,
|
|
37
|
+
description,
|
|
38
|
+
attribution,
|
|
39
|
+
source: {
|
|
40
|
+
type: "raster",
|
|
41
|
+
tiles,
|
|
42
|
+
tileSize: 256,
|
|
43
|
+
maxzoom
|
|
44
|
+
},
|
|
45
|
+
tags
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const CARTO_ATTRIBUTION = "© OpenStreetMap contributors © CARTO";
|
|
49
|
+
const ESRI_ATTRIBUTION = "Tiles © Esri and the GIS User Community";
|
|
50
|
+
const OSM_ATTRIBUTION = "© OpenStreetMap contributors";
|
|
51
|
+
const OPENFREEMAP_ATTRIBUTION = "OpenFreeMap © OpenMapTiles Data from OpenStreetMap";
|
|
52
|
+
const DEFAULT_BASEMAPS = [
|
|
53
|
+
rasterBasemap({
|
|
54
|
+
id: "osm-standard",
|
|
55
|
+
name: "OpenStreetMap Standard",
|
|
56
|
+
provider: "openstreetmap",
|
|
57
|
+
category: "Street",
|
|
58
|
+
description: "Community-maintained street map.",
|
|
59
|
+
attribution: OSM_ATTRIBUTION,
|
|
60
|
+
tiles: [
|
|
61
|
+
"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
62
|
+
"https://b.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
63
|
+
"https://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
64
|
+
],
|
|
65
|
+
tags: ["osm", "street", "standard"]
|
|
66
|
+
}),
|
|
67
|
+
rasterBasemap({
|
|
68
|
+
id: "osm-hot",
|
|
69
|
+
name: "OpenStreetMap HOT",
|
|
70
|
+
provider: "openstreetmap",
|
|
71
|
+
category: "Street",
|
|
72
|
+
description: "Humanitarian OpenStreetMap Team style.",
|
|
73
|
+
attribution: `${OSM_ATTRIBUTION}, Tiles style by Humanitarian OpenStreetMap Team`,
|
|
74
|
+
tiles: ["https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"],
|
|
75
|
+
tags: ["osm", "hot", "humanitarian"]
|
|
76
|
+
}),
|
|
77
|
+
rasterBasemap({
|
|
78
|
+
id: "osm-de",
|
|
79
|
+
name: "OpenStreetMap DE",
|
|
80
|
+
provider: "openstreetmap",
|
|
81
|
+
category: "Regional",
|
|
82
|
+
description: "German OpenStreetMap tile style.",
|
|
83
|
+
attribution: OSM_ATTRIBUTION,
|
|
84
|
+
tiles: ["https://tile.openstreetmap.de/{z}/{x}/{y}.png"],
|
|
85
|
+
tags: ["osm", "germany", "regional"]
|
|
86
|
+
}),
|
|
87
|
+
rasterBasemap({
|
|
88
|
+
id: "osm-ch",
|
|
89
|
+
name: "OpenStreetMap CH",
|
|
90
|
+
provider: "openstreetmap",
|
|
91
|
+
category: "Regional",
|
|
92
|
+
description: "Swiss OpenStreetMap tile style.",
|
|
93
|
+
attribution: OSM_ATTRIBUTION,
|
|
94
|
+
tiles: ["https://tile.osm.ch/switzerland/{z}/{x}/{y}.png"],
|
|
95
|
+
tags: ["osm", "switzerland", "regional"]
|
|
96
|
+
}),
|
|
97
|
+
rasterBasemap({
|
|
98
|
+
id: "google-maps",
|
|
99
|
+
name: "Google Maps",
|
|
100
|
+
provider: "google",
|
|
101
|
+
category: "Street",
|
|
102
|
+
description: "Google road map tiles from the QGIS basemaps source.",
|
|
103
|
+
attribution: "© Google",
|
|
104
|
+
tiles: ["https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"],
|
|
105
|
+
maxzoom: 20,
|
|
106
|
+
tags: ["google", "street"]
|
|
107
|
+
}),
|
|
108
|
+
rasterBasemap({
|
|
109
|
+
id: "google-satellite",
|
|
110
|
+
name: "Google Satellite",
|
|
111
|
+
provider: "google",
|
|
112
|
+
category: "Imagery",
|
|
113
|
+
description: "Google satellite tiles from the QGIS basemaps source.",
|
|
114
|
+
attribution: "© Google",
|
|
115
|
+
tiles: ["https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"],
|
|
116
|
+
maxzoom: 20,
|
|
117
|
+
tags: ["google", "satellite", "imagery"]
|
|
118
|
+
}),
|
|
119
|
+
rasterBasemap({
|
|
120
|
+
id: "google-terrain",
|
|
121
|
+
name: "Google Terrain",
|
|
122
|
+
provider: "google",
|
|
123
|
+
category: "Terrain",
|
|
124
|
+
description: "Google terrain tiles from the QGIS basemaps source.",
|
|
125
|
+
attribution: "© Google",
|
|
126
|
+
tiles: ["https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}"],
|
|
127
|
+
maxzoom: 20,
|
|
128
|
+
tags: ["google", "terrain"]
|
|
129
|
+
}),
|
|
130
|
+
rasterBasemap({
|
|
131
|
+
id: "google-hybrid",
|
|
132
|
+
name: "Google Hybrid",
|
|
133
|
+
provider: "google",
|
|
134
|
+
category: "Imagery",
|
|
135
|
+
description: "Google hybrid imagery tiles from the QGIS basemaps source.",
|
|
136
|
+
attribution: "© Google",
|
|
137
|
+
tiles: ["https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}"],
|
|
138
|
+
maxzoom: 20,
|
|
139
|
+
tags: ["google", "hybrid", "imagery"]
|
|
140
|
+
}),
|
|
141
|
+
rasterBasemap({
|
|
142
|
+
id: "carto-positron",
|
|
143
|
+
name: "Carto Positron",
|
|
144
|
+
provider: "carto",
|
|
145
|
+
category: "Light",
|
|
146
|
+
description: "Light basemap for data overlays.",
|
|
147
|
+
attribution: CARTO_ATTRIBUTION,
|
|
148
|
+
tiles: [
|
|
149
|
+
"https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
|
150
|
+
"https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
|
151
|
+
"https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
|
|
152
|
+
"https://d.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"
|
|
153
|
+
],
|
|
154
|
+
maxzoom: 20,
|
|
155
|
+
tags: ["carto", "light", "positron"]
|
|
156
|
+
}),
|
|
157
|
+
rasterBasemap({
|
|
158
|
+
id: "carto-positron-no-labels",
|
|
159
|
+
name: "Carto Positron No Labels",
|
|
160
|
+
provider: "carto",
|
|
161
|
+
category: "Light",
|
|
162
|
+
description: "Light basemap without labels.",
|
|
163
|
+
attribution: CARTO_ATTRIBUTION,
|
|
164
|
+
tiles: ["https://a.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png"],
|
|
165
|
+
maxzoom: 20,
|
|
166
|
+
tags: ["carto", "light", "no labels"]
|
|
167
|
+
}),
|
|
168
|
+
rasterBasemap({
|
|
169
|
+
id: "carto-positron-only-labels",
|
|
170
|
+
name: "Carto Positron Only Labels",
|
|
171
|
+
provider: "carto",
|
|
172
|
+
category: "Labels",
|
|
173
|
+
description: "Carto Positron labels layer.",
|
|
174
|
+
attribution: CARTO_ATTRIBUTION,
|
|
175
|
+
tiles: ["https://a.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png"],
|
|
176
|
+
maxzoom: 20,
|
|
177
|
+
tags: ["carto", "labels"]
|
|
178
|
+
}),
|
|
179
|
+
rasterBasemap({
|
|
180
|
+
id: "carto-dark-matter",
|
|
181
|
+
name: "Carto Dark Matter",
|
|
182
|
+
provider: "carto",
|
|
183
|
+
category: "Dark",
|
|
184
|
+
description: "Dark basemap for high-contrast overlays.",
|
|
185
|
+
attribution: CARTO_ATTRIBUTION,
|
|
186
|
+
tiles: [
|
|
187
|
+
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
|
188
|
+
"https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
|
189
|
+
"https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
|
190
|
+
"https://d.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"
|
|
191
|
+
],
|
|
192
|
+
maxzoom: 20,
|
|
193
|
+
tags: ["carto", "dark", "matter"]
|
|
194
|
+
}),
|
|
195
|
+
rasterBasemap({
|
|
196
|
+
id: "carto-dark-matter-no-labels",
|
|
197
|
+
name: "Carto Dark Matter No Labels",
|
|
198
|
+
provider: "carto",
|
|
199
|
+
category: "Dark",
|
|
200
|
+
description: "Dark basemap without labels.",
|
|
201
|
+
attribution: CARTO_ATTRIBUTION,
|
|
202
|
+
tiles: ["https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png"],
|
|
203
|
+
maxzoom: 20,
|
|
204
|
+
tags: ["carto", "dark", "no labels"]
|
|
205
|
+
}),
|
|
206
|
+
rasterBasemap({
|
|
207
|
+
id: "carto-dark-matter-only-labels",
|
|
208
|
+
name: "Carto Dark Matter Only Labels",
|
|
209
|
+
provider: "carto",
|
|
210
|
+
category: "Labels",
|
|
211
|
+
description: "Carto Dark Matter labels layer.",
|
|
212
|
+
attribution: CARTO_ATTRIBUTION,
|
|
213
|
+
tiles: ["https://a.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}.png"],
|
|
214
|
+
maxzoom: 20,
|
|
215
|
+
tags: ["carto", "dark", "labels"]
|
|
216
|
+
}),
|
|
217
|
+
rasterBasemap({
|
|
218
|
+
id: "carto-voyager",
|
|
219
|
+
name: "Carto Voyager",
|
|
220
|
+
provider: "carto",
|
|
221
|
+
category: "Street",
|
|
222
|
+
description: "Detailed street basemap with subtle styling.",
|
|
223
|
+
attribution: CARTO_ATTRIBUTION,
|
|
224
|
+
tiles: [
|
|
225
|
+
"https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
|
|
226
|
+
"https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
|
|
227
|
+
"https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
|
|
228
|
+
"https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png"
|
|
229
|
+
],
|
|
230
|
+
maxzoom: 20,
|
|
231
|
+
tags: ["carto", "street", "voyager"]
|
|
232
|
+
}),
|
|
233
|
+
rasterBasemap({
|
|
234
|
+
id: "carto-voyager-no-labels",
|
|
235
|
+
name: "Carto Voyager No Labels",
|
|
236
|
+
provider: "carto",
|
|
237
|
+
category: "Street",
|
|
238
|
+
description: "Carto Voyager without labels.",
|
|
239
|
+
attribution: CARTO_ATTRIBUTION,
|
|
240
|
+
tiles: ["https://a.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png"],
|
|
241
|
+
maxzoom: 20,
|
|
242
|
+
tags: ["carto", "voyager", "no labels"]
|
|
243
|
+
}),
|
|
244
|
+
rasterBasemap({
|
|
245
|
+
id: "carto-voyager-only-labels",
|
|
246
|
+
name: "Carto Voyager Only Labels",
|
|
247
|
+
provider: "carto",
|
|
248
|
+
category: "Labels",
|
|
249
|
+
description: "Carto Voyager labels layer.",
|
|
250
|
+
attribution: CARTO_ATTRIBUTION,
|
|
251
|
+
tiles: ["https://a.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png"],
|
|
252
|
+
maxzoom: 20,
|
|
253
|
+
tags: ["carto", "voyager", "labels"]
|
|
254
|
+
}),
|
|
255
|
+
rasterBasemap({
|
|
256
|
+
id: "carto-voyager-labels-under",
|
|
257
|
+
name: "Carto Voyager Labels Under",
|
|
258
|
+
provider: "carto",
|
|
259
|
+
category: "Street",
|
|
260
|
+
description: "Carto Voyager labels-under variant.",
|
|
261
|
+
attribution: CARTO_ATTRIBUTION,
|
|
262
|
+
tiles: ["https://a.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"],
|
|
263
|
+
maxzoom: 20,
|
|
264
|
+
tags: ["carto", "voyager", "labels"]
|
|
265
|
+
}),
|
|
266
|
+
rasterBasemap({
|
|
267
|
+
id: "cyclosm",
|
|
268
|
+
name: "CyclOSM",
|
|
269
|
+
provider: "cyclosm",
|
|
270
|
+
category: "Cycling",
|
|
271
|
+
description: "Cycling-focused OpenStreetMap style.",
|
|
272
|
+
attribution: "CyclOSM | Map data: © OpenStreetMap contributors",
|
|
273
|
+
tiles: ["https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png"],
|
|
274
|
+
tags: ["cycling", "osm"]
|
|
275
|
+
}),
|
|
276
|
+
rasterBasemap({
|
|
277
|
+
id: "esri-world-imagery",
|
|
278
|
+
name: "World Imagery",
|
|
279
|
+
provider: "esri",
|
|
280
|
+
category: "Imagery",
|
|
281
|
+
description: "Satellite and aerial imagery.",
|
|
282
|
+
attribution: "Tiles © Esri, Maxar, Earthstar Geographics, and the GIS User Community",
|
|
283
|
+
tiles: [
|
|
284
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
|
285
|
+
],
|
|
286
|
+
tags: ["esri", "satellite", "imagery"]
|
|
287
|
+
}),
|
|
288
|
+
rasterBasemap({
|
|
289
|
+
id: "esri-world-topo",
|
|
290
|
+
name: "World Topographic",
|
|
291
|
+
provider: "esri",
|
|
292
|
+
category: "Terrain",
|
|
293
|
+
description: "Reference topographic map.",
|
|
294
|
+
attribution: ESRI_ATTRIBUTION,
|
|
295
|
+
tiles: [
|
|
296
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}"
|
|
297
|
+
],
|
|
298
|
+
tags: ["esri", "topographic", "terrain"]
|
|
299
|
+
}),
|
|
300
|
+
rasterBasemap({
|
|
301
|
+
id: "esri-world-street-map",
|
|
302
|
+
name: "World Street Map",
|
|
303
|
+
provider: "esri",
|
|
304
|
+
category: "Street",
|
|
305
|
+
description: "ESRI street reference basemap.",
|
|
306
|
+
attribution: ESRI_ATTRIBUTION,
|
|
307
|
+
tiles: [
|
|
308
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
|
|
309
|
+
],
|
|
310
|
+
tags: ["esri", "street"]
|
|
311
|
+
}),
|
|
312
|
+
rasterBasemap({
|
|
313
|
+
id: "esri-world-gray-canvas",
|
|
314
|
+
name: "World Gray Canvas",
|
|
315
|
+
provider: "esri",
|
|
316
|
+
category: "Light",
|
|
317
|
+
description: "Light gray canvas basemap.",
|
|
318
|
+
attribution: ESRI_ATTRIBUTION,
|
|
319
|
+
tiles: [
|
|
320
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}"
|
|
321
|
+
],
|
|
322
|
+
tags: ["esri", "gray", "canvas"]
|
|
323
|
+
}),
|
|
324
|
+
rasterBasemap({
|
|
325
|
+
id: "esri-natgeo-world-map",
|
|
326
|
+
name: "NatGeo World Map",
|
|
327
|
+
provider: "esri",
|
|
328
|
+
category: "Street",
|
|
329
|
+
description: "National Geographic style world map.",
|
|
330
|
+
attribution: ESRI_ATTRIBUTION,
|
|
331
|
+
tiles: [
|
|
332
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}"
|
|
333
|
+
],
|
|
334
|
+
tags: ["esri", "natgeo"]
|
|
335
|
+
}),
|
|
336
|
+
rasterBasemap({
|
|
337
|
+
id: "esri-ocean-basemap",
|
|
338
|
+
name: "Ocean Basemap",
|
|
339
|
+
provider: "esri",
|
|
340
|
+
category: "Marine",
|
|
341
|
+
description: "Ocean reference basemap.",
|
|
342
|
+
attribution: ESRI_ATTRIBUTION,
|
|
343
|
+
tiles: [
|
|
344
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}"
|
|
345
|
+
],
|
|
346
|
+
tags: ["esri", "ocean", "marine"]
|
|
347
|
+
}),
|
|
348
|
+
rasterBasemap({
|
|
349
|
+
id: "esri-world-physical",
|
|
350
|
+
name: "World Physical",
|
|
351
|
+
provider: "esri",
|
|
352
|
+
category: "Terrain",
|
|
353
|
+
description: "Physical world map.",
|
|
354
|
+
attribution: ESRI_ATTRIBUTION,
|
|
355
|
+
tiles: [
|
|
356
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}"
|
|
357
|
+
],
|
|
358
|
+
tags: ["esri", "physical", "terrain"]
|
|
359
|
+
}),
|
|
360
|
+
rasterBasemap({
|
|
361
|
+
id: "esri-world-shaded-relief",
|
|
362
|
+
name: "World Shaded Relief",
|
|
363
|
+
provider: "esri",
|
|
364
|
+
category: "Terrain",
|
|
365
|
+
description: "Shaded relief world map.",
|
|
366
|
+
attribution: ESRI_ATTRIBUTION,
|
|
367
|
+
tiles: [
|
|
368
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}"
|
|
369
|
+
],
|
|
370
|
+
tags: ["esri", "relief", "terrain"]
|
|
371
|
+
}),
|
|
372
|
+
rasterBasemap({
|
|
373
|
+
id: "esri-world-terrain",
|
|
374
|
+
name: "World Terrain",
|
|
375
|
+
provider: "esri",
|
|
376
|
+
category: "Terrain",
|
|
377
|
+
description: "ESRI terrain base.",
|
|
378
|
+
attribution: ESRI_ATTRIBUTION,
|
|
379
|
+
tiles: [
|
|
380
|
+
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}"
|
|
381
|
+
],
|
|
382
|
+
tags: ["esri", "terrain"]
|
|
383
|
+
}),
|
|
384
|
+
rasterBasemap({
|
|
385
|
+
id: "nasa-gibs-blue-marble",
|
|
386
|
+
name: "Blue Marble",
|
|
387
|
+
provider: "nasa-gibs",
|
|
388
|
+
category: "Imagery",
|
|
389
|
+
description: "NASA Blue Marble Next Generation imagery.",
|
|
390
|
+
attribution: "Imagery provided by NASA Global Imagery Browse Services",
|
|
391
|
+
tiles: [
|
|
392
|
+
"https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/BlueMarble_NextGeneration/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpeg"
|
|
393
|
+
],
|
|
394
|
+
maxzoom: 8,
|
|
395
|
+
tags: ["nasa", "gibs", "blue marble"]
|
|
396
|
+
}),
|
|
397
|
+
rasterBasemap({
|
|
398
|
+
id: "nasa-gibs-aster-gdem-shaded-relief",
|
|
399
|
+
name: "ASTER GDEM Shaded Relief",
|
|
400
|
+
provider: "nasa-gibs",
|
|
401
|
+
category: "Terrain",
|
|
402
|
+
description: "NASA ASTER GDEM greyscale shaded relief.",
|
|
403
|
+
attribution: "Imagery provided by NASA Global Imagery Browse Services",
|
|
404
|
+
tiles: [
|
|
405
|
+
"https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/ASTER_GDEM_Greyscale_Shaded_Relief/default/GoogleMapsCompatible_Level12/{z}/{y}/{x}.jpg"
|
|
406
|
+
],
|
|
407
|
+
maxzoom: 12,
|
|
408
|
+
tags: ["nasa", "gibs", "relief", "terrain"]
|
|
409
|
+
}),
|
|
410
|
+
rasterBasemap({
|
|
411
|
+
id: "nasa-gibs-modis-terra-true-color",
|
|
412
|
+
name: "MODIS Terra True Color",
|
|
413
|
+
provider: "nasa-gibs",
|
|
414
|
+
category: "Imagery",
|
|
415
|
+
description: "NASA MODIS Terra corrected reflectance true color.",
|
|
416
|
+
attribution: "Imagery provided by NASA Global Imagery Browse Services",
|
|
417
|
+
tiles: [
|
|
418
|
+
"https://map1.vis.earthdata.nasa.gov/wmts-webmerc/MODIS_Terra_CorrectedReflectance_TrueColor/default//GoogleMapsCompatible_Level9/{z}/{y}/{x}.jpg"
|
|
419
|
+
],
|
|
420
|
+
maxzoom: 9,
|
|
421
|
+
tags: ["nasa", "gibs", "modis", "true color"]
|
|
422
|
+
}),
|
|
423
|
+
rasterBasemap({
|
|
424
|
+
id: "nasa-gibs-viirs-earth-at-night",
|
|
425
|
+
name: "VIIRS Earth At Night 2012",
|
|
426
|
+
provider: "nasa-gibs",
|
|
427
|
+
category: "Imagery",
|
|
428
|
+
description: "NASA VIIRS city lights imagery.",
|
|
429
|
+
attribution: "Imagery provided by NASA Global Imagery Browse Services",
|
|
430
|
+
tiles: [
|
|
431
|
+
"https://map1.vis.earthdata.nasa.gov/wmts-webmerc/VIIRS_CityLights_2012/default//GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg"
|
|
432
|
+
],
|
|
433
|
+
maxzoom: 8,
|
|
434
|
+
tags: ["nasa", "gibs", "night", "viirs"]
|
|
435
|
+
}),
|
|
436
|
+
rasterBasemap({
|
|
437
|
+
id: "openrailwaymap",
|
|
438
|
+
name: "OpenRailwayMap",
|
|
439
|
+
provider: "openrailwaymap",
|
|
440
|
+
category: "Transport",
|
|
441
|
+
description: "Railway infrastructure map.",
|
|
442
|
+
attribution: "Map data: © OpenStreetMap contributors | Map style: OpenRailwayMap",
|
|
443
|
+
tiles: ["https://a.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png"],
|
|
444
|
+
tags: ["rail", "transport", "osm"]
|
|
445
|
+
}),
|
|
446
|
+
rasterBasemap({
|
|
447
|
+
id: "opentopomap",
|
|
448
|
+
name: "OpenTopoMap",
|
|
449
|
+
provider: "opentopomap",
|
|
450
|
+
category: "Terrain",
|
|
451
|
+
description: "Topographic map with relief and contour styling.",
|
|
452
|
+
attribution: "Map data © OpenStreetMap contributors, SRTM | Map style © OpenTopoMap",
|
|
453
|
+
tiles: ["https://a.tile.opentopomap.org/{z}/{x}/{y}.png"],
|
|
454
|
+
maxzoom: 17,
|
|
455
|
+
tags: ["terrain", "topo", "relief"]
|
|
456
|
+
}),
|
|
457
|
+
rasterBasemap({
|
|
458
|
+
id: "swisstopo-national-map-color",
|
|
459
|
+
name: "Swiss National Map Color",
|
|
460
|
+
provider: "swisstopo",
|
|
461
|
+
category: "Regional",
|
|
462
|
+
description: "Swiss federal color national map.",
|
|
463
|
+
attribution: "© swisstopo",
|
|
464
|
+
tiles: [
|
|
465
|
+
"https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/{z}/{x}/{y}.jpeg"
|
|
466
|
+
],
|
|
467
|
+
maxzoom: 18,
|
|
468
|
+
tags: ["switzerland", "regional"]
|
|
469
|
+
}),
|
|
470
|
+
rasterBasemap({
|
|
471
|
+
id: "swisstopo-national-map-grey",
|
|
472
|
+
name: "Swiss National Map Grey",
|
|
473
|
+
provider: "swisstopo",
|
|
474
|
+
category: "Regional",
|
|
475
|
+
description: "Swiss federal grey national map.",
|
|
476
|
+
attribution: "© swisstopo",
|
|
477
|
+
tiles: [
|
|
478
|
+
"https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-grau/default/current/3857/{z}/{x}/{y}.jpeg"
|
|
479
|
+
],
|
|
480
|
+
maxzoom: 18,
|
|
481
|
+
tags: ["switzerland", "regional", "grey"]
|
|
482
|
+
}),
|
|
483
|
+
rasterBasemap({
|
|
484
|
+
id: "swisstopo-swissimage",
|
|
485
|
+
name: "SWISSIMAGE",
|
|
486
|
+
provider: "swisstopo",
|
|
487
|
+
category: "Imagery",
|
|
488
|
+
description: "Swiss federal aerial imagery.",
|
|
489
|
+
attribution: "© swisstopo",
|
|
490
|
+
tiles: [
|
|
491
|
+
"https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg"
|
|
492
|
+
],
|
|
493
|
+
maxzoom: 18,
|
|
494
|
+
tags: ["switzerland", "imagery"]
|
|
495
|
+
}),
|
|
496
|
+
rasterBasemap({
|
|
497
|
+
id: "topplusopen-color",
|
|
498
|
+
name: "TopPlusOpen Color",
|
|
499
|
+
provider: "topplusopen",
|
|
500
|
+
category: "Regional",
|
|
501
|
+
description: "German TopPlusOpen color basemap.",
|
|
502
|
+
attribution: "Map data: © dl-de/by-2-0",
|
|
503
|
+
tiles: [
|
|
504
|
+
"https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web/default/WEBMERCATOR/{z}/{y}/{x}.png"
|
|
505
|
+
],
|
|
506
|
+
maxzoom: 18,
|
|
507
|
+
tags: ["germany", "regional"]
|
|
508
|
+
}),
|
|
509
|
+
rasterBasemap({
|
|
510
|
+
id: "topplusopen-grey",
|
|
511
|
+
name: "TopPlusOpen Grey",
|
|
512
|
+
provider: "topplusopen",
|
|
513
|
+
category: "Regional",
|
|
514
|
+
description: "German TopPlusOpen grey basemap.",
|
|
515
|
+
attribution: "Map data: © dl-de/by-2-0",
|
|
516
|
+
tiles: [
|
|
517
|
+
"https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web_grau/default/WEBMERCATOR/{z}/{y}/{x}.png"
|
|
518
|
+
],
|
|
519
|
+
maxzoom: 18,
|
|
520
|
+
tags: ["germany", "regional", "grey"]
|
|
521
|
+
}),
|
|
522
|
+
rasterBasemap({
|
|
523
|
+
id: "usgs-us-imagery",
|
|
524
|
+
name: "USGS US Imagery",
|
|
525
|
+
provider: "usgs",
|
|
526
|
+
category: "Imagery",
|
|
527
|
+
description: "USGS imagery-only basemap.",
|
|
528
|
+
attribution: "Tiles courtesy of the U.S. Geological Survey",
|
|
529
|
+
tiles: [
|
|
530
|
+
"https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"
|
|
531
|
+
],
|
|
532
|
+
tags: ["usgs", "imagery", "united states"]
|
|
533
|
+
}),
|
|
534
|
+
rasterBasemap({
|
|
535
|
+
id: "usgs-us-imagery-topo",
|
|
536
|
+
name: "USGS US Imagery Topo",
|
|
537
|
+
provider: "usgs",
|
|
538
|
+
category: "Imagery",
|
|
539
|
+
description: "USGS imagery with topographic reference.",
|
|
540
|
+
attribution: "Tiles courtesy of the U.S. Geological Survey",
|
|
541
|
+
tiles: [
|
|
542
|
+
"https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}"
|
|
543
|
+
],
|
|
544
|
+
tags: ["usgs", "imagery", "topo", "united states"]
|
|
545
|
+
}),
|
|
546
|
+
rasterBasemap({
|
|
547
|
+
id: "usgs-us-topo",
|
|
548
|
+
name: "USGS US Topo",
|
|
549
|
+
provider: "usgs",
|
|
550
|
+
category: "Terrain",
|
|
551
|
+
description: "USGS topographic basemap.",
|
|
552
|
+
attribution: "Tiles courtesy of the U.S. Geological Survey",
|
|
553
|
+
tiles: [
|
|
554
|
+
"https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}"
|
|
555
|
+
],
|
|
556
|
+
tags: ["usgs", "topo", "united states"]
|
|
557
|
+
}),
|
|
558
|
+
rasterBasemap({
|
|
559
|
+
id: "waymarkedtrails-hiking",
|
|
560
|
+
name: "Waymarked Trails Hiking",
|
|
561
|
+
provider: "waymarkedtrails",
|
|
562
|
+
category: "Outdoor",
|
|
563
|
+
description: "Hiking routes from Waymarked Trails.",
|
|
564
|
+
attribution: "Map data: © OpenStreetMap contributors | Map style: Waymarked Trails",
|
|
565
|
+
tiles: ["https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png"],
|
|
566
|
+
tags: ["hiking", "outdoor", "trails"]
|
|
567
|
+
}),
|
|
568
|
+
rasterBasemap({
|
|
569
|
+
id: "waymarkedtrails-cycling",
|
|
570
|
+
name: "Waymarked Trails Cycling",
|
|
571
|
+
provider: "waymarkedtrails",
|
|
572
|
+
category: "Cycling",
|
|
573
|
+
description: "Cycling routes from Waymarked Trails.",
|
|
574
|
+
attribution: "Map data: © OpenStreetMap contributors | Map style: Waymarked Trails",
|
|
575
|
+
tiles: ["https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png"],
|
|
576
|
+
tags: ["cycling", "outdoor", "trails"]
|
|
577
|
+
}),
|
|
578
|
+
rasterBasemap({
|
|
579
|
+
id: "waymarkedtrails-mtb",
|
|
580
|
+
name: "Waymarked Trails MTB",
|
|
581
|
+
provider: "waymarkedtrails",
|
|
582
|
+
category: "Cycling",
|
|
583
|
+
description: "Mountain biking routes from Waymarked Trails.",
|
|
584
|
+
attribution: "Map data: © OpenStreetMap contributors | Map style: Waymarked Trails",
|
|
585
|
+
tiles: ["https://tile.waymarkedtrails.org/mtb/{z}/{x}/{y}.png"],
|
|
586
|
+
tags: ["mtb", "outdoor", "trails"]
|
|
587
|
+
}),
|
|
588
|
+
rasterBasemap({
|
|
589
|
+
id: "waymarkedtrails-slopes",
|
|
590
|
+
name: "Waymarked Trails Slopes",
|
|
591
|
+
provider: "waymarkedtrails",
|
|
592
|
+
category: "Outdoor",
|
|
593
|
+
description: "Slope routes from Waymarked Trails.",
|
|
594
|
+
attribution: "Map data: © OpenStreetMap contributors | Map style: Waymarked Trails",
|
|
595
|
+
tiles: ["https://tile.waymarkedtrails.org/slopes/{z}/{x}/{y}.png"],
|
|
596
|
+
tags: ["slopes", "outdoor", "trails"]
|
|
597
|
+
}),
|
|
598
|
+
rasterBasemap({
|
|
599
|
+
id: "nlmaps-standaard",
|
|
600
|
+
name: "nlmaps Standaard",
|
|
601
|
+
provider: "nlmaps",
|
|
602
|
+
category: "Regional",
|
|
603
|
+
description: "Netherlands standard background map.",
|
|
604
|
+
attribution: "Kaartgegevens © Kadaster",
|
|
605
|
+
tiles: [
|
|
606
|
+
"https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/standaard/EPSG:3857/{z}/{x}/{y}.png"
|
|
607
|
+
],
|
|
608
|
+
tags: ["netherlands", "regional"]
|
|
609
|
+
}),
|
|
610
|
+
rasterBasemap({
|
|
611
|
+
id: "nlmaps-grijs",
|
|
612
|
+
name: "nlmaps Grijs",
|
|
613
|
+
provider: "nlmaps",
|
|
614
|
+
category: "Regional",
|
|
615
|
+
description: "Netherlands grey background map.",
|
|
616
|
+
attribution: "Kaartgegevens © Kadaster",
|
|
617
|
+
tiles: [
|
|
618
|
+
"https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/grijs/EPSG:3857/{z}/{x}/{y}.png"
|
|
619
|
+
],
|
|
620
|
+
tags: ["netherlands", "regional", "grey"]
|
|
621
|
+
}),
|
|
622
|
+
rasterBasemap({
|
|
623
|
+
id: "nlmaps-pastel",
|
|
624
|
+
name: "nlmaps Pastel",
|
|
625
|
+
provider: "nlmaps",
|
|
626
|
+
category: "Regional",
|
|
627
|
+
description: "Netherlands pastel background map.",
|
|
628
|
+
attribution: "Kaartgegevens © Kadaster",
|
|
629
|
+
tiles: [
|
|
630
|
+
"https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/pastel/EPSG:3857/{z}/{x}/{y}.png"
|
|
631
|
+
],
|
|
632
|
+
tags: ["netherlands", "regional", "pastel"]
|
|
633
|
+
}),
|
|
634
|
+
rasterBasemap({
|
|
635
|
+
id: "nlmaps-water",
|
|
636
|
+
name: "nlmaps Water",
|
|
637
|
+
provider: "nlmaps",
|
|
638
|
+
category: "Regional",
|
|
639
|
+
description: "Netherlands water-focused background map.",
|
|
640
|
+
attribution: "Kaartgegevens © Kadaster",
|
|
641
|
+
tiles: [
|
|
642
|
+
"https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/water/EPSG:3857/{z}/{x}/{y}.png"
|
|
643
|
+
],
|
|
644
|
+
tags: ["netherlands", "regional", "water"]
|
|
645
|
+
}),
|
|
646
|
+
rasterBasemap({
|
|
647
|
+
id: "nlmaps-luchtfoto",
|
|
648
|
+
name: "nlmaps Luchtfoto",
|
|
649
|
+
provider: "nlmaps",
|
|
650
|
+
category: "Imagery",
|
|
651
|
+
description: "Netherlands aerial photography.",
|
|
652
|
+
attribution: "Kaartgegevens © Kadaster",
|
|
653
|
+
tiles: [
|
|
654
|
+
"https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0/Actueel_ortho25/EPSG:3857/{z}/{x}/{y}.jpeg"
|
|
655
|
+
],
|
|
656
|
+
tags: ["netherlands", "imagery", "aerial"]
|
|
657
|
+
}),
|
|
658
|
+
{
|
|
659
|
+
id: "openfreemap-positron",
|
|
660
|
+
name: "OpenFreeMap Positron",
|
|
661
|
+
provider: "openfreemap",
|
|
662
|
+
type: "style",
|
|
663
|
+
category: "Light",
|
|
664
|
+
description: "Light, minimal OpenFreeMap vector style for data overlays.",
|
|
665
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
666
|
+
source: {
|
|
667
|
+
type: "style",
|
|
668
|
+
url: "https://tiles.openfreemap.org/styles/positron"
|
|
669
|
+
},
|
|
670
|
+
tags: ["openfreemap", "vector", "style", "positron", "light"]
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
id: "openfreemap-bright",
|
|
674
|
+
name: "OpenFreeMap Bright",
|
|
675
|
+
provider: "openfreemap",
|
|
676
|
+
type: "style",
|
|
677
|
+
category: "Street",
|
|
678
|
+
description: "Colorful OpenFreeMap vector street style.",
|
|
679
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
680
|
+
source: {
|
|
681
|
+
type: "style",
|
|
682
|
+
url: "https://tiles.openfreemap.org/styles/bright"
|
|
683
|
+
},
|
|
684
|
+
tags: ["openfreemap", "vector", "style", "bright", "street"]
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
id: "openfreemap-liberty",
|
|
688
|
+
name: "OpenFreeMap Liberty",
|
|
689
|
+
provider: "openfreemap",
|
|
690
|
+
type: "style",
|
|
691
|
+
category: "Vector",
|
|
692
|
+
description: "Open vector style loaded as a full MapLibre style.",
|
|
693
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
694
|
+
source: {
|
|
695
|
+
type: "style",
|
|
696
|
+
url: "https://tiles.openfreemap.org/styles/liberty"
|
|
697
|
+
},
|
|
698
|
+
tags: ["openfreemap", "vector", "style"]
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
id: "openfreemap-dark",
|
|
702
|
+
name: "OpenFreeMap Dark",
|
|
703
|
+
provider: "openfreemap",
|
|
704
|
+
type: "style",
|
|
705
|
+
category: "Dark",
|
|
706
|
+
description: "Dark OpenFreeMap vector style.",
|
|
707
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
708
|
+
source: {
|
|
709
|
+
type: "style",
|
|
710
|
+
url: "https://tiles.openfreemap.org/styles/dark"
|
|
711
|
+
},
|
|
712
|
+
tags: ["openfreemap", "vector", "style", "dark"]
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
id: "openfreemap-fiord",
|
|
716
|
+
name: "OpenFreeMap Fiord",
|
|
717
|
+
provider: "openfreemap",
|
|
718
|
+
type: "style",
|
|
719
|
+
category: "Dark",
|
|
720
|
+
description: "Blue-toned dark OpenFreeMap vector style.",
|
|
721
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
722
|
+
source: {
|
|
723
|
+
type: "style",
|
|
724
|
+
url: "https://tiles.openfreemap.org/styles/fiord"
|
|
725
|
+
},
|
|
726
|
+
tags: ["openfreemap", "vector", "style", "fiord", "dark"]
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
id: "openfreemap-3d",
|
|
730
|
+
name: "OpenFreeMap 3D",
|
|
731
|
+
provider: "openfreemap",
|
|
732
|
+
type: "style",
|
|
733
|
+
category: "3D",
|
|
734
|
+
description: "OpenFreeMap Liberty style with a pitched 3D camera view.",
|
|
735
|
+
attribution: OPENFREEMAP_ATTRIBUTION,
|
|
736
|
+
source: {
|
|
737
|
+
type: "style",
|
|
738
|
+
url: "https://tiles.openfreemap.org/styles/liberty"
|
|
739
|
+
},
|
|
740
|
+
view: {
|
|
741
|
+
center: [-0.114, 51.506],
|
|
742
|
+
zoom: 14.2,
|
|
743
|
+
bearing: 55.2,
|
|
744
|
+
pitch: 60
|
|
745
|
+
},
|
|
746
|
+
tags: ["openfreemap", "vector", "style", "3d", "liberty"]
|
|
747
|
+
}
|
|
748
|
+
];
|
|
749
|
+
function combineProviders(defaults, custom = []) {
|
|
750
|
+
const byId = /* @__PURE__ */ new Map();
|
|
751
|
+
defaults.forEach((provider) => byId.set(provider.id, provider));
|
|
752
|
+
custom.forEach((provider) => byId.set(provider.id, provider));
|
|
753
|
+
return [...byId.values()];
|
|
754
|
+
}
|
|
755
|
+
function resolveBasemapProviders(basemaps, customProviders = [], includeDefaultProviders = true) {
|
|
756
|
+
const byId = /* @__PURE__ */ new Map();
|
|
757
|
+
if (includeDefaultProviders) {
|
|
758
|
+
DEFAULT_BASEMAP_PROVIDERS.forEach((provider) => byId.set(provider.id, provider));
|
|
759
|
+
}
|
|
760
|
+
customProviders.forEach((provider) => byId.set(provider.id, provider));
|
|
761
|
+
basemaps.forEach((basemap) => {
|
|
762
|
+
if (basemap.provider && !byId.has(basemap.provider)) {
|
|
763
|
+
byId.set(basemap.provider, { id: basemap.provider, name: basemap.provider });
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
return [...byId.values()];
|
|
767
|
+
}
|
|
768
|
+
function createBasemapCatalog(customBasemaps = [], includeDefaultBasemaps = true) {
|
|
769
|
+
const basemaps = includeDefaultBasemaps ? [...DEFAULT_BASEMAPS, ...customBasemaps] : [...customBasemaps];
|
|
770
|
+
const byId = /* @__PURE__ */ new Map();
|
|
771
|
+
basemaps.forEach((basemap) => byId.set(basemap.id, basemap));
|
|
772
|
+
return [...byId.values()];
|
|
773
|
+
}
|
|
774
|
+
function filterBasemaps(basemaps, filter) {
|
|
775
|
+
var _a;
|
|
776
|
+
const query = ((_a = filter.query) == null ? void 0 : _a.trim().toLowerCase()) ?? "";
|
|
777
|
+
return basemaps.filter((basemap) => {
|
|
778
|
+
if (filter.provider && basemap.provider !== filter.provider) return false;
|
|
779
|
+
if (filter.category && basemap.category !== filter.category) return false;
|
|
780
|
+
if (!query) return true;
|
|
781
|
+
const haystack = [
|
|
782
|
+
basemap.name,
|
|
783
|
+
basemap.provider,
|
|
784
|
+
basemap.category,
|
|
785
|
+
basemap.description,
|
|
786
|
+
...basemap.tags ?? []
|
|
787
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
788
|
+
return haystack.includes(query);
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
function getBasemapCategories(basemaps) {
|
|
792
|
+
return [...new Set(basemaps.map((basemap) => basemap.category).filter(Boolean))].sort();
|
|
793
|
+
}
|
|
794
|
+
const DEFAULT_OPTIONS = {
|
|
795
|
+
collapsed: true,
|
|
796
|
+
position: "top-right",
|
|
797
|
+
title: "Basemaps",
|
|
798
|
+
panelWidth: 340,
|
|
799
|
+
className: "",
|
|
800
|
+
includeDefaultBasemaps: true
|
|
801
|
+
};
|
|
802
|
+
const CONTROL_SOURCE_PREFIX = "maplibre-basemap-control-source";
|
|
803
|
+
const CONTROL_LAYER_PREFIX = "maplibre-basemap-control-layer";
|
|
804
|
+
class BasemapControl {
|
|
805
|
+
constructor(options) {
|
|
806
|
+
__publicField(this, "_map");
|
|
807
|
+
__publicField(this, "_mapContainer");
|
|
808
|
+
__publicField(this, "_container");
|
|
809
|
+
__publicField(this, "_panel");
|
|
810
|
+
__publicField(this, "_content");
|
|
811
|
+
__publicField(this, "_options");
|
|
812
|
+
__publicField(this, "_state");
|
|
813
|
+
__publicField(this, "_basemaps");
|
|
814
|
+
__publicField(this, "_providers");
|
|
815
|
+
__publicField(this, "_eventHandlers", new globalThis.Map());
|
|
816
|
+
__publicField(this, "_managedSourceIds", []);
|
|
817
|
+
__publicField(this, "_managedLayerIds", []);
|
|
818
|
+
__publicField(this, "_resizeHandler", null);
|
|
819
|
+
__publicField(this, "_mapResizeHandler", null);
|
|
820
|
+
__publicField(this, "_clickOutsideHandler", null);
|
|
821
|
+
this._options = { ...DEFAULT_OPTIONS, ...options };
|
|
822
|
+
this._basemaps = createBasemapCatalog(
|
|
823
|
+
options == null ? void 0 : options.basemaps,
|
|
824
|
+
this._options.includeDefaultBasemaps
|
|
825
|
+
);
|
|
826
|
+
this._providers = resolveBasemapProviders(
|
|
827
|
+
this._basemaps,
|
|
828
|
+
options == null ? void 0 : options.providers,
|
|
829
|
+
this._options.includeDefaultBasemaps
|
|
830
|
+
);
|
|
831
|
+
this._state = {
|
|
832
|
+
collapsed: this._options.collapsed,
|
|
833
|
+
panelWidth: this._options.panelWidth,
|
|
834
|
+
activeBasemapId: this._options.defaultBasemapId,
|
|
835
|
+
query: "",
|
|
836
|
+
providerFilter: "",
|
|
837
|
+
categoryFilter: "",
|
|
838
|
+
loading: false
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
onAdd(map) {
|
|
842
|
+
this._map = map;
|
|
843
|
+
this._mapContainer = map.getContainer();
|
|
844
|
+
this._container = this._createContainer();
|
|
845
|
+
this._panel = this._createPanel();
|
|
846
|
+
this._mapContainer.appendChild(this._panel);
|
|
847
|
+
this._setupEventListeners();
|
|
848
|
+
if (!this._state.collapsed) {
|
|
849
|
+
this._panel.classList.add("expanded");
|
|
850
|
+
requestAnimationFrame(() => this._updatePanelPosition());
|
|
851
|
+
}
|
|
852
|
+
this._renderContent();
|
|
853
|
+
if (this._state.activeBasemapId) {
|
|
854
|
+
this._selectBasemap(this._state.activeBasemapId);
|
|
855
|
+
}
|
|
856
|
+
return this._container;
|
|
857
|
+
}
|
|
858
|
+
onRemove() {
|
|
859
|
+
var _a, _b, _c, _d;
|
|
860
|
+
if (this._resizeHandler) {
|
|
861
|
+
window.removeEventListener("resize", this._resizeHandler);
|
|
862
|
+
this._resizeHandler = null;
|
|
863
|
+
}
|
|
864
|
+
if (this._mapResizeHandler && this._map) {
|
|
865
|
+
this._map.off("resize", this._mapResizeHandler);
|
|
866
|
+
this._mapResizeHandler = null;
|
|
867
|
+
}
|
|
868
|
+
if (this._clickOutsideHandler) {
|
|
869
|
+
document.removeEventListener("click", this._clickOutsideHandler);
|
|
870
|
+
this._clickOutsideHandler = null;
|
|
871
|
+
}
|
|
872
|
+
this._removeManagedBasemap();
|
|
873
|
+
(_b = (_a = this._panel) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._panel);
|
|
874
|
+
(_d = (_c = this._container) == null ? void 0 : _c.parentNode) == null ? void 0 : _d.removeChild(this._container);
|
|
875
|
+
this._map = void 0;
|
|
876
|
+
this._mapContainer = void 0;
|
|
877
|
+
this._container = void 0;
|
|
878
|
+
this._panel = void 0;
|
|
879
|
+
this._content = void 0;
|
|
880
|
+
this._eventHandlers.clear();
|
|
881
|
+
}
|
|
882
|
+
getState() {
|
|
883
|
+
return { ...this._state };
|
|
884
|
+
}
|
|
885
|
+
setState(newState) {
|
|
886
|
+
this._state = { ...this._state, ...newState };
|
|
887
|
+
this._renderContent();
|
|
888
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
889
|
+
}
|
|
890
|
+
getBasemaps() {
|
|
891
|
+
return [...this._basemaps];
|
|
892
|
+
}
|
|
893
|
+
setBasemaps(basemaps) {
|
|
894
|
+
this._basemaps = [...basemaps];
|
|
895
|
+
this._providers = resolveBasemapProviders(
|
|
896
|
+
this._basemaps,
|
|
897
|
+
this._options.providers,
|
|
898
|
+
this._options.includeDefaultBasemaps
|
|
899
|
+
);
|
|
900
|
+
if (this._state.activeBasemapId && !this._basemaps.some((basemap) => basemap.id === this._state.activeBasemapId)) {
|
|
901
|
+
this._state = { ...this._state, activeBasemapId: void 0 };
|
|
902
|
+
}
|
|
903
|
+
this._renderContent();
|
|
904
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
905
|
+
}
|
|
906
|
+
getActiveBasemap() {
|
|
907
|
+
return this._basemaps.find((basemap) => basemap.id === this._state.activeBasemapId);
|
|
908
|
+
}
|
|
909
|
+
async setBasemap(id) {
|
|
910
|
+
const basemap = this._basemaps.find((candidate) => candidate.id === id);
|
|
911
|
+
if (!basemap) {
|
|
912
|
+
const error = new Error(`Basemap "${id}" was not found.`);
|
|
913
|
+
this._handleError(error);
|
|
914
|
+
throw error;
|
|
915
|
+
}
|
|
916
|
+
if (!this._map) {
|
|
917
|
+
const error = new Error("BasemapControl must be added to a map before setting a basemap.");
|
|
918
|
+
this._handleError(error, basemap);
|
|
919
|
+
throw error;
|
|
920
|
+
}
|
|
921
|
+
this._state = { ...this._state, loading: true, error: void 0 };
|
|
922
|
+
this._renderContent();
|
|
923
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
924
|
+
try {
|
|
925
|
+
if (basemap.source.type === "raster") {
|
|
926
|
+
await this._waitForStyleReady();
|
|
927
|
+
this._removeManagedBasemap();
|
|
928
|
+
this._addRasterBasemap(basemap);
|
|
929
|
+
} else {
|
|
930
|
+
this._removeManagedBasemap();
|
|
931
|
+
this._map.setStyle(basemap.source.url);
|
|
932
|
+
}
|
|
933
|
+
this._applyBasemapView(basemap);
|
|
934
|
+
this._state = {
|
|
935
|
+
...this._state,
|
|
936
|
+
activeBasemapId: basemap.id,
|
|
937
|
+
loading: false,
|
|
938
|
+
error: void 0
|
|
939
|
+
};
|
|
940
|
+
this._renderContent();
|
|
941
|
+
this._emit({ type: "basemapchange", state: this.getState(), basemap });
|
|
942
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
943
|
+
} catch (cause) {
|
|
944
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
945
|
+
this._state = { ...this._state, loading: false, error: error.message };
|
|
946
|
+
this._renderContent();
|
|
947
|
+
this._handleError(error, basemap);
|
|
948
|
+
throw error;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
// setBasemap rethrows after emitting the error event so callers that await
|
|
952
|
+
// it can react. Internal fire-and-forget callers use this instead to avoid
|
|
953
|
+
// unhandled promise rejections; the failure is still reported via `error`.
|
|
954
|
+
_selectBasemap(id) {
|
|
955
|
+
this.setBasemap(id).catch(() => {
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
toggle() {
|
|
959
|
+
this._state = { ...this._state, collapsed: !this._state.collapsed };
|
|
960
|
+
if (this._panel) {
|
|
961
|
+
if (this._state.collapsed) {
|
|
962
|
+
this._panel.classList.remove("expanded");
|
|
963
|
+
this._emit({ type: "collapse", state: this.getState() });
|
|
964
|
+
} else {
|
|
965
|
+
this._panel.classList.add("expanded");
|
|
966
|
+
this._updatePanelPosition();
|
|
967
|
+
this._emit({ type: "expand", state: this.getState() });
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
971
|
+
}
|
|
972
|
+
expand() {
|
|
973
|
+
if (this._state.collapsed) this.toggle();
|
|
974
|
+
}
|
|
975
|
+
collapse() {
|
|
976
|
+
if (!this._state.collapsed) this.toggle();
|
|
977
|
+
}
|
|
978
|
+
on(event, handler) {
|
|
979
|
+
if (!this._eventHandlers.has(event)) {
|
|
980
|
+
this._eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
981
|
+
}
|
|
982
|
+
this._eventHandlers.get(event).add(handler);
|
|
983
|
+
}
|
|
984
|
+
off(event, handler) {
|
|
985
|
+
var _a;
|
|
986
|
+
(_a = this._eventHandlers.get(event)) == null ? void 0 : _a.delete(handler);
|
|
987
|
+
}
|
|
988
|
+
getMap() {
|
|
989
|
+
return this._map;
|
|
990
|
+
}
|
|
991
|
+
getContainer() {
|
|
992
|
+
return this._container;
|
|
993
|
+
}
|
|
994
|
+
_emit(event) {
|
|
995
|
+
var _a;
|
|
996
|
+
(_a = this._eventHandlers.get(event.type)) == null ? void 0 : _a.forEach((handler) => handler(event));
|
|
997
|
+
}
|
|
998
|
+
_handleError(error, basemap) {
|
|
999
|
+
this._emit({ type: "error", state: this.getState(), error, basemap });
|
|
1000
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
1001
|
+
}
|
|
1002
|
+
_createContainer() {
|
|
1003
|
+
const container = document.createElement("div");
|
|
1004
|
+
container.className = `maplibregl-ctrl maplibregl-ctrl-group basemap-control${this._options.className ? ` ${this._options.className}` : ""}`;
|
|
1005
|
+
const toggleBtn = document.createElement("button");
|
|
1006
|
+
toggleBtn.className = "basemap-control-toggle";
|
|
1007
|
+
toggleBtn.type = "button";
|
|
1008
|
+
toggleBtn.title = this._options.title;
|
|
1009
|
+
toggleBtn.setAttribute("aria-label", this._options.title);
|
|
1010
|
+
toggleBtn.innerHTML = `
|
|
1011
|
+
<span class="basemap-control-icon" aria-hidden="true">
|
|
1012
|
+
<svg viewBox="0 0 24 24" width="22" height="22" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1013
|
+
<path d="m3 6 6-3 6 3 6-3v15l-6 3-6-3-6 3V6Z"/>
|
|
1014
|
+
<path d="M9 3v15"/>
|
|
1015
|
+
<path d="M15 6v15"/>
|
|
1016
|
+
</svg>
|
|
1017
|
+
</span>
|
|
1018
|
+
`;
|
|
1019
|
+
toggleBtn.addEventListener("click", () => this.toggle());
|
|
1020
|
+
container.appendChild(toggleBtn);
|
|
1021
|
+
return container;
|
|
1022
|
+
}
|
|
1023
|
+
_createPanel() {
|
|
1024
|
+
const panel = document.createElement("div");
|
|
1025
|
+
panel.className = "basemap-control-panel";
|
|
1026
|
+
panel.style.width = `${this._options.panelWidth}px`;
|
|
1027
|
+
const header = document.createElement("div");
|
|
1028
|
+
header.className = "basemap-control-header";
|
|
1029
|
+
const title = document.createElement("span");
|
|
1030
|
+
title.className = "basemap-control-title";
|
|
1031
|
+
title.textContent = this._options.title;
|
|
1032
|
+
const closeBtn = document.createElement("button");
|
|
1033
|
+
closeBtn.className = "basemap-control-close";
|
|
1034
|
+
closeBtn.type = "button";
|
|
1035
|
+
closeBtn.setAttribute("aria-label", "Close basemap panel");
|
|
1036
|
+
closeBtn.innerHTML = "×";
|
|
1037
|
+
closeBtn.addEventListener("click", () => this.collapse());
|
|
1038
|
+
header.appendChild(title);
|
|
1039
|
+
header.appendChild(closeBtn);
|
|
1040
|
+
this._content = document.createElement("div");
|
|
1041
|
+
this._content.className = "basemap-control-content";
|
|
1042
|
+
panel.appendChild(header);
|
|
1043
|
+
panel.appendChild(this._content);
|
|
1044
|
+
return panel;
|
|
1045
|
+
}
|
|
1046
|
+
_renderContent() {
|
|
1047
|
+
if (!this._content) return;
|
|
1048
|
+
const categories = getBasemapCategories(this._basemaps);
|
|
1049
|
+
const results = filterBasemaps(this._basemaps, {
|
|
1050
|
+
query: this._state.query,
|
|
1051
|
+
provider: this._state.providerFilter,
|
|
1052
|
+
category: this._state.categoryFilter
|
|
1053
|
+
});
|
|
1054
|
+
this._content.replaceChildren(
|
|
1055
|
+
this._createSearchInput(),
|
|
1056
|
+
this._createFilterRow(this._providers, categories),
|
|
1057
|
+
this._createStatus(results.length),
|
|
1058
|
+
this._createResults(results)
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
_createSearchInput() {
|
|
1062
|
+
const wrapper = document.createElement("div");
|
|
1063
|
+
wrapper.className = "basemap-control-search";
|
|
1064
|
+
const input = document.createElement("input");
|
|
1065
|
+
input.className = "basemap-control-input";
|
|
1066
|
+
input.type = "search";
|
|
1067
|
+
input.placeholder = "Search basemaps";
|
|
1068
|
+
input.value = this._state.query;
|
|
1069
|
+
input.setAttribute("aria-label", "Search basemaps");
|
|
1070
|
+
input.addEventListener("input", () => {
|
|
1071
|
+
this._state = { ...this._state, query: input.value };
|
|
1072
|
+
this._renderContent();
|
|
1073
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
1074
|
+
});
|
|
1075
|
+
wrapper.appendChild(input);
|
|
1076
|
+
return wrapper;
|
|
1077
|
+
}
|
|
1078
|
+
_createFilterRow(providers, categories) {
|
|
1079
|
+
const row = document.createElement("div");
|
|
1080
|
+
row.className = "basemap-control-filters";
|
|
1081
|
+
row.appendChild(
|
|
1082
|
+
this._createSelect(
|
|
1083
|
+
"Provider",
|
|
1084
|
+
this._state.providerFilter,
|
|
1085
|
+
providers.map((provider) => ({ value: provider.id, label: provider.name })),
|
|
1086
|
+
(value) => {
|
|
1087
|
+
this._state = { ...this._state, providerFilter: value };
|
|
1088
|
+
this._renderContent();
|
|
1089
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1092
|
+
);
|
|
1093
|
+
row.appendChild(
|
|
1094
|
+
this._createSelect(
|
|
1095
|
+
"Category",
|
|
1096
|
+
this._state.categoryFilter,
|
|
1097
|
+
categories.map((category) => ({ value: category, label: category })),
|
|
1098
|
+
(value) => {
|
|
1099
|
+
this._state = { ...this._state, categoryFilter: value };
|
|
1100
|
+
this._renderContent();
|
|
1101
|
+
this._emit({ type: "statechange", state: this.getState() });
|
|
1102
|
+
}
|
|
1103
|
+
)
|
|
1104
|
+
);
|
|
1105
|
+
return row;
|
|
1106
|
+
}
|
|
1107
|
+
_createSelect(label, value, options, onChange) {
|
|
1108
|
+
const select = document.createElement("select");
|
|
1109
|
+
select.className = "basemap-control-select";
|
|
1110
|
+
select.setAttribute("aria-label", label);
|
|
1111
|
+
const all = document.createElement("option");
|
|
1112
|
+
all.value = "";
|
|
1113
|
+
all.textContent = `All ${label.toLowerCase()}s`;
|
|
1114
|
+
select.appendChild(all);
|
|
1115
|
+
options.forEach((option) => {
|
|
1116
|
+
const element = document.createElement("option");
|
|
1117
|
+
element.value = option.value;
|
|
1118
|
+
element.textContent = option.label;
|
|
1119
|
+
select.appendChild(element);
|
|
1120
|
+
});
|
|
1121
|
+
select.value = value;
|
|
1122
|
+
select.addEventListener("change", () => onChange(select.value));
|
|
1123
|
+
return select;
|
|
1124
|
+
}
|
|
1125
|
+
_createStatus(resultCount) {
|
|
1126
|
+
const status = document.createElement("div");
|
|
1127
|
+
status.className = "basemap-control-status";
|
|
1128
|
+
if (this._state.loading) {
|
|
1129
|
+
status.textContent = "Applying basemap...";
|
|
1130
|
+
} else if (this._state.error) {
|
|
1131
|
+
status.textContent = this._state.error;
|
|
1132
|
+
status.classList.add("is-error");
|
|
1133
|
+
} else {
|
|
1134
|
+
status.textContent = `${resultCount} basemap${resultCount === 1 ? "" : "s"}`;
|
|
1135
|
+
}
|
|
1136
|
+
return status;
|
|
1137
|
+
}
|
|
1138
|
+
_createResults(results) {
|
|
1139
|
+
const list = document.createElement("div");
|
|
1140
|
+
list.className = "basemap-control-results";
|
|
1141
|
+
if (results.length === 0) {
|
|
1142
|
+
const empty = document.createElement("div");
|
|
1143
|
+
empty.className = "basemap-control-empty";
|
|
1144
|
+
empty.textContent = "No basemaps match your search.";
|
|
1145
|
+
list.appendChild(empty);
|
|
1146
|
+
return list;
|
|
1147
|
+
}
|
|
1148
|
+
results.forEach((basemap) => {
|
|
1149
|
+
const row = document.createElement("button");
|
|
1150
|
+
row.type = "button";
|
|
1151
|
+
row.className = "basemap-control-result";
|
|
1152
|
+
row.dataset.basemapId = basemap.id;
|
|
1153
|
+
if (basemap.id === this._state.activeBasemapId) {
|
|
1154
|
+
row.classList.add("is-active");
|
|
1155
|
+
row.setAttribute("aria-current", "true");
|
|
1156
|
+
}
|
|
1157
|
+
row.disabled = this._state.loading;
|
|
1158
|
+
row.addEventListener("click", () => {
|
|
1159
|
+
this._selectBasemap(basemap.id);
|
|
1160
|
+
});
|
|
1161
|
+
const main = document.createElement("span");
|
|
1162
|
+
main.className = "basemap-control-result-main";
|
|
1163
|
+
const name = document.createElement("span");
|
|
1164
|
+
name.className = "basemap-control-result-name";
|
|
1165
|
+
name.textContent = basemap.name;
|
|
1166
|
+
const meta = document.createElement("span");
|
|
1167
|
+
meta.className = "basemap-control-result-meta";
|
|
1168
|
+
meta.textContent = this._formatBasemapMeta(basemap);
|
|
1169
|
+
main.appendChild(name);
|
|
1170
|
+
main.appendChild(meta);
|
|
1171
|
+
const type = document.createElement("span");
|
|
1172
|
+
type.className = "basemap-control-result-type";
|
|
1173
|
+
type.textContent = basemap.type === "raster" ? "Raster" : "Style";
|
|
1174
|
+
row.appendChild(main);
|
|
1175
|
+
row.appendChild(type);
|
|
1176
|
+
if (basemap.attribution) {
|
|
1177
|
+
const attribution = document.createElement("span");
|
|
1178
|
+
attribution.className = "basemap-control-result-attribution";
|
|
1179
|
+
attribution.textContent = this._stripHtml(basemap.attribution);
|
|
1180
|
+
row.appendChild(attribution);
|
|
1181
|
+
}
|
|
1182
|
+
list.appendChild(row);
|
|
1183
|
+
});
|
|
1184
|
+
return list;
|
|
1185
|
+
}
|
|
1186
|
+
_formatBasemapMeta(basemap) {
|
|
1187
|
+
const provider = this._providers.find((candidate) => candidate.id === basemap.provider);
|
|
1188
|
+
return [(provider == null ? void 0 : provider.name) ?? basemap.provider, basemap.category].filter(Boolean).join(" / ");
|
|
1189
|
+
}
|
|
1190
|
+
_stripHtml(value) {
|
|
1191
|
+
const template = document.createElement("template");
|
|
1192
|
+
template.innerHTML = value;
|
|
1193
|
+
return template.content.textContent ?? value;
|
|
1194
|
+
}
|
|
1195
|
+
_addRasterBasemap(basemap) {
|
|
1196
|
+
if (!this._map || basemap.source.type !== "raster") return;
|
|
1197
|
+
const sourceId = `${CONTROL_SOURCE_PREFIX}-${basemap.id}`;
|
|
1198
|
+
const layerId = `${CONTROL_LAYER_PREFIX}-${basemap.id}`;
|
|
1199
|
+
const source = {
|
|
1200
|
+
type: "raster",
|
|
1201
|
+
tiles: basemap.source.tiles,
|
|
1202
|
+
tileSize: basemap.source.tileSize ?? 256,
|
|
1203
|
+
minzoom: basemap.source.minzoom,
|
|
1204
|
+
maxzoom: basemap.source.maxzoom,
|
|
1205
|
+
scheme: basemap.source.scheme,
|
|
1206
|
+
attribution: basemap.attribution
|
|
1207
|
+
};
|
|
1208
|
+
const layer = {
|
|
1209
|
+
id: layerId,
|
|
1210
|
+
type: "raster",
|
|
1211
|
+
source: sourceId
|
|
1212
|
+
};
|
|
1213
|
+
this._map.addSource(sourceId, source);
|
|
1214
|
+
this._map.addLayer(layer, this._findBasemapInsertBeforeId());
|
|
1215
|
+
this._managedSourceIds = [sourceId];
|
|
1216
|
+
this._managedLayerIds = [layerId];
|
|
1217
|
+
}
|
|
1218
|
+
_waitForStyleReady() {
|
|
1219
|
+
if (!this._map) return Promise.resolve();
|
|
1220
|
+
if (typeof this._map.isStyleLoaded !== "function" || this._map.isStyleLoaded()) {
|
|
1221
|
+
return Promise.resolve();
|
|
1222
|
+
}
|
|
1223
|
+
return new Promise((resolve) => {
|
|
1224
|
+
var _a, _b;
|
|
1225
|
+
const done = () => {
|
|
1226
|
+
var _a2, _b2;
|
|
1227
|
+
(_a2 = this._map) == null ? void 0 : _a2.off("load", done);
|
|
1228
|
+
(_b2 = this._map) == null ? void 0 : _b2.off("style.load", done);
|
|
1229
|
+
resolve();
|
|
1230
|
+
};
|
|
1231
|
+
(_a = this._map) == null ? void 0 : _a.once("load", done);
|
|
1232
|
+
(_b = this._map) == null ? void 0 : _b.once("style.load", done);
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
_removeManagedBasemap() {
|
|
1236
|
+
if (!this._map) return;
|
|
1237
|
+
[...this._managedLayerIds].reverse().forEach((layerId) => {
|
|
1238
|
+
var _a;
|
|
1239
|
+
if ((_a = this._map) == null ? void 0 : _a.getLayer(layerId)) {
|
|
1240
|
+
this._map.removeLayer(layerId);
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
[...this._managedSourceIds].reverse().forEach((sourceId) => {
|
|
1244
|
+
var _a;
|
|
1245
|
+
if ((_a = this._map) == null ? void 0 : _a.getSource(sourceId)) {
|
|
1246
|
+
this._map.removeSource(sourceId);
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
this._managedLayerIds = [];
|
|
1250
|
+
this._managedSourceIds = [];
|
|
1251
|
+
}
|
|
1252
|
+
_applyBasemapView(basemap) {
|
|
1253
|
+
if (!this._map || !basemap.view) return;
|
|
1254
|
+
this._map.jumpTo({
|
|
1255
|
+
center: basemap.view.center,
|
|
1256
|
+
zoom: basemap.view.zoom,
|
|
1257
|
+
bearing: basemap.view.bearing,
|
|
1258
|
+
pitch: basemap.view.pitch
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
_findBasemapInsertBeforeId() {
|
|
1262
|
+
var _a;
|
|
1263
|
+
const layers = ((_a = this._map) == null ? void 0 : _a.getStyle().layers) ?? [];
|
|
1264
|
+
const firstOverlay = layers.find(
|
|
1265
|
+
(layer) => layer.type !== "background" && !layer.id.startsWith(CONTROL_LAYER_PREFIX)
|
|
1266
|
+
);
|
|
1267
|
+
return firstOverlay == null ? void 0 : firstOverlay.id;
|
|
1268
|
+
}
|
|
1269
|
+
_setupEventListeners() {
|
|
1270
|
+
var _a;
|
|
1271
|
+
this._clickOutsideHandler = (e) => {
|
|
1272
|
+
const target = e.target;
|
|
1273
|
+
if (this._container && this._panel && !this._container.contains(target) && !this._panel.contains(target)) {
|
|
1274
|
+
this.collapse();
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
1277
|
+
document.addEventListener("click", this._clickOutsideHandler);
|
|
1278
|
+
this._resizeHandler = () => {
|
|
1279
|
+
if (!this._state.collapsed) this._updatePanelPosition();
|
|
1280
|
+
};
|
|
1281
|
+
window.addEventListener("resize", this._resizeHandler);
|
|
1282
|
+
this._mapResizeHandler = () => {
|
|
1283
|
+
if (!this._state.collapsed) this._updatePanelPosition();
|
|
1284
|
+
};
|
|
1285
|
+
(_a = this._map) == null ? void 0 : _a.on("resize", this._mapResizeHandler);
|
|
1286
|
+
}
|
|
1287
|
+
_getControlPosition() {
|
|
1288
|
+
var _a;
|
|
1289
|
+
const parent = (_a = this._container) == null ? void 0 : _a.parentElement;
|
|
1290
|
+
if (!parent) return this._options.position;
|
|
1291
|
+
if (parent.classList.contains("maplibregl-ctrl-top-left")) return "top-left";
|
|
1292
|
+
if (parent.classList.contains("maplibregl-ctrl-top-right")) return "top-right";
|
|
1293
|
+
if (parent.classList.contains("maplibregl-ctrl-bottom-left")) return "bottom-left";
|
|
1294
|
+
if (parent.classList.contains("maplibregl-ctrl-bottom-right")) return "bottom-right";
|
|
1295
|
+
return this._options.position;
|
|
1296
|
+
}
|
|
1297
|
+
_updatePanelPosition() {
|
|
1298
|
+
if (!this._container || !this._panel || !this._mapContainer) return;
|
|
1299
|
+
const button = this._container.querySelector(".basemap-control-toggle");
|
|
1300
|
+
if (!button) return;
|
|
1301
|
+
const buttonRect = button.getBoundingClientRect();
|
|
1302
|
+
const mapRect = this._mapContainer.getBoundingClientRect();
|
|
1303
|
+
const position = this._getControlPosition();
|
|
1304
|
+
const buttonTop = buttonRect.top - mapRect.top;
|
|
1305
|
+
const buttonBottom = mapRect.bottom - buttonRect.bottom;
|
|
1306
|
+
const buttonLeft = buttonRect.left - mapRect.left;
|
|
1307
|
+
const buttonRight = mapRect.right - buttonRect.right;
|
|
1308
|
+
const panelGap = 5;
|
|
1309
|
+
this._panel.style.top = "";
|
|
1310
|
+
this._panel.style.bottom = "";
|
|
1311
|
+
this._panel.style.left = "";
|
|
1312
|
+
this._panel.style.right = "";
|
|
1313
|
+
switch (position) {
|
|
1314
|
+
case "top-left":
|
|
1315
|
+
this._panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;
|
|
1316
|
+
this._panel.style.left = `${buttonLeft}px`;
|
|
1317
|
+
break;
|
|
1318
|
+
case "top-right":
|
|
1319
|
+
this._panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;
|
|
1320
|
+
this._panel.style.right = `${buttonRight}px`;
|
|
1321
|
+
break;
|
|
1322
|
+
case "bottom-left":
|
|
1323
|
+
this._panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;
|
|
1324
|
+
this._panel.style.left = `${buttonLeft}px`;
|
|
1325
|
+
break;
|
|
1326
|
+
case "bottom-right":
|
|
1327
|
+
this._panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;
|
|
1328
|
+
this._panel.style.right = `${buttonRight}px`;
|
|
1329
|
+
break;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
export {
|
|
1334
|
+
BasemapControl as B,
|
|
1335
|
+
DEFAULT_BASEMAPS as D,
|
|
1336
|
+
DEFAULT_BASEMAP_PROVIDERS as a,
|
|
1337
|
+
createBasemapCatalog as b,
|
|
1338
|
+
combineProviders as c,
|
|
1339
|
+
filterBasemaps as f,
|
|
1340
|
+
getBasemapCategories as g,
|
|
1341
|
+
resolveBasemapProviders as r
|
|
1342
|
+
};
|
|
1343
|
+
//# sourceMappingURL=BasemapControl-C40PophU.js.map
|