Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

UWP : utiliser des cartes 3D

Les américains sont très friands des cartes géographiques, on en voit dans toutes les applications. Même si cet engouement doit être relativisé en France l’affichage d’une belle carte, surtout en mode 3D, est toujours un plus dans une belle UI. C’est vrai que “ça jette” ! Alors comment faire ?

Autoriser la géolocalisation

Je vais partir d’une “UWP Blank App”, donc une application UWP totalement vide possédant juste une MainPage. La première des choses à faire pour rendre notre gestion de carte plus intéressante c’est d’autoriser la géolocalisation dans l’application.

Attention cela n’est pas obligatoire ! Si vous désirez juste afficher des cartes centrées sur des points dont vous disposez déjà des coordonnées (par exemple des photos géotaggées) nul besoin d’avoir accès aux coordonnées spatiales de l’utilisateur.

Mais on va supposer ici qu’on souhaite pouvoir obtenir la position de l’utilisateur pour centrer la carte sur celle-ci.

Donc dans le manifeste de l’application il faut cocher la case “localisation” :

image

L’objet carte XAML

Pour afficher la carte il faut bien entendu utiliser le contrôle spécial fourni par Microsoft.

Il faut commencer par ajouter le namespace XAML :

image

 

Et puis il faut placer le contrôle. Ici pas de présentation savante, je vais le placer “plein pot” dans la fenêtre donc directement la Grid principale :

image

Comme on peut le constater j’ai branché l’évènement OnLoaded du contrôle sur un gestionnaire dans le code behind. Dans la réalité il s’agit d’une méthode d’un ViewModel mais ne mélangeons pas tout et restons simples !

Piloter la carte

Pour afficher une carte il n’y en réalité plus rien à faire. Mais une carte au hasard cela ne sert pas à grand chose.

Il faut donc piloter l’affichage pour pointer une coordonnée précise, celle de l’utilisateur ou autre. Il faut aussi spécifier le style de la carte (3D, avec route, sans route…).

Mais avant tout il faut demander l’autorisation à l’utilisateur !

Cette requête doit avoir lieu une fois au moins pour une application. Ensuite Windows mémorise le choix et la requête ne pose plus de question à l’utilisateur, elle retourne simplement le choix effectué.

Prenons tout le code de l’exemple et je vais ensuite discuter de chaque ligne :

        private async void p3D_OnLoaded(object sender, RoutedEventArgs e)
        {
            var access = await Geolocator.RequestAccessAsync();
            if (access == GeolocationAccessStatus.Allowed)
            {
                Map3D.Style = MapStyle.Aerial3DWithRoads;
                var geolocator = new Geolocator();
                geolocator.DesiredAccuracyInMeters = 100;
                var pos = await geolocator.GetGeopositionAsync();
                var bpos = new BasicGeoposition();
                /* if (pos.Coordinate.Altitude != null) bpos.Altitude = pos.Coordinate.Altitude.Value;
                 bpos.Latitude = pos.Coordinate.Latitude;
                 bpos.Longitude = pos.Coordinate.Longitude;*/

                bpos.Latitude = 48.8867046;
                bpos.Longitude = 2.3431043;

                var point = new Geopoint(bpos);
                var scene = MapScene.CreateFromLocationAndRadius(point, 100, 150, 70);
                await Map3D.TrySetSceneAsync(scene);
            }
            else
            {
                var m = new MessageDialog("Access Denied to geolocation.");
                await m.ShowAsync();
            }
        }

Premièrement nous avons besoin d’un objet GeoLocator. C’est par lui que nous allons demander l’autorisation d’accès à la géolocalisation.

La demande est asynchrone et vu que nous avons besoin de la réponse pour savoir quoi faire cela s’effectue avec un await.

Si on s’arrête là l’application affichera un message de ce type :

image

 

Pour la beauté du geste j’ai répondu non …

Et à chaque fois que je relançais l’application, plus de question mais l’affichage du message d’erreur prévu par le code (le else final du code) :

image

 

C’est propre, c’est net, l’utilisateur n’est plus embêté par une question à laquelle il a déjà répondu. En réalité on n’afficherait pas un message, on adapterai le fonctionnement de notre logiciel sans utiliser la géolocalisation. Dans une application qui affiche des photos par exemple, on peut continuer à faire marcher l’ensemble sans préciser les coordonnées ni afficher de carte. En revanche si comme cette app de démo tout est basé sur la carte … là un message s’impose !

Mieux, il est préférable dans ce message de demander à l’utilisateur s’il souhaite modifier les paramètres de sécurité pour l’application et appeler directement le bon dialogue du système en utilisant l’URI “ms-settings:privacy-location”.

Ici je vais rétablir l’autorisation en allant manuellement dans les paramètres de sécurité du système :

image

 

Nous pouvons continuer le test…

Dans un code réactif il faudrait programmer un gestionnaire d’évènement pour le StatusChanged de l’objet GeoLocator afin d’être averti de tout changement de position pour mettre à jour la carte. Ici je vais me contenter de demander une fois la position de l’utilisateur. C’est le but du code qui suit l’obtention d’une instance de GeoLocator.

Une petite tambouille est nécessaire pour transformer les coordonnées obtenues en coordonnées acceptables par l’objet Map.

Le code en commentaire est celui qui exploite la position retournée pour l’afficher dans la Map.

Pour que le code soit universel dans cette démo j’ai forcé les coordonnées du Sacré Coeur à Paris. Comme cela tout le monde pourra tester le code en sachant ce qu’il va voir.

Une fois les coordonnées trasnformées, ne reste plus qu’à appeler le TrySetSceneAsync() de l’objet Map.

Résultat

Avec LICECap (dont j’ai parlé dans un billet précédent) j’ai fais une capture GIF de l’app en action. Le GIF pèse 16 Mo (et c'est une réduction de 50% !) donc je ne l’affiche pas directement dans ce billet… Si vous voulez le regarder cliquez sur le lien ci-dessous :

Démo Carte 3D (GIF de 16 Mo attention !)

Autorisation annexe

Pour utiliser une carte Bing (puisqu’ici c’est le cas) il faut une autorisation, une clé de développement. Sinon vous verrez s’afficher en bas de la carte :

image

Le token n’est pas spécifié. Il suffit d’en demander un et de l’insérer dans le code.

Conclusion

Les cartes c’est joli, ça fait tout de suite sérieux, ça enjolive l’UI. Ca peut être aussi être très utile et augmenter l’intérêt d’une App…

Comme je viens de vous le montrer l’utilisation de l’objet carte Microsoft est un jeu d’enfant, en UWP donc code valable du smartphone à la Xbox en passant par Surface et les PC, ce qui n’est pas négligeable.

Et pour ne pas perdre le Nord …

Stay Tuned !

Faites des heureux, PARTAGEZ l'article !