Calcolare l'area e il perimetro di poligoni disegnati sulla mappa con le risorse di gb.map
Da Gambas-it.org - Wikipedia.
Versione del 14 apr 2021 alle 08:26 di Vuott (Discussione | contributi)
Mostriamo un possibile codice per calcolare l'area e il perimetro 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) 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 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 ' 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". ' 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