HomeDashboard/.venv/lib/python3.12/site-packages/nicegui/elements/leaflet/leaflet.js
2026-01-03 14:54:18 +01:00

179 lines
5.1 KiB
JavaScript

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: "<div></div>",
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;
},
},
};