Fix geometry comparison and add map multi-select
This commit is contained in:
1 parent
47b58a9b0e
commit
e70a30f7d7
3 files changed
+223
-23
No files matched your search
@@ -29,8 +29,8 @@
|
|||||||
<ApplicationId>it.liviomerola.lmemappecatastali.pro</ApplicationId>
|
<ApplicationId>it.liviomerola.lmemappecatastali.pro</ApplicationId>
|
||||||
|
|
||||||
<!-- Versions -->
|
<!-- Versions -->
|
||||||
<ApplicationDisplayVersion>1.0.20</ApplicationDisplayVersion>
|
<ApplicationDisplayVersion>1.0.21</ApplicationDisplayVersion>
|
||||||
<ApplicationVersion>120</ApplicationVersion>
|
<ApplicationVersion>121</ApplicationVersion>
|
||||||
<Version>$(ApplicationDisplayVersion)</Version>
|
<Version>$(ApplicationDisplayVersion)</Version>
|
||||||
|
|
||||||
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
||||||
|
|||||||
@@ -1271,6 +1271,54 @@ input[type="checkbox"] {
|
|||||||
opacity: 0.72;
|
opacity: 0.72;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lme-geometry-toolbar a.lme-multi-selection-button.is-active {
|
||||||
|
background: #0f766e;
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: inset 0 0 0 2px #99f6e4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lme-geometry-toolbar {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lme-comparison-actions {
|
||||||
|
position: absolute;
|
||||||
|
right: calc(100% + 6px);
|
||||||
|
z-index: 1000;
|
||||||
|
display: grid;
|
||||||
|
min-width: 154px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #b8c1c8;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgb(0 0 0 / 22%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lme-geometry-toolbar .lme-comparison-actions a {
|
||||||
|
display: flex !important;
|
||||||
|
width: auto !important;
|
||||||
|
height: 36px !important;
|
||||||
|
padding: 0 10px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #d7dde1;
|
||||||
|
color: #1f2933;
|
||||||
|
font-size: 13px !important;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lme-geometry-toolbar .lme-comparison-actions a:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lme-geometry-toolbar .lme-comparison-actions a:hover,
|
||||||
|
.lme-geometry-toolbar .lme-comparison-actions a:focus-visible {
|
||||||
|
background: #e8f4f1;
|
||||||
|
color: #075e54;
|
||||||
|
}
|
||||||
|
|
||||||
.leaflet-help {
|
.leaflet-help {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
|
|||||||
+173
-21
@@ -37,6 +37,9 @@ const lmeState = {
|
|||||||
drawingDeleteButton: null,
|
drawingDeleteButton: null,
|
||||||
drawingScopeMenu: null,
|
drawingScopeMenu: null,
|
||||||
geometryToolsControl: null,
|
geometryToolsControl: null,
|
||||||
|
comparisonMenu: null,
|
||||||
|
multiSelectionEnabled: false,
|
||||||
|
multiSelectionButton: null,
|
||||||
fiducialDownloadButton: null,
|
fiducialDownloadButton: null,
|
||||||
ignoreMapClickUntil: 0,
|
ignoreMapClickUntil: 0,
|
||||||
activeDrawHandler: null,
|
activeDrawHandler: null,
|
||||||
@@ -262,6 +265,17 @@ function canAddDrawingObjects(amount = 1) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureLeafletRotateRendererCompatibility() {
|
||||||
|
const rendererPrototype = window.L?.Renderer?.prototype;
|
||||||
|
const currentOnAdd = rendererPrototype?.onAdd;
|
||||||
|
if (!currentOnAdd || currentOnAdd._lmeMapFallback) return;
|
||||||
|
const compatibleOnAdd = function (map) {
|
||||||
|
return currentOnAdd.call(this, map || this._map || lmeState.map);
|
||||||
|
};
|
||||||
|
compatibleOnAdd._lmeMapFallback = true;
|
||||||
|
rendererPrototype.onAdd = compatibleOnAdd;
|
||||||
|
}
|
||||||
|
|
||||||
function init(dotNetReference) {
|
function init(dotNetReference) {
|
||||||
if (dotNetReference) {
|
if (dotNetReference) {
|
||||||
lmeState.dotNetReference = dotNetReference;
|
lmeState.dotNetReference = dotNetReference;
|
||||||
@@ -270,6 +284,7 @@ function init(dotNetReference) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureLeafletRotateRendererCompatibility();
|
||||||
lmeState.map = L.map("map", {
|
lmeState.map = L.map("map", {
|
||||||
zoomControl: false,
|
zoomControl: false,
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
@@ -334,6 +349,7 @@ function init(dotNetReference) {
|
|||||||
});
|
});
|
||||||
lmeState.map.createPane("drawingsMarkerPane", lmeState.map._norotatePane || lmeState.map._mapPane);
|
lmeState.map.createPane("drawingsMarkerPane", lmeState.map._norotatePane || lmeState.map._mapPane);
|
||||||
lmeState.map.createPane("gpsAccuracyPane", lmeState.map._rotatePane || lmeState.map._mapPane);
|
lmeState.map.createPane("gpsAccuracyPane", lmeState.map._rotatePane || lmeState.map._mapPane);
|
||||||
|
lmeState.map.createPane("comparisonPane", lmeState.map._rotatePane || lmeState.map._mapPane);
|
||||||
const managerHighlightPane = lmeState.map.createPane("managerHighlightPane", lmeState.map._rotatePane || lmeState.map._mapPane);
|
const managerHighlightPane = lmeState.map.createPane("managerHighlightPane", lmeState.map._rotatePane || lmeState.map._mapPane);
|
||||||
managerHighlightPane.style.zIndex = "650";
|
managerHighlightPane.style.zIndex = "650";
|
||||||
lmeState.drawingsRenderer = L.canvas({ pane: "drawingsPane", tolerance: 14 });
|
lmeState.drawingsRenderer = L.canvas({ pane: "drawingsPane", tolerance: 14 });
|
||||||
@@ -421,6 +437,10 @@ function init(dotNetReference) {
|
|||||||
&& !event.target?.closest?.(".leaflet-draw-edit-edit, .leaflet-draw-edit-remove")) {
|
&& !event.target?.closest?.(".leaflet-draw-edit-edit, .leaflet-draw-edit-remove")) {
|
||||||
hideDrawingScopeMenu();
|
hideDrawingScopeMenu();
|
||||||
}
|
}
|
||||||
|
if (lmeState.comparisonMenu
|
||||||
|
&& !event.target?.closest?.(".lme-comparison-actions, .lme-comparison-button")) {
|
||||||
|
hideComparisonMenu();
|
||||||
|
}
|
||||||
if (!lmeState.managerHighlightedObjectId && !lmeState.managerHighlightedParentKey) {
|
if (!lmeState.managerHighlightedObjectId && !lmeState.managerHighlightedParentKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1587,7 +1607,7 @@ function setLayerOrder(order) {
|
|||||||
normalized.forEach((key, index) => {
|
normalized.forEach((key, index) => {
|
||||||
const zIndex = String(590 - index * 20);
|
const zIndex = String(590 - index * 20);
|
||||||
const paneNames = [panes[key]];
|
const paneNames = [panes[key]];
|
||||||
if (key === "drawings") paneNames.push("drawingsMarkerPane");
|
if (key === "drawings") paneNames.push("drawingsMarkerPane", "comparisonPane");
|
||||||
if (key === "gpsPosition") paneNames.push("gpsAccuracyPane");
|
if (key === "gpsPosition") paneNames.push("gpsAccuracyPane");
|
||||||
paneNames.forEach(paneName => {
|
paneNames.forEach(paneName => {
|
||||||
const pane = lmeState.map.getPane(paneName);
|
const pane = lmeState.map.getPane(paneName);
|
||||||
@@ -3053,7 +3073,7 @@ function addDrawingFeature(feature, select = false) {
|
|||||||
function storedFeatureStyle(feature) {
|
function storedFeatureStyle(feature) {
|
||||||
const properties = feature?.properties || {};
|
const properties = feature?.properties || {};
|
||||||
return {
|
return {
|
||||||
renderer: lmeState.drawingsRenderer,
|
...(properties._lmeComparisonResult ? { pane: "comparisonPane" } : { renderer: lmeState.drawingsRenderer }),
|
||||||
color: properties._lmeColor || "#f97316",
|
color: properties._lmeColor || "#f97316",
|
||||||
fillColor: properties._lmeFillColor || "#fb923c",
|
fillColor: properties._lmeFillColor || "#fb923c",
|
||||||
weight: Number(properties._lmeWeight) || 3,
|
weight: Number(properties._lmeWeight) || 3,
|
||||||
@@ -3238,22 +3258,116 @@ function compareSelectedGeometries() {
|
|||||||
const onlySecond = turf.difference(turf.featureCollection([second, first]));
|
const onlySecond = turf.difference(turf.featureCollection([second, first]));
|
||||||
const overlap = turf.intersect(turf.featureCollection([first, second]));
|
const overlap = turf.intersect(turf.featureCollection([first, second]));
|
||||||
rememberMapChange();
|
rememberMapChange();
|
||||||
const addResult = (feature, name, color) => {
|
const resultLayers = [];
|
||||||
|
const addResult = (feature, name, color, role) => {
|
||||||
if (!feature) return;
|
if (!feature) return;
|
||||||
feature.properties = { name, _lmeColor: color, _lmeFillColor: color, _lmeFillOpacity: 0.38, _lmeManagerId: undefined };
|
feature.properties = {
|
||||||
addDrawingFeature(feature);
|
name,
|
||||||
|
_lmeColor: color,
|
||||||
|
_lmeFillColor: color,
|
||||||
|
_lmeWeight: 3,
|
||||||
|
_lmeOpacity: 1,
|
||||||
|
_lmeFillOpacity: 0.48,
|
||||||
|
_lmeComparisonResult: true,
|
||||||
|
_lmeComparisonRole: role,
|
||||||
|
_lmeManagerId: undefined
|
||||||
};
|
};
|
||||||
addResult(onlyFirst, `Solo ${managedObjectLabel(polygons[0], 0)}`, "#ef4444");
|
const layer = addDrawingFeature(feature);
|
||||||
addResult(onlySecond, `Solo ${managedObjectLabel(polygons[1], 1)}`, "#3b82f6");
|
if (layer) resultLayers.push(layer);
|
||||||
addResult(overlap, "Sovrapposizione", "#16a34a");
|
};
|
||||||
|
addResult(onlyFirst, `Solo ${managedObjectLabel(polygons[0], 0)}`, "#ef4444", "only-first");
|
||||||
|
addResult(onlySecond, `Solo ${managedObjectLabel(polygons[1], 1)}`, "#2563eb", "only-second");
|
||||||
|
addResult(overlap, "Sovrapposizione", "#16a34a", "overlap");
|
||||||
const firstArea = onlyFirst ? turf.area(onlyFirst) : 0; const secondArea = onlySecond ? turf.area(onlySecond) : 0; const overlapArea = overlap ? turf.area(overlap) : 0;
|
const firstArea = onlyFirst ? turf.area(onlyFirst) : 0; const secondArea = onlySecond ? turf.area(onlySecond) : 0; const overlapArea = overlap ? turf.area(overlap) : 0;
|
||||||
const message = `Confronto creato. Solo primo confine: ${formatArea(firstArea)}. Solo secondo confine: ${formatArea(secondArea)}. Sovrapposizione: ${formatArea(overlapArea)}.`;
|
const message = `Confronto creato. Solo primo confine: ${formatArea(firstArea)}. Solo secondo confine: ${formatArea(secondArea)}. Sovrapposizione: ${formatArea(overlapArea)}.`;
|
||||||
|
lmeState.managerSelectedObjectIds.clear();
|
||||||
|
clearManagerHighlight();
|
||||||
finishManagedGeometryChange(message);
|
finishManagedGeometryChange(message);
|
||||||
|
resultLayers.forEach(layer => layer.bringToFront?.());
|
||||||
showGeometryResult("Confronto completato", `${message} Sulla mappa: rosso solo primo, blu solo secondo, verde sovrapposizione.`, "success");
|
showGeometryResult("Confronto completato", `${message} Sulla mappa: rosso solo primo, blu solo secondo, verde sovrapposizione.`, "success");
|
||||||
return true;
|
return true;
|
||||||
} catch (error) { showGeometryResult("Confronto non riuscito", error.message, "error"); return false; }
|
} catch (error) { showGeometryResult("Confronto non riuscito", error.message, "error"); return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isComparisonResultLayer(layer) {
|
||||||
|
const properties = layer?.feature?.properties || {};
|
||||||
|
if (properties._lmeComparisonResult || properties._lmeComparisonRole) return true;
|
||||||
|
const name = String(properties.name || "");
|
||||||
|
const color = String(properties._lmeFillColor || properties._lmeColor || "").toLowerCase();
|
||||||
|
return (name.startsWith("Solo ") && ["#ef4444", "#3b82f6", "#2563eb"].includes(color))
|
||||||
|
|| (name === "Sovrapposizione" && color === "#16a34a");
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearComparisonResults() {
|
||||||
|
hideComparisonMenu();
|
||||||
|
if (lmeState.readOnly) { setInfo("Il progetto e' in sola lettura."); return false; }
|
||||||
|
const layers = lmeState.drawings?.getLayers?.().filter(isComparisonResultLayer) || [];
|
||||||
|
if (!layers.length) {
|
||||||
|
setInfo("Non ci sono risultati di confronto da rimuovere.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rememberMapChange();
|
||||||
|
layers.forEach(layer => {
|
||||||
|
const id = layer.feature?.properties?._lmeManagerId;
|
||||||
|
if (id) {
|
||||||
|
lmeState.managerSelectedObjectIds.delete(id);
|
||||||
|
clearManagedObjectState(id);
|
||||||
|
}
|
||||||
|
lmeState.drawings.removeLayer(layer);
|
||||||
|
});
|
||||||
|
clearManagerHighlight();
|
||||||
|
const message = `Rimossi ${layers.length} layer del confronto.`;
|
||||||
|
finishManagedGeometryChange(message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showComparisonMenu(button) {
|
||||||
|
if (lmeState.comparisonMenu) {
|
||||||
|
hideComparisonMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const menu = L.DomUtil.create("div", "lme-comparison-actions", button.parentElement);
|
||||||
|
menu.style.top = `${button.offsetTop}px`;
|
||||||
|
menu.innerHTML = `<a href="#" data-comparison-action="compare">Confronta</a><a href="#" data-comparison-action="clear">Pulisci confronto</a>`;
|
||||||
|
lmeState.comparisonMenu = menu;
|
||||||
|
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", () => {
|
||||||
|
const action = link.dataset.comparisonAction;
|
||||||
|
hideComparisonMenu();
|
||||||
|
if (action === "compare") compareSelectedGeometries();
|
||||||
|
else clearComparisonResults();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideComparisonMenu() {
|
||||||
|
lmeState.comparisonMenu?.remove();
|
||||||
|
lmeState.comparisonMenu = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMultiSelection() {
|
||||||
|
lmeState.multiSelectionEnabled = !lmeState.multiSelectionEnabled;
|
||||||
|
lmeState.multiSelectionButton?.classList.toggle("is-active", lmeState.multiSelectionEnabled);
|
||||||
|
lmeState.multiSelectionButton?.setAttribute("aria-pressed", String(lmeState.multiSelectionEnabled));
|
||||||
|
setInfo(lmeState.multiSelectionEnabled
|
||||||
|
? "Selezione multipla attiva: tocca gli oggetti per aggiungerli o rimuoverli dalla selezione."
|
||||||
|
: "Selezione multipla disattivata.");
|
||||||
|
return lmeState.multiSelectionEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshMultipleMapSelection(preferredRecord) {
|
||||||
|
clearManagerHighlight();
|
||||||
|
const selectedRecords = selectedManagedRecords();
|
||||||
|
if (!selectedRecords.length) return;
|
||||||
|
const current = selectedRecords.find(record => record.id === preferredRecord?.id) || selectedRecords.at(-1);
|
||||||
|
lmeState.managerHighlightedObjectId = current?.id || null;
|
||||||
|
lmeState.managerHighlightedCategoryKey = current?.categoryKey || null;
|
||||||
|
renderManagerHighlight(selectedRecords);
|
||||||
|
}
|
||||||
|
|
||||||
function showGeometryResult(title, message, tone = "success") {
|
function showGeometryResult(title, message, tone = "success") {
|
||||||
setInfo(`${title}: ${message}`);
|
setInfo(`${title}: ${message}`);
|
||||||
const icons = { success: "✓", warning: "!", error: "×" };
|
const icons = { success: "✓", warning: "!", error: "×" };
|
||||||
@@ -3275,9 +3389,10 @@ function showLeafletToolbarHelp() {
|
|||||||
<div><dt>▱</dt><dd><strong>Elimina disegni</strong>Premi il cestino e scegli Solo selezionato oppure Tutti. L'oggetto rimosso può essere recuperato con Annulla o dal cestino negli strumenti avanzati.</dd></div>
|
<div><dt>▱</dt><dd><strong>Elimina disegni</strong>Premi il cestino e scegli Solo selezionato oppure Tutti. L'oggetto rimosso può essere recuperato con Annulla o dal cestino negli strumenti avanzati.</dd></div>
|
||||||
<div><dt>✓</dt><dd><strong>Controlla e ripara</strong>Verifica gli oggetti selezionati e prova a correggere coordinate duplicate o poligoni non validi. Esempio: usalo quando un contorno importato non si esporta o si riempie male; al termine compare un riepilogo.</dd></div>
|
<div><dt>✓</dt><dd><strong>Controlla e ripara</strong>Verifica gli oggetti selezionati e prova a correggere coordinate duplicate o poligoni non validi. Esempio: usalo quando un contorno importato non si esporta o si riempie male; al termine compare un riepilogo.</dd></div>
|
||||||
<div><dt>◉</dt><dd><strong>Crea foro</strong>Seleziona esattamente due poligoni: prima l'area esterna, poi quella interna. Esempio: sottrai il cortile dal perimetro di un fabbricato o un'isola esclusa da un'area di lavoro.</dd></div>
|
<div><dt>◉</dt><dd><strong>Crea foro</strong>Seleziona esattamente due poligoni: prima l'area esterna, poi quella interna. Esempio: sottrai il cortile dal perimetro di un fabbricato o un'isola esclusa da un'area di lavoro.</dd></div>
|
||||||
<div><dt>⇄</dt><dd><strong>Confronta due confini</strong>Seleziona esattamente due poligoni. L'app crea il solo primo in rosso, il solo secondo in blu e la sovrapposizione in verde, mostrando le rispettive aree.</dd></div>
|
<div><dt>☑</dt><dd><strong>Selezione multipla</strong>Attiva il comando e tocca più oggetti sulla mappa per aggiungerli o rimuoverli dalla selezione. Disattivalo per tornare alla selezione singola. È utile prima di Confronta, Unisci, Buffer e altre operazioni su più oggetti.</dd></div>
|
||||||
|
<div><dt>⇄</dt><dd><strong>Confronta due confini</strong>Apri il comando e scegli Confronta dopo aver selezionato esattamente due poligoni. L'app crea il solo primo in rosso, il solo secondo in blu e la sovrapposizione in verde. Usa Pulisci confronto per rimuovere soltanto questi risultati.</dd></div>
|
||||||
<div><dt>PF</dt><dd><strong>Scarica Punti Fiduciali</strong>Seleziona una particella o un foglio catastale; in alternativa usa la particella rilevata dal GPS. I PF vengono aggiunti come sottogruppo del relativo foglio e richiedono LME Pro.</dd></div>
|
<div><dt>PF</dt><dd><strong>Scarica Punti Fiduciali</strong>Seleziona una particella o un foglio catastale; in alternativa usa la particella rilevata dal GPS. I PF vengono aggiunti come sottogruppo del relativo foglio e richiedono LME Pro.</dd></div>
|
||||||
<div><dt>?</dt><dd><strong>Guida</strong>Riapre questa descrizione. I risultati di riparazione e confronto vengono mostrati anche in una finestra; per uscire dal confronto usa Annulla oppure avvia un nuovo confronto.</dd></div>
|
<div><dt>?</dt><dd><strong>Guida</strong>Riapre questa descrizione. I risultati di riparazione e confronto vengono mostrati anche in una finestra; per uscire dalla visualizzazione rosso, blu e verde usa Pulisci confronto.</dd></div>
|
||||||
</dl>
|
</dl>
|
||||||
</div>`);
|
</div>`);
|
||||||
}
|
}
|
||||||
@@ -3291,7 +3406,8 @@ function addGeometryToolsControl() {
|
|||||||
const actions = [
|
const actions = [
|
||||||
{ icon: "✓", title: "Controlla e ripara geometrie", run: validateAndRepairSelected },
|
{ icon: "✓", title: "Controlla e ripara geometrie", run: validateAndRepairSelected },
|
||||||
{ icon: "◉", title: "Crea foro da due poligoni", run: createHoleFromSelected },
|
{ icon: "◉", title: "Crea foro da due poligoni", run: createHoleFromSelected },
|
||||||
{ icon: "⇄", title: "Confronta due confini", run: compareSelectedGeometries },
|
{ icon: "☑", title: "Attiva o disattiva selezione multipla", run: toggleMultiSelection, multiSelection: true },
|
||||||
|
{ icon: "⇄", title: "Confronta o pulisci confronto", comparison: true },
|
||||||
{ icon: "PF", title: "Scarica PF del foglio o della particella", run: downloadFiducialsForMapContext, fiducials: true },
|
{ icon: "PF", title: "Scarica PF del foglio o della particella", run: downloadFiducialsForMapContext, fiducials: true },
|
||||||
{ icon: "?", title: "Guida strumenti mappa", run: showLeafletToolbarHelp }
|
{ icon: "?", title: "Guida strumenti mappa", run: showLeafletToolbarHelp }
|
||||||
];
|
];
|
||||||
@@ -3306,7 +3422,17 @@ function addGeometryToolsControl() {
|
|||||||
button.classList.add("lme-fiducial-download");
|
button.classList.add("lme-fiducial-download");
|
||||||
lmeState.fiducialDownloadButton = button;
|
lmeState.fiducialDownloadButton = button;
|
||||||
}
|
}
|
||||||
L.DomEvent.on(button, "click", event => { L.DomEvent.stop(event); action.run(); });
|
if (action.comparison) button.classList.add("lme-comparison-button");
|
||||||
|
if (action.multiSelection) {
|
||||||
|
button.classList.add("lme-multi-selection-button");
|
||||||
|
button.setAttribute("aria-pressed", String(lmeState.multiSelectionEnabled));
|
||||||
|
lmeState.multiSelectionButton = button;
|
||||||
|
}
|
||||||
|
L.DomEvent.on(button, "click", event => {
|
||||||
|
L.DomEvent.stop(event);
|
||||||
|
if (action.comparison) showComparisonMenu(button);
|
||||||
|
else action.run();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
L.DomEvent.disableClickPropagation(container);
|
L.DomEvent.disableClickPropagation(container);
|
||||||
return container;
|
return container;
|
||||||
@@ -4667,12 +4793,17 @@ function startMeasurementDrawing(mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function annotateDrawingLayer(layer, layerType) {
|
function annotateDrawingLayer(layer, layerType) {
|
||||||
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 || {};
|
||||||
|
const isComparisonResult = Boolean(layer.feature.properties._lmeComparisonResult);
|
||||||
|
layer.options.pane = isComparisonResult ? "comparisonPane" : "drawingsPane";
|
||||||
|
if (layer instanceof L.Path) {
|
||||||
|
if (isComparisonResult) {
|
||||||
|
delete layer.options.renderer;
|
||||||
|
} else {
|
||||||
|
layer.options.renderer = lmeState.drawingsRenderer;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (layer instanceof L.Circle) {
|
if (layer instanceof L.Circle) {
|
||||||
layer.feature.properties._lmeShape = "circle";
|
layer.feature.properties._lmeShape = "circle";
|
||||||
layer.feature.properties._lmeRadius = layer.getRadius();
|
layer.feature.properties._lmeRadius = layer.getRadius();
|
||||||
@@ -4698,16 +4829,27 @@ function bindDrawingLayerSelection(layer) {
|
|||||||
L.DomEvent.stopPropagation(event.originalEvent);
|
L.DomEvent.stopPropagation(event.originalEvent);
|
||||||
}
|
}
|
||||||
const id = managedLayerId(layer, "drawings");
|
const id = managedLayerId(layer, "drawings");
|
||||||
if (event.originalEvent?.ctrlKey || event.originalEvent?.metaKey || event.originalEvent?.shiftKey) {
|
const multiple = lmeState.multiSelectionEnabled
|
||||||
|
|| event.originalEvent?.ctrlKey
|
||||||
|
|| event.originalEvent?.metaKey
|
||||||
|
|| event.originalEvent?.shiftKey;
|
||||||
|
if (multiple) {
|
||||||
if (lmeState.managerSelectedObjectIds.has(id)) lmeState.managerSelectedObjectIds.delete(id);
|
if (lmeState.managerSelectedObjectIds.has(id)) lmeState.managerSelectedObjectIds.delete(id);
|
||||||
else lmeState.managerSelectedObjectIds.add(id);
|
else lmeState.managerSelectedObjectIds.add(id);
|
||||||
} else {
|
} else {
|
||||||
lmeState.managerSelectedObjectIds.clear();
|
lmeState.managerSelectedObjectIds.clear();
|
||||||
lmeState.managerSelectedObjectIds.add(id);
|
lmeState.managerSelectedObjectIds.add(id);
|
||||||
}
|
}
|
||||||
selectDrawingLayer(layer);
|
|
||||||
refreshLayerManager();
|
refreshLayerManager();
|
||||||
|
if (multiple) {
|
||||||
|
refreshMultipleMapSelection({ id, categoryKey: "drawings", layer, parent: lmeState.drawings });
|
||||||
|
setInfo(`${lmeState.managerSelectedObjectIds.size} oggetti selezionati.`);
|
||||||
|
} else {
|
||||||
|
selectDrawingLayer(layer);
|
||||||
|
}
|
||||||
|
if (lmeState.managerSelectedObjectIds.has(id)) {
|
||||||
window.requestAnimationFrame(() => revealManagedRecordInLayerManager(id));
|
window.requestAnimationFrame(() => revealManagedRecordInLayerManager(id));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4722,14 +4864,24 @@ function bindManagedMapSelection(layer, categoryKey, parent) {
|
|||||||
L.DomEvent.stopPropagation(event.originalEvent);
|
L.DomEvent.stopPropagation(event.originalEvent);
|
||||||
}
|
}
|
||||||
const record = { id: managedLayerId(layer, categoryKey), categoryKey, layer, parent, source: String(layer?.feature?.properties?._lmeSource || "Progetto corrente") };
|
const record = { id: managedLayerId(layer, categoryKey), categoryKey, layer, parent, source: String(layer?.feature?.properties?._lmeSource || "Progetto corrente") };
|
||||||
const multiple = event.originalEvent?.ctrlKey || event.originalEvent?.metaKey || event.originalEvent?.shiftKey;
|
const multiple = lmeState.multiSelectionEnabled
|
||||||
|
|| event.originalEvent?.ctrlKey
|
||||||
|
|| event.originalEvent?.metaKey
|
||||||
|
|| event.originalEvent?.shiftKey;
|
||||||
if (!multiple) lmeState.managerSelectedObjectIds.clear();
|
if (!multiple) lmeState.managerSelectedObjectIds.clear();
|
||||||
if (multiple && lmeState.managerSelectedObjectIds.has(record.id)) lmeState.managerSelectedObjectIds.delete(record.id);
|
if (multiple && lmeState.managerSelectedObjectIds.has(record.id)) lmeState.managerSelectedObjectIds.delete(record.id);
|
||||||
else lmeState.managerSelectedObjectIds.add(record.id);
|
else lmeState.managerSelectedObjectIds.add(record.id);
|
||||||
highlightManagedObject(record);
|
|
||||||
refreshLayerManager();
|
refreshLayerManager();
|
||||||
window.requestAnimationFrame(() => revealManagedRecordInLayerManager(record.id));
|
if (multiple) {
|
||||||
|
refreshMultipleMapSelection(record);
|
||||||
|
setInfo(`${lmeState.managerSelectedObjectIds.size} oggetti selezionati.`);
|
||||||
|
} else {
|
||||||
|
highlightManagedObject(record);
|
||||||
setInfo(`Selezionato dalla mappa: ${managedObjectEditableName(record) || "oggetto"}.`);
|
setInfo(`Selezionato dalla mappa: ${managedObjectEditableName(record) || "oggetto"}.`);
|
||||||
|
}
|
||||||
|
if (lmeState.managerSelectedObjectIds.has(record.id)) {
|
||||||
|
window.requestAnimationFrame(() => revealManagedRecordInLayerManager(record.id));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user