diff --git a/Components/MenuHelp.razor b/Components/MenuHelp.razor
index 19c58fe..db5ef58 100644
--- a/Components/MenuHelp.razor
+++ b/Components/MenuHelp.razor
@@ -61,7 +61,7 @@
"fiducials" =>
[
"La funzione richiede LME Pro: sono validi sia l'abbonamento Google Play sia una licenza manuale attiva.",
- "Scegli Provincia, Comune catastale e Foglio, quindi premi Cerca Punti Fiduciali. Puoi anche usare il comando PF sulla mappa dopo aver selezionato una particella o un foglio, oppure dalla particella individuata dal GPS.",
+ "Scegli Provincia, Comune catastale e Foglio, quindi premi Cerca Punti Fiduciali. Puoi anche usare il comando PF sulla mappa dopo aver selezionato una particella o un foglio, dalla particella individuata dal GPS oppure, in navigazione, mostrando il layer del foglio catastale corrente.",
"Mantieni i PF dei fogli gia caricati conserva i risultati precedenti come sottogruppi distinti; disattivalo per sostituirli con il nuovo foglio.",
"Il flag Mostra i PF sulla mappa controlla la visibilita generale. Nel pannello Layer puoi inoltre cambiare colore, ordine, visibilita o rimuovere il singolo gruppo del foglio.",
"Tocca un punto rosso per vedere identificativo e coordinate. Quando disponibile, Scarica PDF monografia apre o salva il documento ufficiale dell'Agenzia delle Entrate.",
diff --git a/LMEMappeCatastaliApp.csproj b/LMEMappeCatastaliApp.csproj
index 47cda2c..53c321f 100644
--- a/LMEMappeCatastaliApp.csproj
+++ b/LMEMappeCatastaliApp.csproj
@@ -29,8 +29,8 @@
it.liviomerola.lmemappecatastali.pro
- 1.0.24
- 124
+ 1.0.25
+ 125
$(ApplicationDisplayVersion)
diff --git a/wwwroot/js/lme-map.js b/wwwroot/js/lme-map.js
index d627b49..d5e0c0a 100644
--- a/wwwroot/js/lme-map.js
+++ b/wwwroot/js/lme-map.js
@@ -2224,9 +2224,9 @@ function managedObjectDetails(layer) {
}
function refreshLayerManager() {
- updateFiducialDownloadButton();
const container = document.getElementById("layerManagerTree");
if (!container || !lmeState.map) {
+ updateFiducialDownloadButton();
return;
}
captureLayerManagerExpansion(container);
@@ -2274,6 +2274,7 @@ function refreshLayerManager() {
});
}
if (selectionHasObjects()) renderSelectedManagerHighlight();
+ updateFiducialDownloadButton();
}
function renderLayerManagerCategory(category, records) {
@@ -3625,7 +3626,7 @@ function showLeafletToolbarHelp() {
◉Crea foroSeleziona 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.
✓Modalita di selezioneScegli Singola, Multipla o Disattivata. Mappa, pannello Layer e tabella oggetti condividono la stessa selezione. Disattivata e Cancella selezione deselezionano tutto senza eliminare alcun oggetto.
⇄Confronta due confiniApri il comando e scegli Confronta dopo aver selezionato esattamente due poligoni. Il gruppo Confronto confini viene collocato sopra gli altri layer: rosso indica solo il primo, blu solo il secondo e verde la sovrapposizione. Usa Pulisci confronto per rimuovere soltanto questi risultati.
- PFScarica Punti FiducialiSeleziona 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.
+ PFScarica Punti FiducialiSeleziona una particella o un foglio catastale; in navigazione puoi anche mostrare il foglio catastale corrente. In alternativa usa la particella rilevata dal GPS. I PF vengono aggiunti come sottogruppo del relativo foglio e richiedono LME Pro.
?GuidaRiapre 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.
`);
@@ -3708,6 +3709,16 @@ function currentFiducialMapContext() {
if (context) return context;
}
+ const navigationContext = fiducialContextFromFeature(lmeState.navigationSheetFeature);
+ if (navigationContext) return navigationContext;
+
+ if (lmeState.map && lmeState.cadastreLayers.includes("CP.CadastralZoning")) {
+ const center = lmeState.map.getCenter();
+ const containingSheet = loadedCadastralSheetAt([center.lng, center.lat]);
+ const containingSheetContext = fiducialContextFromFeature(containingSheet);
+ if (containingSheetContext) return containingSheetContext;
+ }
+
const gpsLayers = managedRecordsForCategory(layerManagerCategories().find(category => category.key === "gpsParcels"));
for (const record of gpsLayers) {
const context = fiducialContextFromLayer(record.layer);
@@ -3717,11 +3728,37 @@ function currentFiducialMapContext() {
}
function fiducialContextFromLayer(layer) {
- const properties = layer?.feature?.properties || {};
- const municipalityCode = String(properties._lmeMunicipalityCode || "").trim().toUpperCase();
- const sheet = normalizeFiducialSheet(properties._lmeSheet || properties.foglio || properties.FOGLIO || properties.sheet || properties.SHEET);
- if (/^[A-Z][0-9A-Z]{3}$/.test(municipalityCode) && sheet) {
- return { municipalityCode, sheet, label: `Comune ${municipalityCode}, foglio ${sheet}` };
+ return fiducialContextFromFeature(layer?.feature);
+}
+
+function fiducialContextFromFeature(feature) {
+ const properties = feature?.properties || {};
+ const municipalityValues = [
+ properties._lmeMunicipalityCode,
+ properties.municipalityCode,
+ properties.MUNICIPALITYCODE,
+ properties.codiceComune,
+ properties.CODICECOMUNE,
+ properties.CODICE_COMUNE,
+ properties.codiceCatastale,
+ properties.CODICE_CATASTALE,
+ properties.comune,
+ properties.COMUNE,
+ properties.ADMINISTRATIVEUNIT
+ ];
+ const municipalityCode = municipalityValues
+ .map(normalizeFiducialMunicipalityCode)
+ .find(Boolean) || "";
+ const sheetValues = [
+ properties._lmeSheet,
+ properties.foglio,
+ properties.FOGLIO,
+ properties.sheet,
+ properties.SHEET
+ ];
+ const explicitSheet = sheetValues.map(normalizeSimpleFiducialSheet).find(Boolean) || "";
+ if (municipalityCode && explicitSheet) {
+ return fiducialContext(municipalityCode, explicitSheet);
}
const references = [
@@ -3729,18 +3766,65 @@ function fiducialContextFromLayer(layer) {
properties.NATIONALCADASTRALZONINGREFERENCE,
properties.INSPIREID_LOCALID,
properties._lmeParcelReference,
- properties.LABEL
- ].filter(Boolean).map(value => String(value).toUpperCase());
+ properties._lmeSheetIdentity,
+ properties._lmeSource,
+ properties._lmeFolder,
+ properties._lmeGroupName,
+ properties.LABEL,
+ properties.label,
+ properties.name,
+ properties.Name,
+ ...sheetValues
+ ].filter(Boolean);
for (const reference of references) {
- const match = reference.match(/(?:^|\.)([A-Z][0-9A-Z]{3})[_-](\d{4})(?:\d{2})?(?:[._-]|$)/);
- if (match) {
- const parsedSheet = normalizeFiducialSheet(match[2]);
- return { municipalityCode: match[1], sheet: parsedSheet, label: `Comune ${match[1]}, foglio ${parsedSheet}` };
- }
+ const context = fiducialContextFromText(reference, municipalityCode);
+ if (context) return context;
}
return null;
}
+function fiducialContextFromText(value, fallbackMunicipalityCode = "") {
+ const text = String(value ?? "").trim().toUpperCase();
+ if (!text) return null;
+
+ const codedReference = text.match(/(?:^|[^0-9A-Z])([A-Z][0-9A-Z]{3})[._-](\d{4})(?:[0-9A-Z]{2})?(?=[._/\s-]|$)/);
+ if (codedReference) {
+ return fiducialContext(codedReference[1], codedReference[2]);
+ }
+
+ const fiducialReference = text.match(/\bPF\w*\s*[/_-]\s*0*(\d{1,4})\s*[/_-]\s*([A-Z][0-9A-Z]{3})\b/);
+ if (fiducialReference) {
+ return fiducialContext(fiducialReference[2], fiducialReference[1]);
+ }
+
+ const namedSheet = text.match(/\bFOGLIO\s*[:#._/-]*\s*0*(\d{1,4})\b/);
+ if (fallbackMunicipalityCode && namedSheet) {
+ return fiducialContext(fallbackMunicipalityCode, namedSheet[1]);
+ }
+ return null;
+}
+
+function fiducialContext(municipalityCode, sheet) {
+ const normalizedMunicipalityCode = normalizeFiducialMunicipalityCode(municipalityCode);
+ const normalizedSheet = normalizeFiducialSheet(sheet);
+ if (!normalizedMunicipalityCode || !normalizedSheet) return null;
+ return {
+ municipalityCode: normalizedMunicipalityCode,
+ sheet: normalizedSheet,
+ label: `Comune ${normalizedMunicipalityCode}, foglio ${normalizedSheet}`
+ };
+}
+
+function normalizeFiducialMunicipalityCode(value) {
+ const code = String(value ?? "").trim().toUpperCase();
+ return /^[A-Z][0-9A-Z]{3}$/.test(code) ? code : "";
+}
+
+function normalizeSimpleFiducialSheet(value) {
+ const match = String(value ?? "").trim().toUpperCase().match(/^0*(\d{1,4})(?:[A-Z])?$/);
+ return match ? normalizeFiducialSheet(match[1]) : "";
+}
+
function normalizeFiducialSheet(value) {
const digits = String(value ?? "").match(/\d+/)?.[0] || "";
if (!digits) return "";
@@ -3750,12 +3834,16 @@ function normalizeFiducialSheet(value) {
function updateFiducialDownloadButton() {
const button = lmeState.fiducialDownloadButton;
if (!button) return;
- const enabled = Boolean(lmeState.entitlements?.fiducialPoints && currentFiducialMapContext());
+ const entitled = Boolean(lmeState.entitlements?.fiducialPoints);
+ const context = currentFiducialMapContext();
+ const enabled = Boolean(entitled && context);
button.classList.toggle("is-disabled", !enabled);
button.setAttribute("aria-disabled", String(!enabled));
- button.title = enabled
- ? "Scarica PF del foglio o della particella"
- : "Seleziona una particella o un foglio per scaricare i PF";
+ button.title = !entitled
+ ? "PF disponibili con abbonamento Pro o licenza manuale"
+ : enabled
+ ? `Scarica PF - ${context.label}`
+ : "Seleziona una particella o un foglio, oppure mostra il foglio catastale corrente";
}
async function numericEditManagedRecord(record) {
@@ -6434,6 +6522,7 @@ async function refreshNavigationSheetOutline() {
html: escapeHtml(reference ? `Foglio ${reference}` : "Foglio catastale")
})
}).addTo(lmeState.navigationSheetLayer);
+ updateFiducialDownloadButton();
if (reference && reference !== previousReference) {
setInfo(`Confine del foglio catastale ${reference} caricato.`);
}
@@ -6450,6 +6539,7 @@ function clearNavigationSheetOutline() {
lmeState.navigationSheetFeature = null;
lmeState.navigationSheetLabel = null;
lmeState.navigationSheetLayer?.clearLayers();
+ updateFiducialDownloadButton();
}
function loadedCadastralSheetAt(point) {