Share via


Afficher les points d’intérêt sur une carte

Notes

MapControl et les services de carte nécessitent une clé d’authentification de cartes appelée MapServiceToken. Pour plus d’informations sur l’obtention et la définition d’une clé d’authentification de cartes, voir Demander une clé d’authentification de cartes.

Ajoutez des points d’intérêt à une carte à l’aide des punaises, des images, des formes et des éléments d’interface utilisateur XAML. Un point d’intérêt est un point spécifique sur la carte, qui représente un élément intéressant. Il peut s’agir, par exemple, de l’emplacement d’une entreprise, d’une localité ou d’un ami.

Pour en savoir plus sur l’affichage de POI sur votre application, téléchargez l’exemple suivant à partir de l’exemple de carte Windows-universal-samples sur GitHub : plateforme Windows universelle (UWP).

Affichez des épingles, des images et des formes sur la carte en ajoutant des objets MapIcon, MapBillboard, MapPolygon et MapPolyline à une collection MapElements d’un objet MapElementsLayer . Ensuite, ajoutez cet objet de couche à la collection Layers d’un contrôle de carte.

Notes

Dans les versions précédentes, ce guide vous a montré comment ajouter des éléments de carte à la collection MapElements . Bien que vous puissiez toujours utiliser cette approche, vous passerez à côté de certains des avantages du nouveau modèle de couche de carte. Pour plus d’informations, consultez la section Utilisation des couches de ce guide.

Vous pouvez également afficher des éléments d’interface utilisateur XAML tels qu’un Button, un HyperlinkButton ou un TextBlock sur la carte en les ajoutant à MapItemsControl ou en tant que Enfants du MapControl.

Si vous avez un grand nombre d’éléments à placer sur la carte, songez à superposer des images sous forme de vignettes à la carte. Pour afficher les routes sur la carte, consultez Afficher les itinéraires et les directions

Ajouter une épingle

Affichez une image telle qu’une punaise, avec du texte facultatif, sur la carte à l’aide de la classe MapIcon . Vous pouvez accepter l’image par défaut ou fournir une image personnalisée à l’aide de la propriété Image. L’image suivante affiche l’image par défaut pour un élément MapIcon, sans qu’aucune valeur ne soit spécifiée pour la propriété Title, avec un titre court, un autre long et un autre très long.

exemple de classe MapIcon présentant des titres de différentes longueurs.

L’exemple suivant montre une carte de la ville de Seattle et ajoute une carte MapIcon avec l’image par défaut et un titre facultatif pour indiquer l’emplacement de l’aiguille spatiale. Il centre également la carte sur l’icône et effectue un zoom avant. Pour plus d’informations générales sur l’utilisation du contrôle de carte, voir Afficher des cartes avec des vues 2D, 3D et Streetside.

public void AddSpaceNeedleIcon()
{
    var MyLandmarks = new List<MapElement>();

    BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
    Geopoint snPoint = new Geopoint(snPosition);

    var spaceNeedleIcon = new MapIcon
    {
        Location = snPoint,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        ZIndex = 0,
        Title = "Space Needle"
    };

    MyLandmarks.Add(spaceNeedleIcon);

    var LandmarksLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarks
    };

    myMap.Layers.Add(LandmarksLayer);

    myMap.Center = snPoint;
    myMap.ZoomLevel = 14;

}

Cet exemple affiche le point d’intérêt suivant sur la carte (l’image par défaut au centre).

carte avec l’élément MapIcon

La ligne de code suivante affiche mapIcon avec une image personnalisée enregistrée dans le dossier Assets du projet. La propriété Image de la classe MapIcon attend une valeur de type RandomAccessStreamReference. Ce type nécessite une instruction using pour l’espace de noms Windows.Storage.Streams.

Notes

Si vous utilisez la même image pour plusieurs icônes de carte, déclarez randomAccessStreamReference au niveau de la page ou de l’application pour obtenir des performances optimales.

    MapIcon1.Image =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));

Gardez ces considérations à l’esprit lorsque vous utilisez la classe MapIcon :

  • La propriété Image prend en charge une taille d’image maximale de 2048×2048 pixels.
  • Par défaut, il n’est pas garanti que l’image de l’icône de carte s’affiche. Cette classe peut être masquée quand elle cache d’autres éléments ou étiquettes sur la carte. Pour la garder visible, définissez la propriété CollisionBehaviorDesired de l’icône de carte sur MapElementCollisionBehavior.RemainVisible.
  • L’affichage du titre facultatif de MapIcon n’est pas garanti. Si vous ne voyez pas le texte, effectuez un zoom arrière en diminuant la valeur de la propriété ZoomLevel de MapControl.
  • Quand vous affichez une image MapIcon qui pointe vers un emplacement spécifique sur la carte, par exemple une punaise ou une flèche, envisagez d’affecter à la valeur de la propriété NormalizedAnchorPoint l’emplacement approximatif du pointeur sur l’image. Si vous conservez la valeur par défaut (0, 0) de NormalizedAnchorPoint, qui représente le coin supérieur gauche de l’image, des modifications de la propriété ZoomLevel de la carte peuvent laisser l’image pointer vers un autre emplacement.
  • Si vous ne définissez pas explicitement d’Altitude et d’AltitudeReferenceSystem, le MapIcon sera placé sur la surface.

Ajouter une épingle 3D

Vous pouvez ajouter des objets 3D à une carte. Utilisez la classe MapModel3D pour importer un objet 3D à partir d’un fichier 3D Manufacturing Format (3MF).

Cette image utilise des tasses de café 3D pour marquer les emplacements des cafés dans un quartier.

mugs sur les cartes

Le code suivant ajoute une tasse à café à la carte à l’aide de l’importation d’un fichier 3MF. Pour simplifier les choses, ce code ajoute l’image au centre de la carte, mais votre code ajouterait probablement l’image à un emplacement spécifique.

public async void Add3DMapModel()
{
    var mugStreamReference = RandomAccessStreamReference.CreateFromUri
        (new Uri("ms-appx:///Assets/mug.3mf"));

    var myModel = await MapModel3D.CreateFrom3MFAsync(mugStreamReference,
        MapModel3DShadingOption.Smooth);

    myMap.Layers.Add(new MapElementsLayer
    {
       ZIndex = 1,
       MapElements = new List<MapElement>
       {
          new MapElement3D
          {
              Location = myMap.Center,
              Model = myModel,
          },
       },
    });
}

Ajouter une image

Affichez des images volumineuses qui se rapportent à des emplacements de carte, comme une image d’un restaurant ou d’un point de repère. Lorsque les utilisateurs effectuent un zoom arrière, la taille de l’image diminue proportionnellement pour permettre à l’utilisateur d’afficher davantage de la carte. Il s’agit d’un peu différent d’un MapIcon qui marque un emplacement spécifique, est généralement petit et reste de la même taille que les utilisateurs effectuent un zoom avant et arrière d’une carte.

Image MapBillboard

Le code suivant montre le MapBillboard présenté dans l’image ci-dessus.

public void AddLandmarkPhoto()
{
    // Create MapBillboard.

    RandomAccessStreamReference mapBillboardStreamReference =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/billboard.jpg"));

    var mapBillboard = new MapBillboard(myMap.ActualCamera)
    {
        Location = myMap.Center,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        Image = mapBillboardStreamReference
    };

    // Add MapBillboard to a layer on the map control.

    var MyLandmarkPhotos = new List<MapElement>();

    MyLandmarkPhotos.Add(mapBillboard);

    var LandmarksPhotoLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarkPhotos
    };

    myMap.Layers.Add(LandmarksPhotoLayer);
}

Trois parties de ce code méritent d’être examinées de plus près : l’image, la caméra de référence et la propriété NormalizedAnchorPoint .

Image

Cet exemple montre une image personnalisée enregistrée dans le dossier Assets du projet. La propriété Image du MapBillboard attend une valeur de type RandomAccessStreamReference. Ce type nécessite une instruction using pour l’espace de noms Windows.Storage.Streams.

Notes

Si vous utilisez la même image pour plusieurs icônes de carte, déclarez randomAccessStreamReference au niveau de la page ou de l’application pour obtenir des performances optimales.

Caméra de référence

Étant donné qu’une image MapBillboard est mise à l’échelle à mesure que le ZoomLevel de la carte change, il est important de définir où dans zoomLevel l’image apparaît à une échelle normale 1x. Cette position est définie dans la caméra de référence du MapBillboard et pour la définir, vous devez passer un objet MapCamera dans le constructeur du MapBillboard.

Vous pouvez définir la position souhaitée dans un Geopoint, puis utiliser ce geopoint pour créer un objet MapCamera . Toutefois, dans cet exemple, nous utilisons simplement l’objet MapCamera retourné par la propriété ActualCamera du contrôle de carte. Il s’agit de la caméra interne de la carte. La position actuelle de cette caméra devient la position de la caméra de référence; position où l’image MapBillboard s’affiche à une échelle 1x.

Si votre application permet aux utilisateurs de faire un zoom arrière sur la carte, la taille de l’image diminue, car la caméra interne des cartes augmente en altitude tandis que l’image à l’échelle 1x reste fixe à la position de la caméra de référence.

NormalizedAnchorPoint

NormalizedAnchorPoint est le point de l’image ancré à la propriété Location du MapBillboard. Le point 0,5,1 est le centre inférieur de l’image. Étant donné que nous avons défini la propriété Location du MapBillboard au centre du contrôle de la carte, le centre inférieur de l’image sera ancré au centre du contrôle maps. Si vous souhaitez que votre image apparaisse centrée directement sur un point, définissez NormalizedAnchorPoint sur 0,5,0,5.

Ajouter une forme

Utilisez la classe MapPolygon pour afficher une forme multipoint sur la carte. L’exemple suivant, tiré de l’exemple de carte UWP, affiche une zone rouge bordée de bleu sur la carte.

public void HighlightArea()
{
    // Create MapPolygon.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;

    var mapPolygon = new MapPolygon
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude+0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        ZIndex = 1,
        FillColor = Colors.Red,
        StrokeColor = Colors.Blue,
        StrokeThickness = 3,
        StrokeDashed = false,
    };

    // Add MapPolygon to a layer on the map control.
    var MyHighlights = new List<MapElement>();

    MyHighlights.Add(mapPolygon);

    var HighlightsLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyHighlights
    };

    myMap.Layers.Add(HighlightsLayer);
}

Ajouter une ligne

Affichez une ligne sur la carte à l’aide de la classe MapPolyline . L’exemple suivant, tiré de l’exemple de carte UWP, affiche une ligne en pointillé sur la carte.

public void DrawLineOnMap()
{
    // Create Polyline.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;
    var mapPolyline = new MapPolyline
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        StrokeColor = Colors.Black,
        StrokeThickness = 3,
        StrokeDashed = true,
    };

   // Add Polyline to a layer on the map control.

   var MyLines = new List<MapElement>();

   MyLines.Add(mapPolyline);

   var LinesLayer = new MapElementsLayer
   {
       ZIndex = 1,
       MapElements = MyLines
   };

   myMap.Layers.Add(LinesLayer);

}

Ajouter du code XAML

Utilisez du code XAML pour afficher des éléments d’interface utilisateur personnalisés sur la carte. Positionnez le code XAML sur la carte en spécifiant son emplacement et son point d’ancrage normalisé.

  • Appelez SetLocation pour définir l’emplacement du code XAML sur la carte.
  • Définissez l’emplacement relatif sur le CODE XAML qui correspond à l’emplacement spécifié en appelant SetNormalizedAnchorPoint.

L’exemple suivant montre une carte de la ville de Seattle et ajoute un contrôle de bordure XAML pour indiquer l’emplacement de l’aiguille spatiale. Il centre également la carte sur la zone et effectue un zoom avant. Pour plus d’informations générales sur l’utilisation du contrôle de carte, voir Afficher des cartes avec des vues 2D, 3D et Streetside.

private void displayXAMLButton_Click(object sender, RoutedEventArgs e)
{
   // Specify a known location.
   BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
   Geopoint snPoint = new Geopoint(snPosition);

   // Create a XAML border.
   Border border = new Border
   {
      Height = 100,
      Width = 100,
      BorderBrush = new SolidColorBrush(Windows.UI.Colors.Blue),
      BorderThickness = new Thickness(5),
   };

   // Center the map over the POI.
   MapControl1.Center = snPoint;
   MapControl1.ZoomLevel = 14;

   // Add XAML to the map.
   MapControl1.Children.Add(border);
   MapControl.SetLocation(border, snPoint);
   MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));
}

Cet exemple affiche une bordure bleue sur la carte.

Capture d’écran d’un balisage XAML à l’emplacement du point d’intérêt sur la carte

Les exemples suivants montrent comment ajouter des éléments d’interface utilisateur en code XAML directement dans le balisage XAML de la page à l’aide de la liaison de données. Comme avec d’autres éléments XAML qui affichent du contenu, Children est la propriété de contenu par défaut de MapControl et n’a pas besoin d’être spécifié explicitement dans le balisage XAML.

Cet exemple montre comment afficher deux contrôles XAML en tant qu’enfants implicites de MapControl. Ces contrôles s’affichent sur la carte aux emplacements liés aux données.

<maps:MapControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>

Définissez ces emplacements à l’aide d’une propriété dans votre fichier code-behind.

public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }

Cet exemple montre comment afficher deux contrôles XAML contenus dans un MapItemsControl. Ces contrôles s’affichent sur la carte aux emplacements liés aux données.

<maps:MapControl>
  <maps:MapItemsControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
  </maps:MapItemsControl>
</maps:MapControl>

Cet exemple affiche une collection d’éléments XAML liés à un MapItemsControl.

<maps:MapControl x:Name="MapControl" MapTapped="MapTapped" MapDoubleTapped="MapTapped" MapHolding="MapTapped">
  <maps:MapItemsControl ItemsSource="{x:Bind LandmarkOverlays}">
      <maps:MapItemsControl.ItemTemplate>
          <DataTemplate>
              <StackPanel Background="Black" Tapped ="Overlay_Tapped">
                  <TextBlock maps:MapControl.Location="{Binding Location}" Text="{Binding Title}"
                    maps:MapControl.NormalizedAnchorPoint="0.5,0.5" FontSize="20" Margin="5"/>
              </StackPanel>
          </DataTemplate>
      </maps:MapItemsControl.ItemTemplate>
  </maps:MapItemsControl>
</maps:MapControl>

La ItemsSource propriété dans l’exemple ci-dessus est liée à une propriété de type IList dans le fichier code-behind.

public sealed partial class Scenario1 : Page
{
    public IList LandmarkOverlays { get; set; }

    public MyClassConstructor()
    {
         SetLandMarkLocations();
         this.InitializeComponent();   
    }

    private void SetLandMarkLocations()
    {
        LandmarkOverlays = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        LandmarkOverlays.Add(pikePlaceIcon);

        var SeattleSpaceNeedleIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.6205, Longitude = -122.3493 }),
            Title = "Seattle Space Needle"
        };

        LandmarkOverlays.Add(SeattleSpaceNeedleIcon);
    }
}

Utilisation des couches

Les exemples de ce guide ajoutent des éléments à une collection MapElementLayers . Ils montrent ensuite comment ajouter cette collection à la propriété Layers du contrôle de carte. Dans les versions précédentes, ce guide vous a montré comment ajouter des éléments de carte à la collection MapElements comme suit :

var pikePlaceIcon = new MapIcon
{
    Location = new Geopoint(new BasicGeoposition
    { Latitude = 47.610, Longitude = -122.342 }),
    NormalizedAnchorPoint = new Point(0.5, 1.0),
    ZIndex = 0,
    Title = "Pike Place Market"
};

myMap.MapElements.Add(pikePlaceIcon);

Bien que vous puissiez toujours utiliser cette approche, vous passerez à côté de certains des avantages du nouveau modèle de couche de carte. En regroupant vos éléments en couches, vous pouvez manipuler chaque couche indépendamment les unes des autres. Par exemple, chaque couche possède son propre ensemble d’événements, de sorte que vous pouvez répondre à un événement sur une couche particulière et effectuer une action spécifique de cet événement.

En outre, vous pouvez lier xaml directement à un MapLayer. C’est quelque chose que vous ne pouvez pas faire à l’aide de la collection MapElements .

Pour ce faire, vous pouvez utiliser une classe de modèle d’affichage, un code-behind d’une page XAML et une page XAML.

Afficher la classe de modèle

public class LandmarksViewModel
{
    public ObservableCollection<MapLayer> LandmarkLayer
        { get; } = new ObservableCollection<MapLayer>();

    public LandmarksViewModel()
    {
        var MyElements = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        MyElements.Add(pikePlaceIcon);

        var LandmarksLayer = new MapElementsLayer
        {
            ZIndex = 1,
            MapElements = MyElements
        };

        LandmarkLayer.Add(LandmarksLayer);         
    }

Code-behind d’une page XAML

Connectez la classe de modèle d’affichage à votre page code-behind.

public LandmarksViewModel ViewModel { get; set; }

public myMapPage()
{
    this.InitializeComponent();
    this.ViewModel = new LandmarksViewModel();
}

Page XAML

Dans votre page XAML, liez à la propriété dans votre classe de modèle d’affichage qui retourne la couche.

<maps:MapControl
    x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
    MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>