Verificare le tessere dei livelli delle Map tiles
Le "Map tiles", che si usano tutte insieme sul web per offrire la rappresentazione corrente della mappa, sono formate per ciascun livello di zoom da molteplici tessere (tile), ciascuna solitamente avente dimensione 256x256 pixel. [nota 1]
La descrizione delle "Coordinate delle tessere ", che formano l'intera mappa georeferenziata, è riportata nelle seguenti pagine:
https://docs.microsoft.com/it-it/azure/azure-maps/zoom-levels-and-tile-grid?tabs=csharp https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/coordinates?hl=it#tile-coordinates
e qui una esposizione pratica della griglia delle tessere e delle loro coordinate x, y sulla mappa del mondo:
http://tools.geofabrik.de/map/#2/29.1466/31.9609&type=Geofabrik_Standard&grid=1
Di seguito saranno mostrati alcuni esempi per visualizzare tali tessere, costituenti la mappa fornita da "Google Maps", e di conoscerne i relativi parametri "x" (Longitudine), "y" (Latitudine) e "z" (Zoom). Al riguardo va detto che il numero del parametro "x" (Longitudine) delle tessere aumenta procedendo da Ovest verso Est; mentre il valore del parametro "y" (Latitudine) aumenta procedendo verso da Nord verso SUD.
x ⁕------------> | | | | y | V
Indice
- 1 Conoscere i parametri "x" e "y" (Longitudine e Latitudine) delle tessere di una mappa mediante le risorse del Componente "gb.map"
- 2 Visualizzare le tessere di una mappa e i relativi parametri "x", "y" e "z" mediante le risorse del Componente "gb.map"
- 3 Visualizzare le tessere di una mappa e i relativi parametri "x", "y" e "z" mediante il Controllo "WebView"
- 4 Ottenere i riferimenti di una tessera attraverso appositi calcoli
- 5 Scaricare dal web e ri-assemblare coerentemente le tessere di una mappa
- 6 Note
- 7 Riferimenti
Conoscere i parametri "x" e "y" (Longitudine e Latitudine) delle tessere di una mappa mediante le risorse del Componente "gb.map"
Mostriamo un primo semplice esempio pratico usando il Metodo "MapPointToTile()" della Classe statica "Geo" del Componente "gb.map" per conoscere semplicemente i parametri "x" e "y" (Longitudine e Latitudine) della tessera, alla quale corrisponde e in cui sono comprese le coordinate di un punto ulla mappa.
Questo Metodo fornisce i parametri della "x" e della "y" della tessera individuata:
Public Sub Form_Open() Dim mp As New MapPoint(41.8902142, 12.4900422) MapView1.Map.AddTile("OpenTopo", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png") ' Il Metodo ".MapPointToTile()" fornisce i parametri "x" e "y" della tessera individuata: Print Geo.MapPointToTile(mp, 13) End
Visualizzare le tessere di una mappa e i relativi parametri "x", "y" e "z" mediante le risorse del Componente "gb.map"
Quando le risorse del Componente gb.map mostrano una mappa, questa - come sappiamo - è composta da numerose tessere (tile) solitamente ciascuna delle dimensioni di 256x256 pixel, disposte da Nord verso Sud e da Est verso Ovest.
Tali tessere sono in realtà dei file immagine, solitamente di formato PNG, che Gambas scarica in copia nella cartella del seguente percorso principale:
/home/[utente]/.cache/gb.map/
ma sono salvati anche nella cartella del seguente percorso:
/tmp/gambas.1000/numero_processo/2.tmp
laddove "numero_processo" è il numero del processo del programma Gambas lanciato che sta mostrando la mappa.
Questa cartella, ove sono presenti le tessere dei file immagine della mappa, può essere rilevata anche invocando la Proprietà ".TempDir" della Classe Application:
Application.TempDir &/ 2.tmp
Esempio per visualizzare sulla mappa le tessere e i relativi parametri "x", "y" e "z"
In questo esempio si visualizzeranno sulla mappa le tessere e i relativi parametri "x", "y" e "z".
Cliccando con il tasto destro su un punto della mappa, saranno visualizzati i contorni di un quadrato di dimensioni - come già detto - di 256x256 pixel a riprodurre la tessera corrispondente al punto, nonché i suoi predetti tre parametri.
Ruotando la rotellina del mouse, per cambiare zoom, i contorni delle tessere precedentemente visualizzati saranno cancellati.
Private MapView1 As MapView Private mmpp As MapPoint[] Private tl As Point Private z As Byte = 14 Public Sub Form_Open() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight End With With MapView1 = New MapView(Me) As "MapView1" .X = 0 .Y = 0 .W = Me.W .H = Me.H .Map.AddTile("GoogleMap", "http://mt0.google.com/vt/lyrs=s&hl=&x={x}&y={y}&z={z}") .Map.Center = MapPoint(41.8902142, 12.4900422) .Map.Zoom = z End With End Public Sub MapView1_MouseWheel() ' Mostra il livello di zoom della mappa ad ogni rotazione della rotellina del mouse: Me.Text = "Zoom: " & CStr(MapView1.Map.Zoom) EliminaContornoTessera() End Public Sub MapView1_MouseDown() Dim pt As New Point(Mouse.X, Mouse.Y) Dim mb As MapBounds ' Mostra la latitudine e la longitudine del punto ove si è cliccato: Me.Text = "Lat. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lat, "0.000000") & " - Lon. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lon, "0.000000") If z <> MapView1.Map.Zoom Then EliminaContornoTessera() z = MapView1.Map.Zoom If Not Mouse.Right Then Return tl = Geo.MapPointToTile(MapView1.Map.PixelToMapPointRel(pt), MapView1.Map.Zoom) mb = Geo.TileBounds(tl.X, tl.Y, MapView1.Map.Zoom) ' Crea un vettore di Oggetti "MapPoint" contenenti i 4 vertici della tessera: With mmpp = New MapPoint[] .Push(MapPoint(mb.North, mb.Est)) .Push(MapPoint(mb.North, mb.West)) .Push(MapPoint(mb.South, mb.West)) .Push(MapPoint(mb.South, mb.Est)) .Push(MapPoint(mb.North, mb.Est)) End With MapView1.Map.Center = MapPoint.GetCenter(mmpp) End Private Procedure EliminaContornoTessera() If Not Object.IsValid(MapView1.Map.GetShape("polyline")) Then Return ' Compie un ciclo pari al numero di item validi inseriti: Repeat With MapView1 .Map.Remove("polyline") .Map.Remove("testo") .Refresh() End With ' Compie un ciclo fino a che l'oggetto "_MapShape" è valido, ossia fino a che sono ancora presenti gli item precedentemente inseriti: Until Not Object.IsValid(MapView1.Map.GetShape("polyline")) End Public Sub MapView1_MouseUp() Dim im As Image If Not Mouse.Right Then Return ' Crea un Oggetto "Image", per scriverci i tre parametri della tessera e passarlo quindi al Metodo ".AddShape()": im = New Image(256, 256, Color.Transparent, Image.Standard) With Paint .Begin(im) .Brush = .Color(Color.SoftOrange) .DrawText("x = " & CStr(tl.X) & "\ny = " & CStr(tl.Y) & "\nz = " & Format(MapView1.Map.Zoom, "######"), 0, 0, im.W, im.H, Align.Center) .End End With With MapView1 .Map.AddShape("polyline").AddPolyLine("polyline", mmpp, Color.Yellow, 2, Line.DashDot) .Map.AddShape("testo").AddPoint("testo", MapPoint.GetCenter(mmpp), Color.Default, im) .Refresh() End With End
Visualizzare le tessere di una mappa e i relativi parametri "x", "y" e "z" mediante il Controllo "WebView"
Il seguente codice fa uso della Classe "WebView", e pertanto bisognerà attivare il relativo Componente (come ad esempio gb.qt5.webkit). Quindi non è necessario attivare il Componente gb.map .
Il programma mostra nel riquadro del Controllo WebView una sola tessera per volta (la tessera di partenza mostra la foce del fiume Tevere ad un livello di zoom = 12). Sulla destra sono mostrati anche i tre parametri relativi alla corrente tessera mostrata.
Per vedere le tessere contigue a quella corrente visibile (quindi per spostarsi sul territorio), è necessario modificare i valori dei parametri x (Longitudine) e y (Latitudine) delle tile, che potranno essere variati cliccando sulle parti visibili di colore arancione del "Panel" di contorno al WebView, come segue: se si clicca sulla parte sinistra, sarà mostrata la tessera contigua a sinistra della tessera corrente; se si clicca sulla parte superiore, sarà mostrata la tessera contigua al di sopra della tessera corrente; e così via per le restanti due parti del Panel arancione. Per modificare lo zoom della mappa, ruotare la rotellina del mouse al di sopra dell'Oggetto WebView.
Si provvederà anche a salvare in apposita cartella "/tmp/TESSERE" le tessere di volta in volta visualizzate nell'Oggetto WebView. A tal fine bisognerà attivare anche i Componenti gb.net e gb.net.curl. [nota 2]
Va ricordato che il numero del parametro "x" (Longitudine) delle tessere aumenta procedendo verso Est; mentre il valore del parametro "y" (Latitudine) aumenta procedendo verso SUD.
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) Private z As Byte ' Indica lo Zoom della mappa Public Sub _new() With Me .Center .W = 580 .H = 500 End With With Panel1 = New Panel(Me) As "Panel1" .X = 100 .Y = 50 .W = 350 .H = 350 .Background = Color.Orange End With With Label1 = New Label(Me) .X = Me.W * 0.82 .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.82 .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.82 .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() x = 2187 y = 1524 z = 12 AggiornaLabel() Ricarica() End Public Sub WebView1_MouseWheel() Select Case Mouse.Delta Case 1 If z == 22 Then Return x *= 2 y *= 2 z += 1 Case -1 If z == 0 Then Return x \= 2 y \= 2 z -= 1 End Select AggiornaLabel() Ricarica() 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(z, "########") Label3.W = Label3.Font.TextWidth(Label3.Text) End Private Procedure Ricarica() Dim prc As String = "https://mt1.google.com/vt/lyrs=s&x=" & CStr(x) & "&y=" & CStr(y) & "&z=" & CStr(z) 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 = 256 ' Imposta la lunghezza del "WebView" come la lunghezza delle tessere: 256 pixel .H = 256 ' Imposta l'altezza del "WebView" come l'altezza delle tessere: 256 pixel .Url = prc End With ' Scarica il file immagine della tessera corrente visualizzata: s = tp.Download(prc) tp.Close ' Ricrea il file immagine della tessera corrente visualizzata nella cartella "/tmp/TESSERE": File.Save("/tmp/TESSERE" &/ CStr(x) & "-" & CStr(y) & "-" & CStr(z), s) End
In quest'altra soluzione, simile alla precedente, per vedere le tessere contigue a quella corrente visibile (quindi per spostarsi sul territorio), è necessario modificare i valori dei parametri x e y delle tiles, variandoli direttamente dagli SpinBox laterali, oppure cliccando sulle parti visibili di colore arancione del Panel, come segue: se si clicca sulla parte sinistra, sarà mostrata la tessera contigua a sinistra della tessera corrente; se si clicca sulla parte superiore, sarà mostrata la tessera contigua al di sopra della tessera corrente; e così via per le restanti due parti del Panel arancione.
Private WebView1 As WebView Private Panel1 As Panel Private SpinBox1 As SpinBox Private SpinBox2 As SpinBox Private SpinBox3 As SpinBox Private pn2 As Panel Private eti As Label Private zm As Byte Public Sub Form_Open() With Me .Center .W = 580 .H = 500 .X = (Screen.AvailableWidth / 2) - (Me.W / 2) .Y = Screen.AvailableHeight * 0.1 End With With Panel1 = New Panel(Me) As "Panel1" .X = 100 .Y = 50 .W = 350 .H = 350 .Background = Color.Orange End With With eti = New Label(Me) .X = Panel1.X .Y = Panel1.Y + Panel1.H .W = Panel1.W .H = 20 .Alignment = Align.Center End With With SpinBox1 = New SpinBox(Me) As "SpinBox1" .X = Me.W * 0.82 .Y = Me.H * 0.5 .W = 80 .H = 35 .MaxValue = 10000000 End With With SpinBox2 = New SpinBox(Me) As "SpinBox2" .X = Me.W * 0.82 .Y = Me.H * 0.6 .W = 80 .H = 35 .MaxValue = 10000000 End With With SpinBox3 = New SpinBox(Me) As "SpinBox3" .X = Me.W * 0.82 .Y = Me.H * 0.7 .W = 80 .H = 35 .Value = 12 .MaxValue = 24 .MinValue = 1 End With With SpinBox1 .MinValue = 1 .Value = 2187 End With With SpinBox2 .MinValue = 1 .Value = 1524 End With zm = SpinBox3.Value End Public Sub SpinBox1_Change() Ricarica() End Public Sub SpinBox2_Change() Ricarica() End Public Sub SpinBox3_Change() If SpinBox3.Value > zm Then SpinBox1.Value *= 2 SpinBox2.Value *= 2 Endif If SpinBox3.Value < zm Then SpinBox1.Value \= 2 SpinBox2.Value \= 2 Endif zm = SpinBox3.Value eti.Text = "Se l'immagine non è visibile, cliccare sul riquadro bianco." Ricarica() End Public Sub Panel1_MouseUp() If Mouse.X < WebView1.X Then SpinBox1.Value -= 1 If Mouse.X > (WebView1.X + WebView1.W) Then SpinBox1.Value += 1 If Mouse.Y < WebView1.Y Then SpinBox2.Value -= 1 If Mouse.Y > (WebView1.Y + WebView1.H) Then SpinBox2.Value += 1 Object.Lock(pn2) eti.Text = Null End Public Sub Panel2_MouseUp() Ricarica() Object.Lock(pn2) eti.Text = Null End Private Procedure Ricarica() If Object.IsValid(WebView1) Then WebView1.Delete With WebView1 = New WebView(Panel1) As "WebView1" .X = 50 .Y = 50 .W = 256 .H = 256 .Url = "https://mt1.google.com/vt/lyrs=s&x=" & CStr(SpinBox1.Value) & "&y=" & CStr(SpinBox2.Value) & "&z=" & CStr(SpinBox3.Value) End With With pn2 = New Panel(Panel1) As "Panel2" .X = WebView1.X .Y = WebView1.Y .W = WebView1.W .H = WebView1.H .Background = Color.Transparent End With End
Ottenere i riferimenti di una tessera attraverso appositi calcoli
Si potranno ottenere i riferimenti di una tessera di dimensioni 256x256 pixel anche attraverso un complesso calcolo esplicito:
Private ZOOM As Integer = 15 ' Imposta lo zoom ad esempio sul valore 15 Public Sub Main() Dim lat, lon, f, wc1, wc2 As Float Dim scale As Integer scale = Shl(1, ZOOM) lat = latitidine_in_decimale: DD.dddddd lon = longitudine_in_decimale: DD.dddddd f = Sin(Rad(lat)) ' oppure in modo esplicito: Sin((lat * Pi) / 180) f = Min(Max(f, -0.9999), 0.9999) wc1 = (0.5 + lon / 360) wc2 = (0.5 - Log((1 + f) / (1 - f)) / (4 * Pi)) Print "X tessera: "; Floor(wc1 * scale) Print "Y tessera: "; Floor(wc2 * scale) End
Scaricare dal web e ri-assemblare coerentemente le tessere di una mappa
Ora con un semplice codice proviamo a scaricare dal web i file immagine di tre tessere fra loro contigue orizzontalmente, ossia il Longitudine, e successivamente a mostrarle insieme ri-assemblandole in modo coerente.
E' necessario attivare i Componenti gb.net e gb.net.curl.
Va ricordato che il numero del parametro "x" (Longitudine) delle tessere aumenta procedendo verso Est; mentre il valore del parametro "y" (Latitudine) aumenta procedendo verso SUD.
Public Sub Form_Open() Dim tp As New HttpClient Dim ss As New String[] Dim iimm As New Image[] Dim img, im As Image Dim b As Byte Dim PictureBox1 As PictureBox ' Scarica tre immagini-tessere: ss.Push(tp.Download("https://mt1.google.com/vt/lyrs=s&x=2187&y=1524&z=12")) ss.Push(tp.Download("https://mt1.google.com/vt/lyrs=s&x=2188&y=1524&z=12")) ss.Push(tp.Download("https://mt1.google.com/vt/lyrs=s&x=2189&y=1524&z=12")) tp.Close im = New Image For b = 0 To ss.Max iimm.Push(im.FromString(ss[b])) Next img = New Image(iimm[0].W * iimm.Count, iimm[0].H) With Me .Center .W = img.W + 50 .H = img.H + 50 End With For b = 0 To ss.Max With Paint .Begin(img) .DrawImage(iimm[b], b * iimm[0].W, 0, iimm[0].W, iimm[0].H) .End End With Next With PictureBox1 = New PictureBox(Me) .X = 20 .Y = 20 .W = img.W .H = img.H .Image = img End With End
Va detto che la denominazione dei file delle tessere (tile) scaricati è formata da 4 numeri separati da un trattino, ad esempio:
15-12177-17521-1.png
- il primo numero si riferisce allo Zoom, al quale la tessera appartiene;
- il secondo numero si riferisce alla Latitudine (parametro "y");
- il terzo numero si riferisce alla Longitudine (parametro "x").
Note
[1] Vedere anche la seguente pagina: Utilizzare le tessere di una mappa senza connessione a internet
[2] Su come scaricare un file immagine da internet, vedere la seguente pagina: Scaricare una immagine da un sito internet
Riferimenti
- https://docs.microsoft.com/it-it/azure/azure-maps/zoom-levels-and-tile-grid?tabs=csharp
- https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/coordinates?hl=it#tile-coordinates
- https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/map-coordinates?hl=it
- https://docs.oracle.com/middleware/12211/lcm/JIMPV/toc.htm
- https://wiki.openstreetmap.org/wiki/Main_Page
- https://wiki.openstreetmap.org/wiki/Category:Slippy_map
- https://en.wikipedia.org/wiki/Tiled_web_map
- https://it.wikipedia.org/wiki/Web_Map_Service
- https://www.ogc.org/standards/wmts