|
|
@@ -22,8 +22,13 @@ const lmeState = {
|
|
|
|
importedSheetsVisible: false,
|
|
|
|
importedSheetsVisible: false,
|
|
|
|
importedMeasurements: null,
|
|
|
|
importedMeasurements: null,
|
|
|
|
drawings: null,
|
|
|
|
drawings: null,
|
|
|
|
|
|
|
|
drawingsRenderer: null,
|
|
|
|
|
|
|
|
drawingSelection: null,
|
|
|
|
drawingMeasurements: null,
|
|
|
|
drawingMeasurements: null,
|
|
|
|
drawControl: null,
|
|
|
|
drawControl: null,
|
|
|
|
|
|
|
|
drawingDeleteButton: null,
|
|
|
|
|
|
|
|
drawingScopeMenu: null,
|
|
|
|
|
|
|
|
ignoreMapClickUntil: 0,
|
|
|
|
activeDrawHandler: null,
|
|
|
|
activeDrawHandler: null,
|
|
|
|
drawEventsBound: false,
|
|
|
|
drawEventsBound: false,
|
|
|
|
includeKmlSheetLayer: false,
|
|
|
|
includeKmlSheetLayer: false,
|
|
|
@@ -178,10 +183,12 @@ function init(dotNetReference) {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const managerHighlightPane = lmeState.map.createPane("managerHighlightPane");
|
|
|
|
const managerHighlightPane = lmeState.map.createPane("managerHighlightPane");
|
|
|
|
managerHighlightPane.style.zIndex = "650";
|
|
|
|
managerHighlightPane.style.zIndex = "650";
|
|
|
|
|
|
|
|
lmeState.drawingsRenderer = L.canvas({ pane: "drawingsPane", tolerance: 14 });
|
|
|
|
setLayerOrder(lmeState.layerOrder);
|
|
|
|
setLayerOrder(lmeState.layerOrder);
|
|
|
|
lmeState.imported = L.featureGroup().addTo(lmeState.map);
|
|
|
|
lmeState.imported = L.featureGroup().addTo(lmeState.map);
|
|
|
|
lmeState.importedSheets = L.featureGroup();
|
|
|
|
lmeState.importedSheets = L.featureGroup();
|
|
|
|
lmeState.drawings = L.featureGroup().addTo(lmeState.map);
|
|
|
|
lmeState.drawings = L.featureGroup().addTo(lmeState.map);
|
|
|
|
|
|
|
|
lmeState.drawingSelection = L.featureGroup();
|
|
|
|
lmeState.importedMeasurements = L.layerGroup().addTo(lmeState.map);
|
|
|
|
lmeState.importedMeasurements = L.layerGroup().addTo(lmeState.map);
|
|
|
|
lmeState.drawingMeasurements = L.layerGroup().addTo(lmeState.map);
|
|
|
|
lmeState.drawingMeasurements = L.layerGroup().addTo(lmeState.map);
|
|
|
|
lmeState.selectedParcelsLayer = L.featureGroup().addTo(lmeState.map);
|
|
|
|
lmeState.selectedParcelsLayer = L.featureGroup().addTo(lmeState.map);
|
|
|
@@ -205,6 +212,10 @@ function init(dotNetReference) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lmeState.map.on("click", async event => {
|
|
|
|
lmeState.map.on("click", async event => {
|
|
|
|
|
|
|
|
if (event.originalEvent?._lmeDrawingSelected || Date.now() < lmeState.ignoreMapClickUntil) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
clearManagerHighlight();
|
|
|
|
clearManagerHighlight();
|
|
|
|
const info = await queryFeatureInfo(event.latlng);
|
|
|
|
const info = await queryFeatureInfo(event.latlng);
|
|
|
|
if (info) {
|
|
|
|
if (info) {
|
|
|
@@ -229,9 +240,17 @@ function init(dotNetReference) {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (!lmeState.managerOutsideSelectionBound) {
|
|
|
|
if (!lmeState.managerOutsideSelectionBound) {
|
|
|
|
document.addEventListener("pointerdown", event => {
|
|
|
|
document.addEventListener("pointerdown", event => {
|
|
|
|
|
|
|
|
if (lmeState.drawingScopeMenu
|
|
|
|
|
|
|
|
&& !event.target?.closest?.(".lme-drawing-scope-actions")
|
|
|
|
|
|
|
|
&& !event.target?.closest?.(".leaflet-draw-edit-edit, .leaflet-draw-edit-remove")) {
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
|
|
|
|
}
|
|
|
|
if (!lmeState.managerHighlightedObjectId && !lmeState.managerHighlightedParentKey) {
|
|
|
|
if (!lmeState.managerHighlightedObjectId && !lmeState.managerHighlightedParentKey) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.target?.closest?.(".leaflet-draw")) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
const selectedObject = event.target?.closest?.(".layer-manager-object");
|
|
|
|
const selectedObject = event.target?.closest?.(".layer-manager-object");
|
|
|
|
const selectedParent = event.target?.closest?.("[data-highlight-key]");
|
|
|
|
const selectedParent = event.target?.closest?.("[data-highlight-key]");
|
|
|
|
if (selectedObject?.dataset.objectId === lmeState.managerHighlightedObjectId
|
|
|
|
if (selectedObject?.dataset.objectId === lmeState.managerHighlightedObjectId
|
|
|
@@ -1288,6 +1307,17 @@ function applyLayerManagerPalette(row, key) {
|
|
|
|
row.style.setProperty("--layer-group-accent", palette.accent);
|
|
|
|
row.style.setProperty("--layer-group-accent", palette.accent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function clearManagedObjectState(id) {
|
|
|
|
|
|
|
|
lmeState.managerHiddenObjects.delete(id);
|
|
|
|
|
|
|
|
lmeState.managerHiddenObjectIds.delete(id);
|
|
|
|
|
|
|
|
lmeState.managerHiddenMeasurementSummaryIds.delete(id);
|
|
|
|
|
|
|
|
lmeState.managerHiddenMeasurementSideIds.delete(id);
|
|
|
|
|
|
|
|
Object.keys(lmeState.managerObjectOrder).forEach(categoryKey => {
|
|
|
|
|
|
|
|
lmeState.managerObjectOrder[categoryKey] = lmeState.managerObjectOrder[categoryKey]
|
|
|
|
|
|
|
|
.filter(objectId => objectId !== id);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function removeManagedRecords(records, subject) {
|
|
|
|
function removeManagedRecords(records, subject) {
|
|
|
|
if (!records.length) {
|
|
|
|
if (!records.length) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@@ -1304,10 +1334,7 @@ function removeManagedRecords(records, subject) {
|
|
|
|
if (record.parent?.hasLayer?.(record.layer)) {
|
|
|
|
if (record.parent?.hasLayer?.(record.layer)) {
|
|
|
|
record.parent.removeLayer(record.layer);
|
|
|
|
record.parent.removeLayer(record.layer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lmeState.managerHiddenObjects.delete(record.id);
|
|
|
|
clearManagedObjectState(record.id);
|
|
|
|
lmeState.managerHiddenObjectIds.delete(record.id);
|
|
|
|
|
|
|
|
lmeState.managerHiddenMeasurementSummaryIds.delete(record.id);
|
|
|
|
|
|
|
|
lmeState.managerHiddenMeasurementSideIds.delete(record.id);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
categoryKeys.forEach(categoryKey => {
|
|
|
|
categoryKeys.forEach(categoryKey => {
|
|
|
|
const order = lmeState.managerObjectOrder[categoryKey] || [];
|
|
|
|
const order = lmeState.managerObjectOrder[categoryKey] || [];
|
|
|
@@ -1761,10 +1788,63 @@ function highlightManagedObject(record) {
|
|
|
|
document.querySelectorAll(".layer-manager-object").forEach(row => {
|
|
|
|
document.querySelectorAll(".layer-manager-object").forEach(row => {
|
|
|
|
row.classList.toggle("layer-manager-object-selected", row.dataset.objectId === record.id);
|
|
|
|
row.classList.toggle("layer-manager-object-selected", row.dataset.objectId === record.id);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
setSelectedDrawing(record.categoryKey === "drawings" ? record.layer : null);
|
|
|
|
renderManagerHighlight([record]);
|
|
|
|
renderManagerHighlight([record]);
|
|
|
|
fitLayer(record.layer);
|
|
|
|
fitLayer(record.layer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function drawingEditToolbar() {
|
|
|
|
|
|
|
|
return lmeState.drawControl?._toolbars?.[L.EditToolbar.TYPE] || null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function drawingEditActive() {
|
|
|
|
|
|
|
|
return Boolean(drawingEditToolbar()?.enabled?.());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateDrawingSelectionActions() {
|
|
|
|
|
|
|
|
const hasSelection = Boolean(lmeState.drawingSelection?.getLayers?.().length);
|
|
|
|
|
|
|
|
const hasDrawings = Boolean(lmeState.drawings?.getLayers?.().length);
|
|
|
|
|
|
|
|
lmeState.drawingDeleteButton?.classList.toggle("leaflet-disabled", !hasDrawings);
|
|
|
|
|
|
|
|
if (lmeState.drawingDeleteButton) {
|
|
|
|
|
|
|
|
lmeState.drawingDeleteButton.setAttribute("aria-disabled", String(!hasDrawings));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lmeState.drawingScopeMenu?.querySelector("[data-drawing-scope='selected']")
|
|
|
|
|
|
|
|
?.setAttribute("aria-disabled", String(!hasSelection));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setSelectedDrawing(layer) {
|
|
|
|
|
|
|
|
if (!lmeState.drawingSelection || drawingEditActive()) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lmeState.drawingSelection.clearLayers();
|
|
|
|
|
|
|
|
if (layer) {
|
|
|
|
|
|
|
|
lmeState.drawingSelection.addLayer(layer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
updateDrawingSelectionActions();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function selectDrawingLayer(layer) {
|
|
|
|
|
|
|
|
if (drawingEditActive()) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const record = {
|
|
|
|
|
|
|
|
id: managedLayerId(layer, "drawings"),
|
|
|
|
|
|
|
|
categoryKey: "drawings",
|
|
|
|
|
|
|
|
layer,
|
|
|
|
|
|
|
|
parent: lmeState.drawings,
|
|
|
|
|
|
|
|
source: String(layer?.feature?.properties?._lmeSource || "Progetto corrente")
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
clearManagerHighlight();
|
|
|
|
|
|
|
|
lmeState.managerHighlightedObjectId = record.id;
|
|
|
|
|
|
|
|
lmeState.managerHighlightedCategoryKey = "drawings";
|
|
|
|
|
|
|
|
document.querySelectorAll(".layer-manager-object").forEach(row => {
|
|
|
|
|
|
|
|
row.classList.toggle("layer-manager-object-selected", row.dataset.objectId === record.id);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
setSelectedDrawing(layer);
|
|
|
|
|
|
|
|
renderManagerHighlight([record]);
|
|
|
|
|
|
|
|
setInfo(`Selezione: ${managedObjectLabel(record, 0)}. Usa la matita per modificare o il cestino per eliminare.`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function bindManagedParentHighlight(row, key, records) {
|
|
|
|
function bindManagedParentHighlight(row, key, records) {
|
|
|
|
const summary = row.querySelector(":scope > summary");
|
|
|
|
const summary = row.querySelector(":scope > summary");
|
|
|
|
row.dataset.highlightKey = key;
|
|
|
|
row.dataset.highlightKey = key;
|
|
|
@@ -1804,6 +1884,7 @@ function highlightManagedParent(row, key, records) {
|
|
|
|
lmeState.managerHighlightedParentKey = key;
|
|
|
|
lmeState.managerHighlightedParentKey = key;
|
|
|
|
lmeState.managerHighlightedParentRecords = records;
|
|
|
|
lmeState.managerHighlightedParentRecords = records;
|
|
|
|
lmeState.managerHighlightedCategoryKey = records[0]?.categoryKey || null;
|
|
|
|
lmeState.managerHighlightedCategoryKey = records[0]?.categoryKey || null;
|
|
|
|
|
|
|
|
setSelectedDrawing(null);
|
|
|
|
row.classList.add("layer-manager-parent-selected");
|
|
|
|
row.classList.add("layer-manager-parent-selected");
|
|
|
|
renderManagerHighlight(records);
|
|
|
|
renderManagerHighlight(records);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1853,6 +1934,7 @@ function clearManagerHighlight() {
|
|
|
|
lmeState.managerHighlightedParentRecords = null;
|
|
|
|
lmeState.managerHighlightedParentRecords = null;
|
|
|
|
lmeState.managerHoveredParentKey = null;
|
|
|
|
lmeState.managerHoveredParentKey = null;
|
|
|
|
lmeState.managerHoveredParentRecords = null;
|
|
|
|
lmeState.managerHoveredParentRecords = null;
|
|
|
|
|
|
|
|
setSelectedDrawing(null);
|
|
|
|
document.querySelectorAll(".layer-manager-object-selected").forEach(row => {
|
|
|
|
document.querySelectorAll(".layer-manager-object-selected").forEach(row => {
|
|
|
|
row.classList.remove("layer-manager-object-selected");
|
|
|
|
row.classList.remove("layer-manager-object-selected");
|
|
|
|
});
|
|
|
|
});
|
|
|
@@ -2126,16 +2208,17 @@ function clearImported() {
|
|
|
|
function addProjectMarker(name) {
|
|
|
|
function addProjectMarker(name) {
|
|
|
|
const center = lmeState.map.getCenter();
|
|
|
|
const center = lmeState.map.getCenter();
|
|
|
|
const label = (name || "Nuovo POI").trim();
|
|
|
|
const label = (name || "Nuovo POI").trim();
|
|
|
|
const marker = L.marker(center, { pane: "drawingsPane", draggable: true }).addTo(lmeState.drawings);
|
|
|
|
const marker = L.marker(center, { pane: "drawingsPane", draggable: false }).addTo(lmeState.drawings);
|
|
|
|
marker.lmeManagerLabel = `POI: ${label}`;
|
|
|
|
marker.lmeManagerLabel = `POI: ${label}`;
|
|
|
|
marker.feature = {
|
|
|
|
marker.feature = {
|
|
|
|
type: "Feature",
|
|
|
|
type: "Feature",
|
|
|
|
properties: { name: label }
|
|
|
|
properties: { name: label }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
marker.bindPopup(`<strong>${escapeHtml(label)}</strong><br>${center.lat.toFixed(6)}, ${center.lng.toFixed(6)}`).openPopup();
|
|
|
|
marker.bindPopup(`<strong>${escapeHtml(label)}</strong><br>${center.lat.toFixed(6)}, ${center.lng.toFixed(6)}`).openPopup();
|
|
|
|
|
|
|
|
bindDrawingLayerSelection(marker);
|
|
|
|
refreshDrawingMeasurements();
|
|
|
|
refreshDrawingMeasurements();
|
|
|
|
setInfo(`POI aggiunto: ${label}`);
|
|
|
|
|
|
|
|
refreshLayerManager();
|
|
|
|
refreshLayerManager();
|
|
|
|
|
|
|
|
selectDrawingLayer(marker);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function configureDrawLabels() {
|
|
|
|
function configureDrawLabels() {
|
|
|
@@ -2144,8 +2227,8 @@ function configureDrawLabels() {
|
|
|
|
L.drawLocal.draw.toolbar.buttons.circle = "Misura cerchio";
|
|
|
|
L.drawLocal.draw.toolbar.buttons.circle = "Misura cerchio";
|
|
|
|
L.drawLocal.draw.toolbar.buttons.rectangle = "Disegna rettangolo";
|
|
|
|
L.drawLocal.draw.toolbar.buttons.rectangle = "Disegna rettangolo";
|
|
|
|
L.drawLocal.draw.toolbar.buttons.marker = "Aggiungi POI";
|
|
|
|
L.drawLocal.draw.toolbar.buttons.marker = "Aggiungi POI";
|
|
|
|
L.drawLocal.edit.toolbar.buttons.edit = "Modifica disegni";
|
|
|
|
L.drawLocal.edit.toolbar.buttons.edit = "Scegli quali disegni modificare";
|
|
|
|
L.drawLocal.edit.toolbar.buttons.remove = "Elimina disegni";
|
|
|
|
L.drawLocal.edit.toolbar.buttons.remove = "Scegli quali disegni eliminare";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.start = "Tocca il primo vertice dell'area.";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.start = "Tocca il primo vertice dell'area.";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.cont = "Tocca per aggiungere un vertice.";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.cont = "Tocca per aggiungere un vertice.";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.end = "Tocca il primo punto per chiudere l'area.";
|
|
|
|
L.drawLocal.draw.handlers.polygon.tooltip.end = "Tocca il primo punto per chiudere l'area.";
|
|
|
@@ -2173,6 +2256,7 @@ function bindDrawingEvents() {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
setInfo(completedLabels[event.layerType] || "Disegno completato.");
|
|
|
|
setInfo(completedLabels[event.layerType] || "Disegno completato.");
|
|
|
|
refreshLayerManager();
|
|
|
|
refreshLayerManager();
|
|
|
|
|
|
|
|
selectDrawingLayer(event.layer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lmeState.map.on(L.Draw.Event.EDITED, event => {
|
|
|
|
lmeState.map.on(L.Draw.Event.EDITED, event => {
|
|
|
|
event.layers.eachLayer(layer => annotateDrawingLayer(layer));
|
|
|
|
event.layers.eachLayer(layer => annotateDrawingLayer(layer));
|
|
|
@@ -2180,7 +2264,9 @@ function bindDrawingEvents() {
|
|
|
|
updateGpsInsideState();
|
|
|
|
updateGpsInsideState();
|
|
|
|
refreshLayerManager();
|
|
|
|
refreshLayerManager();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lmeState.map.on(L.Draw.Event.DELETED, () => {
|
|
|
|
lmeState.map.on(L.Draw.Event.DELETED, event => {
|
|
|
|
|
|
|
|
event.layers?.eachLayer(layer => lmeState.drawings.removeLayer(layer));
|
|
|
|
|
|
|
|
clearManagerHighlight();
|
|
|
|
refreshDrawingMeasurements();
|
|
|
|
refreshDrawingMeasurements();
|
|
|
|
updateGpsInsideState();
|
|
|
|
updateGpsInsideState();
|
|
|
|
refreshLayerManager();
|
|
|
|
refreshLayerManager();
|
|
|
@@ -2198,10 +2284,28 @@ function enableDrawTools() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
configureDrawLabels();
|
|
|
|
configureDrawLabels();
|
|
|
|
const orangeArea = { pane: "drawingsPane", color: "#f97316", weight: 4, fillColor: "#fb923c", fillOpacity: 0.2 };
|
|
|
|
const orangeArea = {
|
|
|
|
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 4,
|
|
|
|
|
|
|
|
fillColor: "#fb923c",
|
|
|
|
|
|
|
|
fillOpacity: 0.2
|
|
|
|
|
|
|
|
};
|
|
|
|
lmeState.drawControl = new L.Control.Draw({
|
|
|
|
lmeState.drawControl = new L.Control.Draw({
|
|
|
|
position: "topright",
|
|
|
|
position: "topright",
|
|
|
|
edit: { featureGroup: lmeState.drawings },
|
|
|
|
edit: {
|
|
|
|
|
|
|
|
featureGroup: lmeState.drawings,
|
|
|
|
|
|
|
|
remove: false,
|
|
|
|
|
|
|
|
edit: {
|
|
|
|
|
|
|
|
selectedPathOptions: {
|
|
|
|
|
|
|
|
color: "#ff00d4",
|
|
|
|
|
|
|
|
fillColor: "#00fff0",
|
|
|
|
|
|
|
|
fillOpacity: 0.16,
|
|
|
|
|
|
|
|
maintainColor: false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
draw: {
|
|
|
|
draw: {
|
|
|
|
circle: { metric: true, feet: false, showRadius: true, shapeOptions: orangeArea },
|
|
|
|
circle: { metric: true, feet: false, showRadius: true, shapeOptions: orangeArea },
|
|
|
|
circlemarker: false,
|
|
|
|
circlemarker: false,
|
|
|
@@ -2217,14 +2321,146 @@ function enableDrawTools() {
|
|
|
|
metric: true,
|
|
|
|
metric: true,
|
|
|
|
feet: false,
|
|
|
|
feet: false,
|
|
|
|
showLength: true,
|
|
|
|
showLength: true,
|
|
|
|
shapeOptions: { pane: "drawingsPane", color: "#f97316", weight: 4, opacity: 0.95 }
|
|
|
|
shapeOptions: {
|
|
|
|
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 4,
|
|
|
|
|
|
|
|
opacity: 0.95
|
|
|
|
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
rectangle: { metric: true, shapeOptions: orangeArea }
|
|
|
|
rectangle: { metric: true, shapeOptions: orangeArea }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lmeState.map.addControl(lmeState.drawControl);
|
|
|
|
lmeState.map.addControl(lmeState.drawControl);
|
|
|
|
|
|
|
|
installDrawingScopeControls();
|
|
|
|
bindDrawingEvents();
|
|
|
|
bindDrawingEvents();
|
|
|
|
setInfo("Barra strumenti attiva: misure, disegni, POI, modifica e cancellazione.");
|
|
|
|
setInfo("Barra strumenti attiva: seleziona un disegno sulla mappa, poi usa matita o cestino.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function installDrawingScopeControls() {
|
|
|
|
|
|
|
|
const toolbar = drawingEditToolbar();
|
|
|
|
|
|
|
|
const container = toolbar?._toolbarContainer;
|
|
|
|
|
|
|
|
if (!container) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const editButton = toolbar._modes?.[L.EditToolbar.Edit.TYPE]?.button;
|
|
|
|
|
|
|
|
editButton?.addEventListener("click", event => {
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
|
|
|
showDrawingScopeMenu(editButton, "edit");
|
|
|
|
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
const button = L.DomUtil.create("a", "leaflet-draw-edit-remove", container);
|
|
|
|
|
|
|
|
button.href = "#";
|
|
|
|
|
|
|
|
button.title = L.drawLocal.edit.toolbar.buttons.remove;
|
|
|
|
|
|
|
|
button.setAttribute("role", "button");
|
|
|
|
|
|
|
|
button.setAttribute("aria-label", L.drawLocal.edit.toolbar.buttons.remove);
|
|
|
|
|
|
|
|
const accessibleLabel = L.DomUtil.create("span", "sr-only", button);
|
|
|
|
|
|
|
|
accessibleLabel.textContent = L.drawLocal.edit.toolbar.buttons.remove;
|
|
|
|
|
|
|
|
L.DomEvent.on(button, "click", L.DomEvent.stop)
|
|
|
|
|
|
|
|
.on(button, "mousedown", L.DomEvent.stopPropagation)
|
|
|
|
|
|
|
|
.on(button, "touchstart", L.DomEvent.stopPropagation)
|
|
|
|
|
|
|
|
.on(button, "click", () => showDrawingScopeMenu(button, "delete"));
|
|
|
|
|
|
|
|
lmeState.drawingDeleteButton = button;
|
|
|
|
|
|
|
|
updateDrawingSelectionActions();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showDrawingScopeMenu(button, action) {
|
|
|
|
|
|
|
|
if (drawingEditActive()) {
|
|
|
|
|
|
|
|
setInfo("Salva o annulla la modifica corrente prima di scegliere un altro comando.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!lmeState.drawings?.getLayers?.().length) {
|
|
|
|
|
|
|
|
setInfo("Non ci sono disegni o POI su cui operare.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lmeState.drawingScopeMenu?.dataset.action === action) {
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
|
|
|
|
const menu = document.createElement("ul");
|
|
|
|
|
|
|
|
menu.className = "leaflet-draw-actions lme-drawing-scope-actions";
|
|
|
|
|
|
|
|
menu.dataset.action = action;
|
|
|
|
|
|
|
|
menu.style.display = "block";
|
|
|
|
|
|
|
|
menu.style.top = `${button.offsetTop - 1}px`;
|
|
|
|
|
|
|
|
menu.innerHTML = `<li><a href="#" data-drawing-scope="selected">Solo selezionato</a></li><li><a href="#" data-drawing-scope="all">Tutti</a></li>`;
|
|
|
|
|
|
|
|
button.closest(".leaflet-draw-section")?.appendChild(menu);
|
|
|
|
|
|
|
|
lmeState.drawingScopeMenu = menu;
|
|
|
|
|
|
|
|
const hasSelection = Boolean(lmeState.drawingSelection?.getLayers?.().length);
|
|
|
|
|
|
|
|
const selectedAction = menu.querySelector("[data-drawing-scope='selected']");
|
|
|
|
|
|
|
|
selectedAction.setAttribute("aria-disabled", String(!hasSelection));
|
|
|
|
|
|
|
|
menu.querySelectorAll("a").forEach(link => {
|
|
|
|
|
|
|
|
L.DomEvent.on(link, "click", L.DomEvent.stop)
|
|
|
|
|
|
|
|
.on(link, "mousedown", L.DomEvent.stopPropagation)
|
|
|
|
|
|
|
|
.on(link, "touchstart", L.DomEvent.stopPropagation)
|
|
|
|
|
|
|
|
.on(link, "click", () => runDrawingScopeAction(action, link.dataset.drawingScope));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function hideDrawingScopeMenu() {
|
|
|
|
|
|
|
|
lmeState.drawingScopeMenu?.remove();
|
|
|
|
|
|
|
|
lmeState.drawingScopeMenu = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function runDrawingScopeAction(action, scope) {
|
|
|
|
|
|
|
|
const targetGroup = scope === "selected" ? lmeState.drawingSelection : lmeState.drawings;
|
|
|
|
|
|
|
|
if (!targetGroup?.getLayers?.().length) {
|
|
|
|
|
|
|
|
setInfo("Seleziona prima un oggetto sulla mappa.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
|
|
|
|
if (action === "edit") {
|
|
|
|
|
|
|
|
startScopedDrawingEdit(targetGroup, scope);
|
|
|
|
|
|
|
|
} else if (scope === "selected") {
|
|
|
|
|
|
|
|
removeSelectedDrawing();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
clearDrawings();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function startScopedDrawingEdit(targetGroup, scope) {
|
|
|
|
|
|
|
|
const toolbar = drawingEditToolbar();
|
|
|
|
|
|
|
|
const mode = toolbar?._modes?.[L.EditToolbar.Edit.TYPE];
|
|
|
|
|
|
|
|
if (!mode?.handler) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mode.handler._featureGroup = targetGroup;
|
|
|
|
|
|
|
|
mode.handler.options.featureGroup = targetGroup;
|
|
|
|
|
|
|
|
mode.handler.enable();
|
|
|
|
|
|
|
|
setInfo(scope === "selected"
|
|
|
|
|
|
|
|
? "Modifica attiva sul solo oggetto selezionato."
|
|
|
|
|
|
|
|
: "Modifica attiva su tutti i disegni e POI.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function removeSelectedDrawing() {
|
|
|
|
|
|
|
|
const layer = lmeState.drawingSelection?.getLayers?.()[0];
|
|
|
|
|
|
|
|
if (!layer) {
|
|
|
|
|
|
|
|
setInfo("Seleziona prima il disegno da eliminare toccandolo sulla mappa.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (drawingEditActive()) {
|
|
|
|
|
|
|
|
setInfo("Salva o annulla la modifica prima di eliminare il disegno.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const record = {
|
|
|
|
|
|
|
|
id: managedLayerId(layer, "drawings"),
|
|
|
|
|
|
|
|
categoryKey: "drawings",
|
|
|
|
|
|
|
|
layer,
|
|
|
|
|
|
|
|
parent: lmeState.drawings
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const name = managedObjectLabel(record, 0);
|
|
|
|
|
|
|
|
if (!window.confirm(`Eliminare solo '${name}' dal progetto?`)) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lmeState.drawingSelection.clearLayers();
|
|
|
|
|
|
|
|
lmeState.drawings.removeLayer(layer);
|
|
|
|
|
|
|
|
clearManagedObjectState(record.id);
|
|
|
|
|
|
|
|
clearManagerHighlight();
|
|
|
|
|
|
|
|
refreshDrawingMeasurements();
|
|
|
|
|
|
|
|
updateGpsInsideState();
|
|
|
|
|
|
|
|
refreshLayerManager();
|
|
|
|
|
|
|
|
setInfo(`'${name}' eliminato dal progetto.`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function startMeasurementDrawing(mode) {
|
|
|
|
function startMeasurementDrawing(mode) {
|
|
|
@@ -2232,6 +2468,7 @@ function startMeasurementDrawing(mode) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bindDrawingEvents();
|
|
|
|
bindDrawingEvents();
|
|
|
|
|
|
|
|
hideDrawingScopeMenu();
|
|
|
|
if (lmeState.activeDrawHandler) {
|
|
|
|
if (lmeState.activeDrawHandler) {
|
|
|
|
lmeState.activeDrawHandler.disable();
|
|
|
|
lmeState.activeDrawHandler.disable();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2242,19 +2479,39 @@ function startMeasurementDrawing(mode) {
|
|
|
|
showArea: true,
|
|
|
|
showArea: true,
|
|
|
|
metric: true,
|
|
|
|
metric: true,
|
|
|
|
feet: false,
|
|
|
|
feet: false,
|
|
|
|
shapeOptions: { pane: "drawingsPane", color: "#f97316", weight: 4, fillColor: "#fb923c", fillOpacity: 0.2 }
|
|
|
|
shapeOptions: {
|
|
|
|
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 4,
|
|
|
|
|
|
|
|
fillColor: "#fb923c",
|
|
|
|
|
|
|
|
fillOpacity: 0.2
|
|
|
|
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
distance: () => new L.Draw.Polyline(lmeState.map, {
|
|
|
|
distance: () => new L.Draw.Polyline(lmeState.map, {
|
|
|
|
metric: true,
|
|
|
|
metric: true,
|
|
|
|
feet: false,
|
|
|
|
feet: false,
|
|
|
|
showLength: true,
|
|
|
|
showLength: true,
|
|
|
|
shapeOptions: { pane: "drawingsPane", color: "#f97316", weight: 4, opacity: 0.95 }
|
|
|
|
shapeOptions: {
|
|
|
|
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 4,
|
|
|
|
|
|
|
|
opacity: 0.95
|
|
|
|
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
circle: () => new L.Draw.Circle(lmeState.map, {
|
|
|
|
circle: () => new L.Draw.Circle(lmeState.map, {
|
|
|
|
metric: true,
|
|
|
|
metric: true,
|
|
|
|
feet: false,
|
|
|
|
feet: false,
|
|
|
|
showRadius: true,
|
|
|
|
showRadius: true,
|
|
|
|
shapeOptions: { pane: "drawingsPane", color: "#f97316", weight: 4, fillColor: "#fb923c", fillOpacity: 0.2 }
|
|
|
|
shapeOptions: {
|
|
|
|
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 4,
|
|
|
|
|
|
|
|
fillColor: "#fb923c",
|
|
|
|
|
|
|
|
fillOpacity: 0.2
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const createHandler = handlers[mode];
|
|
|
|
const createHandler = handlers[mode];
|
|
|
@@ -2275,6 +2532,9 @@ function startMeasurementDrawing(mode) {
|
|
|
|
|
|
|
|
|
|
|
|
function annotateDrawingLayer(layer, layerType) {
|
|
|
|
function annotateDrawingLayer(layer, layerType) {
|
|
|
|
layer.options.pane = "drawingsPane";
|
|
|
|
layer.options.pane = "drawingsPane";
|
|
|
|
|
|
|
|
if (layer instanceof L.Path) {
|
|
|
|
|
|
|
|
layer.options.renderer = lmeState.drawingsRenderer;
|
|
|
|
|
|
|
|
}
|
|
|
|
layer.feature = layer.feature || { type: "Feature", properties: {} };
|
|
|
|
layer.feature = layer.feature || { type: "Feature", properties: {} };
|
|
|
|
layer.feature.properties = layer.feature.properties || {};
|
|
|
|
layer.feature.properties = layer.feature.properties || {};
|
|
|
|
if (layer instanceof L.Circle) {
|
|
|
|
if (layer instanceof L.Circle) {
|
|
|
@@ -2284,6 +2544,25 @@ function annotateDrawingLayer(layer, layerType) {
|
|
|
|
layer.feature.properties._lmeShape = layerType;
|
|
|
|
layer.feature.properties._lmeShape = layerType;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
layer.lmeManagerLabel = drawingLayerLabel(layer, layerType);
|
|
|
|
layer.lmeManagerLabel = drawingLayerLabel(layer, layerType);
|
|
|
|
|
|
|
|
bindDrawingLayerSelection(layer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function bindDrawingLayerSelection(layer) {
|
|
|
|
|
|
|
|
if (layer.lmeDrawingSelectionBound) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
layer.lmeDrawingSelectionBound = true;
|
|
|
|
|
|
|
|
layer.on("click", event => {
|
|
|
|
|
|
|
|
if (drawingEditActive()) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lmeState.ignoreMapClickUntil = Date.now() + 1000;
|
|
|
|
|
|
|
|
if (event.originalEvent) {
|
|
|
|
|
|
|
|
event.originalEvent._lmeDrawingSelected = true;
|
|
|
|
|
|
|
|
L.DomEvent.stopPropagation(event.originalEvent);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
selectDrawingLayer(layer);
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function setDrawToolsVisible(visible) {
|
|
|
|
function setDrawToolsVisible(visible) {
|
|
|
@@ -2303,6 +2582,8 @@ function setDrawToolsVisible(visible) {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lmeState.map.removeControl(lmeState.drawControl);
|
|
|
|
lmeState.map.removeControl(lmeState.drawControl);
|
|
|
|
lmeState.drawControl = null;
|
|
|
|
lmeState.drawControl = null;
|
|
|
|
|
|
|
|
lmeState.drawingDeleteButton = null;
|
|
|
|
|
|
|
|
lmeState.drawingScopeMenu = null;
|
|
|
|
setInfo("Strumenti di disegno nascosti.");
|
|
|
|
setInfo("Strumenti di disegno nascosti.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -2317,6 +2598,9 @@ function clearDrawings() {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawingEditToolbar()?.disable?.();
|
|
|
|
|
|
|
|
lmeState.drawingSelection?.clearLayers();
|
|
|
|
|
|
|
|
clearManagerHighlight();
|
|
|
|
lmeState.drawings.clearLayers();
|
|
|
|
lmeState.drawings.clearLayers();
|
|
|
|
clearManagedCategoryState("drawings");
|
|
|
|
clearManagedCategoryState("drawings");
|
|
|
|
lmeState.drawingMeasurements.clearLayers();
|
|
|
|
lmeState.drawingMeasurements.clearLayers();
|
|
|
@@ -2699,12 +2983,18 @@ function loadProjectSnapshot(raw, projectName) {
|
|
|
|
|
|
|
|
|
|
|
|
const restoredDrawings = L.geoJSON(data.drawings || emptyFeatureCollection(), {
|
|
|
|
const restoredDrawings = L.geoJSON(data.drawings || emptyFeatureCollection(), {
|
|
|
|
pane: "drawingsPane",
|
|
|
|
pane: "drawingsPane",
|
|
|
|
style: { color: "#f97316", weight: 3, fillOpacity: 0.16 },
|
|
|
|
style: {
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
|
|
|
|
color: "#f97316",
|
|
|
|
|
|
|
|
weight: 3,
|
|
|
|
|
|
|
|
fillOpacity: 0.16
|
|
|
|
|
|
|
|
},
|
|
|
|
pointToLayer: (feature, latlng) => {
|
|
|
|
pointToLayer: (feature, latlng) => {
|
|
|
|
const properties = feature?.properties || {};
|
|
|
|
const properties = feature?.properties || {};
|
|
|
|
if (properties._lmeShape === "circle" && Number(properties._lmeRadius) > 0) {
|
|
|
|
if (properties._lmeShape === "circle" && Number(properties._lmeRadius) > 0) {
|
|
|
|
return L.circle(latlng, {
|
|
|
|
return L.circle(latlng, {
|
|
|
|
pane: "drawingsPane",
|
|
|
|
pane: "drawingsPane",
|
|
|
|
|
|
|
|
renderer: lmeState.drawingsRenderer,
|
|
|
|
radius: Number(properties._lmeRadius),
|
|
|
|
radius: Number(properties._lmeRadius),
|
|
|
|
color: "#f97316",
|
|
|
|
color: "#f97316",
|
|
|
|
weight: 3,
|
|
|
|
weight: 3,
|
|
|
@@ -2712,7 +3002,7 @@ function loadProjectSnapshot(raw, projectName) {
|
|
|
|
fillOpacity: 0.2
|
|
|
|
fillOpacity: 0.2
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return L.marker(latlng, { pane: "drawingsPane", draggable: true });
|
|
|
|
return L.marker(latlng, { pane: "drawingsPane", draggable: false });
|
|
|
|
},
|
|
|
|
},
|
|
|
|
onEachFeature: (feature, layer) => {
|
|
|
|
onEachFeature: (feature, layer) => {
|
|
|
|
bindStoredFeaturePopup(feature, layer);
|
|
|
|
bindStoredFeaturePopup(feature, layer);
|
|
|
@@ -2947,6 +3237,8 @@ function managedGroupGeoJson(group, categoryKey) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function resetLayerManagerProjectState() {
|
|
|
|
function resetLayerManagerProjectState() {
|
|
|
|
|
|
|
|
drawingEditToolbar()?.disable?.();
|
|
|
|
|
|
|
|
lmeState.drawingSelection?.clearLayers();
|
|
|
|
lmeState.managerHiddenObjects.clear();
|
|
|
|
lmeState.managerHiddenObjects.clear();
|
|
|
|
lmeState.managerHiddenObjectIds.clear();
|
|
|
|
lmeState.managerHiddenObjectIds.clear();
|
|
|
|
lmeState.managerHiddenMeasurementSummaryIds.clear();
|
|
|
|
lmeState.managerHiddenMeasurementSummaryIds.clear();
|
|
|
|