Blog technique sur mes expériences de développeur.
17 janvier 2013
Ayant récemment animé une formation Windows Phone 7, j’ai été amené à expliquer et mettre en pratique les fonctionnalités de base de l’OS Mobile de Microsoft (base de données, data binding, carte Bings, isolated storage, etc.).
Autant que possible, je vais tenter de mettre sur ce blog une partie de cette formation en une série d’articles.
Je vous propose de débuter tout de suite avec notre premier billet portant sur le thème de la géolocalisation.
Le but de cet article aura pour objectif d’afficher à l’écran les coordonnées du téléphone, ainsi qu’un marqueur sur une carte indiquant la mention «Vous êtes ici».
Commencez par ajouter 4 TextBlocks à votre page :
<!--LayoutRoot est la grille racine où tout le contenu de la page est placé-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,6,0,0" Name="lblLatitude" Text="Latitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,42,0,0" Name="lblLongitude" Text="Longitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,42,0,0" Name="lblLongitudeValue" Text="" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,6,0,0" Name="lblLatitudeValue" Text="" VerticalAlignment="Top" />
</Grid>
Pour géolocaliser notre téléphone, nous allons utiliser l’objet GeoCoordinateWatcher. Un delegate y sera associé : PositionChanged qui est appelé lorsque la position du téléphone change. **A noter que vous pouvez également utiliser le delegate **StatusChanged qui permet de détecter les changements d’état de notre watcher.
Pour pouvoir utiliser l’objet GeoCoordinateWatcherk, vous devez ajouter la référence System.Device à votre solution.
Voici alors le morceau de code à ajouter à notre fichier xaml.cs pour afficher les coordonnées :
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
//Constructeur dans lequel on précise la précision voulue
GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
//Détermine la distance minimale parcourue entre les appels au delegate positionChanged
watcher.MovementThreshold = 10.0;
//Mise en place des delegates
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
//On tente de démarrer le service de localisation
if (watcher.Permission == GeoPositionPermission.Granted)
{
watcher.Start();
}
}
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//On affiche les coordonnées
lblLatitudeValue.Text = e.Position.Location.Latitude.ToString();
lblLongitudeValue.Text = e.Position.Location.Longitude.ToString();
}
Normalement, des coordonnées doivent s’afficher. Par défaut, il s’agit de locaux Microsoft aux Etats-Unis. Vous pouvez vous amuser à changer votre emplacement grâce aux fonctions de l’émulateur. Votre application doit normalement se mettre à jour.
Nous allons maintenant ajouter une carte qui se centrera sur l’endroit où le téléphone nous géolocalise.
La première étape consiste à récupérer une clef pour notre Bing Map. Pour ce faire, rendez-vous sur le site http://www.bingmapsportal.com.
Une fois identifié, cliquez sur le lien «Create or view keys» dans le sous-menu «My Account». Saisissez les informations demandées dans le formulaire et créez votre clef.
Nous allons maintenant mettre à jour notre fichier XAML pour y ajouter le composant Map.
Voici ce à quoi ressemble maintenant notre fichier :
<!--LayoutRoot est la grille racine où tout le contenu de la page est placé-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,6,0,0" Name="lblLatitude" Text="Latitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,42,0,0" Name="lblLongitude" Text="Longitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,42,0,0" Name="lblLongitudeValue" Text="" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,6,0,0" Name="lblLatitudeValue" Text="" VerticalAlignment="Top" />
<my:Map Height="678" HorizontalAlignment="Left" Margin="12,78,0,0" Name="bingMap" VerticalAlignment="Top" Width="456" ZoomLevel="17" LogoVisibility="Collapsed" CopyrightVisibility="Collapsed">
<my:Map.CredentialsProvider>
<my:ApplicationIdCredentialsProvider ApplicationId="AuSncdh..." />
</my:Map.CredentialsProvider>
</my:Map>
</Grid>
N’oubliez pas de remplacer le CredentialsProvider par votre clef !
Il convient maintenant de centrer la carte sur la position du téléphone et ce à chaque fois que celui-ci détecte un changement de position. Tout se passe donc dans la méthode watcher_PositionChanged.
Voici donc notre méthode mise à jour :
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//On affiche les coordonnées
lblLatitudeValue.Text = e.Position.Location.Latitude.ToString();
lblLongitudeValue.Text = e.Position.Location.Longitude.ToString();
//On centre la carte
bingMap.SetView(e.Position.Location, 17);
}
Nous allons maintenant ajouter un marqueur à notre carte pour indiquer plus précisément où nous sommes.
Ce coup ci, tout se passe dans le code behind. C’est la classe Pushpin qui va nous permettre de modéliser nos marqueurs.
Commencez par déclarer un Pushpin :
Pushpin pin;
Instanciez le dans la méthode OnNavigatedTo :
//On instancie le marqueur
pin = new Pushpin();
pin.Location = new GeoCoordinate(0, 0);
pin.Content = "Vous êtes ici ";
//On ajoute le marqueur à la carte
bingMap.Children.Add(pin);
Il faut maintenant modifier l’emplacement du marqueur avec les changements de positions détectés. Cette mise à jour se passe dans la méthode watcher_PositionChanged :
pin.Location = e.Position.Location;
Voici alors ce que vous devriez avoir à l’exécution :
Pour ceux qui en auraient besoin, voici le code complet :
<phone:PhoneApplicationPage
x:Class="Blog_GeoCoordinateWatcher.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True" xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps">
<!--LayoutRoot est la grille racine où tout le contenu de la page est placé-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,6,0,0" Name="lblLatitude" Text="Latitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,42,0,0" Name="lblLongitude" Text="Longitude :" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,42,0,0" Name="lblLongitudeValue" Text="" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="118,6,0,0" Name="lblLatitudeValue" Text="" VerticalAlignment="Top" />
<my:Map Height="678" HorizontalAlignment="Left" Margin="12,78,0,0" Name="bingMap" VerticalAlignment="Top" Width="456" ZoomLevel="17" LogoVisibility="Collapsed" CopyrightVisibility="Collapsed">
<my:Map.CredentialsProvider>
<my:ApplicationIdCredentialsProvider ApplicationId="AuSncdh..." />
</my:Map.CredentialsProvider>
</my:Map>
</Grid>
</phone:PhoneApplicationPage>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Controls.Maps;
namespace Blog_GeoCoordinateWatcher
{
public partial class MainPage : PhoneApplicationPage
{
Pushpin pin;
// Constructeur
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
//On instancie le marqueur
pin = new Pushpin();
pin.Location = new GeoCoordinate(0, 0);
pin.Content = "Vous êtes ici";
//On ajoute le marqueur à la carte
bingMap.Children.Add(pin);
//Constructeur dans lequel on précise la précision voulue
GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
//Détermine la distance minimale parcourue entre les appels au delegate positionChanged
watcher.MovementThreshold = 10.0;
//Mise en place des delegates
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
//On tente de démarrer le service de localisation
if (watcher.Permission == GeoPositionPermission.Granted)
{
watcher.Start();
}
}
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//On récupère notre objet
GeoCoordinateWatcher watcher = sender as GeoCoordinateWatcher;
//On affiche les coordonnées
lblLatitudeValue.Text = e.Position.Location.Latitude.ToString();
lblLongitudeValue.Text = e.Position.Location.Longitude.ToString();
//On met à jour le marqueur
pin.Location = e.Position.Location;
//On centre la carte
bingMap.SetView(e.Position.Location, 17);
}
}
}