Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

WinRT: Introduzione all'uso di Bing Maps

Poche settimane fa è stato rilasciato il Bing Maps SDK, che permette di utilizzare le mappe di Bing all'interno delle nostre app per Windows 8.

In questo post faremo un'introduzione all'uso di questo SDK, cercando di capire cosa serve e i passaggi principali.

L'SDK può essere scaricato come file VSIX dal link di cui sopra, oppure direttamente dall'Extension Manager di Visual Studio 2012. Per poter utilizzare le Bing Maps all'interno delle proprie app, è dapprima necessario registrarsi e dotarsi di un token, ossia di credenziali in assenza delle quali le mappe non funzionano. Il procedimento va fatto da questo indirizzo: https://www.bingmapsportal.com/

Il tipo di account che dovrete scegliere è quello Basic, specificando, come tipologia di applicazione, Windows Store App:

Memorizzate poi da qualche parte il vostro token. Si passa poi a Visual Studio 2012, ovviamente anche Express per Windows 8, dove supponiamo di avere un progetto vuoto. Per usare le mappe ci sono da fare due cose:

  • impostare l'architettura del processore a x86 nella configurazione corrente, questo perché l'SDK non supporta, in sviluppo, architetture x64 e ARM. Questo si può fare nella finestra Configuration Manager.
  • aggiungere un riferimento a Bing Maps e al Microsoft Visual C++ Runtime Package, come in figura:

A questo punto potrete trascinare dalla toolbox il controllo Map dalla Toolbox sul designer, come in figura:

Il controllo Map può essere completamente gestito in modalità dichiarativa, quindi XAML, nel caso in cui vogliate predisporre una mappa già completa di tutti gli elementi. Spesso, però, vi capiterà di determinare un punto sulla mappa a seconda di una scelta dell'utente, cosa che dovrete fare da codice managed e che vedremo in questo post. Ad ogni buon conto, una volta che il controllo si trova nel designer, sarà definito in modo simile al seguente:

<Maps:Map Name="Map1" Credentials="YOUR TOKEN HERE" ZoomLevel="15" Grid.Row="1" />

Due note veloci: la proprietà Credentials deve contenere il token ricevuto in fase di registrazione sul portale per sviluppatori Bing. Il nome del controllo deve essere specificato manualmente, così come il posizionamento all'interno di altri contenitori. ZoomLevel è una proprietà che permette di impostare il livello di zoom della mappa, 15 è stato specificato da me ed è un buon compromesso di visibilità.

Definiamo anche un TextBlock banale, che ci permetterà più avanti di visualizzare ulteriori info:

<

TextBlock Name="DistanceTextBlock" />

Normalmente si ha necessità di determinare la posizione corrente, ad esempio tramite il dispositivo GPS di un tablet, cosa che si fa nella prima pagina dell'app affinché Windows chieda all'utente il permesso di utilizzare questa caratteristica, per ragioni di privacy. Questo non è strettamente legato alle mappe di Bing, poiché è offerto dal namespace Windows.Devices.Geolocation, ma serve. Ad esempio quando si apre la pagina dell'app potremmo avere:

    Dim locator As Geolocator
    Dim currentPosition As Bing.Maps.Location

 

    Protected Overrides Sub LoadState(navigationParameter As Object, pageState As Dictionary(Of StringObject))         If Me.locator Is Nothing Then Me.locator = New Geolocator         AddHandler Me.locator.PositionChanged, AddressOf locator_PositionChanged     End Sub

La classe Geolocator permette di interagire col dispositivo di localizzazione. Si sottoscrive l'evento PositionChanged che viene sollevato quando la posizione del dispositivo cambia. Tale evento è gestito da un metodo che, attraverso l'utilizzo del dispatcher, rileva latitudine e longitudine della nuova posizione grazie all'oggetto PositionChangedEventArgs, elementi che vanno a costituire gli argomenti dell'istanza di un oggetto di tipo Bing.Maps.Location:

    Private Async Function locator_PositionChanged(sender As Geolocator, args As PositionChangedEventArgsAs Task
        Await Me.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                     New DispatchedHandler(Sub()
                                                               'Richiede una direttiva Imports Bing.Maps
                                                               Dim location As New Location(args.Position.Coordinate.Latitude,
                                                                                            args.Position.Coordinate.Longitude)
                                                               Me.currentPosition = location
                                                           End Sub))
 
    End Function

Ipotizzando poi che l'utente abbia specificato latitudine e longitudine del posto da raggiungere (probabilmente sceglierà un oggetto da voi predisposto e tale oggetto conterrà tali informazioni), la modalità per creare un punto sulla mappa è la seguente:

        Dim location As Bing.Maps.Location
 
        location = New Bing.Maps.Location(item.Latitudine, item.Longitudine)
        Me.Map1.Center = location
        Me.Map1.SetView(location)
        Me.AddPushpin(location, "1")

La mappa viene centrata sulle due coordinate attraverso la proprietà Center e il posizionamento tramite SetView. E' anche disponibile la proprietà MapType che riceve un valore dall'enumerazione Bing.Maps.MapType (Aerial, Road, Birdseye, Empty) che consente di impostare da codice la modalità di visualizzazione della mappa (es. aerea piuttosto che stradale) e che comunque l'utente può cambiare attraverso comandi nel controllo. Si può utilizzare un oggetto Pushpin, che serve a evidenziare con un "bollino blu" il punto di interesse. A tale riguardo predisponiamo questo metodo:

    Private Sub AddPushpin(location As Bing.Maps.Location, text As String)
 
        Dim pushpin As New Bing.Maps.Pushpin With {.Text = text}
        Bing.Maps.MapLayer.SetPosition(pushpin, location)
 
        Me.Map1.Children.Add(pushpin)
    End Sub

L'oggetto Pushpin ha una proprietà Text che può contenere un carattere come un numero o una lettera. Fatto questo, potremmo voler visualizzare in un controllo TextBlock la distanza dalla posizione attuale a quella evidenziata nella mappa. Poiché il punto in questione è rappresentato dalle due coordinate latitudine e longitudine, e che queste sono poco user-friendly, può essere utile avere a disposizione un metodo che le converta in una distanza in KM dal punto corrente. Vi riporto la traduzione in Visual Basic di metodi che ho trovato su questo http://www.geodatasource.com/developers/c-sharp:

    Public Function CalculateDistance(lat1 As Double, lon1 As Double, lat2 As Double, lon2 As Double, unit As CharAs Double
 
        Dim theta As Double = lon1 - lon2
        Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta))
        dist = Math.Acos(dist)
        dist = rad2deg(dist)
        dist = dist * 60 * 1.1515
        If unit = "K"c Then
            dist = dist * 1.609344
        ElseIf unit = "N"c Then
            dist = dist * 0.8684
        End If
        Return dist
    End Function
    Private Function deg2rad(deg As DoubleAs Double
        Return (deg * Math.PI / 180.0)
    End Function
    Private Function rad2deg(rad As DoubleAs Double
        Return (rad / Math.PI * 180.0)
    End Function

Ipotizzando di voler scrivere le informazioni sulla distanza di seguito all'impostazione del punto sulla mappa, il codice di assegnazione del punto sulla mappa può essere esteso con questo:

Dim distance = CalculateDistance(currentPosition.Latitude, currentPosition.Longitude, location.Latitude, location.Longitude, "K"c)
 
Me.DistanceTextBlock.Text = "Distanza dalla posizione attuale: " + CInt(distance).ToString + " KM"

L'utilizzo del literal "K" indica che vogliamo una conversione in KM. La conversione in intero avviene per arrotondare il valore Double. Ovviamente questo calcolo non è sempre necessario né lo è l'utilizzo del GPS integrato, però è utile averlo a disposizione quanto meno come snippet.

Nel caso decidiate però di usare il servizio di localizzazione, ricordatevi di specificarlo nelle capabilities del manifesto dell'app, pena errore in fase di certificazione:

Le mappe di Bing offrono possibilità infinite. Questo post ha solo introdotto tali possibilità, l'obiettivo non era di certo essere la bibbia ma dare un punto di partenza e qualche indicazione soprattutto a chi sviluppa in VB.

Alessandro

Print | posted on venerdì 23 novembre 2012 23:32 | Filed Under [ UWP e Windows Store Apps Visual Studio 2012 ]

Powered by:
Powered By Subtext Powered By ASP.NET