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.

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.

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)
   .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
     Paint.Translate(-(.Width / 2), -(.Height / 2))
     .Draw()
   End With
   .End
 End With

 Me.Refresh()

End

Public Sub MapView1_Mouseup()

 While (Not Mouse.Right)
   c += 10
   If c == 360 Then c = 0
   Wait 0.5
   If Not Object.IsValid(MapView1) Then Break 
   MapView1.Refresh
 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:

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)
   c += 10
   If c == 360 Then c = 0
   DrawingArea1.Refresh
   Wait 0.5
 Wend

End

Public Sub DrawingArea1_Draw()

 With Paint
   .Translate(Me.W / 2, Me.H / 2)
   .Rotate(Rad(c))
   With mappa
     .Center = mp
     .Width = Paint.W
     .Height = Paint.H
     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