В первой публикации из этой серии мы начали с обзора класса MapControl в универсальной платформе Windows (UWP). Во второй публикации мы поработали с геолокацией, геокодированием и картами маршрутов. В этой финальной публикации мы собираемся кастомизировать MapControl для своих нужд, изменив его флажки и внешние элементы.
Флажки
Все знакомы с культом полицейских детективов в кино и телевидении, и могут представить себе детектива стоящего перед картой на стене и втыкающего в карту флажки на иголке, соединяющие все точки. Рано или поздно мы узнаем, что детектив выяснил где находится плохой парень / мешок с деньгами / тикающая бомба с замедлителем. Этот телевизионный образ является убедительным, поскольку он является идеальным зеркалом того, как работает наш мозг — человеческий мозг постоянно оценивает случайные куски визуальной информации для того, чтобы найти закономерности и смысл.
Флажки в приложениях с картой точно таким же образом являются убедительными. Они предоставляют вам возможность привлечь внимание пользователя с помощью интересного визуального образа. В UWP MapControl аналог флажка называется MapIcon. Вы можете использовать его только для обозначения «Вы находитесь здесь» в вашем приложении, или создать символ для интересных близлежащих достопримечательностей, а так же для списка торговых центров. Чтобы добавить один флажок на карту, вам нужны всего лишь геокоординаты точки и заголовок.
-
var pushpin = new MapIcon();
-
// assign pushpin geoposition
-
pushpin.Location = new Geopoint(new BasicGeoposition()
-
{
-
Latitude = 51.178840,
-
Longitude = —1.826189
-
});
-
// assign pushpin title
-
pushpin.Title = «Here’s something interesting!»;
-
// make sure pushpin always appears
-
pushpin.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
-
// set pushpin bottom center over geoposition
-
pushpin.NormalizedAnchorPoint = new Point(0.5, 1.0);
-
// put pushpin on the map
-
this.myMap.MapElements.Add(pushpin);
Флажки имеют изображение по умолчанию, которое иногда могут быть скрыты с помощью меток или других элементов. Вы можете установить свойство CollisionBehaviorDesired в состояние RemainVisible для того, чтобы не допустить этого. По умолчанию верхний левый угол изображения будет появляться над геоположением для MapIcon. Вы можете сдвинуть его, присвая параметру NormalizedAnchorPoint х и у значения от 0 до 1 (устанавливается 0, 0, если не используется).
В то время как обычный флажок может быть полезным как показано выше, то MapIcon становится наиболее интересным, когда вы используете его для выявления скрытых закономерностей на карте. Например, сколько кофеен находится в радиусе одной мили вокруг вашего пользователя? Где чаще встречается НЛО на карте США? Как распределены средневековые замки на юге Франции? Каждая из этих моделей рассказывает историю, которая делает карты и ваше приложение привлекательным, а не просто утилитарным.
Вы можете использовать собственные изображения для замены изображения по умолчанию для того, чтобы дать вашему приложение больше индивидуальности и сделать ваши карты более актуальными. Изображение должно быть меньше, чем 2048 на 2048 пикселей.
Допустим вам нужен флажок в виде Стоунхенджа на равнине Солсбери в Англии. Вы можете изменить изображение MapIcon с помощью класса RandomAccessStreamReference, чтобы указать ваш выбор.
-
// set pushpin title
-
pushpin.Title = «Stonehenge»;
-
// add custom Stonehenge image
-
var myImageUri = new Uri(«ms-appx:///Assets/upright.png»);
-
pushpin.Image = RandomAccessStreamReference.CreateFromUri(myImageUri);
Как соединить флажки
Обычно на карте в телевизионных детективах, о которых говорили выше, между воткнутыми флажками прорисовывают линии, которые образуют фигуры и узоры. Вы можете сделать то же самое в MapControl с помощью класса MapPolyline. Как и следовало ожидать, для MapPolyline требуются геокоординаты, чтобы закрепить ломаную линию. Он также позволяет выбрать цвет, толщину и стиль линии. Точно также как и с флажками, добавляя полилинию вы создаете элементы MapElements для вашей собственной карты.
-
// create Stonehenge geoposition
-
var locStonehenge = new BasicGeoposition()
-
{
-
Latitude = 51.178840,
-
Longitude = —1.826189
-
};
-
// create Swinside circle geoposition
-
var locSwinside = new BasicGeoposition()
-
{
-
Latitude = 54.282490,
-
Longitude = —3.273860
-
};
-
// instantiate mappolyline
-
var polyline = new MapPolyline();
-
// add geopsitions to path
-
polyline.Path = new Geopath(new List<BasicGeoposition>() {locStonehenge, locSwinside});
-
//set appearance of connector line
-
polyline.StrokeColor = Colors.OrangeRed;
-
polyline.StrokeThickness = 2;
-
polyline.StrokeDashed = true;
-
// add to map
-
this.myMap.MapElements.Add(polyline);
Вы можете пойти на шаг дальше и добавить несколько местоположений в список Geopath, чтобы создать более яркий набор связей. На рисунке ниже, все знаковые места эпохи неолита добавлены в список.
Добавление фигур на вашу карту
Класс MapPolygon позволяет добавлять фигуры на карту таким же образом как класс MapPolyline позволяет добавлять линии. Разница состоит в том, что полигон может иметь цвет заливки. Для забавы давайте нарисуем фигуру между трёх каменных кругов ближе к югу.
-
// instantiate mappolygon
-
var polygon = new MapPolygon();
-
// set appearance
-
polygon.StrokeColor = Colors.DeepSkyBlue;
-
polygon.FillColor = Color.FromArgb(100,255,255,0);
-
polygon.StrokeThickness = 4;
-
//create path
-
polygon.Path = new Geopath(new List<BasicGeoposition>()
-
{
-
new BasicGeoposition() {Latitude=52.5, Longitude=-3.5 },
-
new BasicGeoposition() {Latitude=52.5, Longitude=-2.5 },
-
new BasicGeoposition() {Latitude=52, Longitude=-2.5 },
-
new BasicGeoposition() {Latitude=52, Longitude=-3.5 },
-
});
-
// add to map
-
this.myMap.MapElements.Add(polygon);
Что интересно, MapPolygon подобен простому рисованию фигур точно также как и в декартовой системе координат. Разница, конечно в том, что вершины фигуры в этом случае могут иметь глобальный масштаб, растянувшийся на сотни километров.
Добавление элементов XAML на вашу карту
Наконец, вы можете также рассматривать MapControl как своего рода холст и добавить XAML элементы в коллекцию Children вашей карты. Затем с помощью прикрепленных свойств вы можете настроить элемент XAML, как только он будет добавлен в визуальную иерархию.
-
// create new button
-
var button = new Button();
-
button.Content = «Push this!»;
-
this.myMap.Children.Add(button);
-
// assign geoposition
-
var position = new Geopoint(new BasicGeoposition()
-
{
-
Latitude = 52.25,
-
Longitude = —3.0
-
});
-
MapControl.SetLocation(button, position);
-
// center button over geoposition
-
MapControl.SetNormalizedAnchorPoint(button, new Point(0.5, 0.5));
Не добавляйте много элементов XAML без особой необходимости. Они добавляют некоторые издержки производительности, поэтому используйте их только когда вам требуется богатый стиль оформления или интерактивность.
Подводя итоги
MapControl является чрезвычайно мощным и универсальным классом. В то время как в предыдущих публикациях этой серии было показано как его использовать относительно привычным способом, в этой публикации мы пошли дальше и показали вам как создать уникальное приложение с картой, специфичное для ваших целей, интересов, потребностей пользователей.
Имея почти полный контроль над визуализацией карты — это даже побуждает некоторых разработчиков использовать MapControl для целей, отличных обычных карт, например, воссоздавая настольную игру Risk, использующую карту в качестве подосновы. Один инновационный разработчик даже использовал Kinect для сканирования 3D-модели своей головы, которую он мог затем поместить в любую точку мира на подобие передвижной горы Рашмор.
UWP класс MapControl и сервисы локации предлагают вам современными картами мира в качестве игровой площадки. Воспользуйтесь по своей сути увлекательным характером карт Земли, чтобы построить картографические приложения и для других целей. Помогите людям увидеть те вещи на картах, которые они не смогли бы увидеть без вас.
Перевод оригинальной публикации Map APIs and controls: Adding external elements
Перевод: Сергей Урусов