maplibre-gl-layer
Version:
A layer control for MapLibre GL JS
120 lines (119 loc) • 5.36 kB
JavaScript
var u = Object.defineProperty;
var g = (c, e, t) => e in c ? u(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
var a = (c, e, t) => g(c, typeof e != "symbol" ? e + "" : e, t);
class m {
constructor(e, t) {
a(this, "dialog");
a(this, "options");
a(this, "layerChangeCallback", () => {
});
this.options = e, this.dialog = document.createElement("dialog"), this.dialog.classList.add("maplibregl-ctrl-layer-dialog"), document.body.appendChild(this.dialog), this.dialog.addEventListener("click", () => {
this.dialog.close();
});
const i = document.createElement("div");
i.classList.add("maplibregl-ctrl-layer-dialog-content"), i.addEventListener("click", (l) => {
l.stopPropagation();
}), this.dialog.appendChild(i), this.options.layers.forEach((l) => {
const o = document.createElement("div");
o.classList.add("maplibregl-ctrl-layer-dialog-item");
const d = document.createElement("label");
o.appendChild(d);
const n = document.createElement("input");
n.setAttribute("type", "radio"), n.setAttribute("name", "layer"), t.name === l.name && n.setAttribute("checked", "checked"), n.addEventListener("change", () => {
var p;
(p = this.layerChangeCallback) == null || p.call(this, l);
}), d.appendChild(n);
const h = document.createElement("span");
h.textContent = l.name, d.appendChild(h), i.appendChild(o);
});
}
open(e, t = null) {
this.dialog.showModal(), this.setPosition(e, t);
}
close() {
this.dialog.close();
}
on(e, t) {
e === "layerchange" && (this.layerChangeCallback = t);
}
setPosition(e, t) {
const i = e.getBoundingClientRect();
let l = "", o = "";
t === "top-right" ? (l = `${i.y}px`, o = `${i.x - this.dialog.clientWidth - 12}px`) : t === "top-left" ? (l = `${i.y}px`, o = `${i.x + i.width + 12}px`) : t === "bottom-right" ? (l = `${i.y - this.dialog.clientHeight + i.height}px`, o = `${i.x - this.dialog.clientWidth - 12}px`) : t === "bottom-left" && (l = `${i.y - this.dialog.clientHeight + i.height}px`, o = `${i.x + i.width + 12}px`), this.dialog.style.setProperty("top", l), this.dialog.style.setProperty("left", o);
}
}
class b {
constructor(e) {
a(this, "map", null);
a(this, "options");
a(this, "container");
a(this, "currentLayer");
a(this, "currentInitStyle", null);
a(this, "addedSources", {});
a(this, "addedLayers", []);
a(this, "layerDialog");
this.options = e, this.container = document.createElement("div"), this.container.classList.add("maplibregl-ctrl", "maplibregl-ctrl-group"), this.currentLayer = e.layers.find((t) => t.checked) || e.layers[0], this.layerDialog = new m(this.options, this.currentLayer), this.layerDialog.on("layerchange", (t) => {
this.changeLayer(t), this.layerDialog.close();
});
}
onAdd(e) {
this.map = e, this.currentInitStyle = this.map.getStyle(), this.currentInitStyle || this.map.once("style.load", () => {
this.map && (this.currentInitStyle = this.map.getStyle());
});
const t = this.createButton();
return t.addEventListener("click", () => {
this.layerDialog.open(t, this.getPosition());
}), this.container.appendChild(t), this.container;
}
onRemove() {
var e;
(e = this.container.parentNode) == null || e.removeChild(this.container);
}
getPosition() {
if (!this.map) return null;
const e = this.map._controlPositions;
return e["top-left"].querySelector(".maplibregl-ctrl-layer") ? "top-left" : e["top-right"].querySelector(".maplibregl-ctrl-layer") ? "top-right" : e["bottom-left"].querySelector(".maplibregl-ctrl-layer") ? "bottom-left" : e["bottom-right"].querySelector(".maplibregl-ctrl-layer") ? "bottom-right" : null;
}
createButton() {
const e = document.createElement("button");
e.classList.add("maplibregl-ctrl-layer"), e.setAttribute("title", "Change map style"), e.setAttribute("aria-label", "Change map style");
const t = document.createElement("i");
return t.classList.add("maplibregl-ctrl-icon"), e.appendChild(t), e;
}
changeLayer(e) {
if (!this.map) return;
const t = this.currentInitStyle.layers, i = this.map.getStyle().layers, l = i.filter(
(r) => !t.some((s) => s.id === r.id)
);
this.addedLayers = [...this.addedLayers, ...l];
const o = t.filter(
(r) => !i.some((s) => s.id === r.id)
);
this.addedLayers = this.addedLayers.filter(
(r) => !o.some((s) => s.id === r.id)
), this.addedLayers.forEach((r) => {
const s = i.find((y) => y.id === r.id);
r.filter = s == null ? void 0 : s.filter;
});
const d = this.currentInitStyle.sources, n = this.map.getStyle().sources, h = {};
Object.entries(n).forEach(([r, s]) => {
Object.keys(d).includes(r) || (h[r] = s);
}), this.addedSources = { ...this.addedSources, ...h }, Object.keys(d).filter(
(r) => !Object.keys(n).includes(r)
).forEach((r) => {
delete this.addedSources[r];
}), this.map.setStyle(e.style, {
transformStyle: (r, s) => {
const y = {
...s,
sources: { ...s.sources, ...this.addedSources },
layers: s.layers.concat(this.addedLayers)
};
return this.currentInitStyle = y, y;
}
});
}
}
export {
b as LayerControl
};