Show cadastral sheets while navigating

This commit is contained in:
livio committed 2026-10-02 11:24:35 +02:00
1 parent 5ea424b46c
commit 342935d99d
6 files changed
+206 -22

No files matched your search

+15
View File
@@ -1318,6 +1318,21 @@ input[type="checkbox"] {
height: 38px;
}
.cadastral-sheet-label {
width: auto !important;
height: auto !important;
border: 1px solid #9a5b00;
border-radius: 4px;
padding: 3px 6px;
background: rgba(255, 251, 235, 0.94);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.28);
color: #713f12;
font-size: 11px;
font-weight: 800;
line-height: 1.2;
white-space: nowrap;
}
.lme-drawing-scope-actions a[aria-disabled="true"] {
opacity: 0.45;
pointer-events: none;
+177 -18
View File
@@ -14,8 +14,14 @@ const lmeState = {
"cadastre"
],
cadastre: null,
cadastreZoning: null,
cadastreLayers: ["CP.CadastralParcel", "codice_plla", "CP.CadastralZoning", "fabbricati"],
cadastreOpacity: 0.75,
navigationSheetLayer: null,
navigationSheetFeature: null,
navigationSheetLabel: null,
navigationSheetRefreshTimer: null,
navigationSheetRequestId: 0,
imported: null,
importedVisible: true,
importedSheets: null,
@@ -305,6 +311,13 @@ function init(dotNetReference) {
lmeState.drawingMeasurements = L.layerGroup().addTo(lmeState.map);
lmeState.selectedParcelsLayer = L.featureGroup().addTo(lmeState.map);
lmeState.gpsParcelLayer = L.featureGroup().addTo(lmeState.map);
const navigationSheetPane = lmeState.map.createPane("navigationSheetPane");
navigationSheetPane.style.zIndex = "465";
navigationSheetPane.style.pointerEvents = "none";
const cadastreZoningPane = lmeState.map.createPane("cadastreZoningPane");
cadastreZoningPane.style.zIndex = "455";
cadastreZoningPane.style.pointerEvents = "none";
lmeState.navigationSheetLayer = L.layerGroup().addTo(lmeState.map);
lmeState.gpsTrail = L.polyline([], {
pane: "gpsTrailPane",
color: "#f97316",
@@ -339,6 +352,7 @@ function init(dotNetReference) {
lmeState.map.on("moveend", () => {
void updateAzureAttribution();
scheduleMeasurementRefresh();
scheduleNavigationSheetRefresh();
});
document.getElementById("closeWmsPreview")?.addEventListener("click", closeCadastrePreview);
@@ -5387,6 +5401,9 @@ function setCadastreOpacity(value) {
if (lmeState.cadastre) {
lmeState.cadastre.setOpacity(lmeState.cadastreOpacity);
}
if (lmeState.cadastreZoning) {
lmeState.cadastreZoning.setOpacity(Math.max(0.8, lmeState.cadastreOpacity));
}
}
function toggleCadastreLayer(layer, enabled) {
@@ -5398,6 +5415,13 @@ function toggleCadastreLayer(layer, enabled) {
lmeState.cadastreLayers = lmeState.cadastreLayers.filter(item => item !== layer);
}
refreshCadastreLayer();
if (layer === "CP.CadastralZoning") {
if (enabled) {
scheduleNavigationSheetRefresh(true);
} else {
clearNavigationSheetOutline();
}
}
const layerNames = {
"CP.CadastralParcel": "Confini particelle",
codice_plla: "Numeri particelle",
@@ -5413,29 +5437,166 @@ function toggleCadastreLayer(layer, enabled) {
setInfo(`${layerNames[layer] || layer}: ${enabled ? "attivo" : "nascosto"}.`);
}
function scheduleNavigationSheetRefresh(immediate = false) {
window.clearTimeout(lmeState.navigationSheetRefreshTimer);
if (!lmeState.map
|| !lmeState.dotNetReference
|| !lmeState.cadastreLayers.includes("CP.CadastralZoning")) {
return;
}
if (lmeState.map.getZoom() < 15) {
clearNavigationSheetOutline();
return;
}
lmeState.navigationSheetRefreshTimer = window.setTimeout(
() => void refreshNavigationSheetOutline(),
immediate ? 0 : 650);
}
async function refreshNavigationSheetOutline() {
if (!lmeState.map
|| !lmeState.dotNetReference
|| !lmeState.cadastreLayers.includes("CP.CadastralZoning")) {
return;
}
const center = lmeState.map.getCenter();
const point = [center.lng, center.lat];
if (loadedCadastralSheetAt(point)) {
clearNavigationSheetOutline();
return;
}
if (lmeState.navigationSheetFeature?.geometry
&& geometryContainsPoint(lmeState.navigationSheetFeature.geometry, point)) {
lmeState.navigationSheetLabel?.setLatLng(center);
return;
}
const requestId = ++lmeState.navigationSheetRequestId;
try {
const xml = await lmeState.dotNetReference.invokeMethodAsync(
"GetOfficialCadastralSheetsNear",
center.lat,
center.lng);
if (requestId !== lmeState.navigationSheetRequestId
|| !lmeState.cadastreLayers.includes("CP.CadastralZoning")) {
return;
}
const candidates = gmlParcelsToGeoJson(xml).features || [];
const sheet = findContainingPolygon(point, { type: "FeatureCollection", features: candidates })
|| candidates[0];
if (!sheet) {
return;
}
const reference = String(sheet.properties?.NATIONALCADASTRALZONINGREFERENCE
|| sheet.properties?.LABEL
|| "").trim();
const previousReference = String(
lmeState.navigationSheetFeature?.properties?.NATIONALCADASTRALZONINGREFERENCE
|| lmeState.navigationSheetFeature?.properties?.LABEL
|| "").trim();
lmeState.navigationSheetFeature = sheet;
lmeState.navigationSheetLayer.clearLayers();
L.geoJSON(sheet, {
pane: "navigationSheetPane",
interactive: false,
style: {
color: "#f59e0b",
weight: 4,
opacity: 0.95,
dashArray: "10 6",
fillColor: "#fbbf24",
fillOpacity: 0.055
}
}).addTo(lmeState.navigationSheetLayer);
lmeState.navigationSheetLabel = L.marker(center, {
pane: "navigationSheetPane",
interactive: false,
icon: L.divIcon({
className: "cadastral-sheet-label",
html: escapeHtml(reference ? `Foglio ${reference}` : "Foglio catastale")
})
}).addTo(lmeState.navigationSheetLayer);
if (reference && reference !== previousReference) {
setInfo(`Confine del foglio catastale ${reference} caricato.`);
}
} catch {
if (requestId === lmeState.navigationSheetRequestId) {
setInfo("Confine del foglio catastale non disponibile dal servizio AdE. Riprovo al prossimo spostamento.");
}
}
}
function clearNavigationSheetOutline() {
window.clearTimeout(lmeState.navigationSheetRefreshTimer);
lmeState.navigationSheetRequestId++;
lmeState.navigationSheetFeature = null;
lmeState.navigationSheetLabel = null;
lmeState.navigationSheetLayer?.clearLayers();
}
function loadedCadastralSheetAt(point) {
const features = [
...(lmeState.importedSheets?.toGeoJSON?.()?.features || []),
...(lmeState.imported?.toGeoJSON?.()?.features || [])
].filter(feature => ["Polygon", "MultiPolygon"].includes(feature?.geometry?.type)
&& (feature.properties?._lmeOfficialSheet
|| feature.properties?.NATIONALCADASTRALZONINGREFERENCE
|| isSheetOrOverlayFeature(feature)));
return findContainingPolygon(point, { type: "FeatureCollection", features });
}
function refreshCadastreLayer() {
if (lmeState.cadastre) {
lmeState.map.removeLayer(lmeState.cadastre);
}
const layers = activeCadastreLayers();
lmeState.cadastre = null;
if (!layers.length) {
return;
if (lmeState.cadastreZoning) {
lmeState.map.removeLayer(lmeState.cadastreZoning);
}
const cadastreLayer = L.tileLayer.wms(cadastreUrl(), {
pane: "cadastrePane",
layers: layers.join(","),
format: "image/png",
transparent: true,
version: "1.1.1",
crs: cadastreCrs,
maxZoom: 22,
opacity: lmeState.cadastreOpacity,
attribution: "Agenzia delle Entrate - CC BY 4.0"
});
const zoningEnabled = lmeState.cadastreLayers.includes("CP.CadastralZoning");
const layers = activeCadastreLayers().filter(layer => layer !== "CP.CadastralZoning");
lmeState.cadastre = null;
lmeState.cadastreZoning = null;
if (layers.length) {
const cadastreLayer = L.tileLayer.wms(cadastreUrl(), {
pane: "cadastrePane",
layers: layers.join(","),
format: "image/png",
transparent: true,
version: "1.1.1",
crs: cadastreCrs,
maxZoom: 22,
opacity: lmeState.cadastreOpacity,
attribution: "Agenzia delle Entrate - CC BY 4.0"
});
attachCadastreTileRecovery(cadastreLayer);
lmeState.cadastre = cadastreLayer.addTo(lmeState.map);
}
if (zoningEnabled) {
const zoningLayer = L.tileLayer.wms(cadastreUrl(), {
pane: "cadastreZoningPane",
layers: "CP.CadastralZoning",
format: "image/png",
transparent: true,
version: "1.1.1",
crs: cadastreCrs,
minZoom: 8,
maxZoom: 14,
opacity: Math.max(0.8, lmeState.cadastreOpacity),
attribution: "Agenzia delle Entrate - CC BY 4.0"
});
attachCadastreTileRecovery(zoningLayer);
lmeState.cadastreZoning = zoningLayer.addTo(lmeState.map);
scheduleNavigationSheetRefresh(true);
}
}
function attachCadastreTileRecovery(cadastreLayer) {
let errorShown = false;
cadastreLayer.on("tileerror", event => {
const tile = event?.tile;
@@ -5459,8 +5620,6 @@ function refreshCadastreLayer() {
cadastreLayer.on("load", () => {
errorShown = false;
});
lmeState.cadastre = cadastreLayer.addTo(lmeState.map);
}
function activeCadastreLayers() {