Отображение карт с помощью двумерных и трехмерных представлений, а также с помощью представлений Streetside

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

Загрузите пример карты, чтобы опробовать некоторые функции, описанные в данном руководстве.

Показ карты в карточке места

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

На этой карточке места показан город Сиэтл.

карточка места с Сиэтлом

Вот код, который показывает Сиэтл в карточке места под кнопкой.

private void Seattle_Click(object sender, RoutedEventArgs e)
{
    Geopoint seattlePoint = new Geopoint
        (new BasicGeoposition { Latitude = 47.6062, Longitude = -122.3321 });

    PlaceInfo spaceNeedlePlace = PlaceInfo.Create(seattlePoint);

    FrameworkElement targetElement = (FrameworkElement)sender;

    GeneralTransform generalTransform =
        targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);

    Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
        (targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));

    spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}

Эта карточка места показывает расположение башни Спейс-Нидл в Сиэтле.

карточка места с расположением спейс-нидл

Вот код, который показывает Спейс-Нидл в карточке места под кнопкой.

private void SpaceNeedle_Click(object sender, RoutedEventArgs e)
{
    Geopoint spaceNeedlePoint = new Geopoint
        (new BasicGeoposition { Latitude = 47.6205, Longitude = -122.3493 });

    PlaceInfoCreateOptions options = new PlaceInfoCreateOptions();

    options.DisplayAddress = "400 Broad St, Seattle, WA 98109";
    options.DisplayName = "Seattle Space Needle";

    PlaceInfo spaceNeedlePlace =  PlaceInfo.Create(spaceNeedlePoint, options);

    FrameworkElement targetElement = (FrameworkElement)sender;

    GeneralTransform generalTransform =
        targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);

    Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
        (targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));

    spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}

Показ карты в элементе управления

Используйте элемент управления с картой для отображения полнофункциональной и настраиваемой карты в приложении. Элемент управления картой может отображать карты дорог и гибридный трехмерный вид, маршруты, результаты поиска и сведения о ситуации на дорогах. На карте можно показать положение пользователя, маршруты и интересные места. Карта может также показывать трехмерный гибридный вид, представления Streetside, предоставлять сведения о ситуации на дорогах и показывать сведения о местных организациях и заведениях.

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

Примечание

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

Добавление элемента управления с картой в приложение

Карту можно отображать на странице XAML, добавив класс MapControl. Для использования MapControl необходимо объявить пространство имен Windows.UI.Xaml.Controls.Maps на странице XAML или в коде. Если перетащить элемент управления с панели элементов, объявление пространства имен будет добавлено автоматически. Если вы добавляете MapControl на страницу XAML вручную, придется вручную добавить и объявление пространства имен в верхнюю часть страницы.

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

<Page
    x:Class="MapsAndLocation1.DisplayMaps"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MapsAndLocation1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
    mc:Ignorable="d">

 <Grid x:Name="pageGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Maps:MapControl
       x:Name="MapControl1"            
       ZoomInteractionMode="GestureAndControl"
       TiltInteractionMode="GestureAndControl"   
       MapServiceToken="EnterYourAuthenticationKeyHere"/>

 </Grid>
</Page>

Если вы добавляете элемент управления картой в код, придется вручную добавить и объявление пространства имен в верхнюю часть файла кода.

using Windows.UI.Xaml.Controls.Maps;
...

// Add the MapControl and the specify maps authentication key.
MapControl MapControl2 = new MapControl();
MapControl2.ZoomInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.TiltInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.MapServiceToken = "EnterYourAuthenticationKeyHere";
pageGrid.Children.Add(MapControl2);

Получение и установка ключа проверки подлинности карт

Прежде чем использовать класс MapControl и службы карт, необходимо в качестве значения свойства MapServiceToken указать ключ проверки подлинности карт. В предыдущих примерах замените код EnterYourAuthenticationKeyHere ключом, полученным из Центра разработки Карт Bing. Текст Внимание! Не указан MapServiceToken будет отображаться под элементом управления, до тех пор пока вы не укажете ключ проверки подлинности карт. Дополнительные сведения о получении и установке ключа проверки подлинности карт см. в статье Запрос ключа проверки подлинности карт.

Задайте местоположение для карты

Направьте карту на любое местоположение, которое требуется использовать, или текущее расположение пользователя.

Установите начальное местоположение для карты

Укажите местоположение для отображения на карте, задав свойство Center класса MapControl в коде или путем привязки свойства в разметке XAML. В примере ниже показано, как отобразить карту, в центре которой расположен город Сиэтл.

Примечание

Так как строку невозможно преобразовать в класс Geopoint, то, соответственно, невозможно задать значение для свойства Center в разметке XAML, если вы не используете привязку данных. (Это ограничение также применяется к вложенному свойству MapControl.Location.)

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   // Specify a known location.
   BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 47.604, Longitude = -122.329 };
   Geopoint cityCenter = new Geopoint(cityPosition);

   // Set the map location.
   MapControl1.Center = cityCenter;
   MapControl1.ZoomLevel = 12;
   MapControl1.LandmarksVisible = true;
}

Пример элемента управления картой.

Настройте карту в соответствии с текущим местоположением

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

С помощью метода GetGeopositionAsync класса Geolocator получите текущее местоположение устройства (если доступна функция определения местоположения). Чтобы получить соответствующий класс Geopoint, используйте свойство Point геокоординаты геоположения. Дополнительные сведения см. в статье Получение сведений о текущем местоположении.

// Set your current location.
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
   case GeolocationAccessStatus.Allowed:

      // Get the current location.
      Geolocator geolocator = new Geolocator();
      Geoposition pos = await geolocator.GetGeopositionAsync();
      Geopoint myLocation = pos.Coordinate.Point;

      // Set the map location.
      MapControl1.Center = myLocation;
      MapControl1.ZoomLevel = 12;
      MapControl1.LandmarksVisible = true;
      break;

   case GeolocationAccessStatus.Denied:
      // Handle the case  if access to location is denied.
      break;

   case GeolocationAccessStatus.Unspecified:
      // Handle the case if  an unspecified error occurs.
      break;
}

При отображении местоположения устройства на карте рекомендуется отображать рисунки и задавать масштаб на основе точности данных о местоположении. Дополнительные сведения см. в статье Руководство по приложениям с определением местонахождения.

Изменение местоположения на карте

Чтобы изменить местоположение, отображаемое на двумерной карте, вызовите одну из перегрузок метода TrySetViewAsync. Используйте этот метод для определения новых значений для Center, ZoomLevel, Heading, и Pitch. Кроме того, можно настроить использование дополнительной анимации при изменениях представления с помощью константы из перечисления MapAnimationKind.

Чтобы изменить местоположение трехмерной карты, используйте метод TrySetSceneAsync. Дополнительные сведения см. в статье Отображение трехмерных гибридных представлений.

Вызовите метод TrySetViewBoundsAsync, чтобы отобразить содержимое GeoboundingBox на карте. Например, с помощью этого метода можно отобразить на карте маршрут или часть маршрута. Подробности см. в разделе Отображение маршрутов и направлений на карте.

Изменение внешнего вида карты

Чтобы настроить внешний вид карты, задайте свойство StyleSheet элемента управления картой любому из существующих объектов MapStyleSheet.

myMap.StyleSheet = MapStyleSheet.RoadDark();

Карта в темном стиле

Можно также использовать JSON для определения пользовательских стилей и затем использовать этот JSON для создания объекта MapStyleSheet.

Таблица стилей JSON можно создать в интерактивном режиме с помощью приложения Редактор таблицы стилей карты .

myMap.StyleSheet = MapStyleSheet.ParseFromJson(@"
    {
        ""version"": ""1.0"",
        ""settings"": {
            ""landColor"": ""#FFFFFF"",
            ""spaceColor"": ""#000000""
        },
        ""elements"": {
            ""mapElement"": {
                ""labelColor"": ""#000000"",
                ""labelOutlineColor"": ""#FFFFFF""
            },
            ""water"": {
                ""fillColor"": ""#DDDDDD""
            },
            ""area"": {
                ""fillColor"": ""#EEEEEE""
            },
            ""political"": {
                ""borderStrokeColor"": ""#CCCCCC"",
                ""borderOutlineColor"": ""#00000000""
            }
        }
    }
");

Карта в пользовательском стиле

Полный справочник по JSON см. в разделе Пример таблицы стилей карты.

Можно начать с существующего листа и затем использовать JSON для переопределения любых требуемых элементов. Этот пример начинается с существующего стиля и использует JSON для изменения цвета водоемов на карте.

 MapStyleSheet \customSheet = MapStyleSheet.ParseFromJson(@"
    {
        ""version"": ""1.0"",
        ""elements"": {
            ""water"": {
                ""fillColor"": ""#DDDDDD""
            }
        }
    }
");

MapStyleSheet builtInSheet = MapStyleSheet.RoadDark();

myMap.StyleSheet = MapStyleSheet.Combine(new List<MapStyleSheet> { builtInSheet, customSheet });

Сочетание стилей карты

Примечание

Стили, определенные во второй таблице стилей, обладают приоритетом перед стилями в первой таблице.

Задание ориентации и точки обзора

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

  • Установите центр карты в географическую точку, определив свойство Center.
  • Установите масштаб карты, присвоив значение свойству ZoomLevel от 1 до 20.
  • Установите вращение карты, задав свойство Heading, для которого 0 или 360 градусов обозначают север, 90 — восток, 180 — юг и 270 — запад.
  • Установите наклон карты, присвоив значение свойству DesiredPitch от 0 до 65 градусов.

Показ и сокрытие элементов карты

Показывайте или скрывайте элементы карты, такие как дороги и ориентиры, путем установки значений следующих свойств объекта MapControl.

  • Отобразите здания и ориентиры на карте, включив или отключив свойство LandmarksVisible.

    Примечание

    Можно показать или скрыть здания, но вы не можете предотвратить их появление в трехмерном виде.

  • Чтобы показать на карте объекты для пешеходов, например надземные переходы, включите или отключите свойство PedestrianFeaturesVisible.

  • Чтобы показать на карте пробки, включите или отключите свойство TrafficFlowVisible.

  • Чтобы указать, необходимо ли отображать водяной знак на карте, присвойте свойству WatermarkMode значение одной из констант MapWatermarkMode.

  • Чтобы показать на карте маршруты для движения пешком или на автомобиле, добавьте MapRouteView в коллекцию Routes элемента управления картой. Подробности и примеры см. в разделе Отображение маршрутов и направлений на карте.

Сведения о том, как отображать вешки, фигуры и элементы управления XAML в объекте MapControl, см. в статье Отображение объектов на карте.

Отображение представлений Streetside

Представление Streetside — это перспектива уровня улицы для местоположения, отображаемая в верхней части элемента управления картой.

Пример представления Streetside элемента управления картой.

Рассмотрите возможность отделения взаимодействия «внутри» представления Streetside от карты, изначально отображаемой в элементе управления картой. Например, изменение расположения в представлении Streetside не изменяет расположение и внешний вид карты в представлении Streetside. После закрытия представления Streetside (с помощью значка X в правом верхнем углу элемента управления) исходная карта останется неизменной.

Чтобы отобразить представление Streetside, выполните указанные ниже действия.

  1. Проверьте свойство IsStreetsideSupported, чтобы узнать, поддерживаются ли представления Streetside на устройстве.
  2. Если представление Streetside поддерживается, создайте класс StreetsidePanorama возле указанного местоположения, вызвав метод FindNearbyAsync.
  3. Узнайте, обнаружена ли ближайшая панорама, проверив, имеет ли класс StreetsidePanorama значение null.
  4. Если ближайшая панорама обнаружена, создайте объект StreetsideExperience для свойства CustomExperience элемента управления картой.

В этом примере показано, как отображать представление Streetside, аналогичное предыдущему изображению.

Примечание

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

private async void showStreetsideView()
{
   // Check if Streetside is supported.
   if (MapControl1.IsStreetsideSupported)
   {
      // Find a panorama near Avenue Gustave Eiffel.
      BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 48.858, Longitude = 2.295};
      Geopoint cityCenter = new Geopoint(cityPosition);
      StreetsidePanorama panoramaNearCity = await StreetsidePanorama.FindNearbyAsync(cityCenter);

      // Set the Streetside view if a panorama exists.
      if (panoramaNearCity != null)
      {
         // Create the Streetside view.
         StreetsideExperience ssView = new StreetsideExperience(panoramaNearCity);
         ssView.OverviewMapVisible = true;
         MapControl1.CustomExperience = ssView;
      }
   }
   else
   {
      // If Streetside is not supported
      ContentDialog viewNotSupportedDialog = new ContentDialog()
      {
         Title = "Streetside is not supported",
         Content ="\nStreetside views are not supported on this device.",
         PrimaryButtonText = "OK"
      };
      await viewNotSupportedDialog.ShowAsync();            
   }
}

Отображение трехмерных гибридных представлений

Задайте трехмерную перспективу карты с помощью класса MapScene. Сцена карты представляет трехмерное представление, отображаемое на карте. Класс MapCamera представляет положение камеры, отображающей такое представление.

Схема расположения MapCamera для расположения сцены карты

Чтобы здания и другие объекты на карте отображались в трехмерном представлении, задайте для свойства Style элемента управления картой значение MapStyle.Aerial3DWithRoads. Это пример трехмерного представления со стилем Aerial3DWithRoads.

Пример трехмерного представления карты.

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

  1. Проверьте свойство Is3DSupported, чтобы узнать, поддерживаются ли трехмерные представления на устройстве.
  2. Если трехмерные представления поддерживаются, задайте для свойства Style элемента управления картой значение MapStyle.Aerial3DWithRoads.
  3. Создайте объект MapScene с помощью одного из множества методов CreateFrom, например CreateFromLocationAndRadius и CreateFromCamera.
  4. Вызовите метод TrySetSceneAsync, чтобы отобразить трехмерное представление. Кроме того, можно настроить использование дополнительной анимации при изменениях представления с помощью константы из перечисления MapAnimationKind.

В данном примере показано, как отображать трехмерное представление.

private async void display3DLocation()
{
   if (MapControl1.Is3DSupported)
   {
      // Set the aerial 3D view.
      MapControl1.Style = MapStyle.Aerial3DWithRoads;

      // Specify the location.
      BasicGeoposition hwGeoposition = new BasicGeoposition() { Latitude = 43.773251, Longitude = 11.255474};
      Geopoint hwPoint = new Geopoint(hwGeoposition);

      // Create the map scene.
      MapScene hwScene = MapScene.CreateFromLocationAndRadius(hwPoint,
                                                                           80, /* show this many meters around */
                                                                           0, /* looking at it to the North*/
                                                                           60 /* degrees pitch */);
      // Set the 3D view with animation.
      await MapControl1.TrySetSceneAsync(hwScene,MapAnimationKind.Bow);
   }
   else
   {
      // If 3D views are not supported, display dialog.
      ContentDialog viewNotSupportedDialog = new ContentDialog()
      {
         Title = "3D is not supported",
         Content = "\n3D views are not supported on this device.",
         PrimaryButtonText = "OK"
      };
      await viewNotSupportedDialog.ShowAsync();
   }
}

Получении информации о местоположениях

Чтобы получить информацию о местоположениях на карте, вызовите указанные ниже методы объекта MapControl.

  • Метод TryGetLocationFromOffset — получение географического расположения, соответствующего указанной точке в окне просмотра элемента управления Map.
  • Метод GetOffsetFromLocation: получение в окне просмотра элемента управления картой точки, которая соответствует заданному географическому расположению.
  • Метод IsLocationInView: определение того, отображается ли в текущий момент заданное географическое расположение в окне просмотра элемента управления картой.
  • Метод FindMapElementsAtOffset: получение элементов на карте, расположенных в заданной точке окна просмотра элемента управления картой.

Обработка взаимодействия и изменений

Чтобы обработать жесты ввода пользователя на карте, необходимо обработать указанные ниже события объекта MapControl. Получите информацию о географическом положении на карте и физическом положении в окне просмотра, где был выполнен жест, проверив значения свойств Location и Position класса MapInputEventArgs.

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

Чтобы обработать изменения, которые происходят при изменении пользователем или приложением параметров карты, необходимо обработать указанные ниже события объекта MapControl.

Рекомендации

  • Используйте свободное место на экране (или весь экран) для отображения карты, чтобы пользователям не приходилось постоянно сдвигать и масштабировать карту для просмотра географических сведений.

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

  • Укажите достопримечательности на карте, используя map elements. Любые дополнительные сведения могут быть отображены в качестве прозрачного наложения пользовательского интерфейса на карту.