Ruotare la mappa

Da Gambas-it.org - Wikipedia.

Ruotare la mappa della MapView

Premessa

E' opportuno ricordare che il Controllo MapView è formato da un Oggetto "Figlio" Panel, il quale è a sua volta ha un Oggetto "Figlio" che è una DrawingArea:

MapView
 genitore di un
Panel
 genitore di una
DrawingArea

Per ottenere la rotazione della mappa, mostrata dalla MapView, agiremo sul predetto Oggetto DrawingArea, usando all'interno del Risponditore dell'Evento "_Draw()" di MapView le risorse della Classe Paint ed in particolare i Metodi ".Translate()" e ".Rotate()".

Esempio pratico di rotazione della mappa usando la MapView

Mostriamo un esempio pratico, nel quale cliccando con il tasto sinistro o con quello centrale del mouse si avvierà la rotazione continua della mappa sino a quando non si cliccherà con il tasto destro del mouse.
Ovviamente è necessario attivare anche il Componente gb.map.

Private MapView1 As MapView
Private DrawingArea1 As DrawingArea
Private c As Short

Public Sub _new()

 Dim mp As New MapPoint(41.89018, 12.49230)

 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", "https://mt0.google.com/vt/lyrs=s&hl=&x={x}&y={y}&z={z}")
   .Map.Zoom = 15 
   .Map.Center = mp
 End With

End

Public Sub Form_Open()

 Dim pn As Panel

 pn = MapView1.Children[0]
 DrawingArea1 = pn.Children[0]

End

Public Sub MapView1_Draw()

 With Paint
   .Begin(DrawingArea1)
' Imposta il punto di rotazione della mappa al centro del "Form" contenitore della "MapView":
   .Translate(Me.W / 2, Me.H / 2)
   .Rotate(Rad(c))
' L'uso del Metodo ".Scale()" consente alla mappa durante la sua rotazione di comprire interamente il "Form":
   .Scale(1.15, 1.15)
   With MapView1.Map
     .Width = Paint.W
     .Height = Paint.H
' Compie gli aggiustamenti, affinché il punto di rotazione sia il centro della mappa mostrata:
     Paint.Translate(-(.Width / 2), -(.Height / 2))
     .Draw()
   End With
   .End
 End With

End

Public Sub MapView1_Mouseup()

 While Not Mouse.Right And Object.IsValid(MapView1)
   MapView1.Refresh
' Imposta di quanti gradi ruoterà ogni volta la mappa mostrata:
   c += 10
   If c == 360 Then c = 0
   Wait 0.5
 Wend

End


Ruotare la mappa usando una DrawingArea

In questo caso useremo soltanto una DrawingArea [nota 1] per mostrare la mappa e agiremo all'interno del suo Evento "_Draw()" per ruotare la mappa.
Ovviamente è necessario attivare anche il Componente gb.map.

Private DrawingArea1 As DrawingArea
Private mappa As Map
Private mp As New MapPoint(41.9, 12.5)
Private c As Short
Private mx As Integer
Private my As Integer
Private pt As New Point
Private cpx As New Point

Public Sub _new()

 With mappa = New Map
   .AddTile("GoogleMaps", "https://khms{s}.google.it/kh/v={version}&src=app&x={x}&y={y}&z={z}&s=Galile", ["version": "908"]).SubDomains = ["0", "1", "2"]
   .Center = mp
   .Zoom = 15
 End With
 With Me  
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .Text = "Zoom: " & CStr(mappa.Zoom)
 End With
 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
' Il ridimensionamento della "DrawingArea" come figura di quadrato, avente ciascun lato uguale alla diagonale del "Form", consente alla mappa durante la sua rotazione di comprire interamente il "Form":
   .W = Sqr((Me.W ^ 2) + (Me.H ^ 2))
   .H = .W
   .Background = Color.Yellow
 End With

End 

Public Sub DrawingArea1_Mouseup()

 While (Not Mouse.Right) And Object.IsValid(DrawingArea1)
' Imposta di quanti gradi ruoterà ogni volta la mappa mostrata:
   c += 10
   If c == 360 Then c = 0
   DrawingArea1.Refresh
   Wait 0.5
 Wend

End

Public Sub DrawingArea1_Draw()

 With Paint
' Imposta il punto di rotazione della mappa al centro del "Form" contenitore della "DrawingARea":
   .Translate(Me.W / 2, Me.H / 2)
   .Rotate(Rad(c))
   With mappa
     .Center = mp
     .Width = Paint.W
     .Height = Paint.H
' Compie gli aggiustamenti, affinché il punto di rotazione sia il centro della mappa mostrata:
     Paint.Translate(-(.Width / 2), -(.Height / 2))
     .Draw()
   End With
   .End
 End With

 Me.Refresh()

End

Public Sub DrawingArea1_MouseDown()  

 pt = Point(Mouse.X, Mouse.Y)

 Me.Text = "Lat. " & Format(mappa.PixelToMapPointRel(pt).Lat, "0.000000") & 
           "   Lon. " & Format(mappa.PixelToMapPointRel(pt).Lon, "0.000000") &
           "  -  Zoom: " & CStr(mappa.Zoom)

 mx = pt.X  
 my = pt.Y
 cpx = Geo.MapPointToPixel(mappa.Center, mappa.Zoom)

End

Public Sub DrawingArea1_MouseMove()  

 Dim pix As New Point(cpx.X, cpx.Y)

 pix.X += mx - Mouse.X
 pix.Y += my - Mouse.Y

' Le seguenti righe di comando consentono uno spostamento morbido e uniforme della mappa per ciascun livello di zoom:
 mappa.Center.Lat = Geo.PixelToMapPoint(pix, mappa.Zoom).Lat
 mappa.Center.Lon = Geo.PixelToMapPoint(pix, mappa.Zoom).Lon
 
End

Public Sub DrawingArea1_MouseWheel()

' Impedisce che si vada oltre il massimo livello di zoom della mappa:
 If mappa.Zoom + Mouse.Delta > mappa.MaxZoom Then Return 

' Pone al centro della mappa il punto ove si è ruotata la rotellina:
 pt = Point(Mouse.X, Mouse.Y)
 mp.Lat = mappa.PixelToMapPointRel(pt).Lat
 mp.Lon = mappa.PixelToMapPointRel(pt).Lon

' Valuta il verso della rotazione della rotellina e modifica lo zoom della mappa:
 mappa.Zoom += Mouse.Delta
 Me.Text = "Zoom: " & CStr(mappa.Zoom)

End


Note

[1] Vedere al riguardo la seguente pagina: Utilizzare una DrawingArea o una ImageView con gb.map anziché una MapView