UNPKG

vue-maplibre-gl

Version:
1,388 lines 59.1 kB
/*! * vue-maplibre-gl v5.6.1 * (c) 2026 Volker Nauruhn * @license MIT */ import { watch as D, defineComponent as ne, inject as B, ref as Ce, onBeforeUnmount as Se, createCommentVNode as Re, h as V, Teleport as Ue, nextTick as Fe, warn as Ne, reactive as Ge } from "vue"; import "maplibre-gl"; import "geojson"; function Ut(t, e = 250, i = !1) { let o; function s() { const r = arguments, n = () => { o = void 0, i !== !0 && t.apply(this, r); }; clearTimeout(o), i === !0 && o === void 0 && t.apply(this, r), o = window.setTimeout(n, e); } return s.cancel = () => { clearTimeout(o); }, s; } function se(t, e) { let i, o; return function() { const s = arguments, r = this; return i || (i = !0, setTimeout(() => i = !1, e), o = t.apply(r, s)), o; }; } const Ae = /* @__PURE__ */ Symbol("map"), He = /* @__PURE__ */ Symbol("isLoaded"), Be = /* @__PURE__ */ Symbol("isInitialized"), Ft = /* @__PURE__ */ Symbol("componentId"), Nt = /* @__PURE__ */ Symbol("sourceId"), Gt = /* @__PURE__ */ Symbol("sourceLayerRegistry"), Ht = /* @__PURE__ */ Symbol("emitter"), $e = /* @__PURE__ */ Symbol("fitBoundsOptions"); function Bt(t) { return Object.keys(t); } function $t(t) { return Object.keys(t); } var K = /* @__PURE__ */ ((t) => (t.TOP_LEFT = "top-left", t.TOP_RIGHT = "top-right", t.BOTTOM_LEFT = "bottom-left", t.BOTTOM_RIGHT = "bottom-right", t))(K || {}); const Pe = Object.values(K); function qe(t, e, i) { D(t, (o) => { o && Pe.indexOf(o) === -1 || (e.value?.hasControl(i) && e.value.removeControl(i), e.value?.addControl(i, o)); }, { immediate: !0 }); } class N { constructor(e, i) { this.isAdded = e, this.container = document.createElement("div"), this.setClasses(i); } static CONTROL_CLASS = "maplibregl-ctrl"; static CONTROL_GROUP_CLASS = "maplibregl-ctrl-group"; container; getDefaultPosition() { return K.TOP_LEFT; } onAdd() { return Fe(() => this.isAdded.value = !0), this.container; } onRemove() { this.isAdded.value = !1, this.container.remove(); } setClasses(e) { e ? (this.container.classList.remove(N.CONTROL_CLASS), this.container.classList.remove(N.CONTROL_GROUP_CLASS)) : (this.container.classList.add(N.CONTROL_CLASS), this.container.classList.add(N.CONTROL_GROUP_CLASS)); } } const ce = /* @__PURE__ */ ne({ name: "MglCustomControl", props: { position: { type: String, validator: (t) => Pe.indexOf(t) !== -1 }, noClasses: { type: Boolean, default: !1 } }, slots: Object, setup(t, { slots: e }) { const i = B(Ae), o = B(Be), s = Ce(!1), r = new N(s, t.noClasses); return qe(() => t.position, i, r), D(() => t.noClasses, (n) => r.setClasses(n)), Se(() => o.value && i.value?.removeControl(r)), () => s.value ? V( Ue, { to: r.container }, e.default?.({}) ) : Re("custom-component"); } }); var $ = /* @__PURE__ */ ((t) => (t.DEFAULT = "default", t.TEXT = "text", t.MDI = "mdi", t.SIMPLE_ICON = "simple-icons", t))($ || {}); const Ze = Object.values($), Y = { text: void 0, mdi: { size: 21, viewbox: "0 0 24 24" }, "simple-icons": { size: 21, viewbox: "0 0 24 24" }, default: { size: 0, viewbox: "0 0 0 0" } }, j = /* @__PURE__ */ ne({ name: "MglButton", props: { type: { type: String, default: "default", validator: (t) => Ze.indexOf(t) !== -1 }, path: { type: String }, size: Number, viewbox: String }, slots: Object, setup(t, { slots: e }) { !t.path && t.type !== "text" && Ne("property `path` must be set on MaplibreButton"); const i = Ce(Y[t.type] || Y.default); return D(() => t.type, (o) => i.value = Y[o] || Y.default), () => t.type === "text" ? V("button", { type: "button" }, e.default?.({})) : V( "button", { type: "button", class: "maplibregl-ctrl-icon" }, [ V( "svg", { width: t.size || i.value.size, height: t.size || i.value.size, viewBox: t.viewbox || i.value.viewbox }, V("path", { fill: "currentColor", d: t.path }) ), e.default?.({}) ] ); } }); var P = 63710088e-1, Le = { centimeters: P * 100, centimetres: P * 100, degrees: 360 / (2 * Math.PI), feet: P * 3.28084, inches: P * 39.37, kilometers: P / 1e3, kilometres: P / 1e3, meters: P, metres: P, miles: P / 1609.344, millimeters: P * 1e3, millimetres: P * 1e3, nauticalmiles: P / 1852, radians: 1, yards: P * 1.0936 }; function Q(t, e, i = {}) { const o = { type: "Feature" }; return (i.id === 0 || i.id) && (o.id = i.id), i.bbox && (o.bbox = i.bbox), o.properties = e || {}, o.geometry = t, o; } function he(t, e, i = {}) { if (!t) throw new Error("coordinates is required"); if (!Array.isArray(t)) throw new Error("coordinates must be an Array"); if (t.length < 2) throw new Error("coordinates must be at least 2 numbers long"); if (!pe(t[0]) || !pe(t[1])) throw new Error("coordinates must contain numbers"); return Q({ type: "Point", coordinates: t }, e, i); } function We(t, e, i = {}) { for (const s of t) { if (s.length < 4) throw new Error( "Each LinearRing of a Polygon must have 4 or more Positions." ); if (s[s.length - 1].length !== s[0].length) throw new Error("First and last Position are not equivalent."); for (let r = 0; r < s[s.length - 1].length; r++) if (s[s.length - 1][r] !== s[0][r]) throw new Error("First and last Position are not equivalent."); } return Q({ type: "Polygon", coordinates: t }, e, i); } function ue(t, e, i = {}) { if (t.length < 2) throw new Error("coordinates must be an array of two or more positions"); return Q({ type: "LineString", coordinates: t }, e, i); } function Ye(t, e = "kilometers") { const i = Le[e]; if (!i) throw new Error(e + " units is invalid"); return t * i; } function Je(t, e = "kilometers") { const i = Le[e]; if (!i) throw new Error(e + " units is invalid"); return t / i; } function de(t) { return t % (2 * Math.PI) * 180 / Math.PI; } function U(t) { return t % 360 * Math.PI / 180; } function pe(t) { return !isNaN(t) && t !== null && !Array.isArray(t); } function Xe(t) { return t !== null && typeof t == "object" && !Array.isArray(t); } function Ee(t, e, i) { if (t !== null) for (var o, s, r, n, a, l, h, d = 0, c = 0, u, p = t.type, m = p === "FeatureCollection", g = p === "Feature", y = m ? t.features.length : 1, f = 0; f < y; f++) { h = m ? ( // @ts-expect-error: Known type conflict t.features[f].geometry ) : g ? ( // @ts-expect-error: Known type conflict t.geometry ) : t, u = h ? h.type === "GeometryCollection" : !1, a = u ? h.geometries.length : 1; for (var v = 0; v < a; v++) { var w = 0, b = 0; if (n = u ? h.geometries[v] : h, n !== null) { l = n.coordinates; var M = n.type; switch (d = 0, M) { case null: break; case "Point": if ( // @ts-expect-error: Known type conflict e( l, c, f, w, b ) === !1 ) return !1; c++, w++; break; case "LineString": case "MultiPoint": for (o = 0; o < l.length; o++) { if ( // @ts-expect-error: Known type conflict e( l[o], c, f, w, b ) === !1 ) return !1; c++, M === "MultiPoint" && w++; } M === "LineString" && w++; break; case "Polygon": case "MultiLineString": for (o = 0; o < l.length; o++) { for (s = 0; s < l[o].length - d; s++) { if ( // @ts-expect-error: Known type conflict e( l[o][s], c, f, w, b ) === !1 ) return !1; c++; } M === "MultiLineString" && w++, M === "Polygon" && b++; } M === "Polygon" && w++; break; case "MultiPolygon": for (o = 0; o < l.length; o++) { for (b = 0, s = 0; s < l[o].length; s++) { for (r = 0; r < l[o][s].length - d; r++) { if ( // @ts-expect-error: Known type conflict e( l[o][s][r], c, f, w, b ) === !1 ) return !1; c++; } b++; } w++; } break; case "GeometryCollection": for (o = 0; o < n.geometries.length; o++) if ( // @ts-expect-error: Known type conflict Ee(n.geometries[o], e) === !1 ) return !1; break; default: throw new Error("Unknown Geometry Type"); } } } } } function Oe(t, e) { var i, o, s, r, n, a, l, h, d, c, u = 0, p = t.type === "FeatureCollection", m = t.type === "Feature", g = p ? t.features.length : 1; for (i = 0; i < g; i++) { for (a = p ? ( // @ts-expect-error: Known type conflict t.features[i].geometry ) : m ? ( // @ts-expect-error: Known type conflict t.geometry ) : t, h = p ? ( // @ts-expect-error: Known type conflict t.features[i].properties ) : m ? ( // @ts-expect-error: Known type conflict t.properties ) : {}, d = p ? ( // @ts-expect-error: Known type conflict t.features[i].bbox ) : m ? ( // @ts-expect-error: Known type conflict t.bbox ) : void 0, c = p ? ( // @ts-expect-error: Known type conflict t.features[i].id ) : m ? ( // @ts-expect-error: Known type conflict t.id ) : void 0, l = a ? a.type === "GeometryCollection" : !1, n = l ? a.geometries.length : 1, s = 0; s < n; s++) { if (r = l ? a.geometries[s] : a, r === null) { if ( // @ts-expect-error: Known type conflict e( // @ts-expect-error: Known type conflict null, u, h, d, c ) === !1 ) return !1; continue; } switch (r.type) { case "Point": case "LineString": case "MultiPoint": case "Polygon": case "MultiLineString": case "MultiPolygon": { if ( // @ts-expect-error: Known type conflict e( r, u, h, d, c ) === !1 ) return !1; break; } case "GeometryCollection": { for (o = 0; o < r.geometries.length; o++) if ( // @ts-expect-error: Known type conflict e( r.geometries[o], u, h, d, c ) === !1 ) return !1; break; } default: throw new Error("Unknown Geometry Type"); } } u++; } } function Ke(t, e, i) { var o = i; return Oe( t, function(s, r, n, a, l) { o = e( // @ts-expect-error: Known type conflict o, s, r, n, a, l ); } ), o; } function Qe(t) { return Ke( t, (e, i) => e + je(i), 0 ); } function je(t) { let e = 0, i; switch (t.type) { case "Polygon": return fe(t.coordinates); case "MultiPolygon": for (i = 0; i < t.coordinates.length; i++) e += fe(t.coordinates[i]); return e; case "Point": case "MultiPoint": case "LineString": case "MultiLineString": return 0; } return 0; } function fe(t) { let e = 0; if (t && t.length > 0) { e += Math.abs(me(t[0])); for (let i = 1; i < t.length; i++) e -= Math.abs(me(t[i])); } return e; } var et = P * P / 2, ee = Math.PI / 180; function me(t) { const e = t.length - 1; if (e <= 2) return 0; let i = 0, o = 0; for (; o < e; ) { const s = t[o], r = t[o + 1 === e ? 0 : o + 1], n = t[o + 2 >= e ? (o + 2) % e : o + 2], a = s[0] * ee, l = r[1] * ee, h = n[0] * ee; i += (h - a) * Math.sin(l), o++; } return i * et; } var tt = Qe; function Z(t) { if (!t) throw new Error("coord is required"); if (!Array.isArray(t)) { if (t.type === "Feature" && t.geometry !== null && t.geometry.type === "Point") return [...t.geometry.coordinates]; if (t.type === "Point") return [...t.coordinates]; } if (Array.isArray(t) && t.length >= 2 && !Array.isArray(t[0]) && !Array.isArray(t[1])) return [...t]; throw new Error("coord must be GeoJSON Point or an Array of numbers"); } function q(t) { if (Array.isArray(t)) return t; if (t.type === "Feature") { if (t.geometry !== null) return t.geometry.coordinates; } else if (t.coordinates) return t.coordinates; throw new Error( "coords must be GeoJSON Feature, Geometry Object or an Array" ); } function it(t) { return t.type === "Feature" ? t.geometry : t; } function ot(t, e) { return t.type === "FeatureCollection" ? "FeatureCollection" : t.type === "GeometryCollection" ? "GeometryCollection" : t.type === "Feature" && t.geometry !== null ? t.geometry.type : t.type; } function rt(t, e, i, o = {}) { const s = Z(t), r = U(s[0]), n = U(s[1]), a = U(i), l = Je(e, o.units), h = Math.asin( Math.sin(n) * Math.cos(l) + Math.cos(n) * Math.sin(l) * Math.cos(a) ), d = r + Math.atan2( Math.sin(a) * Math.sin(l) * Math.cos(n), Math.cos(l) - Math.sin(n) * Math.sin(h) ), c = de(d), u = de(h); return s[2] !== void 0 ? he([c, u, s[2]], o.properties) : he([c, u], o.properties); } function nt(t, e, i = {}) { const o = i.steps || 64, s = i.properties ? i.properties : !Array.isArray(t) && t.type === "Feature" && t.properties ? t.properties : {}, r = []; for (let n = 0; n < o; n++) r.push( rt(t, e, n * -360 / o, i).geometry.coordinates ); return r.push(r[0]), We([r], s); } var st = nt; class ae { isTouchEventSupported = window !== void 0 && !!window.TouchEvent; plugin; map; source; collection; constructor(e, i, o) { this.plugin = e, this.map = i, this.source = o; } hasPolygon() { return !!this.collection?.features[0]; } getPolygon() { return this.collection.features[0]; } clonePolygon() { return this.getPolygon().geometry.coordinates[0].map((e) => [e[0], e[1]]); } isNearby(e, i, o) { const s = o ? this.plugin.options.pointerPrecision.touch : this.plugin.options.pointerPrecision.mouse, r = this.map.project(e); return Math.sqrt((i.x - r.x) ** 2 + (i.y - r.y) ** 2) <= s; } getMidpoint(e, i) { return [(e[0] + i[0]) / 2, (e[1] + i[1]) / 2]; } clear() { this.source?.setData({ type: "FeatureCollection", features: [] }); } render() { if (this.source) { if (this.plugin.options.minArea.size && this.collection?.features[0]) { const e = this.getAreaSize(this.collection.features[0]); this.collection.features[0].properties.area = e, this.collection.features[0].properties.tooSmall = e < this.plugin.options.minArea.size && !this.collection.features[0].properties.hasHelperVertex, this.collection.features[0].properties.minSizeLabel = this.plugin.options.minArea.label; } this.source.setData(this.collection ?? { type: "FeatureCollection", features: [] }); } } emitOnUpdate(e) { e ? this.plugin.options.onUpdate?.(e) : this.collection && this.plugin.options.onUpdate?.(this.collection.features[0]); } createCircle(e, i, o = 64) { const s = st( e, i, { units: "meters", steps: o, properties: { center: e, radius: i, meta: "circle", minSizeLabel: this.plugin.options.minArea.label } } ); return s.properties.area = this.getAreaSize(s), s.properties.tooSmall = s.properties.area < (this.plugin.options.minArea.size ?? -1), s; } // returns m² getAreaSize(e) { return e.properties.meta === "circle" && e.properties.radius ? Math.PI * Math.pow(e.properties.radius, 2) : tt(e); } isTouchEvent(e) { return this.isTouchEventSupported ? e.originalEvent instanceof TouchEvent : !1; } } const R = 11102230246251565e-32, S = 134217729, at = (3 + 8 * R) * R; function te(t, e, i, o, s) { let r, n, a, l, h = e[0], d = o[0], c = 0, u = 0; d > h == d > -h ? (r = h, h = e[++c]) : (r = d, d = o[++u]); let p = 0; if (c < t && u < i) for (d > h == d > -h ? (n = h + r, a = r - (n - h), h = e[++c]) : (n = d + r, a = r - (n - d), d = o[++u]), r = n, a !== 0 && (s[p++] = a); c < t && u < i; ) d > h == d > -h ? (n = r + h, l = n - r, a = r - (n - l) + (h - l), h = e[++c]) : (n = r + d, l = n - r, a = r - (n - l) + (d - l), d = o[++u]), r = n, a !== 0 && (s[p++] = a); for (; c < t; ) n = r + h, l = n - r, a = r - (n - l) + (h - l), h = e[++c], r = n, a !== 0 && (s[p++] = a); for (; u < i; ) n = r + d, l = n - r, a = r - (n - l) + (d - l), d = o[++u], r = n, a !== 0 && (s[p++] = a); return (r !== 0 || p === 0) && (s[p++] = r), p; } function lt(t, e) { let i = e[0]; for (let o = 1; o < t; o++) i += e[o]; return i; } function W(t) { return new Float64Array(t); } const ct = (3 + 16 * R) * R, ht = (2 + 12 * R) * R, ut = (9 + 64 * R) * R * R, F = W(4), ge = W(8), ye = W(12), ve = W(16), A = W(4); function dt(t, e, i, o, s, r, n) { let a, l, h, d, c, u, p, m, g, y, f, v, w, b, M, _, E, C; const O = t - s, T = i - s, x = e - r, k = o - r; b = O * k, u = S * O, p = u - (u - O), m = O - p, u = S * k, g = u - (u - k), y = k - g, M = m * y - (b - p * g - m * g - p * y), _ = x * T, u = S * x, p = u - (u - x), m = x - p, u = S * T, g = u - (u - T), y = T - g, E = m * y - (_ - p * g - m * g - p * y), f = M - E, c = M - f, F[0] = M - (f + c) + (c - E), v = b + f, c = v - b, w = b - (v - c) + (f - c), f = w - _, c = w - f, F[1] = w - (f + c) + (c - _), C = v + f, c = C - v, F[2] = v - (C - c) + (f - c), F[3] = C; let I = lt(4, F), G = ht * n; if (I >= G || -I >= G || (c = t - O, a = t - (O + c) + (c - s), c = i - T, h = i - (T + c) + (c - s), c = e - x, l = e - (x + c) + (c - r), c = o - k, d = o - (k + c) + (c - r), a === 0 && l === 0 && h === 0 && d === 0) || (G = ut * n + at * Math.abs(I), I += O * d + k * a - (x * h + T * l), I >= G || -I >= G)) return I; b = a * k, u = S * a, p = u - (u - a), m = a - p, u = S * k, g = u - (u - k), y = k - g, M = m * y - (b - p * g - m * g - p * y), _ = l * T, u = S * l, p = u - (u - l), m = l - p, u = S * T, g = u - (u - T), y = T - g, E = m * y - (_ - p * g - m * g - p * y), f = M - E, c = M - f, A[0] = M - (f + c) + (c - E), v = b + f, c = v - b, w = b - (v - c) + (f - c), f = w - _, c = w - f, A[1] = w - (f + c) + (c - _), C = v + f, c = C - v, A[2] = v - (C - c) + (f - c), A[3] = C; const De = te(4, F, 4, A, ge); b = O * d, u = S * O, p = u - (u - O), m = O - p, u = S * d, g = u - (u - d), y = d - g, M = m * y - (b - p * g - m * g - p * y), _ = x * h, u = S * x, p = u - (u - x), m = x - p, u = S * h, g = u - (u - h), y = h - g, E = m * y - (_ - p * g - m * g - p * y), f = M - E, c = M - f, A[0] = M - (f + c) + (c - E), v = b + f, c = v - b, w = b - (v - c) + (f - c), f = w - _, c = w - f, A[1] = w - (f + c) + (c - _), C = v + f, c = C - v, A[2] = v - (C - c) + (f - c), A[3] = C; const Ie = te(De, ge, 4, A, ye); b = a * d, u = S * a, p = u - (u - a), m = a - p, u = S * d, g = u - (u - d), y = d - g, M = m * y - (b - p * g - m * g - p * y), _ = l * h, u = S * l, p = u - (u - l), m = l - p, u = S * h, g = u - (u - h), y = h - g, E = m * y - (_ - p * g - m * g - p * y), f = M - E, c = M - f, A[0] = M - (f + c) + (c - E), v = b + f, c = v - b, w = b - (v - c) + (f - c), f = w - _, c = w - f, A[1] = w - (f + c) + (c - _), C = v + f, c = C - v, A[2] = v - (C - c) + (f - c), A[3] = C; const Ve = te(Ie, ye, 4, A, ve); return ve[Ve - 1]; } function pt(t, e, i, o, s, r) { const n = (e - r) * (i - s), a = (t - s) * (o - r), l = n - a, h = Math.abs(n + a); return Math.abs(l) >= ct * h ? l : -dt(t, e, i, o, s, r, h); } function ft(t, e) { var i, o, s = 0, r, n, a, l, h, d, c, u = t[0], p = t[1], m = e.length; for (i = 0; i < m; i++) { o = 0; var g = e[i], y = g.length - 1; if (d = g[0], d[0] !== g[y][0] && d[1] !== g[y][1]) throw new Error("First and last coordinates in a ring must be the same"); for (n = d[0] - u, a = d[1] - p, o; o < y; o++) { if (c = g[o + 1], l = c[0] - u, h = c[1] - p, a === 0 && h === 0) { if (l <= 0 && n >= 0 || n <= 0 && l >= 0) return 0; } else if (h >= 0 && a <= 0 || h <= 0 && a >= 0) { if (r = pt(n, l, a, h, 0, 0), r === 0) return 0; (r > 0 && h > 0 && a <= 0 || r < 0 && h <= 0 && a > 0) && s++; } d = c, a = h, n = l; } } return s % 2 !== 0; } function mt(t, e, i = {}) { if (!t) throw new Error("point is required"); if (!e) throw new Error("polygon is required"); const o = Z(t), s = it(e), r = s.type, n = e.bbox; let a = s.coordinates; if (n && gt(o, n) === !1) return !1; r === "Polygon" && (a = [a]); let l = !1; for (var h = 0; h < a.length; ++h) { const d = ft(o, a[h]); if (d === 0) return !i.ignoreBoundary; d && (l = !0); } return l; } function gt(t, e) { return e[0] <= t[0] && e[1] <= t[1] && e[2] >= t[0] && e[3] >= t[1]; } var J = mt; function yt(t, e, i = {}) { var o = Z(t), s = Z(e), r = U(s[1] - o[1]), n = U(s[0] - o[0]), a = U(o[1]), l = U(s[1]), h = Math.pow(Math.sin(r / 2), 2) + Math.pow(Math.sin(n / 2), 2) * Math.cos(a) * Math.cos(l); return Ye( 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h)), i.units ); } var oe = yt; class vt extends ae { _mode; _moveStart; _resizeAnker; constructor(e, i, o, s) { super(e, i, o), this.onClick = this.onClick.bind(this), this.onMouseMove = se(this.onMouseMove.bind(this), 16), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.setModel(s); } onClick(e) { if (this._mode) return; if (this.hasPolygon()) { const n = this.getPolygon(); if (J(e.lngLat.toArray(), n)) { e.preventDefault(); return; } } const i = e.lngLat.toArray(), o = this.map.unproject([e.point.x + this.plugin.options.circleMode.creationSize, e.point.y]), s = oe(i, o.toArray(), { units: "meters" }), r = this.createCircle(i, s); this.createFeatureCollection(r), this.generateVertices(), this.render(), this.emitOnUpdate(); } onMouseDown(e) { if (!this.collection?.features.length || e.points?.length > 1) return; for (let o = 0, s = this.collection.features[1].geometry.coordinates.length; o < s; o++) if (this.isNearby(this.collection.features[1].geometry.coordinates[o], e.point, this.isTouchEvent(e))) { e.preventDefault(), this._resizeAnker = o, this._mode = "resize"; return; } const i = this.getPolygon(); J(e.lngLat.toArray(), i) && (e.preventDefault(), this._moveStart = { polygon: this.clonePolygon(), point: [...i.properties.center], start: e.lngLat }, this._mode = "move"); } onMouseMove(e) { if (!this._mode || !this.collection?.features.length) return; let i; switch (this._mode) { case "move": if (!this._moveStart) return; e.preventDefault(), i = this.getPolygon(); const o = e.lngLat.lat - this._moveStart.start.lat, s = e.lngLat.lng - this._moveStart.start.lng; for (let n = 0, a = i.geometry.coordinates[0].length; n < a; n++) i.geometry.coordinates[0][n][1] = this._moveStart.polygon[n][1] + o, i.geometry.coordinates[0][n][0] = this._moveStart.polygon[n][0] + s; i.properties.center[1] = this._moveStart.point[1] + o, i.properties.center[0] = this._moveStart.point[0] + s, this.generateVertices(), this.render(); break; case "resize": if (!this._resizeAnker) return; e.preventDefault(), i = this.getPolygon(); const r = oe(i.properties.center, e.lngLat.toArray(), { units: "meters" }); i.geometry.coordinates[0] = this.createCircle(i.properties.center, r).geometry.coordinates[0], i.properties.radius = r, this.generateVertices(), this.render(); break; } } onMouseUp(e) { if (this._mode) switch (this._mode) { case "move": case "resize": e.preventDefault(), this._mode = void 0, this._moveStart = void 0, this._resizeAnker = void 0, this.emitOnUpdate(); break; } } generateVertices() { if (!this.collection) return; const e = this.getPolygon(), i = this.createCircle(e.properties.center, e.properties.radius, 4); this.collection.features[1].geometry.coordinates = i.geometry.coordinates[0].slice(0, -1); } createFeatureCollection(e) { this.collection = { type: "FeatureCollection", features: [ e, { type: "Feature", geometry: { type: "MultiPoint", coordinates: [] }, properties: { meta: "vertex" } } ] }; } register() { this.map.on("click", this.onClick), this.map.on("mousemove", this.onMouseMove), this.map.on("mousedown", this.onMouseDown), this.map.on("mouseup", this.onMouseUp), this.map.on("touchstart", this.onMouseDown), this.map.on("touchmove", this.onMouseMove), this.map.on("touchend", this.onMouseUp); } unregister() { this.map.off("click", this.onClick), this.map.off("mousemove", this.onMouseMove), this.map.off("mousedown", this.onMouseDown), this.map.off("mouseup", this.onMouseUp), this.map.off("touchstart", this.onMouseDown), this.map.off("touchmove", this.onMouseMove), this.map.off("touchend", this.onMouseUp); } setModel(e) { e?.properties?.meta === "circle" ? (this.createFeatureCollection(e), this.generateVertices()) : this.collection = void 0, this.render(); } onOptionsUpdate() { this.collection?.features[0] && (this.collection.features[0].properties.minSizeLabel = this.plugin.options.minArea.label); } } function H(t, e) { const i = document.createElement(t); return i.classList.add(e), i; } class bt extends ae { _model; _container; _circle; _widthContstraint; _heightConstraint; _minSizeLabel; constructor(e, i, o, s) { super(e, i, o), this.onViewportChangeEnd = this.onViewportChangeEnd.bind(this), this.onViewportChange = se(this.onViewportChange.bind(this), 100), this._model = s, this._container = H("div", "maplibregl-draw-circle-mode"), this._widthContstraint = H("div", "maplibregl-draw-circle-mode-width-constraint"), this._heightConstraint = H("div", "maplibregl-draw-circle-mode-height-constraint"), this._circle = H("div", "maplibregl-draw-circle-mode-circle"), this._circle.innerHTML = `<svg class="maplibre-draw-min-area-pattern" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> <defs> <pattern id="maplibre-draw-min-area-pattern" patternUnits="userSpaceOnUse" width="4.5" height="4.5" patternTransform="rotate(135)"> <line x1="0" y="0" x2="0" y2="4.5" stroke="currentColor" stroke-width="1" /> </pattern> </defs> <rect width="100%" height="100%" fill="url(#maplibre-draw-min-area-pattern)" :opacity="1" /> </svg>`, this._minSizeLabel = H("div", "maplibre-draw-circle-mode-below-min-area-size-label"), e.options.minArea.label && (this._minSizeLabel.textContent = e.options.minArea.label), this._container.appendChild(this._heightConstraint), this._heightConstraint.appendChild(this._widthContstraint), this._widthContstraint.appendChild(this._circle), this._circle.appendChild(this._minSizeLabel), this.setPadding(); } onViewportChange() { this._model = this.viewportToModel(), this._model.properties.tooSmall ? this._circle.classList.add("maplibregl-draw-circle-too-small") : this._circle.classList.remove("maplibregl-draw-circle-too-small"); } onViewportChangeEnd() { this._model = this.viewportToModel(), this.emitOnUpdate(this._model), this._model.properties.tooSmall ? this._circle.classList.add("maplibregl-draw-circle-too-small") : this._circle.classList.remove("maplibregl-draw-circle-too-small"); } viewportToModel() { const e = this._container.offsetLeft + this._circle.offsetLeft, i = this._container.offsetTop + this._circle.offsetTop, o = this.map.unproject([e + this._circle.offsetWidth / 2, i + this._circle.offsetHeight / 2]), s = this.map.unproject([e + this._circle.offsetWidth / 2, i]), r = o.toArray(), n = oe(s.toArray(), r, { units: "meters" }); return this.createCircle(r, n); } register() { this.map.getCanvasContainer().appendChild(this._container), this.map.on("dragend", this.onViewportChangeEnd), this.map.on("zoomend", this.onViewportChangeEnd), this.map.on("zoom", this.onViewportChange); } unregister() { this.map.getCanvasContainer().removeChild(this._container), this.map.off("dragend", this.onViewportChangeEnd), this.map.off("zoomend", this.onViewportChangeEnd), this.map.off("zoom", this.onViewportChange); } setModel(e) { e?.properties.meta === "circle" ? this._model = this.createCircle(e.properties.center, e.properties.radius) : this._model = void 0; } setPadding() { const e = this.plugin.options.fitBoundsOptions?.padding; switch (typeof e) { case "number": this._container.style.setProperty("--padding", `${e}px`); break; case "object": let i; for (i in e) typeof e[i] == "number" && this._container.style.setProperty(`--padding-${i}`, `${e[i]}px`); break; } } onOptionsUpdate() { this.plugin.options.minArea.label && (this._minSizeLabel.textContent = this.plugin.options.minArea.label); } } function be(t, e, i = {}) { const o = Z(t), s = q(e); for (let r = 0; r < s.length - 1; r++) { let n = !1; if (i.ignoreEndVertices && (r === 0 && (n = "start"), r === s.length - 2 && (n = "end"), r === 0 && r + 1 === s.length - 1 && (n = "both")), wt( s[r], s[r + 1], o, n, typeof i.epsilon > "u" ? null : i.epsilon )) return !0; } return !1; } function wt(t, e, i, o, s) { const r = i[0], n = i[1], a = t[0], l = t[1], h = e[0], d = e[1], c = i[0] - a, u = i[1] - l, p = h - a, m = d - l, g = c * m - u * p; if (s !== null) { if (Math.abs(g) > s) return !1; } else if (g !== 0) return !1; if (Math.abs(p) === Math.abs(m) && Math.abs(p) === 0) return o ? !1 : i[0] === t[0] && i[1] === t[1]; if (o) { if (o === "start") return Math.abs(p) >= Math.abs(m) ? p > 0 ? a < r && r <= h : h <= r && r < a : m > 0 ? l < n && n <= d : d <= n && n < l; if (o === "end") return Math.abs(p) >= Math.abs(m) ? p > 0 ? a <= r && r < h : h < r && r <= a : m > 0 ? l <= n && n < d : d < n && n <= l; if (o === "both") return Math.abs(p) >= Math.abs(m) ? p > 0 ? a < r && r < h : h < r && r < a : m > 0 ? l < n && n < d : d < n && n < l; } else return Math.abs(p) >= Math.abs(m) ? p > 0 ? a <= r && r <= h : h <= r && r <= a : m > 0 ? l <= n && n <= d : d <= n && n <= l; return !1; } function Mt(t, e = {}) { var i = typeof e == "object" ? e.mutate : e; if (!t) throw new Error("geojson is required"); var o = ot(t), s = []; switch (o) { case "LineString": s = ie(t, o); break; case "MultiLineString": case "Polygon": q(t).forEach(function(n) { s.push(ie(n, o)); }); break; case "MultiPolygon": q(t).forEach(function(n) { var a = []; n.forEach(function(l) { a.push(ie(l, o)); }), s.push(a); }); break; case "Point": return t; case "MultiPoint": var r = {}; q(t).forEach(function(n) { var a = n.join("-"); Object.prototype.hasOwnProperty.call(r, a) || (s.push(n), r[a] = !0); }); break; default: throw new Error(o + " geometry not supported"); } return t.coordinates ? i === !0 ? (t.coordinates = s, t) : { type: o, coordinates: s } : i === !0 ? (t.geometry.coordinates = s, t) : Q({ type: o, coordinates: s }, t.properties, { bbox: t.bbox, id: t.id }); } function ie(t, e) { const i = q(t); if (i.length === 2 && !we(i[0], i[1])) return i; const o = []; let s = 0, r = 1, n = 2; for (o.push(i[s]); n < i.length; ) be(i[r], ue([i[s], i[n]])) ? r = n : (o.push(i[r]), s = r, r++, n = r), n++; if (o.push(i[r]), e === "Polygon" || e === "MultiPolygon") { if (be( o[0], ue([o[1], o[o.length - 2]]) ) && (o.shift(), o.pop(), o.push(o[0])), o.length < 4) throw new Error("invalid polygon, fewer than 4 points"); if (!we(o[0], o[o.length - 1])) throw new Error("invalid polygon, first and last points not equal"); } return o; } function we(t, e) { return t[0] === e[0] && t[1] === e[1]; } function Te(t) { if (!t) throw new Error("geojson is required"); switch (t.type) { case "Feature": return xe(t); case "FeatureCollection": return _t(t); case "Point": case "LineString": case "Polygon": case "MultiPoint": case "MultiLineString": case "MultiPolygon": case "GeometryCollection": return le(t); default: throw new Error("unknown GeoJSON type"); } } function xe(t) { const e = { type: "Feature" }; return Object.keys(t).forEach((i) => { switch (i) { case "type": case "properties": case "geometry": return; default: e[i] = t[i]; } }), e.properties = ke(t.properties), t.geometry == null ? e.geometry = null : e.geometry = le(t.geometry), e; } function ke(t) { const e = {}; return t && Object.keys(t).forEach((i) => { const o = t[i]; typeof o == "object" ? o === null ? e[i] = null : Array.isArray(o) ? e[i] = o.map((s) => s) : e[i] = ke(o) : e[i] = o; }), e; } function _t(t) { const e = { type: "FeatureCollection" }; return Object.keys(t).forEach((i) => { switch (i) { case "type": case "features": return; default: e[i] = t[i]; } }), e.features = t.features.map((i) => xe(i)), e; } function le(t) { const e = { type: t.type }; return t.bbox && (e.bbox = t.bbox), t.type === "GeometryCollection" ? (e.geometries = t.geometries.map((i) => le(i)), e) : (e.coordinates = ze(t.coordinates), e); } function ze(t) { const e = t; return typeof e[0] != "object" ? e.slice() : e.map((i) => ze(i)); } var Ct = Te; function St(t, e) { var i = t[0] - e[0], o = t[1] - e[1]; return i * i + o * o; } function At(t, e, i) { var o = e[0], s = e[1], r = i[0] - o, n = i[1] - s; if (r !== 0 || n !== 0) { var a = ((t[0] - o) * r + (t[1] - s) * n) / (r * r + n * n); a > 1 ? (o = i[0], s = i[1]) : a > 0 && (o += r * a, s += n * a); } return r = t[0] - o, n = t[1] - s, r * r + n * n; } function Pt(t, e) { for (var i = t[0], o = [i], s, r = 1, n = t.length; r < n; r++) s = t[r], St(s, i) > e && (o.push(s), i = s); return i !== s && o.push(s), o; } function re(t, e, i, o, s) { for (var r = o, n, a = e + 1; a < i; a++) { var l = At(t[a], t[e], t[i]); l > r && (n = a, r = l); } r > o && (n - e > 1 && re(t, e, n, o, s), s.push(t[n]), i - n > 1 && re(t, n, i, o, s)); } function Lt(t, e) { var i = t.length - 1, o = [t[0]]; return re(t, 0, i, e, o), o.push(t[i]), o; } function X(t, e, i) { if (t.length <= 2) return t; var o = e !== void 0 ? e * e : 1; return t = i ? t : Pt(t, o), t = Lt(t, o), t; } function Et(t, e = {}) { var i, o, s; if (e = e ?? {}, !Xe(e)) throw new Error("options is invalid"); const r = (i = e.tolerance) != null ? i : 1, n = (o = e.highQuality) != null ? o : !1, a = (s = e.mutate) != null ? s : !1; if (!t) throw new Error("geojson is required"); if (r && r < 0) throw new Error("invalid tolerance"); return a !== !0 && (t = Te(t)), Oe(t, function(l) { Ot(l, r, n); }), t; } function Ot(t, e, i) { const o = t.type; if (o === "Point" || o === "MultiPoint") return t; if (Mt(t, { mutate: !0 }), o !== "GeometryCollection") switch (o) { case "LineString": t.coordinates = X( t.coordinates, e, i ); break; case "MultiLineString": t.coordinates = t.coordinates.map( (s) => X(s, e, i) ); break; case "Polygon": t.coordinates = Me( t.coordinates, e, i ); break; case "MultiPolygon": t.coordinates = t.coordinates.map( (s) => Me(s, e, i) ); } return t; } function Me(t, e, i) { return t.map(function(o) { if (o.length < 4) throw new Error("invalid polygon"); let s = e, r = X(o, s, i); for (; !_e(r) && s >= Number.EPSILON; ) s -= s * 0.01, r = X(o, s, i); return _e(r) ? ((r[r.length - 1][0] !== r[0][0] || r[r.length - 1][1] !== r[0][1]) && r.push(r[0]), r) : o; }); } function _e(t) { return t.length < 3 ? !1 : !(t.length === 3 && t[2][0] === t[0][0] && t[2][1] === t[0][1]); } var Tt = Et; class xt extends ae { _mode; _moveStart; constructor(e, i, o, s) { super(e, i, o), this.onClick = this.onClick.bind(this), this.onDoubleClick = this.onDoubleClick.bind(this), this.onMouseMove = se(this.onMouseMove.bind(this), 16), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.setModel(s); } onClick(e) { const i = e.lngLat.toArray(); let o; switch (this._mode) { case "create": if (o = this.getPolygon(), this.isNearby(o.geometry.coordinates[0][0], e.point, this.isTouchEvent(e))) { this.getPolygon().geometry.coordinates[0].splice(1, 1), this.endCreation(); return; } o.geometry.coordinates[0].splice(1, 0, i), this.collection.features[1].geometry.coordinates[1] = i; const s = o.geometry.coordinates[0].length, r = s - 2; o.properties.hasHelperVertex && s === 5 && (o.geometry.coordinates[0].splice(r, 1), o.properties.hasHelperVertex = !1); break; default: if (e.originalEvent.ctrlKey && this.collection) { e.preventDefault(); const n = this.getPolygon(), a = n.geometry.coordinates[0].length; if (a < 5) return; for (let l = 0; l < a; l++) if (this.isNearby(n.geometry.coordinates[0][l], e.point, this.isTouchEvent(e))) { n.geometry.coordinates[0].splice(l, 1), l === 0 && (n.geometry.coordinates[0].splice(-1, 1), n.geometry.coordinates[0].push(n.geometry.coordinates[0][0])), this.generateCollectionWithVertexes(), this.source?.setData(this.collection), this.emitOnUpdate(); return; } } if (this.hasPolygon() && (o = this.getPolygon(), J(e.lngLat.toArray(), o))) { e.preventDefault(); return; } this.createFeatureCollection({ type: "Feature", geometry: { type: "Polygon", coordinates: [[i, i, i, i]] }, properties: { meta: "polygon", hasHelperVertex: !0 } }), this.collection.features[1].geometry.coordinates = [i, i], this._mode = "create"; } this.render(); } onDoubleClick(e) { !this._mode || !this.collection || this._mode === "create" && (e.preventDefault(), this.endCreation()); } onMouseMove(e) { if (!this._mode || !this.collection?.features.length) return; let i, o; switch (this._mode) { case "create": e.preventDefault(), i = this.getPolygon(), o = e.lngLat.toArray(); const s = i.geometry.coordinates[0].length, r = s - 2; if (i.geometry.coordinates[0][1] = o, i.properties.hasHelperVertex) { const l = this.map.unproject([e.point.x + 1, e.point.y]), h = Math.abs((l.lng - o[0]) / 3); i.geometry.coordinates[0][r] = this.calculateB(o, i.geometry.coordinates[0][0], h); } this.render(); break; case "move": if (!this._moveStart) return; e.preventDefault(), i = this.getPolygon(); const n = e.lngLat.lng - this._moveStart.start.lng, a = e.lngLat.lat - this._moveStart.start.lat; for (let l = 0, h = i.geometry.coordinates[0].length; l < h; l++) i.geometry.coordinates[0][l][0] = this._moveStart.polygon[l][0] + n, i.geometry.coordinates[0][l][1] = this._moveStart.polygon[l][1] + a; this.generateCollectionWithVertexes(), this.render(); break; case "move_vertex": if (!this._moveStart) return; e.preventDefault(), i = this.getPolygon(), o = e.lngLat.toArray(); for (let l = 0, h = i.geometry.coordinates[0].length; l < h; l++) if (this._moveStart.polygon[l][0] === this._moveStart.point[0] && this._moveStart.polygon[l][1] === this._moveStart.point[1]) { i.geometry.coordinates[0][l] = o, l === 0 && (i.geometry.coordinates[0][i.geometry.coordinates[0].length - 1] = o); break; } this.generateCollectionWithVertexes(), this.render(); break; case "add_vertex": if (!this._moveStart) return; e.preventDefault(), i = this.getPolygon(), o = e.lngLat.toArray(); for (let l = 0, h = i.geometry.coordinates[0].length; l < h - 1; l++) { const d = this.getMidpoint(i.geometry.coordinates[0][l], i.geometry.coordinates[0][l + 1]); if (d[0] === this._moveStart.point[0] && d[1] === this._moveStart.point[1]) { i.geometry.coordinates[0].splice(l + 1, 0, d), this._moveStart = { polygon: this.clonePolygon(), point: d, start: e.lngLat }, this._mode = "move_vertex"; break; } } this.generateCollectionWithVertexes(), this.render(); break; } } onMouseDown(e) { if (this._mode === "create" || !this.collection?.features.length || e.points?.length > 1) return; for (let o = 0, s = this.collection.features[1].geometry.coordinates.length; o < s; o++) if (this.isNearby(this.collection.features[1].geometry.coordinates[o], e.point, this.isTouchEvent(e))) { e.preventDefault(), this._moveStart = { polygon: this.clonePolygon(), point: this.collection.features[1].geometry.coordinates[o], start: e.lngLat }, this._mode = "move_vertex"; return; } for (let o = 0, s = this.collection.features[2].geometry.coordinates.length; o < s; o++) if (this.isNearby(this.collection.features[2].geometry.coordinates[o], e.point, this.isTouchEvent(e))) { e.preventDefault(), this._moveStart = { polygon: this.clonePolygon(), point: this.collection.features[2].geometry.coordinates[o], start: e.lngLat }, this._mode = "add_vertex"; return; } const i = this.getPolygon(); J(e.lngLat.toArray(), i) && (e.preventDefault(), this._moveStart = { polygon: this.clonePolygon(), start: e.lngLat }, this._mode = "move"); } onMouseUp(e) { if (this._mode) switch (this._mode) { case "move": case "move_vertex": case "add_vertex": e.preventDefault(), this._mode = void 0, this._moveStart = void 0, e.originalEvent.ctrlKey || this.emitOnUpdate(); break; } } register() { this.map.on("click", this.onClick), this.map.on("dblclick", this.onDoubleClick), this.map.on("mousemove", this.onMouseMove), this.map.on("mousedown", this.onMouseDown), this.map.on("mouseup", this.onMouseUp), this.map.on("touchstart", this.onMouseDown), this.map.on("touchmove", this.onMouseMove), this.map.on("touchend", this.onMouseUp); } unregister() { this.map.off("click", this.onClick), this.map.off("dblclick", this.onDoubleClick), this.map.off("mousemove", this.onMouseMove), this.map.off("mousedown", this.onMouseDown), this.map.off("mouseup", this.onMouseUp), this.map.off("touchstart", this.onMouseDown), this.map.off("touchmove", this.onMouseMove), this.map.off("touchend", this.onMouseUp); } setModel(e) { e?.properties?.meta === "polygon" ? (this.createFeatureCollection(e), this.generateCollectionWithVertexes()) : this.collection = void 0, this.render(); } onOptionsUpdate() { this.collection?.features[0] && (this.collection.features[0].properties.minSizeLabel = this.plugin.options.minArea.label); } createFeatureCollection(e) { this.collection = { type: "FeatureCollection", features: [ e, { type: "Feature", geometry: { type: "MultiPoint", coordinates: [] }, properties: { meta: "vertex" } }, { type: "Feature", geometry: { type: "MultiPoint", coordinates: [] }, properties: { meta: "midpoint" } } ] }; } endCreation() { const e = this.getPolygon(); this._mode = void 0, this.collection.features[0] = Tt(e, { tolerance: 1e-5, highQuality: !0 }), this.generateCollectionWithVertexes(), this.render(), this.emitOnUpdate(); } generateCollectionWithVertexes() { if (!this.collection) return; const e = this.getPolygon(), i = e.geometry.coordinates[0].length; this.collection.features[1].geometry.coordinates = e.geometry.coordinates[0].slice(0, -1); const o = new Array(i - 1); for (let s = 0; s < i - 1; s++) o[s] = this.getMidpoint(e.geometry.coordinates[0][s], e.geometry.coordinates[0][s + 1]); this.collection.features[2].geometry.coordinates = o; } calculateB(e, i, o) { const s = e[0] - i[0], r = e[1] - i[1], n = Math.sqrt(s * s + r * r), a = i[0] + o * (-r / n), l = i[1] + o * (s / n); return [a, l]; } } const kt = [ // ACTIVE (being drawn) // line stroke { id: "gl-draw-line", type: "line", filter: ["all", ["==", "$type", "LineString"], ["!=", "mode", "static"]], layout: { "line-cap": "round", "line-join": "round" }, paint: { "line-color": "#e74b3c", "line-dasharray": [0.2, 2], "line-width": 2 } }, // polygon fill { id: "gl-draw-polygon-fill", type: "fill", filter: ["all", ["==", "$type", "Polygon"], ["!=", "mode", "static"]], paint: { "fill-color": "#3c99e7", "fill-outline-color": "#3c99e7", "fill-opacity": 0.1 } }, // polygon fill below min area size { id: "gl-draw-polygon-fill-below-min-area-size", type: "fill", filter: ["all", ["==", "$type", "Polygon"], ["==", "tooSmall", !0]], paint: { "fill-pattern": "maplibre-draw-min-area-pattern" } }, // polygon label below min area size { id: "gl-draw-polygon-fill-below-min-area-size-label", type: "symbol", filter: ["all", ["==", "$type", "Polygon"], ["==", "tooSmall", !0], ["has", "minSizeLabel"]], layout: { "text-field": ["get", "minSizeLabel"], "text-font": ["Open Sans Bold"], "text-size": 24, "text-justify": "center", "text-anchor": "center" }, paint: { "text-color": "#e74b3c", "text-halo-color": "#fff", "text-halo-width": 3 } }, // polygon mid points { id: "gl-draw-polygon-midpoint", type: "circle", filter: [ "all", ["==", "$type", "Point"], ["==", "meta", "midpoint"] ], paint: { "circle-radius": 4, "circle-color": "#e74b3c" } }, // polygon outline stroke // This doesn't style the first edge of the polygon, which uses the line stroke styling instead { id: "gl-draw-polygon-stroke-active", type: "line", filter: ["all", ["==", "$type", "Polygon"], ["!=", "mode", "static"]], layout: { "line-cap": "round", "line-join": "round" }, paint: { "line-color": "#e74b3c", "line-dasharray": [0.2, 2], "line-width": 2 } }, // vertex point halos { id: "gl-draw-polygon-and-line-vertex-halo-active", type: "circle", filter: ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["!=", "mode", "static"]], paint: { "circle-radius": 8, "circle-color": "#FFF" } }, // vertex points { id: "gl-draw-polygon-and-line-vertex-active", type: "circle", filter: ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["!=", "mode", "static"]], paint: { "circle-radius": 5, "circle-color": "#e74b3c" } }, // INACTIVE (static, already drawn) // line stroke { id: "gl-draw-line-static", type: "line", filter: ["all", ["==", "$type", "LineString"], ["==", "mode", "static"]], layout: { "line-cap": "round", "line-join": "round" }, paint: { "line-color": "#000", "line-width": 3 } }, // polygon fill { id: "gl-draw-polygon-fill-static", type: "fill", filter: ["all", ["==", "$type", "Polygon"], ["=