Mostrare la mappa topografica IGM 1 25000 fornita dal Geoportale Nazionale del Ministero dell'Ambiente

Da Gambas-it.org - Wikipedia.
Versione del 26 ago 2023 alle 07:07 di Vuott (Discussione | contributi) (Creata pagina con "=Mostrare su una DawingArea la mappa topografica IGM 1:25000 fornita dal Ministero dell'Ambiente e della Sicurezza Energetica (M.A.S.E.)= Il Geoportale Nazionale del Ministero...")

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

Mostrare su una DawingArea la mappa topografica IGM 1:25000 fornita dal Ministero dell'Ambiente e della Sicurezza Energetica (M.A.S.E.)

Il Geoportale Nazionale del Ministero dell'Ambiente e della Sicurezza Energetica dispone, come Servizio WMS, anche della carta topografica I.G.M. 1:25000, che solitamente va sovrapposta agli altri strati di mappe presenti nel sito del Geoportale Nazionale.

E' possibile richiamare dal Server le tessere (tile) della predetta mappa topografica, scaricarle e mostrarle riordinate su una DrawingArea senza l'uso del Componente gb.map di Gambas.

Riguardo al codice Gambas, di seguito descritto, va precisato che:

  • si richiameranno e si utilizzeranno le tessere con lo zoom a 11. Detto valore non deve essere modificato, pena la non corrispondenza e l'incoerenza con i valori delle tessere prescelte.
  • Il nome del file immagine .png di ciascuna tessera della mappa è formato dal valore dello Zoom, dal numero di tessera in Latitudine e dal numero di tessera in Longitudine.
  • Le tessere vengono lette da Nord verso Sud e da Ovest verso Est.

Pertanto nelle risorse del codice:
- La Costante "LATINIZ" imposta il valore iniziale di y (latitudine a Sud) e rappresenta il valore della tessera più a Nord.
- La Costante "LONINIZ" imposta il valore iniziale di x (longitudine a Est) e rappresenta il valore della tessera più a Ovest.
- Le Costanti "LATINIZ" e "LONINIZ", insieme, individuano dunque la tessera più in alto e più a sinistra del quadrilatero di mappa da mostrare.
- La Costante "LATMAX" imposta la quantità di tessere che saranno caricate a partire da quella impostata in LATMAX. In sostanza, di una griglia/matrice ideale tale Costante rappresenta la quantità di Righe, cosicché il valore della latitudine presente nel nome delle tessere aumenta con l'aumentare dello spostamento verso Sud.
- La Costante "LONMAX" imposta la quantità di tessere che saranno caricate a partire da quella impostata in LONINIZ. In sostanza di una griglia/matrice ideale tale Costante rappresenta la quantità di Colonne, cosicché il valore della longitudine presente nel nome delle tessere aumenta con l'aumentare dello spostamento verso Est.
- Per cambiare l'area da visualizzare, è possibile agire sia impostando la tessera più in alto a sinistra (spostando così il quadrilatero che ricomprende tale area da visualizzare) attraverso la modifica del valore di una o entrambe le Costanti "LATINIZ" e "LONINIZ", sia allungando il quadrilatero dell'area da visualizzare modificando i valori della quantità delle tessere da visualizzare attraverso "LATMAX" e "LONMAX".
- Le tessere in questo caso non sono georeferenziate, pertanto cliccando sulla mappa, mostrata dalla DrawingArea, non sarà possibile (...per ora) ottenere le coordinate geografiche del punto cliccato.
- Poiché le tessere scaricate hanno una dimensione uguale a 512x512 pixel, e poiché allo zoom 11 la lunghezza di ogni lato del reticolato della mappa mostrata è uguale a circa mm. 63,5, per ottenere il valore originario delle carte topografiche IGM 1:25000 (dove mm 40 = km 1,00), sarà necessario effettuare le seguenti operazioni:

mm 63,5 : 100% = mm 40 : x ---> (40 * 100) / 63,5 = 62,992
512px : 100% = Xpx : 62,992 ---> (512 * 62,992) / 100 = 322,519

Pertanto, se si desidera ottenere il valore originario delle carte topografiche IGM 1:25000, ogni tessera dovrà essere ridotta dalle dimensioni 512x512 pixel a 322x322 pixel.
- E' possibile spostare con il mouse agevolmente la mappa, mostrata sulla DrawingArea. Va detto al riguardo che non sarà spostata la DrawingArea (che resterà ferma sul Form), bensì il disegno della mappa visibile. Per far funzionare il codice, sotto mostrato, è necessario attivare i Componenti gb.net e gb.net.curl .

Private Const CACHE As String = "/tmp/IGM Mase"       ' Imposta il percorso ove verranno caricate tutte le tessere necessarie
Private COPYR As String = "Mappa fornita da: © M.A.S.E. - Geoportale Nazionale"
Private Const INFO1 As String = "tasto destro per visualizzare dimensione originale IGM 1:25000 della mappa"
Private Const INFO2 As String = "tasto destro per visualizzare dimensione predefinita della mappa"
Private Const ZOOM As Byte = 11                       ' NON MODIFICARE ! Il valore dello zoom è connesso con i valori delle tessere !
Private Const PIXEL512 As Short = 512
Private Const LATINIZ As Short = 2645
Private Const LONINIZ As Short = 2718
Private Const LATMAX As Short = 6
Private Const LONMAX As Short = 6
Private DrawingArea1 As DrawingArea
Private ht As New HttpClient As "HTTP"
Private pixtess As Short = PIXEL512
Private riduzione As Short =  CShort((PIXEL512 * ((40 * 100) / 63.5)) / 100)
Private lon As Short = LONINIZ
Private lat As Short = LATINIZ
Private latFine As Short
Private lonFine As Short
Private t As Short
Private spx As Short
Private spy As Short
Private dx As Short
Private dy As Short
Private iimm As Image[][]
Private online As Boolean
Private sc As Short


Public Sub Form_Open()

 With Me
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .Arrangement = Arrange.Fill
   .Show()
   Wait
 End With

 If Not Exist(CACHE) Then Mkdir CACHE

 Dim tc As String = "tasto sinistro per caricare online  -  tasto destro per caricare offline"
 sc = (Me.W / 2) - Me.Font.TextWidth(tc)
 Repeat
   Me.Caption = Quote(tc) & String(sc, Chr(32))
   Dec sc
   Wait 0.05
 Until sc == 0

End


Public Sub Form_MouseUp()
 
 sc = 0

 Select Case Mouse.Button
   Case 1
     online = True
     CreaDraw()
     Scarica()
   Case 2
     If Dir(CACHE, "*.png", gb.File).Count == 0 Then
       Me.Caption = "A T T E N Z I O N E. . .  tessere immagine assenti nella cartella: " & CACHE & " !"
       Return
     Endif
     CreaDraw()
     Carica()
 End Select

End


Private Procedure CreaDraw()

 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
   .X = 0
   .Y = 0
   .Border = Border.Plain
   .Background = Color.DarkGray
 End With

End


Private Procedure Scarica()

 If online Then
   If lon > (LONINIZ + LONMAX) Then    ' Fa sì che non sia superato il numero massimo di tessere verso la longitudine Est
     Inc lat
     lon = LONINIZ
   Endif
 
   If lat > (LATINIZ + LATMAX) Then    ' Fa sì che non sia superato il numero massimo di tessere verso la latitudine Sud
     ht.Close                          ' e termina il caricamento di tutte le tessere previste per disegnare l'intera mappa
     online = False
     Carica()
   Endif
 
   If online Then
     With ht
' Invia la richiesta al server per scaricare il file immagine:
       .URL = "http://www.pcn.minambiente.it/arcgis/rest/services/immagini/IGM_25000/MapServer/tile" &/ CStr(ZOOM) &/ CStr(lat) &/ CStr(lon)
       .Timeout = 15
' Scarica i dati del file immagine in un percorso prescelto, contenente anche il nome del file immagine ricreato:
       .Get(Null, cache &/ CStr(ZOOM) & "-" & CStr(lat) & "-" & CStr(lon) & ".png")
     End With
     Inc t
     Me.Title = "ATTENDERE scarico tessere della mappa:  " & Format((t * 100) / ((LONMAX + 1) * (LATMAX + 1)), "#.0") & "%"
   Endif
 Endif

End


Public Sub HTTP_Finished()  

 If online Then
   Inc lon
   Scarica()
 Endif

End


Private Procedure Carica()
 
 Dim a, b, n As Short
 Dim c1, c2, c3, c4, spz As Short
 Dim im As Image
 Dim ss As String[]
 Dim s1, s2 As String
 
 iimm = New Image[][]
 
 ss = Dir(CACHE, "*.png", gb.File).Sort()
 lat = Val(Scan(ss[0], "*-*-*.*")[1])
 lon = Val(Scan(ss[0], "*-*-*.*")[2])
 latFine = Val(Scan(ss[ss.Max], "*-*-*.*")[1])
 lonFine = Val(Scan(ss[ss.Max], "*-*-*.*")[2])
 For a = 0 To latFine - lat
   iimm.Push([])
   For b = 0 To lonFine - lon
     im = Image.Load(CACHE &/ ss[n])
     If pixtess == riduzione Then im = im.Stretch((PIXEL512 * 62.992) / 100, (PIXEL512 * 62.992) / 100)   ' per ridurre il rapporto all'originario IGM 1:25000
     iimm[a].Push(im)
     Inc n
     Me.Caption = "Totale tessere caricate: " & CStr(n)
   Next
 Next
 
 DrawingArea1.Refresh
 
 Wait
 
' Algoritmo per porre nell'intestazione del "Form" tutto a sinistra il testo del copyright e al centro il messaggio INFO1 oppure INFO2:
 c1 = (Me.W / 2) + (Me.Font.TextWidth(INFO2) / 2)
 If pixtess == PIXEL512 Then c1 = (Me.W / 2) + (Me.Font.TextWidth(INFO1) / 2)
 c2 = Me.W - c1
 c3 = c2 - Me.Font.TextWidth(COPYR)
 spz = Me.Font.TextWidth(Chr(32))
 c4 = c3 \ spz
 s1 = COPYR & String(c4, Chr(32))
 s2 = String(c2 \ spz, Chr(32))
 If pixtess == PIXEL512 Then
   Me.Title = s1 & "tasto destro per visualizzare dimensione originale IGM 1:25000 della mappa" & s2
 Else
   Me.Title = s1 & "tasto destro per visualizzare dimensione predefinita della mappa" & s2
 Endif

End


Public Sub DrawingArea1_Draw()
 
 Dim c, d As Short
 
 If online Then Return

 For c = 0 To iimm.Max
   For d = 0 To iimm[0].Max
     With Paint
       .Begin(DrawingArea1)
       .Brush = .Color(Color.Blue)
       .DrawImage(iimm[c][d], dx + (d * pixtess), dy + (c * pixtess), pixtess, pixtess, 1)
       .end
     End With
   Next
 Next

End


Public Sub DrawingArea1_MouseDown()
   
 spx = Mouse.X - dx
 spy = Mouse.Y - dy

End


Public Sub DrawingArea1_MouseMove()
 
 DrawingArea1.Mouse = 18
 
 dx = Mouse.X - spx
 dy = Mouse.Y - spy
 
 DrawingArea1.Refresh

End


Public Sub DrawingArea1_MouseUp()
 
 DrawingArea1.Mouse = Mouse.Default
 
 If Mouse.Right Then
   If pixtess == PIXEL512 Then
     pixtess = riduzione         ' Visualizza la mappa con le dimensioni e i rapporti originari IGM 1:25000 (mm 40 == km 1)
     Balloon.Delay = 3000
     Balloon.Info("Vista originale dimensioni IGM 1:25000", DrawingArea1, Mouse.X, Mouse.Y)
   Else
     pixtess = PIXEL512          ' Visualizza la mappa con le dimensioni e i rapporti predefiniti
     Balloon.Delay = 3000
     Balloon.Info("Vista dimensioni predefinite.", DrawingArea1, Mouse.X, Mouse.Y)
   Endif
   Carica()
 Endif

End


Public Sub Form_Close()
 
 sc = 0
 ht.Close

End
       

Mostrare su una ImageView la mappa topografica IGM 1:25000, ma senza le tessere

Si potrà mostrare la medesima mappa topografica IGM 1:25000, fornita dal Mi.T.E., senza però l'uso delle tessere Bisognerà cambiare URL del Server.

Mostriamo un esempio:

' Nell'individuazione del Layer si dovrà impostare correttamente la Zona "32" o "33":
Private Const INDIRIZZO As String = "http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/WMS_v1.3/raster/IGM_25000.map&SERVICE=WMS&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=TRUE&STYLES=&VERSION=1.3.0&LAYERS=CB.IGM25000.33&"
Private Const COPYR As String = "Mappa fornita da: © M.A.S.E. - Geoportale Nazionale"
Private Const LATOAREA As Float = 6125        ' Con il valore 6125 si ha la dimensione originaria di mm 40 del lato del reticolo presente nelle carte IGM 1:25000 (ovviamente il valore può essere impostato a piacere)
Private f1 As Float = 1440000.00              ' La coordinata minima (massima a Ovest) di Longitudine del quadrilatero d'area considerato
Private f2 As Float = 5000000.00 - LATOAREA   ' La coordinata minima (massima a Sud) di Latitudine del quadrilatero d'area considerato
Private f3 As Float = 1440000.00 + LATOAREA   ' La coordinata massima a Est di Longitudine del quadrilatero d'area considerato
Private f4 As Float = 5000000.00              ' La coordinata massima a Nord di Latitudine del quadrilatero d'area considerato
Private imageview1 As ImageView


Public Sub Form_Open()
 
 With Me
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .Arrangement = Arrange.Fill
   .Show
 End With
 
' La dimensione della "ImageView" deve rappresentare un "quadrato"...:
 With imageview1 = New ImageView(Me)
   .X = 0
   .Y = 0
 End With
 
' Se la dimensione della "ImageView" non rappresenta un quadrato, bensì un rettangolo con la longitudine come lato più lungo, allora è necessario un adeguamento del disegno della mappa considerando la lunghezza di detto lato più lungo:
 f3 += ((((Screen.AvailableWidth * 100) / Screen.AvailableHeight) - 100) * LATOAREA) / 100
 
 Carica()
  
End


Private Procedure Carica()
 
 Dim ind, s As String
 Dim tp As New HttpClient
 Dim im As Image
 
 Me.Title = "ATTENDERE IL CARICAMENTO !"
 
 Wait 0.3
 
 ind = INDIRIZZO &
       "WIDTH=" & CStr(imageview1.W) & "&HEIGHT=" & CStr(imageview1.H) & "&CRS=EPSG:900913&" &
      "BBOX=" & CStr(f1) & "," & CStr(f2) & "," & CStr(f3) & "," & CStr(f4) 
      
 tp.Timeout = 15
 s = tp.Download(ind)
 
 tp.Close
 
 im = Image.FromString(s)

 With imageview1
' Modifica il valore del colore dello sfondo dell'immagine caricata:
   .Image = im.Replace(&FFFFFFFF&, &FFFFDF)
' Salva l'immagine caricata della mappa in un file formato PNG:
   .Image.Save("/tmp/IGM.png", 100)
 End With

 Me.Title = COPYR & String(Me.Font.TextWidth(COPYR), Chr(32))

End
       

Mostrare in un WebView una sola tessera della mappa topografica IGM 1:25000

Per mostrare in un "WebView" una sola tessera della mappa topografica IGM 1:25000, fornita dal Mi.T.E., si dovranno individuare i numeri corrispondenti alle coordinate "x" e "y" di ciascuna tessera tenendo bene in conto del valore dello zoom prescelto.

Mostriamo un esempio, nel quale lo zoom è impostato a "11". E' necessario ricordare che:
- le tessere in questione hanno una dimensione 512x512 pixel;
- in questo caso il protocollo per individuare la tessera è: "zoom", "y" e "x". Poiché si provvederà a scaricare i dati immagine di ciascuna tessera visualizzata e contestualmente salvarli in file immagine in un'apposita cartella, bisognerà attivare anche i Componenti gb.net e gb.net.curl .

Private Const TESSERA As Short = 512  ' Indica la dimensione in pixel di ciascuna tessera costituente la mappa IGM 1:25000
Private Const ZOOM As Byte = 11       ' Imposta lo zoom dell'immagine riprodotta su ciascuna tessera
Private Const COPYR As String = "Mappa fornita da: © M.A.S.E. - Geoportale Nazionale"
Private WebView1 As WebView
Private Panel1 As Panel
Private Label1 As Label
Private Label2 As Label
Private Label3 As Label
Private x As Integer     ' Indica lo spostamento in Longitudine (Ovest-Est)
Private y As Integer     ' Indica lo spostamento in Latitudine (Nord-Sud)


Public Sub _new()

 Me.Move((Screen.AvailableWidth / 2) - 375, 0, 750, Screen.AvailableHeight)
 With Panel1 = New Panel(Me) As "Panel1"
   .X = 50
   .Y = 50
   .W = 600
   .H = 600
   .Background = Color.Orange
 End With
 With Label1 = New Label(Me)
   .X = Me.W * 0.9
   .Y = Me.H * 0.3
   .Alignment = Align.Right
   .W = .Font.TextWidth(.Text)
   .H = 20
 End With
 With Label2 = New Label(Me)
   .X = Me.W * 0.9
   .Y = Label1.Y + Label1.H + 10
   .Alignment = Align.Right
   .W = .Font.TextWidth(.Text)
   .H = 20
 End With
 With Label3 = New Label(Me)
   .X = Me.W * 0.9
   .Y = Label2.Y + Label2.H + 10
   .Alignment = Align.Right
   .W = .Font.TextWidth(.Text)
   .H = 20
 End With

 MkDir "/tmp/TESSERE"

End 

Public Sub Form_Open()

' Imposta le coordinate "x,y" della tessera iniziale da mostrare:
 y = 2650
 x = 2727

 AggiornaLabel()
 Ricarica()

 Me.Title = COPYR

End


Public Sub Panel1_MouseUp()

 If Mouse.X < WebView1.X Then x -= 1
 If Mouse.X > (WebView1.X + WebView1.W) Then x += 1

 If Mouse.Y < WebView1.Y Then y -= 1
 If Mouse.Y > (WebView1.Y + WebView1.H) Then y += 1

 AggiornaLabel()

 Ricarica()

End


Private Procedure AggiornaLabel()

 Label1.Text = "x = " & Format(x, "########")
 Label1.W = Label1.Font.TextWidth(Label1.Text)
 Label2.Text = "y = " & Format(y, "########")
 Label2.W = Label2.Font.TextWidth(Label2.Text)
 Label3.Text = "z = " & Format(ZOOM, "########")
 Label3.W = Label3.Font.TextWidth(Label3.Text)

End


Private Procedure Ricarica()

 Dim prc As String = "http://www.pcn.minambiente.it/arcgis/rest/services/immagini/IGM_25000/MapServer/tile" &/
                      CStr(ZOOM) &/ CStr(y) &/ CStr(x)
 Dim tp As New HttpClient
 Dim s As String

 If Object.IsValid(WebView1) Then WebView1.Delete

 With WebView1 = New WebView(Panel1) As "WebView1"
   .X = 50
   .Y = 50
   .W = TESSERA
   .H = TESSERA
   .Url = prc
 End With

 s = tp.Download(prc)
 tp.Close

 File.Save("/tmp/TESSERE" &/ CStr(ZOOM) & "-" & CStr(y) & "-" & CStr(x) & ".png", s)

End