import { leaflet as L, loadLeafletDraw } from "nicegui-leaflet"; import { loadResource } from "../../static/utils/resources.js"; import { cleanObject } from "../../static/utils/json.js"; export default { template: "
", props: { center: Array, zoom: Number, options: Object, draw_control: Object, resource_path: String, hide_drawn_items: Boolean, additional_resources: Array, }, async mounted() { await this.$nextTick(); // NOTE: wait for window.path_prefix to be set await loadResource(window.path_prefix + `${this.resource_path}/leaflet/leaflet.css`); window.L = L; await Promise.all(this.additional_resources.map((resource) => loadResource(resource))); if (this.draw_control) { await Promise.all([ loadResource(window.path_prefix + `${this.resource_path}/leaflet-draw/leaflet.draw.css`), loadLeafletDraw(), ]); } this.map = L.map(this.$el, { ...this.options, center: this.center, zoom: this.zoom, }); for (const type of [ "baselayerchange", "overlayadd", "overlayremove", "zoomlevelschange", "resize", "unload", "viewreset", "load", "zoomstart", "movestart", "zoom", "move", "zoomend", "moveend", "popupopen", "popupclose", "autopanstart", "tooltipopen", "tooltipclose", "locationerror", "locationfound", "click", "dblclick", "mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "contextmenu", "keypress", "keydown", "keyup", "preclick", "zoomanim", ]) { this.map.on(type, (e) => { this.$emit(`map-${type}`, { ...e, originalEvent: undefined, target: undefined, sourceTarget: undefined, center: [e.target.getCenter().lat, e.target.getCenter().lng], zoom: e.target.getZoom(), }); }); } for (const type of ["layeradd", "layerremove"]) { this.map.on(type, (e) => { this.$emit(`map-${type}`, { id: e.layer.id, leaflet_id: e.layer._leaflet_id, }); }); } if (this.draw_control) { for (const key in L.Draw.Event) { const type = L.Draw.Event[key]; this.map.on(type, async (e) => { await this.$nextTick(); // NOTE: allow drawn layers to be added const cleanedObject = cleanObject(e, [ "_map", "_events", "_eventParents", "_handlers", "_mapToAdd", "_initHooksCalled", ]); this.$emit(type, { ...cleanedObject, target: undefined, sourceTarget: undefined, }); }); } // HACK: set window.type to avoid a bug in leaflet-draw (https://github.com/Leaflet/Leaflet.draw/issues/1026) const originalType = window.type; window.type = "Feature"; const drawnItems = new L.FeatureGroup(); window.type = originalType; this.map.addLayer(drawnItems); // Normalize draw_control options: allow boolean True -> {} const dc = this.draw_control && typeof this.draw_control === "object" ? this.draw_control : {}; const drawOptions = dc.draw === true || dc.draw === undefined ? {} : dc.draw || {}; let editOptions = dc.edit === true || dc.edit === undefined ? {} : dc.edit || {}; if (typeof editOptions === "object" && "edit" in editOptions) { const { edit: _ignoredEditFlag, ...rest } = editOptions; editOptions = rest; } const drawControl = new L.Control.Draw({ draw: drawOptions, edit: { ...editOptions, featureGroup: drawnItems, }, }); this.map.addControl(drawControl); if (!this.hide_drawn_items) { this.map.on("draw:created", (e) => drawnItems.addLayer(e.layer)); } } const connectInterval = setInterval(async () => { if (window.socket.id === undefined) return; this.$emit("init"); clearInterval(connectInterval); }, 100); }, methods: { add_layer(layer, id) { let obj = L; for (const part of layer.type.split(".")) { obj = obj[part]; } const l = obj(...layer.args); l.id = id; l.addTo(this.map); }, remove_layer(id) { this.map.eachLayer((layer) => layer.id === id && this.map.removeLayer(layer)); }, clear_layers() { this.map.eachLayer((layer) => this.map.removeLayer(layer)); }, run_map_method(name, ...args) { if (name.startsWith(":")) { name = name.slice(1); args = args.map((arg) => new Function(`return (${arg})`)()); } return runMethod(this.map, name, args); }, run_layer_method(id, name, ...args) { let result = null; this.map.eachLayer((layer) => { if (layer.id !== id) return; if (name.startsWith(":")) { name = name.slice(1); args = args.map((arg) => new Function(`return (${arg})`)()); } result = runMethod(layer, name, args); }); return result; }, }, };