Каждое поколение Windows Phone приносит улучшенные возможности в работе с картами, и Windows Phone 8.1 с новым элементом управления Map, введенным в Visual Studio 2013 Update 3, не является исключением. Если вам нужна лишь простая карта, центрируемая на определенном месте, вы можете добиться этого всего несколькими строками кода, используя новый элемент управления Map. Но если вам требуется реагировать на действия пользователя, адаптировать внешний вид элемента управления или вычислять маршруты, то и в этом случае вы можете использовать новый элемент управления Map в сочетании с API картографических сервисов для поддержки более сложных сценариев.
Эта статья посвящена новому элементу управления Map в Windows Phone 8.1 и API картографических сервисов. Я начну с демонстрации базовых средств отображения карты, затем рассмотрю более продвинутые средства, позволяющие, в частности, помечать определенные адреса на карте кнопками (push pins). Я также покажу, как помещать XAML-элементы управления на Map и как определять местонахождение (вместе с адресом) по GPS, соответствующее конкретной точке на карте. Это полезно, если вы хотите, чтобы пользователь мог указать интересующее его место, и определить GPS-координаты и адрес. Наконец, я покажу, как вычислять автомобильные и пешие маршруты.
Хорошим дополнением к моей статье является статья Тони Чэмпиона (Tony Champion) «Creating a Location-Aware App with Geofencing» за сентябрь 2014 г. Геозона (geofence) — определенная область вокруг GPS-координат, которую можно регистрировать в Windows. После регистрации геозоны приложение может принимать уведомления, когда устройство попадает в эту область или покидает ее. Настройка геозон (geofencing) также является новшеством Windows Phone 8.1. Если вы намерены создать приложение, использующее поддержку геозон, подумайте о применении элемента управления Map, который позволяет пользователям указывать новые геозоны и просматривать уже существующие.
На момент написания этой статьи для каждой разновидности мобильных и планшетных платформ были свои элементы управления Map:
- приложения Windows Phone Silverlight 8.0/8.1: Microsoft.Phone.Maps.Controls.Map;
- приложения Windows Store 8.x: Bing.Maps.Map;
- приложения Windows Phone 8.1 Runtime: Windows.UI.Xaml.Controls.Maps.
В этой статье основное внимание уделяется новому элементу управления Map и картографическим сервисам, которые можно использовать в приложениях, написанных для Windows Phone 8.1 Runtime.
Приступаем к работе
Аутентификация приложения Ваше приложение Windows Phone должно аутентифицироваться всякий раз, когда оно использует элемент управления Map или картографические сервисы, находящиеся в пространстве имен Windows.Services.Maps. Чтобы аутентифицировать свое приложение, вам нужны ApplicationID и AuthenticationToken сервиса Map; их можно получить в Developer Dashboard в Windows Phone Dev Center. Пошаговые инструкции по получению ApplicationID и AuthenticationToken см. в статье из MSDN Library по ссылке bit.ly/1y78M2F.
После этого вы должны поместить ApplicationID в файл Package.appxmanifest вашего приложения. Инструкции о том, как это сделать, вы найдете в той же статье из MSDN Library. Как используется AuthenticationToken в коде, вы увидите позже в этой статье.
Возможности (capabilities) Во многих примерах в этой статье используется текущее местоположение пользователя, и поэтому элементу управления Map может потребоваться соединение с Интернетом. В связи с этим в файле манифеста приложения требуется объявить возможности Internet и Location, как показано на рис. 1. Однако картографические сервисы работают и без подключения к Интернету, если вы скачали карты для автономного использования. Подробнее о скачивании карт см. «How to Download and Update Offline Maps (XAML)» по ссылке bit.ly/1nXBOrS.
Рис. 1. Объявление возможностей Internet и Location
Отображение карт
Отображение простой карты→ Добавить элемент управления Map на страницу так же легко, как и любой другой элемент управления. Вы можете перетащить его на страницу из Visual Studio Toolbox или набрать следующий XAML:
<Maps:MapControl
x:Name="myMapControl"
MapServiceToken="Place your token here."
Height="200" Width="300"
HorizontalAlignment="Center"
Margin="0,0,0,12"
/>
Обратите внимание на свойство MapServiceToken. Этому свойству следует присвоить значение Map Service Authentication Token, назначенное вашему приложению в Developer Dashboard в Windows Phone Dev Center. Кроме того, вы можете размещать Map, как и любой другой элемент управления. Map не должен закрывать весь экран. Небольшая карта, на которой увеличивается конкретное место, может быть очень наглядным элементом на странице, содержащей специфичную для этого места информацию. С другой стороны, карты, которые можно увеличивать, потребуют дополнительного пространства на экране. Для таких карт лучше задействовать полную страницу.
Предыдущий XAML дает малоинтересные результаты, если его поместить в приложение и запустить. Этот элемент управления покажет карту с полным приближением. Так что следующий шаг в использовании Map — идентификация конкретного местоположения в центральной точке карты, а также уровень приближения.
Следующий код сначала вычисляет текущее местоположение пользователя, а затем присваивает эту позицию свойству Center карты. Кроме того, он задает уровень масштабирования, равный 15. Минимальное значение уровня масштабирования — 1, что соответствует полностью уменьшенной карте, когда в вашем элементе управления Map отображается половина глобуса. Максимальное значение этого уровня — 20, при котором содержимое элемента управления Map масштабируется до определенного адреса:
Geolocator geolocator = new Geolocator();
Geoposition geoposition = null;
try
{
geoposition = await geolocator.GetGeopositionAsync();
}
catch (Exception ex)
{
// Обрабатываем ошибки, например неавторизованный доступ
// к сервисам определения местоположения или
// отсутствие соединения с Интернетом
}
myMapControl.Center = geoposition.Coordinate.Point;
myMapControl.ZoomLevel = 15;
Добавление изображений к элементу управления Map Если вы хотите отметить конкретное место на своей карте, то можете добавить изображения в заголовок (title) в Map. Код на рис. 2 укажет текущее местонахождение устройства, добавив изображение из папки Assets проекта в элемент управления Map.
Рис. 2. Добавление собственного изображения в элемент управления Map
Geolocator geolocator = new Geolocator();
Geoposition geoposition = null;
try
{
geoposition = await geolocator.GetGeopositionAsync();
}
catch (Exception ex)
{
// Обрабатываем ошибки, например неавторизованный доступ
// к сервисам определения местоположения или
// отсутствие соединения с Интернетом
}
MapIcon mapIcon = new MapIcon();
mapIcon.Image = RandomAccessStreamReference.CreateFromUri(
new Uri("ms-appx:///Assets/PinkPushPin.png"));
mapIcon.NormalizedAnchorPoint = new Point(0.25, 0.9);
mapIcon.Location = geoposition.Coordinate.Point;
mapIcon.Title = "You are here";
myMapControl.MapElements.Add(mapIcon);
Чтобы добавить изображение к Map, сначала создайте объект MapIcon и установите его свойство Location в Geopoint, отражающее нужно место на карте. В коде на рис. 2 используется текущее местоположение. Свойство Title — это текст, который будет показан над изображением, добавленным в Map.
Чтобы указать изображение, установите свойство Image объекта MapIcon, вызвав метод RandomAccessStreamReference.CreateFromUri. Это статический метод в пространстве имен Windows.Storage.Streams. Изображение должно быть примерно 50×50 пикселей; если оно окажется больше, то будет соответственно уменьшено.
Когда цель вашего изображения — указать на конкретное место, лучше всего использовать свойство NormalizedAnchorPoint объекта MapIcon. Оно позволяет указывать точку внутри вашего изображения, которая будет помещена поверх заданного Geopoint. Если изображение представляет собой кнопку, тогда это будет кончик кнопки. Если вы используете изображение стрелки, эта точка будет находиться на острие стрелки. Значение свойства NormalizedAnchorPoint по умолчанию — объект Point, созданный со значением (0,0), которое представляет верхний левый угол изображения. Нижний правый угол изображения соответствует (1,1). Эта координатная система показана на рис. 3 с несколькими примерами точек.
Рис. 3. Координатная система, применяемая для свойства NormalizedAnchorPoint
Если изображение, используемое в качестве значка на карте, содержит указатель, а вы не задали свойство NormalizedAnchorPoint должным образом, значок на карте будет указывать на неправильное место. Если ваше изображение — просто точка или маленький кружок, следует использовать значение (0.5,0.5), что является центром изображения.
Если вы не указываете изображение, MapControl выводит изображение по умолчанию (рис. 4).
Рис. 4. Значок на карте по умолчанию
Как видите, изображение MapIcon по умолчанию имеет указатель, расположенный внизу по центру изображения. Поэтому свойство NormalizedAnchorPoint нужно установить в (0.5, 1.0).
Последняя деталь, на которую стоит обратить внимание в этом коде, — объект MapIcon добавляется в набор MapElements элемента управления Map, поэтому при желании можно добавить к карте более одного MapIcon.
Нет никаких гарантий, что на карте будут показаны значок и заголовок. Один из них или оба могут быть скрыты, если они заслоняют другие элементы или надписи на карте. Особенно в том случае, если карта отдаляется (уровень масштабирования уменьшается) и в окно элемента управления Map нужно уместить больше информации.
Код на рис. 2 выводит карту, как на рис. 5, в предположении, что вы смотрите бейсбольный матч на стадионе Фенуэй Парк (Fenway Park).
Рис. 5. Элемент управления Map, показывающий Фенуэй Парк в Бостоне
Добавление элементов управления в Map Добавление XAML-элемента управления в Map похоже на добавление изображения. Следующий код создает эллипс, изменяет его размеры под окружность, добавляет его в элемент управления Map и центрирует по географическим координатам:
// Создаем окружность
Windows.UI.Xaml.Shapes.Ellipse fence =
new Windows.UI.Xaml.Shapes.Ellipse();
fence.Width = 30;
fence.Height = 30;
fence.Stroke = new SolidColorBrush(Colors.DarkOrange);
fence.StrokeThickness = 2;
MapControl.SetLocation(fence, geoposition.Coordinate.Point);
MapControl.SetNormalizedAnchorPoint(
fence, new Point(0.5, 0.5));
myMapControl.Children.Add(fence);
Заметьте, что для связывания географических координат с объектом Ellipse следует использовать статическую функцию SetLocation элемента управления Map. Аналогично функция SetNormalizedAnchorPoint применяется при связывании свойства Normalized Anchor Point.
Используя эти методологии, в Map можно добавить любой элемент управления, производный от UIElement или MapItemsControl.
Получение местоположения
Сердцевиной элемента управления Map является объект BasicGeoposition, который может представлять любое местоположение на Земле, используя всего три числа: широту, долготу и высоту. Это не только эффективный способ деления глобуса, но и очень точный. Каждая позиция имеет свою уникальную комбинацию широты, долготы и высоты. Ни у одной позиции не может быть одной и той же комбинации.
К сожалению, ваше приложение будет взаимодействовать с людьми, а люди не любят, когда им показывают местоположение в виде голых числовых значений. В связи с этим глобус делится на континенты, страны внутри континентов, регионы (или штаты) внутри стран, города внутри регионов и улицы внутри городов. Хотя названия континентов и стран, а также почтовые индексы уникальны, регионы иногда могут включать два и более городов с одинаковыми названиями. Кроме того, в городе могут быть две и более улиц с одинаковым названием. Вывод заключается в том, что какой-то адрес можно перепутать с другими. Это особенно верно, когда имеешь дело с неполным представлением адреса (без названия штата, почтового индекса или названия города).
Следовательно, если ваше приложение будет показывать нечто большее текущего местоположения пользователя, которое можно получить напрямую от устройства, вам потребуются преобразования между числовыми координатами и ранее описанной системой названий. Процесс преобразования адреса в географическое местоположение известен как геокодирование (geocoding), а процесс преобразования географического местоположения в воспринимаемый человеком адрес — как обратное геокодирование (reverse geocoding).
Преобразование адреса в географическое местоположение (геокодирование) Геокодирование адреса требует использования API картографических сервисов — набора классов в пространстве имен Windows.Services.Maps. Чтобы задействовать эти API, вы должны указать свой Authentication Token в статическом свойстве ServiceToken класса MapService. Следующая строка кода показывает, как это делается (в остальной части этой статьи будет предполагаться, что эта строка кода находится в обработчике события OnLaunched приложения):
MapService.ServiceToken = "Place your token here";
После установки Authentication Token можно вызывать статическую функцию FindLocationsAsync, которая содержится в классе MapLocationFinder. Вот как использовать эту функцию:
Geolocator geolocator = new Geolocator();
Geoposition currentPosition =
await geolocator.GetGeopositionAsync();
MapLocationFinderResult result =
await MapLocationFinder.FindLocationsAsync(
address, currentPosition.Coordinate.Point, 5);
Первый параметр функции FindLocationsAsync — это строковое представление адреса. Этой функции можно передать любую строку. Картографические сервисы на серверной стороны, с которыми взаимодействует функция FindLocationsAsync, приложат максимум усилий, чтобы найти совпадающее местоположение. Второй параметр известен как базовая точка (reference point) и представляет географическое местоположение, откуда следует начинать поиск. Этот параметр иногда называют подсказкой (hint). При правильном использовании он может значительно повысить релевантность возвращаемых местоположений и ускорить их вычисление. Например, если вам известно, что пользователь ищет что-то в своей местности, передайте в качестве базовой точки текущее местонахождение пользователя. Однако, если вы знаете, что пользователь планирует свой отпуск, передайте местоположение его отеля. Последний параметр — максимальное количество возвращаемых местоположений.
Функция FindLocationsAsync возвращает объект типа MapLocationFinderResult. Он сообщает, был ли поиск успешным. Если поиск прошел успешно, объект MapLocationFinderResult будет содержать набор объектов MapLocation. Код на рис. 6 проверяет, был ли поиск успешным, и, если да, помещает набор в элемент управления ListView, чтобы пользователь увидел список всех совпадающих местоположений. Объект MapLocation содержит как адрес, воспринимаемый человеком, так и географическую информацию, которую можно использовать в элементе управления MapControl. Код на рис. 6 можно было бы легко преобразовать так, чтобы он отображал кнопки на карте.
Рис. 6. Получение результатов поиска местоположения
if (result.Status == MapLocationFinderStatus.Success)
{
List<string> locations = new List<string>();
foreach (MapLocation mapLocation in result.Locations)
{
// Создаем отображаемую строку местоположения на карте
string display = mapLocation.Address.StreetNumber + " " +
mapLocation.Address.Street + Environment.NewLine +
mapLocation.Address.Town + ", " +
mapLocation.Address.RegionCode + " " +
mapLocation.Address.PostCode + Environment.NewLine +
mapLocation.Address.CountryCode;
// Добавляем эту строку в список местоположений
locations.Add(display);
}
// Связываем этот список с элементом управления ListView
lvLocations.ItemsSource = locations;
}
else
{
// Предлагаем пользователю попытаться еще раз
}
Преобразование географической позиции в адрес (обратное геокодирование) Другая полезная функциональность, которую может предоставить картографическое приложение — возможность получить читаемый человеком адрес из той области элемента управления Map, которой коснулся пользователь. Чтобы закодировать эту функциональность, вам прежде всего нужен какой-то способ получать позицию касания. Для этого используется событие MapTapped элемента управления Map. Этот элемент также имеет событие Tapped, которое срабатывает, когда происходит касание дочернего XAML-элемента в Map. Любое прямое касание элемента управления Map передается через событие MapTapped. Код на рис. 7 показывает реализацию обработчика события MapTapped, отображающего адрес позиции, которой коснулся пользователь, в элементе управления TextBlock.
Рис. 7. Поиск адреса позиции в Map, которой коснулся пользователь
private async void myMapControl_MapTapped(MapControl sender,
MapInputEventArgs args)
{
// Находим адрес позиции, которой коснулся пользователь
MapLocationFinderResult result = await
MapLocationFinder.FindLocationsAtAsync(args.Location);
if (result.Status == MapLocationFinderStatus.Success)
{
if (result.Locations.Count > 0)
{
string display = result.Locations[0].Address.StreetNumber
+ " " + result.Locations[0].Address.Street;
tbAddress.Text = display;
}
}
}
В этой реализации обработчика события MapTapped есть несколько деталей, на которые стоит обратить внимание. Прежде всего географическая точка (geopoint), сопоставленная с позицией, которой коснулся пользователь, передается этому событию через args.Location. Функция FindLocationsAtAsync может использовать эту географическую точку для получения читаемого человеком адреса. FindLocationsAtAsync — статическая функция в классе MapLocationFinder, который является частью API картографических сервисов (пространство имен Windows.Services.Maps). Эта функция возвращает объект MapLocationFinderResult, содержащий свойство Status и набор объектов MapLocation. Хотя возвращаемое значение допускает наличие набора объектов MapLocation, обычно оно содержит только один объект MapLocation. Однако где-то в мире может найтись многоэтажное здание, с которым связаны адреса по двум или более улицам. Если пользователь щелкает середину большого поля или озера, значение все равно возвращается. Если рядом нет никаких улиц, объект MapLocation будет содержать только Region, Country и Postal Code.
Маршруты
Картографические сервисы способны вычислять маршруты от заданной начальной точки до указанной конечной. Сам элемент управления Map умеет отображать маршрут, который может вычисляться как автомобильный или пеший.
Автомобильные маршруты Само название предполагает, что такие маршруты предназначены для проезда на автомобиле, водитель которого не поедет против направления движения по улице с односторонним движением и будет соблюдать все остальные правила дорожного движения. Код на рис. 8 вычисляет направления движения от Центрального вокзала в Нью-Йорке до Центрального парка.
Рис. 8. Вычисление автомобильного маршрута
// Начинаем с Центрального вокзала
BasicGeoposition startLocation = new BasicGeoposition();
startLocation.Latitude = 40.7517;
startLocation.Longitude = -073.9766;
Geopoint startPoint = new Geopoint(startLocation);
// Заканчиваем в Центральном парке
BasicGeoposition endLocation = new BasicGeoposition();
endLocation.Latitude = 40.7669;
endLocation.Longitude = -073.9790;
Geopoint endPoint = new Geopoint(endLocation);
// Получаем маршрут между этими точками
MapRouteFinderResult routeResult =
await MapRouteFinder.GetDrivingRouteAsync(
startPoint,
endPoint,
MapRouteOptimization.Time,
MapRouteRestrictions.None,
290);
Этот код достаточно прямолинеен. Статической функции MapRouteFinder.GetDrivingRouteAsync передаются начальная и конечная точки, параметр оптимизации (о нем позже) и параметр, задающий ограничения (о нем тоже потом). Пятый и последний параметр — это необязательный курс (heading), который указывает текущее направление пользователя по компасу в градусах (0 градусов соответствует северу, 180 градусов — югу и т. д.). Это удобно, когда маршрут вычисляется, пока пользователь едет по нему. Если параметр heading используется, маршрут вычисляется на основе текущего направления пользователя. Первые несколько частей маршрута будут содержать маневры, которые выведут пользователя на лучший из возможных маршрутов, что особенно полезно в городах, где пользователь может оказаться на односторонней дороге в неправильном направлении. Смена курса на 135 в коде на рис. 8 приведет к тому, что маршрут будет вычислен так, чтобы содержать законный способ смены направлений.
Получив результат от функции MapRouteFinder.GetDrivingRouteAsync, вы должны проверить его. Если маршрут был получен успешно, тогда его можно отобразить как инструкции с указанием каждого поворота. Маршрут также можно визуализировать в элементе управления Map. Код на рис. 9 отображает маршрут от Центрального вокзала в Нью-Йорке до Центрального парка как инструкции с указанием каждого поворота.
Рис. 9. Перебор в цикле участков маршрута и маневров
// Выводит сводную информацию о маршруте
tbTurnByTurn.Inlines.Add(new Run()
{
Text = "Total estimated time (minutes) = " +
routeResult.Route.EstimatedDuration.
TotalMinutes.ToString("F1")
});
tbTurnByTurn.Inlines.Add(new LineBreak());
tbTurnByTurn.Inlines.Add(new Run()
{
Text = "Total length (kilometers) = " +
(routeResult.Route.LengthInMeters / 1000).ToString("F1")
});
tbTurnByTurn.Inlines.Add(new LineBreak());
// Показываем направление
tbTurnByTurn.Inlines.Add(new Run()
{
Text = "DIRECTIONS"
});
tbTurnByTurn.Inlines.Add(new LineBreak());
// Перебираем в цикле участки маршрута и маневры на нем
int legCount = 0;
foreach (MapRouteLeg leg in routeResult.Route.Legs)
{
foreach (MapRouteManeuver maneuver in leg.Maneuvers)
{
tbTurnByTurn.Inlines.Add(new Run()
{
Text = maneuver.InstructionText
});
tbTurnByTurn.Inlines.Add(new LineBreak());
}
}
Объект MapRoute содержит сводную информацию, которая указывает, сколько времени займет маршрут, и его длину в метрах. Объект MapRoute организует информацию о маршруте, используя объекты MapRouteLeg и MapRouteManeuver. MapRoute содержит один или более объектов MapRouteLeg, а каждый MapRouteLeg — один или более объектов MapRouteManeuver. Информация, которая будет показана пользователю, находится в объекте MapRouteManeuver. Эти объекты содержат навигационные инструкции, информацию о выходе (exit information) (если применимо), длину маневра и примечания по маневру (если применимо). Свойство Kind тоже очень полезно. Например, его значения включают «left turn» (поворот налево), «right turn» (поворот направо) и т. д. Это свойство можно использовать для сопоставления изображения с каждым маневром. Полный список возможных значений свойства Kind см. по ссылке bit.ly/1nXOyi7. На рис. 10 показано, как эти указания могли бы выглядеть в приложении.
Рис. 10. Инструкции с указанием поворотов для автомобильного маршрута
Маршруты также можно отображать графически в элементу управления Map (рис. 11).
Рис. 11. Визуальное отображение маршрута в элементе управления Map
if (routeResult.Status == MapRouteFinderStatus.Success)
{
// Используем маршрут для инициализации MapRouteView
MapRouteView viewOfRoute = new MapRouteView(
routeResult.Route);
viewOfRoute.RouteColor = Colors.Blue;
viewOfRoute.OutlineColor = Colors.Blue;
// Добавляем новый MapRouteView в набор Routes
// объекта MapControl
MapwithDrivingRoute.Routes.Add(viewOfRoute);
await MapwithDrivingRoute.TrySetViewBoundsAsync(
routeResult.Route.BoundingBox,
null,
Windows.UI.Xaml.Controls.Maps.MapAnimationKind.Bow);
}
Чтобы отобразить маршрут в элементе управления Map, сначала нужно создать представление маршрута с помощью класса MapRouteView и добавить его в набор Routes элемента управления Map. Наконец, функция TrySetViewBoundsAsync элемента управления Map так отмасштабирует Map, чтобы был виден весь маршрут. У этой функции предусмотрен даже параметр анимации, который обеспечивает визуальный эффект при перерисовке элемента управления Map под полное представление маршрута. На рис. 12 показано, как это выглядит в приложении.
Рис. 12. Автомобильный маршрут в элементе управления Map
Оптимизации маршрута Автомобильные маршруты можно оптимизировать по таким параметрам, как время, расстояние и трафик. Оптимизацию вычисления маршрута обеспечивает перечисление MapRouteOptimization, значения которого приведены в табл. 1.
Табл. 1. Перечисление MapRouteOptimization
Time | Маршрут будет оптимизирован так, чтобы его можно было проехать за минимальное время с учетом расстояния и ограничений скорости на каждом маневре маршрута |
Distance | Маршрут будет оптимизирован так, чтобы его длина была кратчайшей с учетом длины каждого маневра |
TimeWithTraffic | Маршрут будет оптимизирован так, чтобы его можно было проехать за минимальное время с учетом расстояния, ограничений скорости и текущей интенсивности движения на каждом маневре маршрута |
Ограничения маршрута Автомобильные маршруты можно вычислять с ограничениями вроде «без автострад» («no highways») или «без платных дорог» «no toll roads». Ограничения при вычислении автомобильного маршрута вводятся значениями перечисления MapRouteRestrictions, показанного в табл. 2.
Табл. 2. Перечисление MapRouteRestrictions
None | Маршрут вычисляется без ограничений. Маршрут может содержать маневры, включающие автострады, тоннели, переправы, платные дороги и грунтовые дороги |
Highways | Маршрут не будет содержать никаких маневров по автостраде |
TollRoads | Маршрут не будет содержать никаких маневров по платным дорогам |
Ferries | Маршрут не будет содержать никаких маневров, требующих использования переправы |
Tunnels | Маршрут не будет содержать никаких маневров через тоннели |
DirtRoads | Маршрут не будет содержать никаких маневров по грунтовым дорогам |
Эти значения можно логически комбинировать. Например, следующий код определяет ограничение, которое запрещает использование автострад и платных дорог:
MapRouteFinderResult routeResult =
await MapRouteFinder.GetDrivingRouteAsync(
startPoint,
endPoint,
MapRouteOptimization.Time,
MapRouteRestrictions.Highways ||
MapRouteRestrictions.TollRoads);
Пешие маршруты Вычисление пеших маршрутов очень похоже на вычисление автомобильных маршрутов. Следующий код вычисляет пеший маршрут на основе тех де начальной и конечной точек, что и в примере с автомобильным маршрутом:
// Получаем маршрут между двумя точками
MapRouteFinderResult routeResult =
await MapRouteFinder.GetWalkingRouteAsync(
startPoint,
endPoint);
Для выполнения этого вычисления используется статическая функция MapRouteFinder.GetWalkingRouteAsync. В отличие от соответствующей функции для вычисления автомобильных маршрутов эта функция не имеет перегруженных версий, которые поддерживают оптимизацию, ограничения или текущий курс. Эти атрибуты никак не влияют на вычисления пешего маршрута, поскольку ограничения скорости и интенсивность трафика в этом случае не релевантны. Кроме того, текущий курс может легко смениться. Пешие маршруты вычисляются в расчете на кратчайшее расстояние. На рис. 13 и 14 показан пеший маршрут от Центрального вокзала в Нью-Йорке до Центрального парка.
Рис. 13. Инструкции с указанием поворотов для пешего маршрута
Рис. 14. Пеший маршрут, отображаемый в элементе управления Map
Заключение
В этой статье я показал, как использовать новый элемент управления Map для Windows Phone 8.1, включая отображение базовой карты, добавление изображений и элементов управления. Я также познакомил вас с нижележащим API картографических сервисов и кратко рассмотрел геокодирование, обратное геокодирование и вычисления маршрутов.
Следует учитывать ряд других областей, относящихся к картографии: перекрытие плиточных изображений (tiled images), связывание с данными и управление автономными картами. Информацию на этот счет вы найдете в Windows Dev Center (bit.ly/X7S7ei).