Calcolare l'area e il perimetro di poligoni disegnati sulla mappa con le risorse di gb.map

Da Gambas-it.org - Wikipedia.

Mostriamo di seguito un possibile codice essenziale per calcolare l'area di poligoni disegnati sulla mappa con le risorse di "gb.map".
Per il calcolo dell'area dei poligoni sarà utilizzata la Formula dell'area di Gauss.

' 1) Raggiungere il livello di zoom desiderato della mappa.
' 2) Per cominciare ad inserire i punti/vertici del poligono, da disegnare sulla mappa, cliccare con il tasto DESTRO del mouse.
' 3) Cliccando sulla mappa con il tasto centrale, si inserirà il punto geografico scelto. L'inserimento dei punti geografici deve avvenire in senso "ORARIO". Non si deve porre un nuovo punto fra due punti precedentemente inseriti !
' 4) Dopo l'impostazione del secondo punto geografico nell'intestazione del Form sarà mostrata la dimensione dell'area del poligono sino a quel momento disegnato.
Private MapView1 As MapView
Private zero As MapPoint
Private dstlat As New Float[]
Private dstlon As New Float[]


Public Sub Form_Open()

 With Me
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .Text = "PRO MEMORIA: prima di inziare la costruzione di un poligono, cliccare con il tasto 'destro' del mouse !"
 End With
 
 With MapView1 = New MapView(Me) As "MapView1"
   .X = 0
   .Y = 0
   .W = Me.W
   .H = Me.H
   .Map.AddTile("GoogleMap", "https://mt0.google.com/vt/lyrs=s&hl=&x={x}&y={y}&z={z}")
   .Map.Zoom = 6
' Imposta il centro della mappa viasualizzata:
   .Map.Center = MapPoint(41.8903, 12.492255)
 End With 
  
End

Public Sub MapView1_MouseUp()

 Dim pt As New Point(Mouse.X, Mouse.Y)
 Dim mmpp As MapPoint[]
 Dim mq As Float
 
 If Mouse.Right Then
' Il Piano Cartesiano, che fa da riferimento ad ogni punto geografico inserito, ha come coordinate la latitudine la Longitudine del vertice in basso a sinistra della "MapView":
   zero = MapView1.Map.PixelToMapPointRel(Point(0, MapView1.H))
   dstlat = New Float[]
   dstlon = New Float[]
   Me.Text = String.Chr(&33A1) & " 0.00"
 Endif
 If Mouse.Middle Then
' Inserisce il "MapPoint" del punto geografico scelto, cliccato con il mouse sulla mappa:
   With mmpp = New MapPoint[]
     .Push(MapView1.Map.PixelToMapPointRel(Point(MapView1.Map.MapPointToPixelRel(zero).X, pt.Y)))
     .Push(MapView1.Map.PixelToMapPointRel(Point(pt.X, MapView1.Map.MapPointToPixelRel(zero).Y)))
     .Push(MapView1.Map.PixelToMapPointRel(pt))
   End With
   
' Di ogni punto geografico inserito si calcola la distanza in metri dagli assi x,y aventi come coordinata il punto in basso a sinistra della "MapView". I due valori rappresentano i valori dei vertici del poligono definito dall'immissione con il mouse dei punti geografici prescelti.
   dstlat.Push(MapPoint.Distance(mmpp[0], mmpp[2]))
   dstlon.Push(MapPoint.Distance(mmpp[1], mmpp[2]))
   
   If dstlat.Count > 2 Then mq = FormulaGauss(dstlat, dstlon)
   Me.Text = "Area: " & String.Chr(&33A1) & " " & Format(mq, "0.00")
   mmpp = Null
 Endif
  
End

Private Function FormulaGauss(lat As Float[], lon As Float[]) As Float
 
 Dim c As Short
 Dim r1, r2 As Float
 
' Applica la formula dell'area di Gauss:
 For c = 0 To lat.Max - 1
   r1 += lat[c] * lon[c + 1]
 Next 
 r1 += lat[lat.Max] * lon[0]
 
 For c = 0 To lon.Max - 1 
   r2 += (lon[c] * lat[c + 1])
 Next
 r2 += (lon[lon.Max] * lat[0])
 
 Return Abs((r1 - r2) / 2)
 
End


Di seguito, invece, un codice per calcolare l'area e il perimetro di poligoni disegnati sulla mappa con le risorse di "gb.map".
Anche in questo caso sarà utilizzata la "Formula dell'area di Gauss ".

' 1) Raggiungere il livello di zoom desiderato della mappa.
' 2) Per cominciare ad inserire i punti/vertici del poligono, da disegnare sulla mappa, cliccare con il tasto DESTRO del mouse.
' 3) Cliccando sulla mappa con il tasto centrale, si inserirà il punto geografico scelto. L'inserimento dei punti geografici deve avvenire in senso "ORARIO". Non si deve porre un nuovo punto fra due punti precedentemente inseriti !
' 4) Cliccare con il tasto destro, per terminare l'inserimento dei punti geografici, costituenti il poligono, e per mostrare sull'intestazione del Form i risultati in metri e chilometri quadrati afferenti all'area del poligono disegnato e in metri lineari al suo perimetro.
' 5) Cliccando sulla mappa con un il tasto sinistro del mouse, verranno mostrati i valori delle coordinate geografiche (Latitudine e Longitudine) del punto, sul quale si è cliccato.

Private MapView1 As MapView
Private zero As MapPoint
Private mper As MapPoint[]
Private dstlat As New Float[]
Private dstlon As New Float[]
Private perimetro As Float


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.Zoom = 6
' Imposta il centro della mappa visualizzata:
   .Map.Center = MapPoint(41.6543, 13.5131)
 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)
 
End

Public Sub MapView1_MouseDown()
 
 Dim pt As New Point(Mouse.X, Mouse.Y)
 
' Mostra la latitudine e la longitudine del punto ove si è cliccato:
 If Mouse.Left Then Me.Text = "Lat. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lat, "0.000000") &
                              "  -  Lon. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lon, "0.000000")

End

Public Sub MapView1_MouseUp()
 
 Dim pt As New Point(Mouse.X, Mouse.Y)
 Dim mmpp As MapPoint[]
 Dim mq As Float
 
 If Mouse.Right Then 
   If dstlat.Count > 2 Then 
' Fa il calcolo dell'area del poligono:
     mq = FormulaGauss(dstlat, dstlon)
' Aggiunge la lunghezza del lato individuato dall'ultimo punto inserito e il primo:
     perimetro += MapPoint.Distance(mper[0], mper[mper.Max - 1])
' Mostra i risultati afferenti al poligono disegnato:
     Me.Text = "Area: " & String.Chr(&33A1) & " " & Format(mq, "0.00") & "  (" &
               String.Chr(&33A2) & " " & Format(mq / 1e+6, "0.0######") & ")" &
               "   -   Perimetro: m. " & Format(perimetro, "0.00")
   Endif 
   mper = Null
   dstlat = Null
   dstlon = Null
   perimetro = 0.0
' Il Piano Cartesiano, che fa da riferimento ad ogni punto geografico inserito, ha come coordinate la latitudine la Longitudine del vertice in basso a sinistra della "MapView":
   zero = MapView1.Map.PixelToMapPointRel(Point(0, MapView1.H))
   mper = New MapPoint[]
   dstlat = New Float[]
   dstlon = New Float[]
 Endif
 
' L'inserimento dei punti geografici deve avvenire in senso "ORARIO".
' Non si deve porre un nuovo punto fra due punti precedentemente inseriti: l'inserimento in senso "orario" non deve essere interrotto.
 If Mouse.Middle Then
   If Not Object.IsValid(mper) Then 
     Message.Warning("E' necessario innanzitutto cliccare sulla mappa con il tasto destro del mouse !")
     Return 
   Endif
' Ad ogni nuovo calcolo di area i valori, mostrati nell'intestazione del Form, sono azzerati:
   If dstlat.Count == 0 Then 
     Me.Text = "Area: " & String.Chr(&33A1) & " 0,00" &
               "  (" & String.Chr(&33A2) & " 0,00" & ")" &
               "   -   Perimetro: m. 0,00"
   Endif
' Se gli elementi dell'array "mper" sono più di due, rimuove l'ultimo elemento "mper[0]" che è stato aggiunto con la seconda riga di comando sottostante:
   If mper.Count > 2 Then mper.Remove(mper.Max)
   mper.Push(MapView1.Map.PixelToMapPointRel(pt))
' Se gli elementi dell'array "mper" sono più di due, aggiunge un elemento con coordinate eguali al primo punto di "MapPoint" per chiudere temporaneamente il poligono nel disegno:
   If mper.Count > 2 Then mper.Push(mper[0])
   
   With MapView1
' Inserisce il "MapPoint" del punto geografico scelto, cliccato con il mouse sulla mappa:
     With mmpp = New MapPoint[]
       .Push(MapView1.Map.PixelToMapPointRel(Point(MapView1.Map.MapPointToPixelRel(zero).X, pt.Y)))
       .Push(MapView1.Map.PixelToMapPointRel(Point(pt.X, MapView1.Map.MapPointToPixelRel(zero).Y)))
       .Push(MapView1.Map.PixelToMapPointRel(pt))
     End With
' Disegna il poligono in base ai punti sino ad ora impostati con il mouse sulla mappa:
     DisegnaPoligono()
   End With
 
' Di ogni punto geografico inserito si calcola la distanza in metri dagli assi x,y aventi come coordinata il punto in basso a sinistra della "MapView". I due valori rappresentano i valori dei vertici del poligono definito dall'immissione con il mouse dei punti geografici prescelti.
   dstlat.Push(MapPoint.Distance(mmpp[0], mmpp[2]))
   dstlon.Push(MapPoint.Distance(mmpp[1], mmpp[2]))
 
' Calcola il perimetro del poligono corrente disegnato con i punti geografici impostati:
   CalcolaPerimetro()
 Endif 
 
End


Private Procedure DisegnaPoligono()
 
 With MapView1
' Disegna il poligono in base ai punti sino ad ora impostati con il mouse sulla mappa:
     .Map.AddShape("polyline").AddPolyLine("polyline", mper, Color.Red, 1, 4)
     .Refresh()
     .Map.Refresh()
 End With
 
End

Private Procedure CalcolaPerimetro()
 
' Calcola il perimetro del poligono corrente disegnato con i punti geografici impostati:
 If dstlat.Count = 2 Then perimetro = MapPoint.Distance(mper[0], mper[1])
 If dstlat.Count > 2 Then perimetro += MapPoint.Distance(mper[mper.Max - 2], mper[mper.Max - 1])
 
End


Private Function FormulaGauss(lat As Float[], lon As Float[]) As Float
 
 Dim c As Short
 Dim r1, r2 As Float
 
' Applica la formula dell'area di Gauss:
 For c = 0 To lat.Max - 1
   r1 += lat[c] * lon[c + 1]
 Next 
 r1 += lat[lat.Max] * lon[0]
 
 For c = 0 To lon.Max - 1 
   r2 += (lon[c] * lat[c + 1])
 Next
 r2 += (lon[lon.Max] * lat[0])
 
' La funzione "Abs()" qui consente di ottenere un valore positivo impostando i punti in senso "orario":
 Return Abs((r1 - r2) / 2)
 
End