Anzeigen von Sehenswürdigkeiten auf einer Karte

Hinweis

MapControl und Kartendienste erfordern einen Karten-Authentifizierungsschlüssel namens MapServiceToken. Weitere Informationen zum Abrufen und Festlegen eines Kartenauthentifizierungsschlüssels finden Sie unter Anfordern eines Kartenauthentifizierungsschlüssels.

Mit Ortsmarken, Bildern, Formen und XAML-UI-Elementen können Sie interessante Orte (Points of Interest, POI) auf einer Karte hinzufügen. Ein POI ist ein Punkt auf der Karte, der Orte angibt, die von Interesse sind. Beispiele sind die Position eines Geschäfts, eines Orts oder eines Freundes.

Wenn Sie mehr über die Anzeige von POI in Ihrer App erfahren möchten, laden Sie das folgende Beispiel aus dem Repository windows-universal-samples auf GitHub herunter: Universelle Windows-Plattform (UWP)-Kartenbeispiel.

Zeigen Sie Stifte, Bilder und Formen auf der Karte an, indem Sie MapIcon-, MapBillboard-, MapPolygon- und MapPolyline-Objekte zu einer MapElements-Auflistung eines MapElementsLayer-Objekts hinzufügen. Fügen Sie dann dieses Ebenenobjekt der Layers-Auflistung eines Kartensteuerelements hinzu.

Hinweis

In früheren Versionen wurde in diesem Leitfaden gezeigt, wie Sie der MapElements-Auflistung Kartenelemente hinzufügen. Obwohl Sie diesen Ansatz weiterhin verwenden können, verpassen Sie einige der Vorteile des neuen Kartenebenenmodells. Weitere Informationen finden Sie im Abschnitt Arbeiten mit Ebenen dieses Handbuchs.

Sie können auch XAML-Benutzeroberflächenelemente wie eine Schaltfläche, ein HyperlinkButton oder ein TextBlock auf der Karte anzeigen, indem Sie sie dem MapItemsControl oder als Untergeordnete Elemente des MapControl-Steuerelements hinzufügen.

Wenn Sie eine große Anzahl von Elementen auf der Karte platzieren möchten, sollten Sie nebeneinander angeordnete Bilder auf der Karte überlagern. Informationen zum Anzeigen von Straßen auf der Karte finden Sie unter Anzeigen von Routen und Wegbeschreibungen.

Hinzufügen einer Pin

Verwenden Sie die Klasse MapIcon, um Bilder wie eine Ortsmarke mit optionalem Text auf der Karte anzuzeigen. Sie können das Standardbild akzeptieren oder mit der Image-Eigenschaft ein benutzerdefiniertes Bild bereitstellen. Die folgende Abbildung zeigt das Standardbild für ein MapIcon ohne festgelegten Wert für die Eigenschaft Title mit einem kurzen Titel, einem langen Titel und einem sehr langen Titel.

Beispiel für MapIcon mit Titeln unterschiedlicher Länge

Im folgenden Beispiel wird einer Karte von Seattle ein MapIcon mit Standardbild und optionalem Titel hinzugefügt, um den Standort der Space Needle anzugeben. Außerdem wird die Karte auf dem Symbol zentriert und vergrößert. Allgemeine Informationen zur Verwendung des Kartensteuerelements finden Sie unter Anzeigen von Karten mit 2D-, 3D- und Streetside-Ansichten.

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;

}

In diesem Beispiel wird der folgende interessante Ort (POI) auf der Karte angezeigt (mit dem Standardbild in der Mitte).

Karte mit MapIcon

Die folgende Codezeile zeigt MapIcon mit einem benutzerdefinierten Bild an, das im Ordner „Assets“ (Ressourcen) des Projekts gespeichert wurde. Die Eigenschaft Image von MapIcon erwartet einen Wert vom Typ RandomAccessStreamReference. Dieser Typ erfordert die Anweisung using für den Namespace Windows.Storage.Streams.

Hinweis

Wenn Sie dasselbe Bild für mehrere Kartensymbole verwenden, deklarieren Sie randomAccessStreamReference auf Seiten- oder App-Ebene, um die beste Leistung zu erzielen.

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

Berücksichtigen Sie beim Arbeiten mit der MapIcon-Klasse Folgendes:

  • Die Image-Eigenschaft unterstützt eine maximale Bildgröße von 2048 x 2048 Pixeln.
  • Standardmäßig wird die Anzeige des Bilds für das Kartensymbol nicht garantiert. Es wird möglicherweise ausgeblendet, wenn es andere Elemente oder Bezeichnungen auf der Karte verdeckt. Um sie sichtbar zu halten, legen Sie die CollisionBehaviorDesired-Eigenschaft des Kartensymbols auf MapElementCollisionBehavior.RemainVisible fest.
  • Die Anzeige des optionalen Title für MapIcon wird nicht garantiert. Wenn der Text nicht angezeigt wird, verkleinern Sie den Wert der ZoomLevel-Eigenschaft von MapControl.
  • Wenn Sie ein MapIcon-Bild anzeigen, das auf eine bestimmte Position auf der Karte hinweist, z. B. eine Ortsmarkierung oder ein Pfeil, sollten Sie in Erwägung ziehen, den Wert der NormalizedAnchorPoint-Eigenschaft auf den ungefähren Standort des Zeigers auf dem Bild festzulegen. Wenn Sie den Wert von NormalizedAnchorPoint beim Standardwert (0, 0) belassen, der die obere linke Ecke des Bilds darstellt, führen Änderungen am ZoomLevel der Karte möglicherweise dazu, dass das Bild auf eine andere Position zeigt.
  • Wenn Sie nicht explizit ein Altitude und AltitudeReferenceSystem festlegen, wird das MapIcon auf der Oberfläche platziert.

Hinzufügen einer 3D-Stecknadel

Sie können dreidimensionale Objekte auf einer Karte hinzufügen. Verwenden Sie die MapModel3D-Klasse , um ein 3D-Objekt aus einer 3D Manufacturing Format-Datei (3MF) zu importieren.

Dieses Bild verwendet 3D-Kaffeetassen, um die Standorte von Cafés in einer Nachbarschaft zu markieren.

Mugs auf Karten

Der folgende Code fügt der Karte eine Kaffeetasse hinzu, indem eine 3MF-Datei importiert wird. Um die Dinge einfach zu halten, fügt dieser Code das Bild zur Mitte der Karte hinzu, aber Ihr Code würde das Bild wahrscheinlich an einer bestimmten Position hinzufügen.

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,
          },
       },
    });
}

Hinzufügen eines Image

Zeigen Sie große Bilder an, die sich auf Kartenstandorte beziehen, z. B. ein Bild eines Restaurants oder eines Wahrzeichens. Wenn Benutzer verkleinern, wird das Bild proportional verkleinern, damit der Benutzer mehr von der Karte anzeigen kann. Dies unterscheidet sich etwas von einem MapIcon , das einen bestimmten Ort markiert, in der Regel klein ist und dieselbe Größe aufweist, wie Benutzer eine Karte vergrößern und verkleinernen.

MapBillboard-Bild

Der folgende Code zeigt das mapBillboard , das in der obigen Abbildung dargestellt ist.

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);
}

Es gibt drei Teile dieses Codes, die etwas genauer untersucht werden müssen: Das Bild, die Referenzkamera und die NormalizedAnchorPoint-Eigenschaft .

Image

Dieses Beispiel zeigt ein benutzerdefiniertes Bild, das im Ordner Assets des Projekts gespeichert ist. Die Image-Eigenschaft von MapBillboard erwartet einen Wert vom Typ RandomAccessStreamReference. Dieser Typ erfordert die Anweisung using für den Namespace Windows.Storage.Streams.

Hinweis

Wenn Sie dasselbe Bild für mehrere Kartensymbole verwenden, deklarieren Sie randomAccessStreamReference auf Seiten- oder App-Ebene, um die beste Leistung zu erzielen.

Referenzkamera

Da ein MapBillboard-Bild beim Ändern des ZoomLevels der Karte skaliert wird, ist es wichtig zu definieren, wo in diesem ZoomLevel das Bild im normalen 1-fachen Maßstab angezeigt wird. Diese Position wird in der Referenzkamera des MapBillboards definiert, und um sie festzulegen, müssen Sie ein MapCamera-Objekt an den Konstruktor des MapBillboard übergeben.

Sie können die gewünschte Position in einem Geopoint definieren und dann diesen Geopoint verwenden, um ein MapCamera-Objekt zu erstellen. In diesem Beispiel verwenden wir jedoch nur das MapCamera-Objekt , das von der ActualCamera-Eigenschaft des Kartensteuerelements zurückgegeben wird. Dies ist die interne Kamera der Karte. Die aktuelle Position dieser Kamera wird zur Referenzkameraposition; Die Position, an der das MapBillboard-Bild im 1-fachen Maßstab angezeigt wird.

Wenn Ihre App Benutzern die Möglichkeit bietet, die Karte zu verkleinern, nimmt das Bild ab, da die interne Kartenkamera in der Höhe steigt, während das Bild im 1-fachen Maßstab an der Position der Referenzkamera fest bleibt.

NormalizedAnchorPoint

NormalizedAnchorPoint ist der Punkt des Bilds, der mit der Location-Eigenschaft des MapBillboard verankert ist. Der Punkt 0.5,1 ist die untere Mitte des Bilds. Da wir die Location-Eigenschaft von MapBillboard auf die Mitte des Kartensteuerelements festgelegt haben, wird der untere Mittelpunkt des Bilds in der Mitte des Karten-Steuerelements verankert. Wenn Ihr Bild direkt über einem Punkt zentriert angezeigt werden soll, legen Sie NormalizedAnchorPoint auf 0.5,0.5 fest.

Hinzufügen einer Form

Mithilfe der Klasse MapPolygon können Sie eine Form mit mehreren Punkten auf der Karte anzeigen. Im folgenden Beispiel (aus dem Beispiel zu UWP-Karten) wird ein rotes Feld mit blauem Rahmen auf der Karte angezeigt.

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);
}

Hinzufügen einer Linie

Mithilfe der Klasse MapPolyline können Sie eine Linie auf der Karte anzeigen. Im folgenden Beispiel (aus dem Beispiel zu UWP-Karten) wird eine gestrichelte Linie auf der Karte angezeigt.

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);

}

Hinzufügen von XAML

Zeigen Sie benutzerdefinierte UI-Elemente mit XAML auf der Karte an. Positionieren Sie XAML auf der Karte, indem Sie die Position und den normalisierten Ankerpunkt für den XAML-Code angeben.

  • Rufen Sie SetLocation auf, um die Position auf der Karte festzulegen, an der der XAML-Code platziert werden soll.
  • Legen Sie die relative Position im XAML-Code fest, die dem angegebenen Speicherort entspricht, indem Sie SetNormalizedAnchorPoint aufrufen.

Im folgenden Beispiel wird einer Karte von Seattle das XAML-Steuerelement Border hinzugefügt, um den Standort der Space Needle anzugeben. Außerdem wird die Karte in diesem Bereich zentriert und vergrößert. Allgemeine Informationen zur Verwendung des Kartensteuerelements finden Sie unter Anzeigen von Karten mit 2D-, 3D- und Streetside-Ansichten.

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));
}

In diesem Beispiel wird ein blauer Rahmen auf der Karte angezeigt.

Screenshot eines XAML-Elements, das am interessanten Ort auf der Karte angezeigt wird

Die nächsten Beispiele zeigen, wie XAML-UI-Elemente direkt im XAML-Markup der Seite mithilfe der Datenbindung hinzugefügt werden. Wie bei anderen XAML-Elementen zur Anzeige von Inhalten auch, stellt Children die standardmäßige Inhaltseigenschaft von MapControl dar und muss nicht explizit im XAML-Markup angegeben werden.

In diesem Beispiel wird gezeigt, wie zwei XAML-Steuerelemente als implizite untergeordnete Elemente von MapControl angezeigt werden. Diese Steuerelemente werden auf der Karte an den datengebundenen Orten angezeigt.

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

Legen Sie diese Speicherorte mithilfe einer Eigenschaft in Ihrer CodeBehind-Datei fest.

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

In diesem Beispiel wird gezeigt, wie zwei XAML-Steuerelemente angezeigt werden, die in einem MapItemsControl-Steuerelement enthalten sind. Diese Steuerelemente werden auf der Karte an den datengebundenen Orten angezeigt.

<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>

In diesem Beispiel wird eine Auflistung von XAML-Elementen angezeigt, die an ein MapItemsControl gebunden sind.

<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>

Die ItemsSource -Eigenschaft im obigen Beispiel ist an eine Eigenschaft vom Typ IList in der CodeBehind-Datei gebunden.

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);
    }
}

Arbeiten mit Ebenen

In den Beispielen in diesem Leitfaden werden einer MapElementLayers-Auflistung Elemente hinzugefügt. Anschließend wird gezeigt, wie diese Auflistung der Layers-Eigenschaft des Kartensteuerelements hinzugefügt wird. In früheren Versionen haben Sie in dieser Anleitung gezeigt, wie Sie der MapElements-Auflistung Kartenelemente wie folgt hinzufügen:

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);

Obwohl Sie diesen Ansatz weiterhin verwenden können, verpassen Sie einige der Vorteile des neuen Kartenebenenmodells. Indem Sie Ihre Elemente in Ebenen gruppieren, können Sie jede Ebene unabhängig voneinander bearbeiten. Beispielsweise verfügt jede Ebene über einen eigenen Satz an Ereignissen, sodass Sie auf ein Ereignis in einer bestimmten Ebene antworten und eine Aktion ausführen können, die speziell für das Ereignis gilt.

Außerdem können Sie XAML direkt an einen MapLayer binden. Dies ist nicht möglich, indem Sie die MapElements-Auflistung verwenden.

Dazu können Sie unter anderem eine Ansichtsmodellklasse, code-behind eine XAML-Seite und eine XAML-Seite verwenden.

Modellklasse anzeigen

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);         
    }

Codebehind einer XAML-Seite

Verbinden Sie die Ansichtsmodellklasse mit Ihrer Code Behind-Seite.

public LandmarksViewModel ViewModel { get; set; }

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

XAML-Seite

Binden Sie auf Der XAML-Seite an die Eigenschaft in Ihrer Ansichtsmodellklasse, die die Ebene zurückgibt.

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