UNPKG

maplibre-gl-indoor

Version:

A MapLibre plugin to visualize multi-level buildings

1,467 lines (1,466 loc) 39.9 kB
var $ = Object.defineProperty; var j = (o, e, t) => e in o ? $(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t; var n = (o, e, t) => j(o, typeof e != "symbol" ? e + "" : e, t); var p = 63710088e-1, R = { 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(o, e, t = {}) { const i = { type: "Feature" }; return (t.id === 0 || t.id) && (i.id = t.id), t.bbox && (i.bbox = t.bbox), i.properties = e || {}, i.geometry = o, i; } function Y(o, e, t = {}) { if (!o) throw new Error("coordinates is required"); if (!Array.isArray(o)) throw new Error("coordinates must be an Array"); if (o.length < 2) throw new Error("coordinates must be at least 2 numbers long"); if (!S(o[0]) || !S(o[1])) throw new Error("coordinates must contain numbers"); return q({ type: "Point", coordinates: o }, e, t); } function Z(o, e = "kilometers") { const t = R[e]; if (!t) throw new Error(e + " units is invalid"); return o * t; } function V(o, e = "kilometers") { const t = R[e]; if (!t) throw new Error(e + " units is invalid"); return o / t; } function E(o) { return o % (2 * Math.PI) * 180 / Math.PI; } function g(o) { return o % 360 * Math.PI / 180; } function S(o) { return !isNaN(o) && o !== null && !Array.isArray(o); } function b(o) { if (!o) throw new Error("coord is required"); if (!Array.isArray(o)) { if (o.type === "Feature" && o.geometry !== null && o.geometry.type === "Point") return [...o.geometry.coordinates]; if (o.type === "Point") return [...o.coordinates]; } if (Array.isArray(o) && o.length >= 2 && !Array.isArray(o[0]) && !Array.isArray(o[1])) return [...o]; throw new Error("coord must be GeoJSON Point or an Array of numbers"); } function X(o, e, t = {}) { var i = b(o), r = b(e), s = g(r[1] - i[1]), a = g(r[0] - i[0]), d = g(i[1]), l = g(r[1]), c = Math.pow(Math.sin(s / 2), 2) + Math.pow(Math.sin(a / 2), 2) * Math.cos(d) * Math.cos(l); return Z( 2 * Math.atan2(Math.sqrt(c), Math.sqrt(1 - c)), t.units ); } var L = X; function k(o) { const [e, t, i, r] = o; return [(e + i) / 2, (t + r) / 2]; } function P(o, e) { const [t, i, r, s] = o, [a, d] = e, l = i <= d && d <= s; let c = t <= a && a <= r; return t > r && (c = t >= a && a >= r), l && c; } function J(o, e) { return o[0] > e[2] || e[0] > o[2] ? !1 : !(o[3] < e[1] || e[3] < o[1]); } function K(o, e, t = !1) { return t ? [ "all", o, ["any", ["!", ["has", "level"]], B(e)] ] : ["all", o, B(e)]; } function B(o) { return [ "all", [ // level=MIN~... => if LEVEL <= current_level, we can display "<=", [ "to-number", ["slice", ["get", "level"], 0, ["index-of", "~", ["get", "level"]]] ], o ], [ // level=...~MAX => if LEVEL >= current_level, we can display ">=", [ "to-number", [ "slice", ["get", "level"], ["+", ["index-of", "~", ["get", "level"]], 1] ] ], o ] ]; } const C = "indoor"; class Q { constructor(e) { n(this, "_indoorMaps"); n(this, "_level"); n(this, "_map"); n(this, "_mapLoadedPromise"); n(this, "_previousSelectedLevel"); n(this, "_previousSelectedMap"); n(this, "_savedFilters"); n(this, "_selectedMap"); n(this, "_updateMapPromise"); this._map = e, this._level = null, this._indoorMaps = [], this._savedFilters = [], this._selectedMap = null, this._previousSelectedMap = null, this._previousSelectedLevel = null, this._updateMapPromise = Promise.resolve(), this._map.loaded() ? this._mapLoadedPromise = Promise.resolve() : this._mapLoadedPromise = new Promise( (t) => this._map.on("load", t) ), this._map.on("moveend", () => this._updateSelectedMapIfNeeded()); } _addLayerForFiltering(e, t) { this._map.addLayer(e, t), this._savedFilters.push({ filter: this._map.getFilter(e.id) || [ "all" ], layerId: e.id }); } _closestMap() { if (this._map.getZoom() < 16.5) return null; const e = this._map.getBounds(), t = [ e.getWest(), e.getSouth(), e.getEast(), e.getNorth() ], i = this._indoorMaps.filter( (a) => J(a.bounds, t) ); if (i.length === 0) return null; if (i.length === 1) return i[0]; let r = Number.POSITIVE_INFINITY, s = i[0]; for (const a of i) { const d = L( k(a.bounds), k(t) ); d < r && (s = a, r = d); } return s; } _removeLayerForFiltering(e) { this._savedFilters = this._savedFilters.filter( ({ layerId: t }) => e !== t ), this._map.removeLayer(e); } /** * *********************** * Handle level change * *********************** */ _updateFiltering() { const e = this._level; let t; if (e !== null) { const i = this._selectedMap ? this._selectedMap.showFeaturesWithEmptyLevel : !1; t = (r) => K(r, e, i); } else t = (i) => i; this._savedFilters.forEach(({ filter: i, layerId: r }) => { this._map.setFilter(r, t(i)); }); } _updateSelectedMap(e) { const t = this._selectedMap; if (t !== null && (t.layersToHide.forEach( (l) => this._map.setLayoutProperty(l, "visibility", "visible") ), t.layers.forEach(({ id: l }) => this._removeLayerForFiltering(l)), this._map.removeSource(C), e || (this._previousSelectedLevel = this._level, this._previousSelectedMap = t), this.setLevel(null, !1), this._map.fire("indoor.map.unloaded", { indoorMap: t })), this._selectedMap = e, !e) return; const { beforeLayerId: i, geojson: r, layers: s, levelsRange: a } = e; this._map.addSource(C, { data: r, lineMetrics: !0, type: "geojson" }), s.forEach((l) => this._addLayerForFiltering(l, i)), e.layersToHide.forEach( (l) => this._map.setLayoutProperty(l, "visibility", "none") ); const d = this._previousSelectedMap === e ? this._previousSelectedLevel : Math.max( Math.min(e.defaultLevel, a.max), a.min ); this.setLevel(d, !1), this._map.fire("indoor.map.loaded", { indoorMap: e }); } async _updateSelectedMapIfNeeded() { await this._mapLoadedPromise, await this._updateMapPromise, this._updateMapPromise = (async () => { const e = this._closestMap(); e !== this._selectedMap && this._updateSelectedMap(e); })(), await this._updateMapPromise; } addLayerForFiltering(e, t) { this._addLayerForFiltering(e, t), this._updateFiltering(); } async addMap(e) { this._indoorMaps.push(e), await this._updateSelectedMapIfNeeded(); } /** * ************** * Handle maps * ************** */ getLevel() { return this._level; } getSelectedMap() { return this._selectedMap; } removeLayerForFiltering(e) { this._removeLayerForFiltering(e), this._updateFiltering(); } async removeMap(e) { this._indoorMaps = this._indoorMaps.filter( (t) => t !== e ), await this._updateSelectedMapIfNeeded(); } setLevel(e, t = !0) { if (this._selectedMap === null) throw new Error("Cannot set level, no map has been selected"); this._level = e, this._updateFiltering(), t && this._map.fire("indoor.level.changed", { level: e }); } } function ee(o) { return Object.defineProperty(o, "indoor", { get: function() { return this._indoor || (this._indoor = new Q(this)), this._indoor; } }), o; } class me { constructor() { n(this, "_container"); n(this, "_indoor"); n(this, "_indoorMap"); n(this, "_levelsButtons"); n(this, "_map"); n(this, "_selectedButton"); n(this, "_onLevelChanged", ({ level: e }) => this._setSelected(e)); n(this, "_onMapLoaded", ({ indoorMap: e }) => { this._indoorMap = e, this._updateNavigationBar(), this._setSelected(this._indoor.getLevel()); }); n(this, "_onMapUnLoaded", () => { this._indoorMap = null, this._updateNavigationBar(); }); this._levelsButtons = [], this._selectedButton = null, this._indoorMap = null; } _createLevelButton(e, t) { const i = document.createElement("button"); return i.innerHTML = t.toString(), i.classList.add("maplibregl-ctrl-icon"), e.appendChild(i), i.addEventListener("click", () => { var r; (r = this._map) == null || r.fire("indoor.control.clicked", { level: t }), this._indoor.getLevel() !== t && this._indoor.setLevel(t); }), i; } _onContextMenu(e) { e.preventDefault(); } _setSelected(e) { this._levelsButtons.length !== 0 && (this._selectedButton && (this._selectedButton.style.fontWeight = "normal"), e !== null && this._levelsButtons[e] && (this._levelsButtons[e].style.fontWeight = "bold", this._selectedButton = this._levelsButtons[e])); } _updateNavigationBar() { if (!this._container) return; if (this._indoorMap === null) { this._container.style.display = "none"; return; } for (this._container.style.display = "block", this._levelsButtons = []; this._container.firstChild; ) this._container.removeChild(this._container.firstChild); const e = this._indoorMap.levelsRange; for (let t = e.max; t >= e.min; t--) this._levelsButtons[t] = this._createLevelButton(this._container, t); } onAdd(e) { if (e.indoor === void 0) throw Error("call addIndoorTo(map) before creating the IndoorControl"); this._map = e, this._indoor = this._map.indoor; const t = this._container = document.createElement("div"); return t.classList.add("maplibregl-ctrl"), t.classList.add("maplibregl-ctrl-group"), t.style.display = "none", t.addEventListener("contextmenu", this._onContextMenu), this._indoorMap = this._indoor.getSelectedMap(), this._indoor.getSelectedMap() !== null && (this._updateNavigationBar(), this._setSelected(this._indoor.getLevel())), this._map.on("indoor.map.loaded", this._onMapLoaded), this._map.on("indoor.map.unloaded", this._onMapUnLoaded), this._map.on("indoor.level.changed", this._onLevelChanged), t; } onRemove() { var e, t, i, r, s; (e = this._container) == null || e.removeEventListener("contextmenu", this._onContextMenu), (t = this._container) == null || t.remove(), delete this._container, (i = this._map) == null || i.off("indoor.map.loaded", this._onMapLoaded), (r = this._map) == null || r.off("indoor.map.unloaded", this._onMapUnLoaded), (s = this._map) == null || s.off("indoor.level.changed", this._onLevelChanged), delete this._map; } } function D(o, e, t) { if (o !== null) for (var i, r, s, a, d, l, c, u = 0, h = 0, v, x = o.type, F = x === "FeatureCollection", H = x === "Feature", U = F ? o.features.length : 1, f = 0; f < U; f++) { c = F ? o.features[f].geometry : H ? o.geometry : o, v = c ? c.type === "GeometryCollection" : !1, d = v ? c.geometries.length : 1; for (var w = 0; w < d; w++) { var m = 0, y = 0; if (a = v ? c.geometries[w] : c, a !== null) { l = a.coordinates; var _ = a.type; switch (u = 0, _) { case null: break; case "Point": if (e( l, h, f, m, y ) === !1) return !1; h++, m++; break; case "LineString": case "MultiPoint": for (i = 0; i < l.length; i++) { if (e( l[i], h, f, m, y ) === !1) return !1; h++, _ === "MultiPoint" && m++; } _ === "LineString" && m++; break; case "Polygon": case "MultiLineString": for (i = 0; i < l.length; i++) { for (r = 0; r < l[i].length - u; r++) { if (e( l[i][r], h, f, m, y ) === !1) return !1; h++; } _ === "MultiLineString" && m++, _ === "Polygon" && y++; } _ === "Polygon" && m++; break; case "MultiPolygon": for (i = 0; i < l.length; i++) { for (y = 0, r = 0; r < l[i].length; r++) { for (s = 0; s < l[i][r].length - u; s++) { if (e( l[i][r][s], h, f, m, y ) === !1) return !1; h++; } y++; } m++; } break; case "GeometryCollection": for (i = 0; i < a.geometries.length; i++) if (D(a.geometries[i], e) === !1) return !1; break; default: throw new Error("Unknown Geometry Type"); } } } } } function te(o, e = {}) { if (o.bbox != null && e.recompute !== !0) return o.bbox; const t = [1 / 0, 1 / 0, -1 / 0, -1 / 0]; return D(o, (i) => { t[0] > i[0] && (t[0] = i[0]), t[1] > i[1] && (t[1] = i[1]), t[2] < i[0] && (t[2] = i[0]), t[3] < i[1] && (t[3] = i[1]); }), t; } var oe = te; function ie(o) { const e = o.split(";").map(ae).filter((t) => t !== null); return e.length ? { max: Math.max(...e.map((t) => t.max)), min: Math.min(...e.map((t) => t.min)) } : null; } function re(o) { if (o.type !== "FeatureCollection") throw new Error( o.type + " is not allowed as a top level collection, please use FeatureCollection instead." ); const e = o.features.filter( (t) => !!t.properties && typeof t.properties.level == "string" ).map((t) => { var i; return ie(((i = t.properties) == null ? void 0 : i.level) ?? ""); }).filter((t) => t !== null); if (e.length == 0) throw console.debug(o), new Error( "the FeatureCollection does not contain a single level. Cannot compute the range of levels to display" ); return { bounds: oe(o), levelsRange: { max: Math.max(...e.map((t) => t.max)), min: Math.min(...e.map((t) => t.min)) } }; } function ae(o) { const e = o.split("~"), t = { max: parseFloat(e[1]), min: parseFloat(e[0]) }; return isNaN(t.min) || isNaN(t.max) ? null : t; } const I = [ { filter: ["any", ["has", "building"], ["has", "building:part"]], id: "buildings-background", minzoom: 16.5, paint: { "fill-color": "#FFFFFF", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, // unsure if the level is not better displayed :shrug: .. // { // filter: ["==", ["get", "indoor"], "level"], // id: "indoor-level", // minzoom: 16.5, // paint: { // "fill-color": "#b9e1ff", // "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], // }, // source: "indoor", // type: "fill", // }, { filter: ["==", ["get", "leisure"], "garden"], id: "indoor-gardens", minzoom: 16.5, paint: { "fill-color": "#D8E5A4", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: ["==", ["get", "amenity"], "parking"], id: "indoor-parkings", minzoom: 16.5, paint: { "fill-color": "#fbeada", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "fill-outline-color": "#000000" }, source: "indoor", type: "fill" }, { filter: ["==", ["get", "amenity"], "parking"], id: "indoor-parkings-patterns", minzoom: 16.5, paint: { "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 0.1], "fill-pattern": "si-main-3", "fill-translate-anchor": "viewport" }, source: "indoor", type: "fill" }, { filter: [ "any", ["==", ["get", "indoor"], "room"], ["==", ["get", "indoor"], "area"], ["==", ["get", "railway"], "platform"] ], id: "indoor-rooms", minzoom: 16.5, paint: { "fill-color": "#e0e0e0", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: [ "all", [ "any", ["==", ["get", "indoor"], "room"], ["==", ["get", "indoor"], "area"], ["==", ["get", "railway"], "platform"] ], ["==", ["get", "access"], "no"] ], id: "indoor-rooms-no-access", minzoom: 16.5, paint: { "fill-color": "#878787", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: [ "any", ["==", ["get", "indoor"], "room"], ["==", ["get", "indoor"], "area"], ["==", ["get", "railway"], "platform"] ], id: "indoor-rooms-walls", minzoom: 16.5, paint: { "line-color": "#000", "line-offset": 1, "line-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "line" }, { filter: ["==", ["get", "indoor"], "room"], id: "indoor-rooms-borders", minzoom: 16.5, paint: { "line-color": "#000", "line-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "line" }, { filter: [ "all", ["any", ["==", ["get", "indoor"], "door"], ["has", "door"]], ["!", ["has", "entrance"]], ["!=", ["get", "access"], "no"] ], id: "indoor-doors", minzoom: 16.5, paint: { "circle-color": "#e0e0e0", "circle-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "circle-radius": [ "interpolate", ["exponential", 2], ["zoom"], 10, ["*", ["*", 0.5, ["number", ["get", "width"], 1.6]], ["^", 2, -6]], 24, ["*", ["*", 0.5, ["number", ["get", "width"], 1.6]], ["^", 2, 8]] ] }, source: "indoor", type: "circle" }, { filter: ["==", ["get", "highway"], "pedestrian"], id: "indoor-highways-area", paint: { "fill-color": [ "interpolate", ["linear"], ["zoom"], 16, "hsl(230, 16%, 94%)", 16.25, "hsl(230, 50%, 98%)" ], "fill-opacity": 1, "fill-outline-color": "hsl(230, 26%, 88%)" }, source: "indoor", type: "fill" }, { filter: ["==", ["get", "highway"], "pedestrian"], id: "indoor-highways-area-pattern", minzoom: 16.5, paint: { "fill-color": "hsl(0, 0%, 100%)", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "fill-outline-color": "hsl(35, 10%, 83%)", "fill-pattern": "pedestrian-polygon" }, source: "indoor", type: "fill" }, { filter: [ "any", ["==", ["get", "indoor"], "corridor"], ["==", ["get", "room"], "stairs"] ], id: "indoor-corridors", minzoom: 16.5, paint: { "fill-color": "#b9e1ff", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: ["==", ["get", "indoor"], "area"], id: "indoor-area", minzoom: 16.5, paint: { "fill-antialias": !0, // otherwise the outline is invisible sometimes.., "fill-color": "#8dd1fc", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "fill-outline-color": "#000" }, source: "indoor", type: "fill" }, { filter: [ "all", ["==", ["get", "indoor"], "area"], ["==", ["get", "balcony"], "yes"] ], id: "indoor-balcony", minzoom: 16.5, paint: { "fill-color": "#BDBDBD", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: [ "any", ["==", ["get", "elevator"], "yes"], ["==", ["get", "highway"], "elevator"] ], id: "indoor-elevators-below", minzoom: 16.5, paint: { "fill-antialias": !0, "fill-color": "#b9e1ff", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "fill-outline-color": "#000000" }, source: "indoor", type: "fill" }, { filter: [ "all", ["==", ["get", "door"], "sliding"], ["==", ["get", "automatic_door"], "button"], ["!=", ["get", "access"], "no"] ], id: "indoor-elevator-doors", metadata: { "maputnik:comment": `Overlaying with the base color makes a ~~door~~ *glory-wall* :scream:` }, paint: { "circle-color": "#b9e1ff", "circle-radius": [ "interpolate", ["exponential", 2], ["zoom"], 10, ["*", ["*", 0.5, ["number", ["get", "width"], 1.6]], ["^", 2, -6]], 24, ["*", ["*", 0.5, ["number", ["get", "width"], 1.6]], ["^", 2, 8]] ] }, source: "indoor", type: "circle" }, { filter: [ "any", ["==", ["get", "elevator"], "yes"], ["==", ["get", "highway"], "elevator"] ], id: "indoor-elevators-logo", layout: { "icon-allow-overlap": !0, "icon-image": "elevator", "icon-size": [ "interpolate", ["exponential", 1.8], ["zoom"], 17, ["*", 2, ["^", 2, -2]], 24, ["*", 2, ["^", 2, 3]] ] }, paint: { "icon-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1] }, source: "indoor", type: "symbol" }, { filter: ["==", ["get", "indoor"], "wall"], id: "indoor-walls", paint: { "line-color": "#000000", "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 18, 1], "line-width": 2 }, source: "indoor", type: "line" }, { filter: ["has", "barrier"], id: "indoor-barriers", paint: { "line-color": "#000000", "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 18, 1] }, source: "indoor", type: "line" }, { filter: ["==", ["get", "indoor"], "block"], id: "indoor-blocks", paint: { "fill-color": "#000000", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 18, 1] }, source: "indoor", type: "fill" }, { filter: [ "all", ["==", ["get", "handrail"], "yes"], ["!=", ["get", "highway"], "steps"] ], id: "indoor-handrail", paint: { "line-color": "#000000", "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 19, 1] }, source: "indoor", type: "line" }, { filter: ["==", ["get", "railway"], "rail"], id: "indoor-rails", paint: { "line-color": "hsl(230, 10%, 74%)", "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 19, 1] }, source: "indoor", type: "line" }, { filter: ["==", ["get", "railway"], "rail"], id: "indoor-rails-tracks", paint: { "line-color": "hsl(230,10%,74%)", "line-dasharray": [0.1, 15], "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 19, 1], "line-width": [ "interpolate", ["exponential", 1.5], ["zoom"], 14, 4, 20, 8 ] }, source: "indoor", type: "line" }, { filter: [ "any", [ "in", ["get", "indoor"], [ "literal", [ "table", "cupboard", "chair", "kitchen", "sofa", "tv", "shelf", "furniture-item" ] ] ], ["==", ["get", "trashcan"], "yes"], ["==", ["get", "copier"], "yes"], ["==", ["get", "amenity"], "vending_machine"] ], id: "indoor-furniture", minzoom: 18, paint: { "fill-color": "#000", "fill-opacity": ["interpolate", ["linear"], ["zoom"], 18, 0, 19, 0.2], "fill-outline-color": "#000" }, source: "indoor", type: "fill" }, { filter: [ "all", ["==", ["get", "highway"], "steps"], ["!", ["has", "conveying"]] ], id: "indoor-steps-white-base", layout: { "line-join": "round" }, minzoom: 17, paint: { "line-gradient": [ "interpolate", ["linear"], ["line-progress"], 0, "rgba(255, 252, 252, 0)", 1, "rgba(255, 252, 252, 0.8)" ], "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 17.25, 1], "line-width": [ "interpolate", ["exponential", 2], ["zoom"], 10, ["*", 1, ["^", 2, -6]], 24, ["*", 1, ["^", 2, 8]] ] }, source: "indoor", type: "line" }, { filter: [ "all", ["==", ["get", "highway"], "steps"], ["!", ["has", "conveying"]] ], id: "indoor-steps-base", layout: { "line-join": "round" }, minzoom: 17, paint: { "line-gap-width": [ "interpolate", ["exponential", 2], ["zoom"], 10, ["*", 1, ["^", 2, -6]], 24, ["*", 1, ["^", 2, 8]] ], "line-gradient": [ "interpolate", ["linear"], ["line-progress"], 0, "rgba(0,0,0,0)", 1, "rgba(0,0,0,1)" ], "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 17.25, 1], "line-width": [ "interpolate", ["exponential", 2], ["zoom"], 10, ["*", 0.1, ["^", 2, -6]], 24, ["*", 0.1, ["^", 2, 8]] ] }, source: "indoor", type: "line" }, { filter: [ "all", ["all", ["==", ["get", "highway"], "steps"], ["!", ["has", "conveying"]]] ], id: "indoor-steps-middle", layout: { "line-cap": "round", "line-join": "round" }, minzoom: 17, paint: { "line-gradient": [ "interpolate", ["linear"], ["line-progress"], 0, "rgba(0,0,0,0)", 1, "rgba(22, 93, 177, 0.4)" ], "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 17.25, 1], "line-width": [ "interpolate", ["exponential", 1.8], ["zoom"], 17, ["*", 1, ["^", 2, -2]], 24, ["*", 1, ["^", 2, 6]] ] }, source: "indoor", type: "line" }, { filter: ["==", ["get", "highway"], "steps"], id: "indoor-steps-arrow", layout: { "icon-allow-overlap": !0, "icon-ignore-placement": !1, "icon-image": "triangle", "icon-keep-upright": !1, "icon-rotate": 90, "icon-size": [ "interpolate", ["exponential", 1.8], ["zoom"], 17, ["*", 1, ["^", 2, -2]], 24, ["*", 1, ["^", 2, 3]] ], "symbol-avoid-edges": !0, "symbol-placement": "line" }, minzoom: 18, paint: { "icon-color": "rgba(22, 93, 177, 0.4)", "icon-opacity": [ "interpolate", ["linear"], ["zoom"], 17, 0, 17.5, 0.5, 19, 1 ] }, source: "indoor", type: "symbol" }, { filter: ["all", ["==", ["get", "highway"], "steps"], ["has", "conveying"]], id: "indoor-conveying", layout: { "line-join": "round" }, paint: { "line-color": "#FF0000", "line-dasharray": [ "step", ["zoom"], ["literal", [1, 0]], 17.5, ["literal", [1.75, 1]], 18, ["literal", [1, 0.75]], 19, ["literal", [0.3, 0.3]] ], "line-opacity": ["interpolate", ["linear"], ["zoom"], 17, 0, 17.25, 1], "line-width": [ "interpolate", ["exponential", 1.5], ["zoom"], 17, 1, 18, 1.6, 19, 6 ] }, source: "indoor", type: "line" }, { filter: [ "all", [ "!", [ "in", ["get", "amenity"], ["literal", ["toilet", "toilets", "shower", "showers"]] ] ], ["==", ["get", "indoor"], "room"] ], id: "poi-indoor-text-ref", layout: { "text-allow-overlap": !1, "text-anchor": "center", "text-field": [ "case", ["all", ["has", "name"], ["has", "name"]], [ "format", ["get", "name"], {}, ` `, {}, ["get", "ref"], { "font-scale": 0.8 } ], ["has", "name"], ["get", "name"], ["get", "ref"] ], "text-font": ["Roboto Regular"], "text-ignore-placement": !1, "text-justify": "auto", "text-padding": 5, "text-rotation-alignment": "auto", "text-size": [ "interpolate", ["exponential", 1.5], ["zoom"], 16.5, 12, 24, 18 ] }, minzoom: 16.5, paint: { "text-color": "#072140", "text-opacity": [ "interpolate", ["linear"], ["zoom"], 17.5, 0, 18, 0.5, 19, 1 ] }, source: "indoor", type: "symbol" }, { filter: [ "all", [ "any", ["==", ["get", "entrance"], "exit"], ["==", ["get", "entrance"], "emergency"] ] ], id: "poi-exterior-exit-bg", minzoom: 18, paint: { "circle-color": "rgba(255, 255, 255, 1)", "circle-opacity": ["interpolate", ["linear"], ["zoom"], 18, 0, 18.5, 0.8], "circle-radius": 10 }, source: "indoor", type: "circle" }, { filter: [ "all", [ "any", ["==", ["get", "entrance"], "exit"], ["==", ["get", "entrance"], "emergency"] ] ], id: "poi-exterior-exit", layout: { "icon-image": "exit-alt1" }, minzoom: 18, paint: { "icon-opacity": ["interpolate", ["linear"], ["zoom"], 18, 0, 18.5, 1] }, source: "indoor", type: "symbol" }, { filter: [ "all", ["has", "entrance"], ["!=", ["get", "entrance"], "exit"], ["!=", ["get", "entrance"], "emergency"] ], id: "poi-exterior-entrance-bg", minzoom: 16, paint: { "circle-color": "rgba(255, 255, 255, 1)", "circle-opacity": ["interpolate", ["linear"], ["zoom"], 16, 0, 16.5, 1], "circle-radius": 10 }, source: "indoor", type: "circle" }, { filter: ["has", "building"], id: "buildings-walls", minzoom: 16.5, paint: { "line-color": "#FFFFFF", "line-opacity": ["interpolate", ["linear"], ["zoom"], 16.5, 0, 18, 1], "line-width": 2 }, source: "indoor", type: "line" }, { filter: [ "all", ["has", "entrance"], ["!=", ["get", "entrance"], "exit"], ["!=", ["get", "entrance"], "emergency"] ], id: "poi-exterior-entrance", layout: { "icon-allow-overlap": !0, "icon-ignore-placement": !0, "icon-image": "entrance-alt1", "icon-optional": !1, "text-font": [] }, minzoom: 16, paint: { "icon-opacity": ["interpolate", ["linear"], ["zoom"], 16, 0, 16.5, 1] }, source: "indoor", type: "symbol" }, { filter: [ "in", ["get", "amenity"], ["literal", ["toilets", "shower", "showers"]] ], id: "poi-indoor-bathrooms", layout: { "icon-allow-overlap": !0, "icon-anchor": "center", "icon-image": [ "case", ["in", ["get", "amenity"], ["literal", ["shower", "showers"]]], ["literal", "noun-shower-51"], ["==", ["get", "wheelchair"], "yes"], ["literal", "wheelchair"], [ "all", ["==", ["get", "female"], "yes"], ["!=", ["get", "male"], "yes"] ], ["literal", "toilet_female"], [ "all", ["!=", ["get", "female"], "yes"], ["==", ["get", "male"], "yes"] ], ["literal", "toilet_male"], ["literal", "toilet"] ], "icon-size": ["interpolate", ["linear"], ["zoom"], 17, 0.5, 20, 1] }, minzoom: 18, paint: { "icon-opacity": [ "interpolate", ["linear"], ["zoom"], 18, 0, 18.5, 0.5, 19, 1 ] }, source: "indoor", type: "symbol" }, { filter: ["boolean", !1], // changed in the poi-logic id: "poi-indoor", layout: { "icon-allow-overlap": !0, "icon-anchor": "center", "icon-image": ["get", "maki"], // changed in the poi-logic "icon-optional": !1, "icon-size": ["interpolate", ["linear"], ["zoom"], 17, 0.5, 20, 1], "symbol-placement": "point", "symbol-spacing": 250, "text-allow-overlap": !1, "text-anchor": "top", "text-field": [ "case", ["all", ["has", "name"], ["has", "name"]], [ "format", ["get", "name"], {}, ` `, {}, ["get", "ref"], { "font-scale": 0.8 } ], ["has", "name"], ["get", "name"], ["get", "ref"] ], "text-font": ["Roboto Regular"], "text-ignore-placement": !1, "text-line-height": 1.2, "text-max-angle": 38, "text-max-width": 8, "text-offset": [0, 1], "text-padding": 2, "text-rotation-alignment": "viewport", "text-size": ["interpolate", ["linear"], ["zoom"], 17, 11, 20, 13] }, minzoom: 17, paint: { "icon-opacity": [ "interpolate", ["linear"], ["zoom"], 18, 0, 18.5, 0.5, 19, 1 ], "text-color": "#072140", "text-halo-color": "rgb(194, 215, 239, 0.3)", "text-halo-width": 1, "text-opacity": [ "interpolate", ["linear"], ["zoom"], 17, 0, 17.5, 0.5, 19, 1 ] }, source: "indoor", type: "symbol" } ]; let M = I; const T = "poi-indoor", W = [ { maki: "suitcase", shop: "travel_agency" }, { maki: "grocery", shop: "convenience" }, { maki: "bakery", shop: "bakery" }, { maki: "pharmacy", shop: "chemist" }, { maki: "clothing-store", shop: "clothes" } ], N = [ { filter: ["==", ["get", "amenity"], "fast_food"], maki: "fast-food" }, { filter: ["==", ["get", "amenity"], "restaurant"], maki: "restaurant" }, { filter: ["==", ["get", "amenity"], "cafe"], maki: "cafe" }, { filter: [ "in", ["get", "amenity"], ["literal", ["bank", "vending_machine"]] ], maki: "bank" }, { filter: ["==", ["get", "natural"], "tree"], maki: "park" }, ...W.map( ({ maki: o, shop: e }) => ({ filter: ["==", ["get", "shop"], e], maki: o }) ) ]; function ne(o) { const e = W.map((t) => t.shop); return N.push({ filter: ["in", ["get", "shop"], ["literal", e]], maki: "shop" }), N.map((t) => { const i = Object.assign({}, o); return i.id += `-${t.maki}`, i.filter = t.filter, i.layout = Object.assign({}, o.layout), i.layout["icon-image"] = t.maki, i; }); } const A = M.find((o) => o.id === T); A && (ne(A).forEach( (o) => M.push(o) ), M = M.filter((o) => o.id !== T)); const le = M, se = { DefaultLayers: le, defaultLayers: I }; class z { constructor(e, t, i, r, s, a, d, l) { n(this, "beforeLayerId"); n(this, "bounds"); n(this, "defaultLevel"); n(this, "geojson"); n(this, "layers"); n(this, "layersToHide"); n(this, "levelsRange"); n(this, "showFeaturesWithEmptyLevel"); this.bounds = e, this.geojson = t, this.layers = i, this.levelsRange = r, this.layersToHide = s, this.defaultLevel = a, this.showFeaturesWithEmptyLevel = d, this.beforeLayerId = l; } static fromGeojson(e, t = {}) { const { bounds: i, levelsRange: r } = re(e); return new z( i, e, t.layers ? t.layers : se.DefaultLayers, r, t.layersToHide ? t.layersToHide : [], t.defaultLevel ? t.defaultLevel : 0, t.showFeaturesWithEmptyLevel ? t.showFeaturesWithEmptyLevel : !1, t.beforeLayerId ); } } function de(o, e, t, i = {}) { const r = b(o), s = g(r[0]), a = g(r[1]), d = g(t), l = V(e, i.units), c = Math.asin( Math.sin(a) * Math.cos(l) + Math.cos(a) * Math.sin(l) * Math.cos(d) ), u = s + Math.atan2( Math.sin(d) * Math.sin(l) * Math.cos(a), Math.cos(l) - Math.sin(a) * Math.sin(c) ), h = E(u), v = E(c); return Y([h, v], i.properties); } var O = de; const ce = 16.25, pe = 200; class G { constructor(e, t, i) { n(this, "downloadedBounds"); n(this, "indoorMapOptions"); n(this, "loadMapsPromise", Promise.resolve()); n(this, "map"); n(this, "remoteMapsDownloaded"); n(this, "serverUrl"); this.serverUrl = e, this.map = t, this.indoorMapOptions = i, this.remoteMapsDownloaded = [], this.downloadedBounds = null, t.loaded() ? this.loadMapsIfNecessary() : t.on("load", () => this.loadMapsIfNecessary()), t.on("move", () => this.loadMapsIfNecessary()); } static manage(e, t, i) { return new G(e, ee(t), i); } async addCustomMap(e) { const t = await (await fetch(e.url)).json(); e.indoorMap = z.fromGeojson(t, this.indoorMapOptions), await this.map.indoor.addMap(e.indoorMap), this.remoteMapsDownloaded.push(e); } async loadMapsIfNecessary() { if (this.map.getZoom() < ce) return; const e = this.map.getBounds(); if (this.downloadedBounds !== null && P( this.downloadedBounds, e.getNorthEast().toArray() ) && P(this.downloadedBounds, e.getSouthWest().toArray())) return; const t = L( e.getNorthEast().toArray(), e.getNorthWest().toArray(), { units: "meters" } ), i = L( e.getNorthEast().toArray(), e.getSouthEast().toArray(), { units: "meters" } ), r = Math.max(t, i) / 2, s = Math.max( pe, r * 2 ), a = this.map.getCenter().toArray(); console.debug( `requested indoor maps for a bbox ${s}m vertically/horizontally around ${a}` ); const d = s * Math.sqrt(2), l = O(a, d, 50, { units: "meters" }), u = [ ...O(a, d, -130, { units: "meters" }).geometry.coordinates.reverse(), ...l.geometry.coordinates.reverse() ]; this.downloadedBounds = u, await this.loadMapsPromise, this.loadMapsPromise = this.loadMapsInBounds(u); } async loadMapsInBounds(e) { const t = `${this.serverUrl}?bbox=${e[0]},${e[1]},${e[2]},${e[3]}`, i = await (await fetch(t)).json(), r = [], s = []; for (const a of i) i.find((d) => d.url === a.url) ? this.remoteMapsDownloaded.find((d) => d.url === a.url) || s.push(a) : r.push(a); s.forEach(this.addCustomMap.bind(this)), r.forEach(this.removeCustomMap.bind(this)); } async removeCustomMap(e) { await this.map.indoor.removeMap(e.indoorMap), this.remoteMapsDownloaded.splice(this.remoteMapsDownloaded.indexOf(e), 1); } } export { se as DefaultStyle, me as IndoorControl, Q as IndoorLayer, z as IndoorMap, G as MapServerHandler, ee as addIndoorTo }; //# sourceMappingURL=maplibre-gl-indoor.es.js.map