Поделиться через


Отображение точек интереса на карте

Внимание

Bing Maps для выхода на пенсию службы Enterprise

Службы MapControl UWP и карты из пространства имен Windows.Services.Maps используют карты Bing. Карты Bing для предприятия устарели и будут прекращены, в то время как mapControl и службы больше не будут получать данные.

Дополнительные сведения см. в документации по Центру разработчиков карт Bing и картам Bing.

Примечание.

Для служб MapControl и служб карт требуется ключ проверки подлинности карт с именем MapServiceToken. Дополнительные сведения о получении и настройке ключа проверки подлинности карт см. в разделе "Запрос ключа проверки подлинности карт".

Добавьте точки интереса (POI) на карту с помощью pushpins, изображений, фигур и элементов пользовательского интерфейса XAML. POI — это определенная точка на карте, представляющая что-то интересное. Например, расположение бизнеса, города или друга.

Отображение pushpins, изображений и фигур на карте путем добавления MapIcon, MapBillboard, MapPolygon и MapPolyline объектов в коллекцию MapElements объекта MapElementsLayer. Затем добавьте этот объект слоя в коллекцию "Слои " элемента управления картой.

Примечание.

В предыдущих выпусках в этом руководстве показано, как добавить элементы карты в коллекцию MapElements. Хотя вы по-прежнему можете использовать этот подход, вы пропустите некоторые из преимуществ новой модели слоя карты. Дополнительные сведения см. в разделе "Работа с слоями " этого руководства.

Вы также можете отображать элементы пользовательского интерфейса XAML, такие как Button, ГиперссылкаButton или TextBlock на карте, добавив их в MapItemsControl или в качестве дочерних элементов MapControl.

Если на карте есть большое количество элементов, рассмотрите возможность перекладывания плиток на карте. Отображение дорог на карте см. в разделе "Отображение маршрутов и направлений"

Добавление pushpin

Отображение изображения, такого pushpin, с необязательным текстом на карте с помощью класса MapIcon. Вы можете принять изображение по умолчанию или предоставить пользовательский образ с помощью свойства Image. На следующем рисунке отображается изображение по умолчанию для MapIcon без значения, указанного для свойства Title, с коротким заголовком, длинным заголовком и очень длинным заголовком.

пример mapicon с заголовками разных длин.

В следующем примере показана карта города Сиэтла и добавляет MapIcon с изображением по умолчанию и необязательным заголовком, чтобы указать расположение пробела. Он также центрирует карту по значку и увеличивается. Общие сведения об использовании элемента управления картой см. в разделе "Отображение карт" с представлениями 2D, 3D и 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;

}

В этом примере на карте отображается следующий POI (изображение по умолчанию в центре).

карта с mapicon

В следующей строке кода отображается MapIcon с пользовательским изображением, сохраненным в папке "Активы" проекта. Свойство Image mapIcon ожидает значение типа RandomAccessStreamReference. Для этого типа требуется инструкция using для пространства имен Windows.Storage.Streams .

Примечание.

Если вы используете один и тот же образ для нескольких значков карты, объявите RandomAccessStreamReference на уровне страницы или приложения для оптимальной производительности.

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

Помните об этом при работе с классом MapIcon :

  • Свойство Image поддерживает максимальный размер изображения размером 2048×2048 пикселей.
  • По умолчанию изображение значка карты не гарантируется. Он может быть скрыт, если он скрывает другие элементы или метки на карте. Чтобы сохранить его видимым, задайте свойству CollisionBehaviorDesired значок карты значение MapElementCollisionBehavior.RemainVisible.
  • Необязательный заголовок MapIcon не гарантируется. Если текст не отображается, увеличьте масштаб, уменьшая значение свойства ZoomLevel объекта MapControl.
  • При отображении изображения MapIcon , указывающего на определенное расположение на карте ( например, pushpin или стрелка), рекомендуется задать значение свойства NormalizedAnchorPoint в приблизительном расположении указателя на изображении. Если значение NormalizedAnchorPoint по умолчанию равно (0, 0), представляющее левый верхний угол изображения, изменения в ZoomLevel карты могут оставить изображение, указывающее на другое расположение.
  • Если вы явно не задали высоту и высотуReferenceSystem, mapIcon будет помещен на поверхность.

Добавление 3D-pushpin

Трехмерные объекты можно добавлять на карту. Используйте класс MapModel3D для импорта трехмерного объекта из файла трехмерного формата производства (3MF).

На этом изображении используются трехмерные чашки кофе, чтобы пометить места кафе в районе.

кружки на картах

Следующий код добавляет чашку кофе на карту с помощью импорта файла 3MF. Чтобы упростить работу, этот код добавляет изображение в центр карты, но код, скорее всего, добавит изображение в определенное расположение.

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

Добавить изображение

Отображение больших изображений, относящихся к расположениям карты, таким как изображение ресторана или ориентира. По мере уменьшения масштаба изображение будет уменьшаться пропорционально, чтобы пользователь мог просматривать больше карты. Это немного отличается от MapIcon , который помечает определенное расположение, обычно небольшое, и остается таким же размером, как пользователи масштабируется и выходит из карты.

Изображение MapBillboard

В следующем коде показана карта MapBillboard , представленная на приведенном выше рисунке.

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

Существует три части этого кода, которые стоит рассмотреть немного ближе: изображение, эталонная камера и свойство NormalizedAnchorPoint.

Изображения

В этом примере показан пользовательский образ, сохраненный в папке "Активы " проекта. Свойство Image mapBillboard ожидает значение типа RandomAccessStreamReference. Для этого типа требуется инструкция using для пространства имен Windows.Storage.Streams .

Примечание.

Если вы используете один и тот же образ для нескольких значков карты, объявите RandomAccessStreamReference на уровне страницы или приложения для оптимальной производительности.

Эталонная камера

Так как изображение MapBillboard масштабируется и выходит как ZoomLevel карты изменения, важно определить, где в этом Масштабе изображение отображается в обычном масштабе 1x. Это положение определяется в эталонной камере MapBillboard, и чтобы задать его, необходимо передать объект MapCamera в конструктор MapBillboard.

Вы можете определить нужное положение в географической точке, а затем использовать эту геоpoint для создания объекта MapCamera. Однако в этом примере мы просто используем объект MapCamera, возвращаемый свойством ActualCamera элемента управления картой. Это внутренняя камера карты. Текущая позиция этой камеры становится позицией эталонной камеры; позиция, в которой изображение MapBillboard отображается в масштабе 1x.

Если ваше приложение дает пользователям возможность уменьшить масштаб карты, изображение уменьшается, так как внутренняя камера карты растет на высоте, а изображение в масштабе 1x остается фиксированным в позиции эталонной камеры.

НормализацияAnchorPoint

НормализацияAnchorPoint — это точка изображения, привязанного к свойству Location mapBillboard. Точка 0,5,1 — нижний центр изображения. Так как свойство Location объекта MapBillboard установлено в центре элемента управления карты, нижний центр изображения будет привязан в центре элемента управления картами. Если вы хотите, чтобы изображение отображалось в центре непосредственно над точкой, задайте для нормализацииAnchorPoint значение 0,5,0,5.

Добавление фигуры

Отображение многоточечных фигур на карте с помощью класса MapPolygon. В следующем примере на примере карты UWP отображается красное поле с синей границей на карте.

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

Добавить строку

Отображение строки на карте с помощью класса MapPolyline. В следующем примере на примере карты UWP отображается пунктирная линия на карте.

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

}

Добавление XAML

Отображение пользовательских элементов пользовательского интерфейса на карте с помощью XAML. Поместите XAML на карту, указав расположение и нормализованную точку привязки XAML.

  • Задайте расположение на карте, в которой размещается XAML путем вызова SetLocation.
  • Задайте относительное расположение на XAML, соответствующее указанному расположению, вызвав SetNormalizedAnchorPoint.

В следующем примере показана карта города Сиэтла и добавлен элемент управления границы XAML, указывающий расположение иглы пробела. Он также центрирует карту по области и увеличивается. Общие сведения об использовании элемента управления картой см. в разделе "Отображение карт" с представлениями 2D, 3D и 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));
}

В этом примере отображается синяя граница на карте.

Снимок экрана: xaml, отображаемый в точке взаимодействия на карте

В следующих примерах показано, как добавить элементы пользовательского интерфейса XAML непосредственно в разметку XAML страницы с помощью привязки данных. Как и в других элементах XAML, отображающих содержимое, дочерние элементы по умолчанию являются свойством содержимого MapControl и не должны быть явно указаны в разметке XAML.

В этом примере показано, как отобразить два элемента управления XAML как неявные дочерние элементы MapControl. Эти элементы управления отображаются на карте в привязанных к данным расположениях.

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

Задайте эти расположения с помощью свойств в файле кода программной части.

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

В этом примере показано, как отобразить два элемента управления XAML, содержащиеся в MapItemsControl. Эти элементы управления отображаются на карте в привязанных к данным расположениях.

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

В этом примере отображается коллекция элементов XAML, привязанных к 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>

Свойство ItemsSource в приведенном выше примере привязано к свойству типа IList в файле кода программной части.

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

Работа с слоями

Примеры, приведенные в этом руководстве, добавляют элементы в коллекцию MapElementsLayer . Затем они показывают, как добавить коллекцию в свойство "Слои " элемента управления картой. В предыдущих выпусках в этом руководстве показано, как добавить элементы карты в коллекцию MapElements следующим образом:

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

Хотя вы по-прежнему можете использовать этот подход, вы пропустите некоторые из преимуществ новой модели слоя карты. Сгруппируя элементы на слои, вы можете управлять каждым слоем независимо друг от друга. Например, каждый слой имеет собственный набор событий, поэтому можно реагировать на событие в определенном слое и выполнить действие для этого события.

Кроме того, можно привязать XAML непосредственно к MapLayer. Это то, что нельзя сделать с помощью коллекции MapElements .

Одним из способов этого является использование класса модели представления, кода на странице XAML и страницы XAML.

Просмотр класса модели

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

Код за страницей XAML

Подключите класс модели представления к странице за кодом.

public LandmarksViewModel ViewModel { get; set; }

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

Страница XAML

На странице XAML привязывается к свойству в классе модели представления, который возвращает слой.

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