@@ -54,8 +54,12 @@ const lmeState = {
managerOutsideSelectionBound : false ,
managerHiddenObjects : new Map ( ) ,
managerHiddenObjectIds : new Set ( ) ,
managerHiddenMeasurementSummaryIds : new Set ( ) ,
managerHiddenMeasurementSideIds : new Set ( ) ,
managerHiddenCategories : new Set ( ) ,
managerObjectOrder : { }
managerObjectOrder : { } ,
managerExpandedRows : new Set ( ) ,
dotNetReference : null
} ;
// AdE publishes the cadastral WMS in ETRS89. WMS 1.1.1 keeps the longitude,
@@ -108,7 +112,10 @@ window.lmeMap = {
showInfo : setInfo
} ;
function init ( ) {
function init ( dotNetReference ) {
if ( dotNetReference ) {
lmeState . dotNetReference = dotNetReference ;
}
if ( lmeState . map ) {
return ;
}
@@ -1138,6 +1145,42 @@ function managedObjectLabel(record, index) {
return ` Oggetto ${ index + 1 } ` ;
}
function managedObjectEditableName ( record ) {
const properties = record ? . layer ? . feature ? . properties || { } ;
return properties . name || properties . Name || properties . label || properties . LABEL || "" ;
}
function managedObjectCanRename ( record ) {
return [ "drawings" , "imported" , "importedSheets" ] . includes ( record . categoryKey )
&& record . layer ? . feature ? . properties ;
}
function renameManagedObject ( record , index ) {
if ( ! managedObjectCanRename ( record ) ) {
return ;
}
const currentName = String ( managedObjectEditableName ( record ) || managedObjectLabel ( record , index ) ) . trim ( ) ;
const requestedName = window . prompt ( "Nuovo nome oggetto" , currentName ) ;
if ( requestedName === null ) {
return ;
}
const name = requestedName . trim ( ) . slice ( 0 , 120 ) ;
if ( ! name ) {
setInfo ( "Nome non modificato: inserisci un testo." ) ;
return ;
}
const properties = record . layer . feature . properties ;
properties . name = name ;
record . layer . lmeManagerLabel = record . categoryKey === "drawings" && record . layer instanceof L . Marker
? ` POI: ${ name } `
: null ;
updateStoredFeaturePopup ( record . layer ) ;
refreshImportedMeasurements ( ) ;
refreshDrawingMeasurements ( ) ;
refreshLayerManager ( ) ;
setInfo ( ` Oggetto rinominato: ${ name } . ` ) ;
}
function managedObjectDetails ( layer ) {
const details = [ ] ;
const properties = layer ? . feature ? . properties || { } ;
@@ -1180,6 +1223,9 @@ function refreshLayerManager() {
if ( ! container || ! lmeState . map ) {
return ;
}
captureLayerManagerExpansion ( container ) ;
const scrollHost = container . closest ( ".map-layer-panel" ) ;
const scrollTop = scrollHost ? . scrollTop || 0 ;
applyStoredLayerManagerVisibility ( ) ;
container . innerHTML = "" ;
lmeState . managerRecords = new Map ( ) ;
@@ -1200,6 +1246,12 @@ function refreshLayerManager() {
applyManagedVisualOrder ( container ) ;
bindLayerManagerDrag ( container ) ;
bindLayerManagerMoveButtons ( container ) ;
if ( scrollHost ) {
scrollHost . scrollTop = scrollTop ;
window . requestAnimationFrame ( ( ) => {
scrollHost . scrollTop = scrollTop ;
} ) ;
}
}
function renderLayerManagerCategory ( category , records ) {
@@ -1207,6 +1259,7 @@ function renderLayerManagerCategory(category, records) {
group . className = "layer-manager-group" ;
group . dataset . dragType = "category" ;
group . dataset . categoryKey = category . key ;
bindLayerManagerExpansion ( group , ` category: ${ category . key } ` ) ;
const visibleCount = records . filter ( record => ! lmeState . managerHiddenObjectIds . has ( record . id ) ) . length ;
const categoryVisible = ! lmeState . managerHiddenCategories . has ( category . key )
&& ( ! category . roots . length || category . roots . some ( layer => lmeState . map . hasLayer ( layer ) ) ) ;
@@ -1237,6 +1290,7 @@ function renderLayerManagerBlock(category, source, records) {
block . dataset . dragType = "block" ;
block . dataset . categoryKey = category . key ;
block . dataset . blockKey = source ;
bindLayerManagerExpansion ( block , ` block: ${ category . key } : ${ source } ` ) ;
const visibleCount = records . filter ( record => ! lmeState . managerHiddenObjectIds . has ( record . id ) ) . length ;
const visible = visibleCount === records . length ;
block . innerHTML = ` <summary><button type="button" class="layer-drag-handle" aria-label="Trascina blocco">☰</button><input type="checkbox" ${ visible ? "checked" : "" } aria-label="Mostra blocco"><span class="layer-manager-title"> ${ escapeHtml ( source ) } </span> ${ layerManagerMoveButtons ( "blocco" ) } <span class="layer-manager-count"> ${ records . length } </span></summary><div class="layer-manager-children"></div> ` ;
@@ -1260,11 +1314,20 @@ function renderLayerManagerObject(record, index) {
}
object . dataset . dragType = "object" ;
object . dataset . objectId = record . id ;
bindLayerManagerExpansion ( object , ` object: ${ record . id } ` ) ;
const visible = ! lmeState . managerHiddenObjectIds . has ( record . id ) ;
object . innerHTML = ` <summary><button type="button" class="layer-drag-handle" aria-label="Trascina oggetto">☰</button><input type="checkbox" ${ visible ? "checked" : "" } aria-label="Mostra oggetto"><span class="layer-manager-title"> ${ escapeHtml ( managedObjectLabel ( record , index ) ) } </span> ${ layerManagerMoveButtons ( "oggetto" ) } <span class="layer-manager-count">› </span></summary><div class="layer-manager-details"></div> ` ;
const renameButton = managedObjectCanRename ( record )
? ` <button type="button" class="layer-rename-button" aria-label="Rinomina oggetto" title="Rinomina">Rinomina</button> `
: "" ;
object . innerHTML = ` <summary><button type="button" class="layer-drag-handle" aria-label="Trascina oggetto">☰</button><input type="checkbox" ${ visible ? "checked" : "" } aria-label="Mostra oggetto"><span class="layer-manager-title"> ${ escapeHtml ( managedObjectLabel ( record , index ) ) } </span> ${ renameButton } ${ layerManagerMoveButtons ( "oggetto" ) } <span class="layer-manager-count">› </span></summary><div class="layer-manager-details"></div> ` ;
const checkbox = object . querySelector ( "input" ) ;
checkbox . addEventListener ( "click" , event => event . stopPropagation ( ) ) ;
checkbox . addEventListener ( "change" , ( ) => setManagedObjectVisible ( record , checkbox . checked , true ) ) ;
object . querySelector ( ".layer-rename-button" ) ? . addEventListener ( "click" , event => {
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
renameManagedObject ( record , index ) ;
} ) ;
object . querySelector ( ".layer-manager-title" ) . addEventListener ( "click" , event => {
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
@@ -1272,13 +1335,137 @@ function renderLayerManagerObject(record, index) {
highlightManagedObject ( record ) ;
} ) ;
const details = object . querySelector ( ".layer-manager-details" ) ;
details . appendChild ( renderLayerManagerVisibilityOption (
geometryVisibilityLabel ( record . layer ) ,
visible ,
checked => setManagedObjectVisible ( record , checked , true ) ) ) ;
if ( supportsManagedMeasurements ( record ) ) {
managedMeasurementKinds ( record ) . forEach ( kind => {
const measurementsVisible = managedMeasurementsGloballyVisible ( record . categoryKey )
&& ! managedMeasurementHiddenSet ( kind . key ) . has ( record . id ) ;
details . appendChild ( renderLayerManagerVisibilityOption (
kind . label ,
measurementsVisible ,
checked => setManagedMeasurementKindVisible ( record , kind . key , checked ) ) ) ;
} ) ;
}
const rows = managedObjectDetails ( record . layer ) ;
details . innerHTML = rows . length
const info = document . createElement ( "div" ) ;
info . className = "layer-manager-info" ;
info . innerHTML = rows . length
? rows . map ( value => ` <span> ${ escapeHtml ( value ) } </span> ` ) . join ( "" )
: "<span>Nessuna misura disponibile</span>" ;
details . appendChild ( info ) ;
return object ;
}
function renderLayerManagerVisibilityOption ( label , checked , onChange ) {
const option = document . createElement ( "label" ) ;
option . className = "layer-manager-suboption" ;
option . innerHTML = ` <input type="checkbox" ${ checked ? "checked" : "" } ><span> ${ escapeHtml ( label ) } </span> ` ;
const checkbox = option . querySelector ( "input" ) ;
checkbox . addEventListener ( "click" , event => event . stopPropagation ( ) ) ;
checkbox . addEventListener ( "change" , ( ) => onChange ( checkbox . checked ) ) ;
return option ;
}
function geometryVisibilityLabel ( layer ) {
if ( layer instanceof L . Polygon || layer instanceof L . Circle ) {
return "Area/geometria sulla mappa" ;
}
if ( layer instanceof L . Polyline ) {
return "Linea sulla mappa" ;
}
return "Punto sulla mappa" ;
}
function supportsManagedMeasurements ( record ) {
return [ "imported" , "drawings" ] . includes ( record . categoryKey )
&& ( record . layer instanceof L . Circle
|| record . layer instanceof L . Polygon
|| record . layer instanceof L . Polyline ) ;
}
function managedMeasurementsGloballyVisible ( categoryKey ) {
return categoryKey === "imported"
? lmeState . showImportedMeasurements
: lmeState . showDrawingMeasurements ;
}
function managedMeasurementKinds ( record ) {
if ( record . layer instanceof L . Polygon ) {
return [
{ key : "summary" , label : "Superficie e perimetro sulla mappa" } ,
{ key : "sides" , label : "Misure dei lati sulla mappa" }
] ;
}
if ( record . layer instanceof L . Circle ) {
return [ { key : "summary" , label : "Superficie, raggio e circonferenza sulla mappa" } ] ;
}
return [
{ key : "summary" , label : "Lunghezza totale sulla mappa" } ,
{ key : "sides" , label : "Misure dei tratti sulla mappa" }
] ;
}
function managedMeasurementHiddenSet ( kind ) {
return kind === "sides"
? lmeState . managerHiddenMeasurementSideIds
: lmeState . managerHiddenMeasurementSummaryIds ;
}
function setManagedMeasurementKindVisible ( record , kind , visible ) {
const hiddenSet = managedMeasurementHiddenSet ( kind ) ;
if ( visible ) {
if ( ! managedMeasurementsGloballyVisible ( record . categoryKey ) ) {
lmeState . managerRecords . forEach ( candidate => {
if ( candidate . categoryKey === record . categoryKey
&& supportsManagedMeasurements ( candidate ) ) {
lmeState . managerHiddenMeasurementSummaryIds . add ( candidate . id ) ;
lmeState . managerHiddenMeasurementSideIds . add ( candidate . id ) ;
}
} ) ;
if ( record . categoryKey === "imported" ) {
lmeState . showImportedMeasurements = true ;
} else {
lmeState . showDrawingMeasurements = true ;
}
void lmeState . dotNetReference ? . invokeMethodAsync (
"SetMeasurementsFromLayerManager" ,
record . categoryKey ,
true ) ;
}
hiddenSet . delete ( record . id ) ;
} else {
hiddenSet . add ( record . id ) ;
}
refreshImportedMeasurements ( ) ;
refreshDrawingMeasurements ( ) ;
refreshLayerManager ( ) ;
}
function captureLayerManagerExpansion ( container ) {
container . querySelectorAll ( "details[data-expansion-key]" ) . forEach ( row => {
if ( row . open ) {
lmeState . managerExpandedRows . add ( row . dataset . expansionKey ) ;
} else {
lmeState . managerExpandedRows . delete ( row . dataset . expansionKey ) ;
}
} ) ;
}
function bindLayerManagerExpansion ( row , key ) {
row . dataset . expansionKey = key ;
row . open = lmeState . managerExpandedRows . has ( key ) ;
row . addEventListener ( "toggle" , ( ) => {
if ( row . open ) {
lmeState . managerExpandedRows . add ( key ) ;
} else {
lmeState . managerExpandedRows . delete ( key ) ;
}
} ) ;
}
function setManagedCategoryVisible ( category , visible ) {
if ( category . key === "imported" ) {
lmeState . importedVisible = visible ;
@@ -1624,6 +1811,7 @@ function applyImportedSheetVisibility() {
function setImportedMeasurementsVisible ( enabled ) {
lmeState . showImportedMeasurements = Boolean ( enabled ) ;
refreshImportedMeasurements ( ) ;
refreshLayerManager ( ) ;
setInfo ( lmeState . showImportedMeasurements
? "Misure dei file GIS visibili."
: "Misure dei file GIS nascoste." ) ;
@@ -1632,6 +1820,7 @@ function setImportedMeasurementsVisible(enabled) {
function setDrawingMeasurementsVisible ( enabled ) {
lmeState . showDrawingMeasurements = Boolean ( enabled ) ;
refreshDrawingMeasurements ( ) ;
refreshLayerManager ( ) ;
setInfo ( lmeState . showDrawingMeasurements
? "Misure dei disegni visibili."
: "Misure dei disegni nascoste." ) ;
@@ -1901,15 +2090,27 @@ function renderMeasurements(sourceGroup, targetGroup, visible, sourceType) {
sourceType
} ;
visitMeasurableLayers ( sourceGroup , layer => {
const categoryKey = sourceType === "imported" ? "imported" : "drawings" ;
const objectId = managedLayerId ( layer , categoryKey ) ;
const showSummary = ! lmeState . managerHiddenMeasurementSummaryIds . has ( objectId ) ;
const showSides = ! lmeState . managerHiddenMeasurementSideIds . has ( objectId ) ;
if ( ! showSummary && ! showSides ) {
return ;
}
if ( context . count >= context . max || ! layerIsInView ( layer , context . bounds ) ) {
return ;
}
const layerContext = {
... context ,
showSummary ,
showSides : context . showSides && showSides
} ;
if ( layer instanceof L . Circle ) {
renderCircleMeasurement ( layer , targetGroup , context ) ;
renderCircleMeasurement ( layer , targetGroup , layerContext ) ;
} else if ( layer instanceof L . Polygon ) {
renderPolygonMeasurement ( layer , targetGroup , context ) ;
renderPolygonMeasurement ( layer , targetGroup , layerContext ) ;
} else if ( layer instanceof L . Polyline ) {
renderPolylineMeasurement ( layer , targetGroup , context ) ;
renderPolylineMeasurement ( layer , targetGroup , layerContext ) ;
}
} ) ;
}
@@ -1936,6 +2137,9 @@ function layerIsInView(layer, mapBounds) {
}
function renderCircleMeasurement ( layer , targetGroup , context ) {
if ( ! context . showSummary ) {
return ;
}
const radius = layer . getRadius ( ) ;
const area = Math . PI * radius * radius ;
const circumference = 2 * Math . PI * radius ;
@@ -1964,6 +2168,7 @@ function renderPolygonMeasurement(layer, targetGroup, context) {
const center = typeof layer . getCenter === "function"
? layer . getCenter ( )
: layer . getBounds ( ) . getCenter ( ) ;
if ( context . showSummary ) {
addMeasurementLabel (
targetGroup ,
center ,
@@ -1971,6 +2176,7 @@ function renderPolygonMeasurement(layer, targetGroup, context) {
"summary" ,
context ) ;
}
}
function renderPolylineMeasurement ( layer , targetGroup , context ) {
const lines = lineLatLngGroups ( layer . getLatLngs ( ) ) ;
@@ -1979,7 +2185,7 @@ function renderPolylineMeasurement(layer, targetGroup, context) {
lines . forEach ( line => addSegmentLabels ( line , false , targetGroup , context ) ) ;
}
const longest = lines . reduce ( ( current , line ) => line . length > current . length ? line : current , [ ] ) ;
if ( longest . length ) {
if ( context . showSummary && longest . length ) {
addMeasurementLabel (
targetGroup ,
longest [ Math . floor ( longest . length / 2 ) ] ,
@@ -2326,6 +2532,8 @@ function captureDisplayOptions() {
layerOrder : [ ... lmeState . layerOrder ] ,
layerObjectOrder : { ... lmeState . managerObjectOrder } ,
hiddenLayerObjects : [ ... lmeState . managerHiddenObjectIds ] ,
hiddenLayerMeasurementSummaries : [ ... lmeState . managerHiddenMeasurementSummaryIds ] ,
hiddenLayerMeasurementSides : [ ... lmeState . managerHiddenMeasurementSideIds ] ,
hiddenLayerCategories : [ ... lmeState . managerHiddenCategories ] ,
trailEnabled : lmeState . gpsTrailEnabled
} ;
@@ -2362,6 +2570,12 @@ function applyProjectDisplayOptions(options) {
if ( Array . isArray ( options . hiddenLayerObjects ) ) {
lmeState . managerHiddenObjectIds = new Set ( options . hiddenLayerObjects ) ;
}
if ( Array . isArray ( options . hiddenLayerMeasurementSummaries ) ) {
lmeState . managerHiddenMeasurementSummaryIds = new Set ( options . hiddenLayerMeasurementSummaries ) ;
}
if ( Array . isArray ( options . hiddenLayerMeasurementSides ) ) {
lmeState . managerHiddenMeasurementSideIds = new Set ( options . hiddenLayerMeasurementSides ) ;
}
if ( Array . isArray ( options . hiddenLayerCategories ) ) {
lmeState . managerHiddenCategories = new Set ( options . hiddenLayerCategories ) ;
}
@@ -2445,12 +2659,21 @@ function managedGroupGeoJson(group, categoryKey) {
function resetLayerManagerProjectState ( ) {
lmeState . managerHiddenObjects . clear ( ) ;
lmeState . managerHiddenObjectIds . clear ( ) ;
lmeState . managerHiddenMeasurementSummaryIds . clear ( ) ;
lmeState . managerHiddenMeasurementSideIds . clear ( ) ;
lmeState . managerHiddenCategories . clear ( ) ;
lmeState . managerObjectOrder = { } ;
clearManagerHighlight ( ) ;
}
function clearManagedCategoryState ( categoryKey ) {
const category = layerManagerCategories ( ) . find ( item => item . key === categoryKey ) ;
if ( category ) {
managedRecordsForCategory ( category ) . forEach ( record => {
lmeState . managerHiddenMeasurementSummaryIds . delete ( record . id ) ;
lmeState . managerHiddenMeasurementSideIds . delete ( record . id ) ;
} ) ;
}
[ ... lmeState . managerHiddenObjects . entries ( ) ] . forEach ( ( [ id , record ] ) => {
if ( record . categoryKey === categoryKey ) {
lmeState . managerHiddenObjects . delete ( id ) ;
@@ -2462,10 +2685,18 @@ function clearManagedCategoryState(categoryKey) {
}
function bindStoredFeaturePopup ( feature , layer ) {
const properties = feature ? . properties || { } ;
updateStoredFeaturePopup ( layer , feature ? . properties ) ;
}
function updateStoredFeaturePopup ( layer , sourceProperties ) {
const properties = sourceProperties || layer ? . feature ? . properties || { } ;
const label = properties . name || properties . Name || properties . label || properties . LABEL ;
if ( label ) {
layer . bindPopup ( ` <strong> ${ escapeHtml ( label ) } </strong> ` ) ;
return ;
}
if ( typeof layer ? . unbindPopup === "function" ) {
layer . unbindPopup ( ) ;
}
}