Differenze tra le versioni di "Disegnare un percorso su una MapView e calcolarne la lunghezza"
Riga 1: | Riga 1: | ||
− | Mostriamo di seguito | + | Mostriamo di seguito due possibili codici per disegnare su una ''MapView'' un percorso e calcolarne la lunghezza man mano che il tracciato viene disegnato. |
+ | <BR>Per ottenere il calcolo dei vari segmenti del percorso tracciati, è fondamentale l'uso del Metodo ".Distance()" della Classe "MapPoint" del Componente gb.map. | ||
− | + | ||
− | < | + | ===Uso della sola MapView=== |
+ | Nel primo esempio, più semplice, si farà uso della "MapView" e delle sue risorse connesse. | ||
+ | <BR>Per tracciare il percorso, basterà cliccare con il tasto destro del mouse su vari punti: ogni due punti impostati sarà disegnata una sottile linea rossa tratteggiata sulla "MapView". Contestualmente sull'intestazione in alto del "Form" verrà mostrato la lunghezza totale dei segmenti sino a quel momento tracciati. | ||
+ | <BR>Per eliminare l'intero tracciato e azzerare il calcolo, si dovrà cliccare sulla mappa con il tasto centrale (rotellina) del mouse. | ||
+ | Private mmpp As New MapPoint[] | ||
+ | |||
+ | |||
+ | '''Public''' Sub Form_Open() | ||
+ | |||
+ | With MapView1.Map | ||
+ | .AddTile("OpenTopo", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png") | ||
+ | .Center = MapPoint(41.8902142, 12.4900422) | ||
+ | .Zoom = 12 | ||
+ | End With | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | '''Public''' Sub MapView1_MouseUp() | ||
+ | |||
+ | Dim pt As New Point(Mouse.X, Mouse.Y) | ||
+ | Dim c, i As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''Se si clicca con il tasto destro del mouse, si inserisce un oggetto "_MapShape", ossia una "Polyline":''</font> | ||
+ | If Mouse.Right Then | ||
+ | If Not Object.IsValid(mmpp) Then mmpp = New MapPoint[] | ||
+ | With MapView1 | ||
+ | mmpp.Push(.Map.PixelToMapPointRel(pt)) | ||
+ | .Map.AddShape("polyline").AddPolyLine("polyline", mmpp, Color.Red, 1, Line.DashDot) | ||
+ | .refresh() | ||
+ | End With | ||
+ | If mmpp.Count < 2 Then Return | ||
+ | For c = 0 To mmpp.Max - 1 | ||
+ | i += MapPoint.Distance(mmpp[c], mmpp[c + 1]) | ||
+ | Me.Text = "metri: " & CStr(i) | ||
+ | Next | ||
+ | Endif | ||
+ | |||
+ | <FONT Color=gray>' ''Se si clicca con il tasto centrale del mouse, si eliminano tutte le linee inserite del tracciato:''</font> | ||
+ | If Mouse.Middle And Object.IsValid(MapView1.Map.GetShape("polyline")) Then | ||
+ | <FONT Color=gray>' ''Compie un ciclo pari al numero di item validi inseriti:''</font> | ||
+ | Repeat | ||
+ | With MapView1 | ||
+ | .Map.Remove("polyline") | ||
+ | .Refresh() | ||
+ | End With | ||
+ | <FONT Color=gray>' ''Compie un ciclo fina a che l'oggetto "_MapShape" è valido, ossia fino a che sono ancora presenti gli item precedentemente inseriti:''</font> | ||
+ | Until Not Object.IsValid(MapView1.Map.GetShape("polyline")) | ||
+ | <FONT Color=gray>' ''Annulla e azzera alcune risorse del codice:''</font> | ||
+ | mmpp = Null | ||
+ | i = 0 | ||
+ | Me.Text = "metri: 0" | ||
+ | Endif | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | ===Uso della MapView e dei suoi oggetti "Figli"=== | ||
+ | In quest'altro codice esemplificativo si farà uso della "DrawingArea", Oggetto "Figlio" di un "Panel", "Figlio" quest'ultimo a sua volta dell'Oggetto "MapView": | ||
<FONT Size=4>MapView</font> | <FONT Size=4>MapView</font> | ||
<FONT Size=3>⬇</font> <FONT Size=1>padre di un</font> | <FONT Size=3>⬇</font> <FONT Size=1>padre di un</font> |
Versione delle 17:28, 30 apr 2021
Mostriamo di seguito due possibili codici per disegnare su una MapView un percorso e calcolarne la lunghezza man mano che il tracciato viene disegnato.
Per ottenere il calcolo dei vari segmenti del percorso tracciati, è fondamentale l'uso del Metodo ".Distance()" della Classe "MapPoint" del Componente gb.map.
Uso della sola MapView
Nel primo esempio, più semplice, si farà uso della "MapView" e delle sue risorse connesse.
Per tracciare il percorso, basterà cliccare con il tasto destro del mouse su vari punti: ogni due punti impostati sarà disegnata una sottile linea rossa tratteggiata sulla "MapView". Contestualmente sull'intestazione in alto del "Form" verrà mostrato la lunghezza totale dei segmenti sino a quel momento tracciati.
Per eliminare l'intero tracciato e azzerare il calcolo, si dovrà cliccare sulla mappa con il tasto centrale (rotellina) del mouse.
Private mmpp As New MapPoint[] Public Sub Form_Open() With MapView1.Map .AddTile("OpenTopo", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png") .Center = MapPoint(41.8902142, 12.4900422) .Zoom = 12 End With End Public Sub MapView1_MouseUp() Dim pt As New Point(Mouse.X, Mouse.Y) Dim c, i As Integer ' Se si clicca con il tasto destro del mouse, si inserisce un oggetto "_MapShape", ossia una "Polyline": If Mouse.Right Then If Not Object.IsValid(mmpp) Then mmpp = New MapPoint[] With MapView1 mmpp.Push(.Map.PixelToMapPointRel(pt)) .Map.AddShape("polyline").AddPolyLine("polyline", mmpp, Color.Red, 1, Line.DashDot) .refresh() End With If mmpp.Count < 2 Then Return For c = 0 To mmpp.Max - 1 i += MapPoint.Distance(mmpp[c], mmpp[c + 1]) Me.Text = "metri: " & CStr(i) Next Endif ' Se si clicca con il tasto centrale del mouse, si eliminano tutte le linee inserite del tracciato: If Mouse.Middle And Object.IsValid(MapView1.Map.GetShape("polyline")) Then ' Compie un ciclo pari al numero di item validi inseriti: Repeat With MapView1 .Map.Remove("polyline") .Refresh() End With ' Compie un ciclo fina 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")) ' Annulla e azzera alcune risorse del codice: mmpp = Null i = 0 Me.Text = "metri: 0" Endif End
Uso della MapView e dei suoi oggetti "Figli"
In quest'altro codice esemplificativo si farà uso della "DrawingArea", Oggetto "Figlio" di un "Panel", "Figlio" quest'ultimo a sua volta dell'Oggetto "MapView":
MapView ⬇ padre di un Panel ⬇ padre di una DrawingArea
Funzionamento del programma:
per iniziare a disegnare e calcolare la lunghezza di un percorso sulla mappa, cliccare innanzitutto con il tasto DESTRO del mouse sulla mappa medesima. Quindi cliccare con il tasto CENTRALE del mouse sul punto ove si intende fa cominciare il percorso da calcolare, e disegnare il tracciato spostandosi con il mouse, mantenendo premuto il tasto CENTRALE del mouse. E' possibile anche effettuare il calcolo della lunghezza di un tracciato cliccando solo su alcuni punti distanti fra loro (questo metodo ovviamente è preferibile soltanto per tratti rettilinei).
Per spostare la mappa, senza perdere i dati immessi, utili per il calcolo del tracciato, usare esclusivamente il tasto SINISTRO del mouse.
Per iniziare a calcolare un nuovo percorso, cliccare nuovamente con il tasto DESTRO del mouse sulla mappa.
Private MapView1 As MapView Private pn As Panel Private AreaDisegno As DrawingArea Private obs As Observer Private mp As MapPoint = MapPoint(41.8903, 12.49223) Private mmpp As MapPoint[] Private f As Float Private bo As Boolean Public Sub Form_Open() With Me .W = Screen.AvailableWidth .H = Screen.AvailableHeight .Arrangement = Arrange.Fill End With With MapView1 = New MapView(Me) As "MapView1" .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: .Map.Center = mp End With ' Si individua innanzitutto l'Oggetto "Figlio" del widget "MapView", che in questo caso è un "Panel": pn = MapView1.Children[0] ' Si individua quindi l'Oggetto "Figlio" dell'Oggetto "Panel" appena prima individuato, che in questo caso è una "DrawingArea": AreaDisegno = pn.Children[0] ' In questo caso si usa la Classe "Observer" - e non il Metodo "Object.Attach()" - per consentire che la mappa sia visibile: obs = New Observer(AreaDisegno) As "AreaDisegno" End Public Sub AreaDisegno_MouseDown() Dim pt As New Point(Mouse.X, Mouse.Y) Dim lat As Float = MapView1.Map.PixelToMapPointRel(pt).Lat Dim lon As Float = MapView1.Map.PixelToMapPointRel(pt).Lon ' Se si clicca con il tasto DESTRO del mouse, è possibile iniziare un nuovo tracciato: If Mouse.Right Then f = 0.0 mmpp = New MapPoint[] Endif If Not Mouse.Middle Then Return ' Se non è stato premuto sulla mappa con il tasto DESTRO del mouse, viene mostrato un avviso: If Not Object.IsValid(mmpp) Then Message.Warning("Per iniziare un tracciato, cliccare preliminarmente con il tasto DESTRO del mouse sulla mmappa !") Return Endif mp = MapPoint(lat, lon) mmpp.Push(mp) bo = True Me.Mouse = Mouse.Blank ' Consente che sia disegnato il mirino sulla mappa, non appena vi si clicca con il tasto CENTRALE: MapView1.Refresh MapView1.Map.Refresh End Public Sub AreaDisegno_MouseUp() bo = False Me.Mouse = Mouse.Arrow End Public Sub AreaDisegno_MouseMove() Dim pt As New Point(Mouse.X, Mouse.Y) Dim lat As Float = MapView1.Map.PixelToMapPointRel(pt).Lat Dim lon As Float = MapView1.Map.PixelToMapPointRel(pt).Lon If Not Mouse.Middle Then Return Me.Mouse = Mouse.Blank mp = MapPoint(lat, lon) mmpp.Push(mp) MapView1.Refresh MapView1.Map.Refresh End Public Sub MapView1_Draw() Dim c, x, y, r As Short Dim s As String Dim po As Point = MapView1.Map.MapPointToPixelRel(mp) With Paint .Begin(AreaDisegno) .Brush = .Color(Color.DarkOrange) .LineWidth = 2.0 .Arc(MapView1.Map.MapPointToPixelRel(mp).X, MapView1.Map.MapPointToPixelRel(mp).Y, 50, 0, 360, False) .Arc(MapView1.Map.MapPointToPixelRel(mp).X, MapView1.Map.MapPointToPixelRel(mp).Y, 30, 0, 360, False) .Stroke .Brush = .Color(Color.Red) .Arc(MapView1.Map.MapPointToPixelRel(mp).X, MapView1.Map.MapPointToPixelRel(mp).Y, 1.5, 0, 360, False) .Fill r = 50 x = po.X y = po.Y For c = 0 To 270 Step 90 po.X = x + r * Cos(Rad(c)) po.Y = y + r * Sin(Rad(c)) .MoveTo(po.X, po.Y) ' Per ridurre la lunghezza della "x" per i gradi 0, 90, 180 e 270 è necessaria questa sequenza: +n 0 -n 0 che si ottiene con il Coseno di c. ' Per ridurre la lunghezza della "y" per i gradi 0, 90, 180 e 270 è necessaria questa sequenza: 0 -n 0 +n che si ottiene con il Coseno di c + 90. .LineTo(x + (20 * Cos(Rad(c))), y - (20 * Cos(Rad(c + 90)))) .Stroke Next .Brush = .Color(Color.Orange) .Font.Size = 8 .DrawText(Format(mp.Lat, "0.######"), x + r * Cos(Rad(270)) - (Me.Font.TextWidth(Format(mp.Lat, "0.######")) / 2), y + (r + 15) * Sin(Rad(270)), Me.Font.TextWidth(Format(mp.Lat, "0.######")), Me.Font.TextHeight(Format(mp.Lat, "0.######")), Align.Right) .DrawText(Format(mp.Lon, "0.######"), x + r * Cos(Rad(0)) - (Me.Font.TextWidth(Format(mp.Lon, "0.######")) / 2), (y + r * Sin(Rad(0))) - 17, Me.Font.TextWidth(Format(mp.Lon, "0.######")), Me.Font.TextHeight(Format(mp.Lon, "0.######")), Align.Right) If Not Object.IsValid(mmpp) Then .End Return Endif ' Disegna i punti del tracciato seguito: .Brush = .Color(Color.Yellow) For c = 0 To mmpp.Max r = 1 If c = 0 Then r = 4 .Arc(MapView1.Map.MapPointToPixelRel(mmpp[c]).X, MapView1.Map.MapPointToPixelRel(mmpp[c]).Y, r, 0, 360, False) .Fill Next ' Disegna il calcolo in metri dell'intero percorso sino in quel momento tracciato: If mmpp.Count == 1 Then s = "m. 0,00" If mmpp.Count > 1 Then If bo Then f += MapPoint.Distance(mmpp[mmpp.Max - 1], mmpp[mmpp.Max]) s = "m. " & Format(f, "0.##") Endif .Font.Size = 11 .DrawText(s, x + r * Cos(Rad(90)) - (Me.Font.TextWidth(s) / 2), y + (r + 50) * Sin(Rad(90)), Me.Font.TextWidth(s), Me.Font.TextHeight(s), Align.Right) .End End With End