maplibre-gl-layer-control 0.4.0 → 0.5.1
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 +31 -0
- package/dist/index.cjs +357 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +357 -0
- package/dist/index.mjs.map +1 -1
- package/dist/maplibre-gl-layer-control.css +32 -0
- package/dist/types/index.d.ts +84 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -166,6 +166,258 @@ function formatNumericValue(value, step) {
|
|
|
166
166
|
function clamp(value, min, max) {
|
|
167
167
|
return Math.max(min, Math.min(max, value));
|
|
168
168
|
}
|
|
169
|
+
const COLOR_PROPERTY_MAP = {
|
|
170
|
+
fill: ["fill-color", "fill-outline-color"],
|
|
171
|
+
line: ["line-color"],
|
|
172
|
+
circle: ["circle-color", "circle-stroke-color"],
|
|
173
|
+
symbol: ["icon-color", "text-color"],
|
|
174
|
+
background: ["background-color"],
|
|
175
|
+
heatmap: ["heatmap-color"],
|
|
176
|
+
"fill-extrusion": ["fill-extrusion-color"]
|
|
177
|
+
};
|
|
178
|
+
function extractColorFromExpression(expression) {
|
|
179
|
+
if (!Array.isArray(expression) || expression.length === 0) return null;
|
|
180
|
+
for (const item of expression) {
|
|
181
|
+
if (typeof item === "string") {
|
|
182
|
+
if (item.startsWith("#") || item.startsWith("rgb") || item.startsWith("hsl")) {
|
|
183
|
+
return normalizeColor(item);
|
|
184
|
+
}
|
|
185
|
+
} else if (Array.isArray(item)) {
|
|
186
|
+
const result = extractColorFromExpression(item);
|
|
187
|
+
if (result) return result;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
function getLayerColor(map, layerId, layerType) {
|
|
193
|
+
var _a;
|
|
194
|
+
const propertyNames = COLOR_PROPERTY_MAP[layerType];
|
|
195
|
+
if (!propertyNames) return null;
|
|
196
|
+
for (const propertyName of propertyNames) {
|
|
197
|
+
try {
|
|
198
|
+
const runtimeColor = map.getPaintProperty(layerId, propertyName);
|
|
199
|
+
if (runtimeColor) {
|
|
200
|
+
if (typeof runtimeColor === "string") {
|
|
201
|
+
return normalizeColor(runtimeColor);
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(runtimeColor)) {
|
|
204
|
+
const extracted = extractColorFromExpression(runtimeColor);
|
|
205
|
+
if (extracted) return extracted;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
}
|
|
210
|
+
const style = map.getStyle();
|
|
211
|
+
const layer = (_a = style == null ? void 0 : style.layers) == null ? void 0 : _a.find(
|
|
212
|
+
(l) => l.id === layerId
|
|
213
|
+
);
|
|
214
|
+
if (layer && "paint" in layer && layer.paint) {
|
|
215
|
+
const paintColor = layer.paint[propertyName];
|
|
216
|
+
if (paintColor) {
|
|
217
|
+
if (typeof paintColor === "string") {
|
|
218
|
+
return normalizeColor(paintColor);
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(paintColor)) {
|
|
221
|
+
const extracted = extractColorFromExpression(paintColor);
|
|
222
|
+
if (extracted) return extracted;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
function getLayerColorFromSpec(layer) {
|
|
230
|
+
const propertyNames = COLOR_PROPERTY_MAP[layer.type];
|
|
231
|
+
if (!propertyNames) return null;
|
|
232
|
+
for (const propertyName of propertyNames) {
|
|
233
|
+
if ("paint" in layer && layer.paint) {
|
|
234
|
+
const paintColor = layer.paint[propertyName];
|
|
235
|
+
if (paintColor) {
|
|
236
|
+
if (typeof paintColor === "string") {
|
|
237
|
+
return normalizeColor(paintColor);
|
|
238
|
+
}
|
|
239
|
+
if (Array.isArray(paintColor)) {
|
|
240
|
+
const extracted = extractColorFromExpression(paintColor);
|
|
241
|
+
if (extracted) return extracted;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
function darkenColor(hexColor, amount) {
|
|
249
|
+
let hex = hexColor.replace("#", "");
|
|
250
|
+
if (hex.length === 3) {
|
|
251
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
252
|
+
}
|
|
253
|
+
const r = Math.max(
|
|
254
|
+
0,
|
|
255
|
+
parseInt(hex.slice(0, 2), 16) - Math.round(255 * amount)
|
|
256
|
+
);
|
|
257
|
+
const g = Math.max(
|
|
258
|
+
0,
|
|
259
|
+
parseInt(hex.slice(2, 4), 16) - Math.round(255 * amount)
|
|
260
|
+
);
|
|
261
|
+
const b = Math.max(
|
|
262
|
+
0,
|
|
263
|
+
parseInt(hex.slice(4, 6), 16) - Math.round(255 * amount)
|
|
264
|
+
);
|
|
265
|
+
return rgbToHex(r, g, b);
|
|
266
|
+
}
|
|
267
|
+
function createFillSymbol(size, color) {
|
|
268
|
+
const padding = 2;
|
|
269
|
+
const borderColor = darkenColor(color, 0.3);
|
|
270
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
271
|
+
<rect x="${padding}" y="${padding}" width="${size - padding * 2}" height="${size - padding * 2}"
|
|
272
|
+
fill="${color}" stroke="${borderColor}" stroke-width="1" rx="1"/>
|
|
273
|
+
</svg>`;
|
|
274
|
+
}
|
|
275
|
+
function createLineSymbol(size, color, strokeWidth = 2) {
|
|
276
|
+
const y = size / 2;
|
|
277
|
+
const padding = 2;
|
|
278
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
279
|
+
<line x1="${padding}" y1="${y}" x2="${size - padding}" y2="${y}"
|
|
280
|
+
stroke="${color}" stroke-width="${strokeWidth}" stroke-linecap="round"/>
|
|
281
|
+
</svg>`;
|
|
282
|
+
}
|
|
283
|
+
function createCircleSymbol(size, color) {
|
|
284
|
+
const cx = size / 2;
|
|
285
|
+
const cy = size / 2;
|
|
286
|
+
const r = size / 2 - 3;
|
|
287
|
+
const borderColor = darkenColor(color, 0.3);
|
|
288
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
289
|
+
<circle cx="${cx}" cy="${cy}" r="${r}" fill="${color}"
|
|
290
|
+
stroke="${borderColor}" stroke-width="1"/>
|
|
291
|
+
</svg>`;
|
|
292
|
+
}
|
|
293
|
+
function createMarkerSymbol(size, color) {
|
|
294
|
+
const borderColor = darkenColor(color, 0.3);
|
|
295
|
+
const cx = size / 2;
|
|
296
|
+
const pinWidth = size * 0.5;
|
|
297
|
+
const pinHeight = size * 0.7;
|
|
298
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
299
|
+
<path d="M${cx} ${size - 2}
|
|
300
|
+
L${cx - pinWidth / 2} ${size - pinHeight}
|
|
301
|
+
A${pinWidth / 2} ${pinWidth / 2} 0 1 1 ${cx + pinWidth / 2} ${size - pinHeight}
|
|
302
|
+
Z"
|
|
303
|
+
fill="${color}" stroke="${borderColor}" stroke-width="1"/>
|
|
304
|
+
<circle cx="${cx}" cy="${size - pinHeight - pinWidth / 4}" r="${pinWidth / 5}" fill="white"/>
|
|
305
|
+
</svg>`;
|
|
306
|
+
}
|
|
307
|
+
function createRasterSymbol(size) {
|
|
308
|
+
const padding = 2;
|
|
309
|
+
const id = `rasterGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
310
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
311
|
+
<defs>
|
|
312
|
+
<linearGradient id="${id}" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
313
|
+
<stop offset="0%" stop-color="#e0e0e0"/>
|
|
314
|
+
<stop offset="50%" stop-color="#808080"/>
|
|
315
|
+
<stop offset="100%" stop-color="#404040"/>
|
|
316
|
+
</linearGradient>
|
|
317
|
+
</defs>
|
|
318
|
+
<rect x="${padding}" y="${padding}" width="${size - padding * 2}" height="${size - padding * 2}"
|
|
319
|
+
fill="url(#${id})" rx="1"/>
|
|
320
|
+
</svg>`;
|
|
321
|
+
}
|
|
322
|
+
function createBackgroundSymbol(size, color) {
|
|
323
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
324
|
+
<rect x="1" y="1" width="${size - 2}" height="${size - 2}" fill="${color}" rx="2"/>
|
|
325
|
+
<rect x="3" y="3" width="${size - 6}" height="${size - 6}" fill="none"
|
|
326
|
+
stroke="white" stroke-width="1" stroke-opacity="0.5" rx="1"/>
|
|
327
|
+
</svg>`;
|
|
328
|
+
}
|
|
329
|
+
function createHeatmapSymbol(size) {
|
|
330
|
+
const padding = 2;
|
|
331
|
+
const id = `heatmapGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
332
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
333
|
+
<defs>
|
|
334
|
+
<radialGradient id="${id}" cx="50%" cy="50%" r="50%">
|
|
335
|
+
<stop offset="0%" stop-color="#ffff00"/>
|
|
336
|
+
<stop offset="50%" stop-color="#ff8800"/>
|
|
337
|
+
<stop offset="100%" stop-color="#ff0000"/>
|
|
338
|
+
</radialGradient>
|
|
339
|
+
</defs>
|
|
340
|
+
<rect x="${padding}" y="${padding}" width="${size - padding * 2}" height="${size - padding * 2}"
|
|
341
|
+
fill="url(#${id})" rx="1"/>
|
|
342
|
+
</svg>`;
|
|
343
|
+
}
|
|
344
|
+
function createHillshadeSymbol(size) {
|
|
345
|
+
const padding = 2;
|
|
346
|
+
const id = `hillshadeGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
347
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
348
|
+
<defs>
|
|
349
|
+
<linearGradient id="${id}" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
350
|
+
<stop offset="0%" stop-color="#ffffff"/>
|
|
351
|
+
<stop offset="100%" stop-color="#666666"/>
|
|
352
|
+
</linearGradient>
|
|
353
|
+
</defs>
|
|
354
|
+
<rect x="${padding}" y="${padding}" width="${size - padding * 2}" height="${size - padding * 2}"
|
|
355
|
+
fill="url(#${id})" rx="1"/>
|
|
356
|
+
</svg>`;
|
|
357
|
+
}
|
|
358
|
+
function createFillExtrusionSymbol(size, color) {
|
|
359
|
+
const borderColor = darkenColor(color, 0.3);
|
|
360
|
+
const topColor = color;
|
|
361
|
+
const sideColor = darkenColor(color, 0.2);
|
|
362
|
+
const depth = 3;
|
|
363
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
364
|
+
<polygon points="${2 + depth},2 ${size - 2},2 ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2} 2,${2 + depth}"
|
|
365
|
+
fill="${topColor}" stroke="${borderColor}" stroke-width="1"/>
|
|
366
|
+
<polygon points="2,${2 + depth} ${2 + depth},2 ${2 + depth},${size - 2 - depth} 2,${size - 2}"
|
|
367
|
+
fill="${sideColor}" stroke="${borderColor}" stroke-width="0.5"/>
|
|
368
|
+
<polygon points="${2 + depth},${size - 2 - depth} ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2}"
|
|
369
|
+
fill="${sideColor}" stroke="${borderColor}" stroke-width="0.5"/>
|
|
370
|
+
</svg>`;
|
|
371
|
+
}
|
|
372
|
+
function createDefaultSymbol(size, color) {
|
|
373
|
+
const padding = 2;
|
|
374
|
+
const borderColor = darkenColor(color, 0.3);
|
|
375
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
376
|
+
<rect x="${padding}" y="${padding}" width="${size - padding * 2}" height="${size - padding * 2}"
|
|
377
|
+
fill="${color}" stroke="${borderColor}" stroke-width="1"/>
|
|
378
|
+
</svg>`;
|
|
379
|
+
}
|
|
380
|
+
function createStackedLayersSymbol(size) {
|
|
381
|
+
const colors = ["#a8d4a8", "#8ec4e8", "#d4c4a8"];
|
|
382
|
+
const borderColor = "#666666";
|
|
383
|
+
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
384
|
+
<rect x="4" y="1" width="${size - 6}" height="${size - 6}" fill="${colors[2]}" stroke="${borderColor}" stroke-width="0.75" rx="1"/>
|
|
385
|
+
<rect x="2" y="3" width="${size - 6}" height="${size - 6}" fill="${colors[1]}" stroke="${borderColor}" stroke-width="0.75" rx="1"/>
|
|
386
|
+
<rect x="0" y="5" width="${size - 6}" height="${size - 6}" fill="${colors[0]}" stroke="${borderColor}" stroke-width="0.75" rx="1"/>
|
|
387
|
+
</svg>`;
|
|
388
|
+
}
|
|
389
|
+
function createLayerSymbolSVG(layerType, color, options = {}) {
|
|
390
|
+
const size = options.size || 16;
|
|
391
|
+
const strokeWidth = options.strokeWidth || 2;
|
|
392
|
+
const fillColor = color || "#888888";
|
|
393
|
+
switch (layerType) {
|
|
394
|
+
case "fill":
|
|
395
|
+
return createFillSymbol(size, fillColor);
|
|
396
|
+
case "line":
|
|
397
|
+
return createLineSymbol(size, fillColor, strokeWidth);
|
|
398
|
+
case "circle":
|
|
399
|
+
return createCircleSymbol(size, fillColor);
|
|
400
|
+
case "symbol":
|
|
401
|
+
return createMarkerSymbol(size, fillColor);
|
|
402
|
+
case "raster":
|
|
403
|
+
return createRasterSymbol(size);
|
|
404
|
+
case "background":
|
|
405
|
+
return createBackgroundSymbol(size, fillColor);
|
|
406
|
+
case "heatmap":
|
|
407
|
+
return createHeatmapSymbol(size);
|
|
408
|
+
case "hillshade":
|
|
409
|
+
return createHillshadeSymbol(size);
|
|
410
|
+
case "fill-extrusion":
|
|
411
|
+
return createFillExtrusionSymbol(size, fillColor);
|
|
412
|
+
case "background-group":
|
|
413
|
+
return createStackedLayersSymbol(size);
|
|
414
|
+
default:
|
|
415
|
+
return createDefaultSymbol(size, fillColor);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function createBackgroundGroupSymbolSVG(size = 16) {
|
|
419
|
+
return createStackedLayersSymbol(size);
|
|
420
|
+
}
|
|
169
421
|
class LayerControl {
|
|
170
422
|
constructor(options = {}) {
|
|
171
423
|
__publicField(this, "map");
|
|
@@ -179,8 +431,11 @@ class LayerControl {
|
|
|
179
431
|
// Panel width management
|
|
180
432
|
__publicField(this, "minPanelWidth");
|
|
181
433
|
__publicField(this, "maxPanelWidth");
|
|
434
|
+
__publicField(this, "maxPanelHeight");
|
|
182
435
|
__publicField(this, "showStyleEditor");
|
|
183
436
|
__publicField(this, "showOpacitySlider");
|
|
437
|
+
__publicField(this, "showLayerSymbol");
|
|
438
|
+
__publicField(this, "excludeDrawnLayers");
|
|
184
439
|
__publicField(this, "widthSliderEl", null);
|
|
185
440
|
__publicField(this, "widthThumbEl", null);
|
|
186
441
|
__publicField(this, "widthValueEl", null);
|
|
@@ -191,8 +446,11 @@ class LayerControl {
|
|
|
191
446
|
__publicField(this, "widthFrame", null);
|
|
192
447
|
this.minPanelWidth = options.panelMinWidth || 240;
|
|
193
448
|
this.maxPanelWidth = options.panelMaxWidth || 420;
|
|
449
|
+
this.maxPanelHeight = options.panelMaxHeight || 600;
|
|
194
450
|
this.showStyleEditor = options.showStyleEditor !== false;
|
|
195
451
|
this.showOpacitySlider = options.showOpacitySlider !== false;
|
|
452
|
+
this.showLayerSymbol = options.showLayerSymbol !== false;
|
|
453
|
+
this.excludeDrawnLayers = options.excludeDrawnLayers !== false;
|
|
196
454
|
this.state = {
|
|
197
455
|
collapsed: options.collapsed !== false,
|
|
198
456
|
panelWidth: options.panelWidth || 320,
|
|
@@ -248,6 +506,10 @@ class LayerControl {
|
|
|
248
506
|
allLayerIds.forEach((layerId) => {
|
|
249
507
|
const layer = this.map.getLayer(layerId);
|
|
250
508
|
if (!layer) return;
|
|
509
|
+
if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {
|
|
510
|
+
backgroundLayerIds.push(layerId);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
251
513
|
const sourceId = layer.source;
|
|
252
514
|
if (!sourceId || originalSourceIds.has(sourceId)) {
|
|
253
515
|
backgroundLayerIds.push(layerId);
|
|
@@ -373,6 +635,28 @@ class LayerControl {
|
|
|
373
635
|
name = name.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
374
636
|
return name || layerId;
|
|
375
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)
|
|
640
|
+
* @param layerId The layer ID to check
|
|
641
|
+
* @returns true if the layer is from a drawing library
|
|
642
|
+
*/
|
|
643
|
+
isDrawnLayer(layerId) {
|
|
644
|
+
const drawnLayerPatterns = [
|
|
645
|
+
/^gm[-_\s]/i,
|
|
646
|
+
// Geoman (gm-main-*, gm_*, Gm Temporary...)
|
|
647
|
+
/^gl-draw[-_]/i,
|
|
648
|
+
// Mapbox GL Draw
|
|
649
|
+
/^mapbox-gl-draw[-_]/i,
|
|
650
|
+
// Mapbox GL Draw alternative
|
|
651
|
+
/^terra-draw[-_]/i,
|
|
652
|
+
// Terra Draw
|
|
653
|
+
/^maplibre-gl-draw[-_]/i,
|
|
654
|
+
// MapLibre GL Draw
|
|
655
|
+
/^draw[-_]layer/i
|
|
656
|
+
// Generic draw layers
|
|
657
|
+
];
|
|
658
|
+
return drawnLayerPatterns.some((pattern) => pattern.test(layerId));
|
|
659
|
+
}
|
|
376
660
|
/**
|
|
377
661
|
* Create the main container element
|
|
378
662
|
*/
|
|
@@ -402,6 +686,7 @@ class LayerControl {
|
|
|
402
686
|
const panel = document.createElement("div");
|
|
403
687
|
panel.className = "layer-control-panel";
|
|
404
688
|
panel.style.width = `${this.state.panelWidth}px`;
|
|
689
|
+
panel.style.maxHeight = `${this.maxPanelHeight}px`;
|
|
405
690
|
if (!this.state.collapsed) {
|
|
406
691
|
panel.classList.add("expanded");
|
|
407
692
|
}
|
|
@@ -737,6 +1022,17 @@ class LayerControl {
|
|
|
737
1022
|
name.textContent = state.name || layerId;
|
|
738
1023
|
name.title = state.name || layerId;
|
|
739
1024
|
row.appendChild(checkbox);
|
|
1025
|
+
if (this.showLayerSymbol) {
|
|
1026
|
+
if (layerId === "Background") {
|
|
1027
|
+
const symbol = this.createBackgroundGroupSymbol();
|
|
1028
|
+
row.appendChild(symbol);
|
|
1029
|
+
} else {
|
|
1030
|
+
const symbol = this.createLayerSymbol(layerId);
|
|
1031
|
+
if (symbol) {
|
|
1032
|
+
row.appendChild(symbol);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
740
1036
|
row.appendChild(name);
|
|
741
1037
|
if (this.showOpacitySlider) {
|
|
742
1038
|
const opacity = document.createElement("input");
|
|
@@ -773,6 +1069,50 @@ class LayerControl {
|
|
|
773
1069
|
item.appendChild(row);
|
|
774
1070
|
this.panel.appendChild(item);
|
|
775
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Create a symbol element for a layer
|
|
1074
|
+
* @param layerId The layer ID
|
|
1075
|
+
* @returns The symbol HTML element, or null if layer not found
|
|
1076
|
+
*/
|
|
1077
|
+
createLayerSymbol(layerId) {
|
|
1078
|
+
const layer = this.map.getLayer(layerId);
|
|
1079
|
+
if (!layer) return null;
|
|
1080
|
+
const layerType = layer.type;
|
|
1081
|
+
const color = getLayerColor(this.map, layerId, layerType);
|
|
1082
|
+
const svgMarkup = createLayerSymbolSVG(layerType, color);
|
|
1083
|
+
const symbolContainer = document.createElement("span");
|
|
1084
|
+
symbolContainer.className = "layer-control-symbol";
|
|
1085
|
+
symbolContainer.innerHTML = svgMarkup;
|
|
1086
|
+
symbolContainer.title = `Layer type: ${layerType}`;
|
|
1087
|
+
return symbolContainer;
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Create a symbol element for a background layer
|
|
1091
|
+
* @param layer The layer specification
|
|
1092
|
+
* @returns The symbol HTML element
|
|
1093
|
+
*/
|
|
1094
|
+
createBackgroundLayerSymbol(layer) {
|
|
1095
|
+
const color = getLayerColorFromSpec(layer);
|
|
1096
|
+
const svgMarkup = createLayerSymbolSVG(layer.type, color, { size: 14 });
|
|
1097
|
+
const symbolContainer = document.createElement("span");
|
|
1098
|
+
symbolContainer.className = "background-legend-layer-symbol";
|
|
1099
|
+
symbolContainer.innerHTML = svgMarkup;
|
|
1100
|
+
symbolContainer.title = `Layer type: ${layer.type}`;
|
|
1101
|
+
return symbolContainer;
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Create a symbol element for the Background layer group
|
|
1105
|
+
* Shows a stacked layers icon to represent multiple background layers
|
|
1106
|
+
* @returns The symbol HTML element
|
|
1107
|
+
*/
|
|
1108
|
+
createBackgroundGroupSymbol() {
|
|
1109
|
+
const svgMarkup = createBackgroundGroupSymbolSVG(16);
|
|
1110
|
+
const symbolContainer = document.createElement("span");
|
|
1111
|
+
symbolContainer.className = "layer-control-symbol";
|
|
1112
|
+
symbolContainer.innerHTML = svgMarkup;
|
|
1113
|
+
symbolContainer.title = "Background layers";
|
|
1114
|
+
return symbolContainer;
|
|
1115
|
+
}
|
|
776
1116
|
/**
|
|
777
1117
|
* Toggle layer visibility
|
|
778
1118
|
*/
|
|
@@ -1013,6 +1353,9 @@ class LayerControl {
|
|
|
1013
1353
|
const styleLayers = this.map.getStyle().layers || [];
|
|
1014
1354
|
styleLayers.forEach((layer) => {
|
|
1015
1355
|
if (!this.isUserAddedLayer(layer.id)) {
|
|
1356
|
+
if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) {
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1016
1359
|
if (this.state.onlyRenderedFilter && !this.isLayerRendered(layer.id)) {
|
|
1017
1360
|
return;
|
|
1018
1361
|
}
|
|
@@ -1037,6 +1380,12 @@ class LayerControl {
|
|
|
1037
1380
|
typeIndicator.className = "background-legend-layer-type";
|
|
1038
1381
|
typeIndicator.textContent = layer.type;
|
|
1039
1382
|
layerRow.appendChild(checkbox);
|
|
1383
|
+
if (this.showLayerSymbol) {
|
|
1384
|
+
const symbol = this.createBackgroundLayerSymbol(layer);
|
|
1385
|
+
if (symbol) {
|
|
1386
|
+
layerRow.appendChild(symbol);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1040
1389
|
layerRow.appendChild(name);
|
|
1041
1390
|
layerRow.appendChild(typeIndicator);
|
|
1042
1391
|
container.appendChild(layerRow);
|
|
@@ -1526,6 +1875,9 @@ class LayerControl {
|
|
|
1526
1875
|
const layer = this.map.getLayer(layerId);
|
|
1527
1876
|
if (layer) {
|
|
1528
1877
|
if (isAutoDetectMode) {
|
|
1878
|
+
if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1529
1881
|
const sourceId = layer.source;
|
|
1530
1882
|
if (!sourceId || originalSourceIds.has(sourceId)) {
|
|
1531
1883
|
return;
|
|
@@ -1578,7 +1930,12 @@ class LayerControl {
|
|
|
1578
1930
|
export {
|
|
1579
1931
|
LayerControl,
|
|
1580
1932
|
clamp,
|
|
1933
|
+
createBackgroundGroupSymbolSVG,
|
|
1934
|
+
createLayerSymbolSVG,
|
|
1935
|
+
darkenColor,
|
|
1581
1936
|
formatNumericValue,
|
|
1937
|
+
getLayerColor,
|
|
1938
|
+
getLayerColorFromSpec,
|
|
1582
1939
|
getLayerOpacity,
|
|
1583
1940
|
getLayerType,
|
|
1584
1941
|
isStyleableLayerType,
|