2121 Qgis ,
2222 QgsProject ,
2323 QgsVectorLayer ,
24+ QgsRasterLayer ,
2425 QgsCoordinateReferenceSystem ,
2526 QgsCoordinateTransform ,
2627 QgsRectangle ,
3334 QgsExpression ,
3435)
3536from qgis .gui import QgsMapTool , QgsRubberBand
36- from qgis .PyQt .QtCore import Qt , QVariant , QTimer
37+ from qgis .PyQt .QtCore import Qt , QVariant , QTimer , QSettings
3738from qgis .PyQt .QtGui import QColor , QIcon
3839from qgis .PyQt .QtWidgets import (
3940 QAction ,
@@ -136,6 +137,20 @@ def _is_point_layer(layer):
136137# Distanza buffer in metri di default
137138BUFFER_DISTANCE_M = 50
138139
140+ # WMS Catasto
141+ WMS_BASE_URL = "https://wms.cartografia.agenziaentrate.gov.it/inspire/wms/ows01.php"
142+ WMS_LAYERS = [
143+ "province" ,
144+ "CP.CadastralZoning" ,
145+ "acque" ,
146+ "strade" ,
147+ "vestizioni" ,
148+ "fabbricati" ,
149+ "CP.CadastralParcel" ,
150+ ]
151+ WMS_CONNECTION_NAME = "Catasto AdE"
152+ WMS_LAYER_NAME = "Cartografia Catastale WMS AdE"
153+
139154
140155# =============================================================================
141156# FUNZIONI COMUNI
@@ -215,6 +230,68 @@ def _determina_utm_epsg(lon, lat):
215230 return f"EPSG:{ epsg } "
216231
217232
233+ def carica_wms_catasto ():
234+ """
235+ Aggiunge la connessione WMS del Catasto al profilo QGIS (se non presente)
236+ e carica un layer WMS combinato nel progetto corrente.
237+ Il layer viene posizionato in fondo al pannello Layer, prima di eventuali basemap XYZ.
238+ """
239+ # Controlla se il layer WMS è già nel progetto
240+ for layer in QgsProject .instance ().mapLayers ().values ():
241+ if layer .providerType () == "wms" and WMS_BASE_URL in layer .source ():
242+ print (f"[WMS] Layer WMS Catasto già presente nel progetto: { layer .name ()} " )
243+ return
244+
245+ # Aggiungi connessione WMS in QSettings se non presente
246+ settings = QSettings ()
247+ key_prefix = f"qgis/connections-wms/{ WMS_CONNECTION_NAME } "
248+ existing_url = settings .value (f"{ key_prefix } /url" , "" )
249+ if not existing_url :
250+ settings .setValue (f"{ key_prefix } /url" , WMS_BASE_URL )
251+ print (f"[WMS] Connessione '{ WMS_CONNECTION_NAME } ' aggiunta al profilo QGIS" )
252+ else :
253+ print (f"[WMS] Connessione '{ WMS_CONNECTION_NAME } ' già presente nel profilo" )
254+
255+ # Costruisci URI con tutti i layer combinati
256+ layers_params = "&" .join (f"layers={ l } " for l in WMS_LAYERS )
257+ styles_params = "&" .join ("styles=" for _ in WMS_LAYERS )
258+ uri = (
259+ f"contextualWMSLegend=0"
260+ f"&crs=EPSG:6706"
261+ f"&dpiMode=7"
262+ f"&featureCount=10"
263+ f"&format=image/png"
264+ f"&{ layers_params } "
265+ f"&{ styles_params } "
266+ f"&url={ WMS_BASE_URL } "
267+ )
268+
269+ wms_layer = QgsRasterLayer (uri , WMS_LAYER_NAME , "wms" )
270+ if not wms_layer .isValid ():
271+ print ("[WMS] ERRORE: impossibile caricare il layer WMS Catasto" )
272+ return
273+
274+ QgsProject .instance ().addMapLayer (wms_layer , False )
275+ root = QgsProject .instance ().layerTreeRoot ()
276+
277+ # Inserisci in fondo ma prima di eventuali mappe di sfondo (XYZ tiles)
278+ children = root .children ()
279+ pos = len (children ) # default: ultima posizione
280+ for i in range (len (children ) - 1 , - 1 , - 1 ):
281+ node = children [i ]
282+ if hasattr (node , "layer" ) and node .layer ():
283+ src = node .layer ().source ()
284+ if "type=xyz" in src :
285+ pos = i
286+ else :
287+ break
288+ else :
289+ break
290+ root .insertLayer (pos , wms_layer )
291+
292+ print (f"[WMS] Layer '{ WMS_LAYER_NAME } ' caricato nel progetto" )
293+
294+
218295def calcola_griglia_tile (min_lat , min_lon , max_lat , max_lon , max_tile_km2 ):
219296 """
220297 Suddivide il bbox in una griglia di tile, ciascuna con area <= max_tile_km2.
@@ -308,7 +385,8 @@ def scarica_singolo_tile(min_lat, min_lon, max_lat, max_lon):
308385def esegui_download_e_caricamento (min_lat , min_lon , max_lat , max_lon , filter_geom = None ,
309386 layer_name = "Particelle WFS" ,
310387 espandi_catastale = False ,
311- post_filter_points = None ):
388+ post_filter_points = None ,
389+ carica_wms = False ):
312390 """
313391 Gestisce il download WFS: singolo o multi-tile con progress bar.
314392
@@ -744,6 +822,10 @@ def esegui_download_e_caricamento(min_lat, min_lon, max_lat, max_lon, filter_geo
744822 canvas .setExtent (extent_proj )
745823 canvas .refresh ()
746824
825+ # Carica WMS Catasto se richiesto
826+ if carica_wms :
827+ carica_wms_catasto ()
828+
747829 # Riepilogo finale
748830 print ("\n " + "=" * 60 )
749831 print (" COMPLETATO!" )
@@ -776,13 +858,15 @@ class BBoxDrawTool(QgsMapTool):
776858 clicca il secondo angolo per confermare e avviare il download.
777859 """
778860
779- def __init__ (self , canvas , on_completed = None , espandi_catastale = False ):
861+ def __init__ (self , canvas , on_completed = None , espandi_catastale = False ,
862+ carica_wms = False ):
780863 super ().__init__ (canvas )
781864 self .canvas = canvas
782865 self .first_point = None
783866 self .preview_rb = None
784867 self .on_completed = on_completed
785868 self .espandi_catastale = espandi_catastale
869+ self .carica_wms = carica_wms
786870 self ._create_preview_rubberband ()
787871
788872 def _create_preview_rubberband (self ):
@@ -835,7 +919,8 @@ def canvasPressEvent(self, event):
835919 esegui_download_e_caricamento (
836920 min_lat , min_lon , max_lat , max_lon ,
837921 layer_name = "Particelle WFS (BBox)" ,
838- espandi_catastale = self .espandi_catastale
922+ espandi_catastale = self .espandi_catastale ,
923+ carica_wms = self .carica_wms ,
839924 )
840925
841926 # Ripristina Pan e riapri dialog
@@ -875,11 +960,13 @@ class PolySelectTool(QgsMapTool):
875960 Estrae il bbox della geometria e avvia il download WFS.
876961 """
877962
878- def __init__ (self , canvas , on_completed = None , espandi_catastale = False ):
963+ def __init__ (self , canvas , on_completed = None , espandi_catastale = False ,
964+ carica_wms = False ):
879965 super ().__init__ (canvas )
880966 self .canvas = canvas
881967 self .on_completed = on_completed
882968 self .espandi_catastale = espandi_catastale
969+ self .carica_wms = carica_wms
883970
884971 def canvasPressEvent (self , event ):
885972 click_map_point = self .toMapCoordinates (event .pos ())
@@ -968,7 +1055,8 @@ def canvasPressEvent(self, event):
9681055 min_lat , min_lon , max_lat , max_lon ,
9691056 filter_geom = poly_geom_wfs ,
9701057 layer_name = "Particelle WFS (Poligono)" ,
971- espandi_catastale = self .espandi_catastale
1058+ espandi_catastale = self .espandi_catastale ,
1059+ carica_wms = self .carica_wms ,
9721060 )
9731061
9741062 qgis_iface .actionPan ().trigger ()
@@ -1001,12 +1089,13 @@ class LineSelectTool(QgsMapTool):
10011089 """
10021090
10031091 def __init__ (self , canvas , buffer_distance = BUFFER_DISTANCE_M , on_completed = None ,
1004- espandi_catastale = False ):
1092+ espandi_catastale = False , carica_wms = False ):
10051093 super ().__init__ (canvas )
10061094 self .canvas = canvas
10071095 self .buffer_distance = buffer_distance
10081096 self .buffer_rb = None # Rubberband per visualizzare il buffer
10091097 self .espandi_catastale = espandi_catastale
1098+ self .carica_wms = carica_wms
10101099 self .on_completed = on_completed
10111100 # Stato per modalità disegno polilinea
10121101 self ._draw_points = [] # Vertici della polilinea in coordinate mappa
@@ -1075,7 +1164,8 @@ def _esegui_download_da_linea(self, line_geom, geom_crs):
10751164 min_lat , min_lon , max_lat , max_lon ,
10761165 filter_geom = buffer_geom_wfs ,
10771166 layer_name = f"Particelle WFS (Linea buffer { self .buffer_distance } m)" ,
1078- espandi_catastale = self .espandi_catastale
1167+ espandi_catastale = self .espandi_catastale ,
1168+ carica_wms = self .carica_wms ,
10791169 )
10801170
10811171 qgis_iface .actionPan ().trigger ()
@@ -1334,13 +1424,14 @@ class PointSelectTool(QgsMapTool):
13341424 """
13351425
13361426 def __init__ (self , canvas , buffer_distance = 1 , snap_tolerance = 15 ,
1337- on_completed = None , espandi_catastale = False ):
1427+ on_completed = None , espandi_catastale = False , carica_wms = False ):
13381428 super ().__init__ (canvas )
13391429 self .canvas = canvas
13401430 self .buffer_distance = buffer_distance
13411431 self .snap_tolerance = snap_tolerance
13421432 self .buffer_rb = None
13431433 self .espandi_catastale = espandi_catastale
1434+ self .carica_wms = carica_wms
13441435 self .on_completed = on_completed
13451436
13461437 def _visualizza_buffer (self , buffer_geom , buffer_crs ):
@@ -1598,6 +1689,7 @@ def _processa_layer_punti(self, layer):
15981689 layer_name = f"Particelle WFS (Punti buffer { self .buffer_distance } m)" ,
15991690 espandi_catastale = self .espandi_catastale ,
16001691 post_filter_points = wfs_points ,
1692+ carica_wms = self .carica_wms ,
16011693 )
16021694
16031695 qgis_iface .actionPan ().trigger ()
@@ -1663,6 +1755,7 @@ def _processa_click_singolo(self, click_point, click_crs):
16631755 layer_name = "Particelle WFS (click punto)" ,
16641756 espandi_catastale = self .espandi_catastale ,
16651757 post_filter_points = [pt_wfs ],
1758+ carica_wms = self .carica_wms ,
16661759 )
16671760
16681761 qgis_iface .actionPan ().trigger ()
@@ -1761,6 +1854,7 @@ def _on_modalita_scelta(self):
17611854 dlg = self ._dlg
17621855 canvas = self .iface .mapCanvas ()
17631856 espandi = dlg .espandi_catastale
1857+ wms = dlg .carica_wms
17641858
17651859 if dlg .scelta == "disegna" :
17661860 print ("\n MODALITÀ: Disegna BBox" )
@@ -1769,7 +1863,7 @@ def _on_modalita_scelta(self):
17691863 print (" >>> Clicca per il SECONDO angolo" )
17701864 print (" >>> Il download partirà automaticamente\n " )
17711865 tool = BBoxDrawTool (canvas , on_completed = self ._reopen_dialog ,
1772- espandi_catastale = espandi )
1866+ espandi_catastale = espandi , carica_wms = wms )
17731867 canvas .setMapTool (tool )
17741868 self ._active_tool = tool
17751869
@@ -1779,7 +1873,7 @@ def _on_modalita_scelta(self):
17791873 print (" >>> Il bbox verrà estratto e il CRS verificato" )
17801874 print (" >>> Il download partirà automaticamente\n " )
17811875 tool = PolySelectTool (canvas , on_completed = self ._reopen_dialog ,
1782- espandi_catastale = espandi )
1876+ espandi_catastale = espandi , carica_wms = wms )
17831877 canvas .setMapTool (tool )
17841878 self ._active_tool = tool
17851879
@@ -1792,7 +1886,7 @@ def _on_modalita_scelta(self):
17921886 print (" >>> ATTENZIONE: Il layer deve avere un CRS proiettato (metri)\n " )
17931887 tool = LineSelectTool (canvas , buffer_distance = buffer_m ,
17941888 on_completed = self ._reopen_dialog ,
1795- espandi_catastale = espandi )
1889+ espandi_catastale = espandi , carica_wms = wms )
17961890 canvas .setMapTool (tool )
17971891 self ._active_tool = tool
17981892
@@ -1808,7 +1902,7 @@ def _on_modalita_scelta(self):
18081902 tool = PointSelectTool (canvas , buffer_distance = buffer_m ,
18091903 snap_tolerance = snap_px ,
18101904 on_completed = self ._reopen_dialog ,
1811- espandi_catastale = espandi )
1905+ espandi_catastale = espandi , carica_wms = wms )
18121906 canvas .setMapTool (tool )
18131907 self ._active_tool = tool
18141908
0 commit comments