vendredi 28 janvier 2011

vendredi 14 janvier 2011

SQL Server 2008 spatial – WP7 - Bing Maps II

Utilisation du GeoSpatial dans SQL SERVER 2008 et interaction avec WP7 et Bing Maps – Partie2

Introduction

Avec l’amélioration des technologies et les nouvelles Interfaces Homme/Machine, il est intéressant de pouvoir présenter l’information sous une autre forme que la forme, historique, textuelle.

Dans cet article, l’objectif est de présenter, de bout en bout, comment localiser géographiquement des données sur une carte à partir d’un mobile Windows Phone 7. Pour ce faire, nous utilisons l’API Bing Maps pour Windows Phone 7.

En début d’année scolaire, j’ai rédigé un petit article. Et je n’ai jamais pris le temps de le publier. Je me suis fait violence et j’ai publié la première partie le mois dernier. Voici donc la suite.

Ce deuxième volet se concentre plus sur l’interaction avec WP7 et Bing Maps.

Contexte : Comment créer une application Windows Phone 7

Nous avons une liste de points d’intérêts, classés par type, que nous souhaiterions afficher sur une carte géographique (Bing Maps).

Pré requis

Windows Phone Developer Tools

http://developer.windowsphone.com/windows-phone-7/ 

SDK Bing Maps

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=beb29d27-6f0c-494f-b028-1e0e3187e830

Créer une clé de développement Bing Maps

Créer une clé de développement sur le site Bing Maps grâce à votre LiveId.

https://www.bingmapsportal.com/

 

Côté Serveur

L’accès aux données : EF4

Entity Framework 4 ne supportant pas le type SqlGeography, il faudra absolument utiliser une version « textuelle » des points géographiques. Pour ce faire :

· soit il est nécessaire de faire une conversion de données en utilisant l’instruction T-SQL .STAsText() (ex : MonChamp.STAsText()).

· soit il est nécessaire de faire cohabiter à la fois la donnée sous forme géographique et à la fois la donnée sous forme de string. C’est-à-dire avoir un champ de type geography, avoir un champ de type varchar pour la latitude et avoir un champ de type varchar pour la longitude.

Dans cet article, nous avons fait le choix de passer par une vue SQL pour plusieurs raisons :

· EF4 verra cette vue sous forme d’entité, ce qui facilitera son utilisation et sa manipulation entre les couches plutôt que de manipuler un « type complexe » issu d’une procédure stockée.

· On ne duplique pas la donnée de type geography. On ne fait que la convertir.

CREATE VIEW [dbo].[v_PointInteret]
AS
SELECT ID, osm_id, name, type, Position_Geo.STAsText() AS Position_Geo
FROM dbo.PointInteret

Avant de créer le modèle de données EF4, nous allons créer le projet qui contiendra ce modèle.

1. Créer un projet du type WCF Service Application

2. Créer un répertoire Data et ajouter un nouvel élément au projet de type ADO.NET Entity Data Model :

image

image

image

image

image

La couche métier et service : WCF Data Services

1. Une fois le modèle de données implémenté, il va falloir ajouter un élément de type WcfDataService au projet.

image

2. Supprimer l’élément Service1.svc de type WCF Service créé par défaut lors de la création du projet.

3. Et renommer le fichier IService1.cs en IServicePOIViewer.cs.

Cela doit donner l’arborescence suivante :

image

4. Nous allons maintenant implémenter le service en écrivant le code suivant dans le fichier WcfDataServicePOIViewer.svc.cs :

image

A la ligne 12, nous avons donné le type de notre DataModel.

Aux lignes 17 et 18, nous affectons des droits d’accès aux ressources exposées. Ici, nous donnons des droits sur tous les EntitySet et toutes les opérations de service grâce aux « * » ;

A la ligne 23, nous définissons une opération de service. Une opération de service est une méthode exposable via un service WCF Data Services.

« Les opérations de service sont annotées par l'attribut [WebGet] pour celles adressables via une requête HTTP GET et par l'attribut [WebInvoke] pour celles adressables via une requête HTTP POST.

Des paramètres de type simple uniquement peuvent être spécifiés pour les opérations de service. Celles-ci peuvent retourner void (Nothing en VB.NET), IEnumerable, IQueryable, une entité du modèle de donnée ou un type primitif. Retourner IQueryable permet de supporter des options de requête (pagination, filtre, etc.) et de naviguer via les propriétés de navigation des entités retournées. »

Source : http://badger.developpez.com/tutoriels/dotnet/odata-wcf-data-services/

5. Nous allons maintenant modifier le code du fichier IServicePOIViewer.cs pour définir le contrat de l’opération de service créée.

image

6. Vérifier la bonne marche du service :
http://localhost/BSE.POIViewer.Service/WcfDataServicePOIViewer.svc/Types http://localhost/BSE.POIViewer.Service/WcfDataServicePOIViewer.svc/GetPOIs?typeOfPOI='zoo'
Pour plus de détails sur ce type d’URL : http://msdn.microsoft.com/fr-fr/library/dd728279.aspx .

 

Côté Client

Silverlight for Windows Phone 7

1. Ajouter un projet du type Windows Phone List Application

image

2. Ajouter les références suivantes au projet :

· Microsoft.Maps.MapControl.Common.dll

· Microsoft.Maps.MapControl.dll

· System.Windows.Browser.dll

· System.Data.Services.Client.dll

image

3. Créer un répertoire « Classes » dans lequel nous mettrons les différentes classes que nous créerons.

4. Générer le proxy client du service :
DataSvcutil.exe /uri:http://localhost/BSE.POIViewer.Service/WcfDataServicePOIViewer.svc/ /DataServiceCollection /Version:2.0 /out:C:\wcf\WcfDataServicePOIViewer.cs
(DataSvcutil.exe se situe dans C:\Windows\Microsoft.NET\Framework\v4.0.30319)

5. Ajouter la classe générée au projet.

image

6. Le Binding et le ViewModel sont déjà générés. Nous allons nous appuyer dessus en le modifiant un peu pour répondre à notre besoin.

7. Créer la classe ItemLocation:

image

8. Ouvrir le fichier MainViewModel.cs et supprimer la méthode SampleMethod()

9. Renommer la propriété sampleProperty en SelectedTypeOfPOI

10. Créer la propriété privée suivante :
private POIViewerDataModelcnx _context;

11. Créer la collection suivante :
public ObservableCollection<ItemLocation> Locations { get; private set; }

12. Créer la méthode suivante pour récupérer la liste des types de POI :

image

13. Créer la méthode suivant pour vider la collection Locations :

image

14. Créer les deux méthodes suivantes pour récupérer la liste des points d’intérêt :

image

La première exécute une requête. La deuxième traite le résultat de la requête obtenu de façon asynchrone.

15. Remplacer le corps du constructeur MainViewModel() par le suivant :

image

A cette étape, si vous lancez l’application, vous devriez déjà avoir une première page listant les types de point d’intérêt.

image

Pour éviter d’avoir des espaces entre les lignes, il suffit de mettre en commentaire la ligne 39 du fichier MainPage.xaml

image

A la ligne 26, vous pouvez écrire le nom de votre application dans l’attribut Text. A la ligne 27, vous pouvez écrire le nom de la liste qui est affichée, dans l’attribut Text également.

Nous allons maintenant nous occuper de la deuxième page : la page de détails. Elle sera affichée lorsqu’on sélectionne un type de point d’intérêt.

7. Pour la partie graphique, le XAML, ouvrons le fichier DetailsPage.xaml et modifions le XAML pour qu’il soit identique à celui-ci :

image

A la ligne 9, nous rajoutons un lien vers l’assembly fournit par Bing Maps qui nous permettra d’utiliser le fameux control Bing Maps.

A la ligne 18, nous définissons la manière dont chaque Point d’intérêt va être affiché. Ici nous utilisons des contrôles PushPin tout simple. Ce contrôle est fourni par l’API de Bing Maps.

A la ligne 34, nous modifions le titre de la page dans l’attribut Text.

A la ligne 35, nous modifions le binding pour pointer vers la propriété SelectedTypeOfPOI. Cela permettra de se souvenir de quel type de point d’intérêt nous avons sélectionné.

Enfin, à la ligne 40, nous mettons en commentaire le TextBlock qui était généré, pour insérer notre contrôle Bing Maps :

· L’attribut NavigationVisibility permet de masquer ou d’afficher la barre à outil noire, de zoom et de déplacement sur la carte.

· L’attribut Mode permet de définir le type de vue que l’on souhaite avoir en fond de carte : vue du relief, nom des villes et routes, ect…

· L’attribut Center permet de positionner la vue d’arrivée sur la carte. Ici nous ciblons la France.

· L’attribut ZoomLevel permet de zoomer sur la France plutôt que de rester trop élevé dans la vue de la carte.

· L’attribut CredentialProvider doit contenir la clé de développement que vous avez précédemment créée sur le site de Bing Maps.

A la ligne 44, nous affectons le binding à la collection des objets de type ItemLocation du ViewModel en spécifiant que le rendu devait se faire grâce au template POITemplate.

image

8. Pour le code de la page, modifiez l’évènement OnNavigatedTo :

Rappel : Dans cet article, nous nous appuyons au maximum sur ce qui est généré.

Vous devriez maintenant voir apparaitre une liste de point d’intérêt sur une carte de la France :

image

 

Axe d’améliorations

Bien entendu, il ne s’agit ici que d’un article décrivant pas à pas comment faire de l’affichage géospatial sur Windows Phone 7 en utilisant Bing Maps. Les aspects, architecture de la solution, ergonomie, fonctionnalités, ect, peuvent être nettement améliorés.

Remerciements

Je tiens à remercier Lionel et Franck pour leur aide dans la réalisation du prototype de cet article.
Lionel LIMOZIN http://www.paslatek.net/ 
Franck LIZZI http://dotnet.over-blog.fr/

 

Pour aller plus loin…

Bibliographie

Pro Silverlight 4 in C# 
Pro Entity Framework 4.0 
Programming Entity Framework 
Learning Windows Phone Programming

Webographie
WCF Data Services

http://msdn.microsoft.com/fr-fr/library/cc668792.aspx

Windows Phone 7

http://developer.windowsphone.com/windows-phone-7/

Bing Maps

http://www.microsoft.com/maps/ 
http://msdn.microsoft.com/en-us/library/ff941093(VS.92).aspx 
http://www.microsoft.com/maps/isdk/silverlight/#MapControlInteractiveSdk.Tutorials.ShowMap.ShowMapWithCulture