Карта
Элемент управления Map в .NET MAUI — это кроссплатформенное средство для отображения и аннотирования карт. Элемент управления Map использует встроенный элемент управления картой на каждой платформе и предоставляется пакетом NuGet Microsoft.Maui.Controls.Maps.
Важный
Элемент управления Map не поддерживается в Windows из-за отсутствия элемента управления картой в WinUI. Однако пакет NuGet CommunityToolkit.Maui.Maps предоставляет доступ к Картам Bing через WebView
в системе Windows. Дополнительную информацию см. в разделе Как начать.
Настройка
Элемент управления Map использует собственный элемент управления картой на каждой платформе. Это обеспечивает быстрый и знакомый интерфейс карт для пользователей, но означает, что некоторые действия по настройке необходимы для соблюдения требований API для каждой платформы.
Инициализация карты
Элемент управления Map предоставляется пакетом NuGet Microsoft.Maui.Controls.Maps, который следует добавить в проект приложения .NET MAUI.
После установки пакета NuGet его необходимо инициализировать в приложении, вызвав метод UseMauiMaps объекта MauiAppBuilder
в методе CreateMauiApp
класса MauiProgram
:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseMauiMaps();
return builder.Build();
}
}
После добавления и инициализации пакета NuGet Map API можно использовать в проекте.
Конфигурация платформы
Дополнительная конфигурация требуется в Android, прежде чем карта будет отображаться. Кроме того, в iOS, Android и Mac Catalyst доступ к расположению пользователя требует предоставления приложению разрешений на расположение.
IOS и Mac Catalyst
Отображение и взаимодействие с картой в iOS и Mac Catalyst не требует дополнительной настройки. Однако для доступа к службам расположения необходимо указать нужные запросы служб расположения в Info.plist. Обычно они будут одним или несколькими из следующих:
-
NSLocationAlwaysAndWhenInUseUsageDescription
— для использования служб геолокации в любое время. -
NSLocationWhenInUseUsageDescription
— для использования служб расположения при использовании приложения.
Для получения дополнительной информации см. на сайте developer.apple.com раздел «Выбор уровня доступа к службам геолокации для запроса».
Ниже показано xml-представление этих ключей в Info.plist. Необходимо обновить значения string
, чтобы отразить, как ваше приложение использует сведения о расположении:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Can we use your location at all times?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can we use your location when your app is being used?</string>
Затем появится запрос, когда приложение пытается получить доступ к расположению пользователя, запрашивая доступ:
Андроид
Процесс конфигурации для отображения и взаимодействия с картой в Android — это:
- Получите ключ API Google Maps и добавьте его в манифест приложения.
- Укажите номер версии служб Google Play в манифесте.
- [необязательно] Укажите разрешения расположения в манифесте.
- [необязательно] Укажите разрешение WRITE_EXTERNAL_STORAGE в манифесте.
Получение ключа API Google Maps
Чтобы использовать элемент управления Map на Android, необходимо создать ключ API, который будет использоваться пакетом SDK Google Maps , от которого элемент управления Map зависит в Android. Для этого следуйте инструкциям по настройке в Google Cloud Console и использованию ключей API на developers.google.com.
Получив ключ API, его необходимо добавить в элемент <application>
файла Platform/Android/AndroidManifest.xml, указав его в качестве значения метаданных com.google.android.geo.API_KEY
:
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
<meta-data android:name="com.google.android.geo.API_KEY" android:value="PASTE-YOUR-API-KEY-HERE" />
</application>
Это внедряет ключ API в манифест. Без допустимого ключа API элемент управления Map отобразит пустую сетку.
Заметка
com.google.android.geo.API_KEY
— это рекомендуемое имя метаданных для ключа API. Ключ с таким именем можно использовать для проверки подлинности нескольких API на основе Google Maps в Android. Для обратной совместимости можно использовать имя метаданных com.google.android.maps.v2.API_KEY
, но разрешает только проверку подлинности в Android Maps API v2. Приложение может указать только одно из имен метаданных ключа API.
Укажите номер версии служб Google Play
Добавьте следующее объявление в элемент <application>
AndroidManifest.xml:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Это внедряет версию служб Google Play, с которыми было скомпилировано приложение, в манифест.
Указание разрешений на доступ к местоположению
Если вашему приложению необходимо получить доступ к геопозиции пользователя, вы должны запросить разрешение, добавив разрешение ACCESS_COARSE_LOCATION
или ACCESS_FINE_LOCATION
(или оба) в манифест в качестве дочернего элемента <manifest>
.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<!-- Required to access the user's location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>
Разрешение ACCESS_COARSE_LOCATION
позволяет API использовать wi-fi или мобильные данные или оба, чтобы определить расположение устройства. Разрешения ACCESS_FINE_LOCATION
позволяют API использовать глобальную систему позиционирования (GPS), Wi-Fi или мобильные данные, чтобы определить точное расположение.
Затем появится запрос, когда приложение пытается получить доступ к расположению пользователя, запрашивая доступ:
Кроме того, эти разрешения можно включить в редакторе манифестов Android в Visual Studio.
Укажите разрешение WRITE_EXTERNAL_STORAGE, которое позволяет приложению записывать данные на внешнее хранилище.
Если приложение предназначено для API 22 или ниже, необходимо добавить разрешение WRITE_EXTERNAL_STORAGE
в манифест в качестве дочернего элемента <manifest>
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Это не обязательно, если приложение предназначено для API 23 или более поздней версии.
Элемент управления картой
Класс Map определяет следующие свойства, управляющие внешним видом и поведением карты:
-
IsShowingUser
типаbool
указывает, отображается ли карта текущего расположения пользователя. -
ItemsSource
типаIEnumerable
, который указывает коллекцию элементов закрепленияIEnumerable
для отображения. -
ItemTemplate
типа DataTemplate, который задает DataTemplate, чтобы применить к каждому элементу в коллекции отображаемых значков. -
ItemTemplateSelector
типа DataTemplateSelector, который указывает DataTemplateSelector, который будет использоваться для выбора DataTemplate для пин-кода во время выполнения. -
IsScrollEnabled
типаbool
определяет, разрешено ли прокручивать карту. -
IsTrafficEnabled
типаbool
указывает, нанесены ли данные о движении на карту. -
IsZoomEnabled
типаbool
определяет, разрешено ли масштабирование карты. -
MapElements
типаIList<MapElement>
представляет список элементов на карте, таких как многоугольники и многолинейные линии. -
MapType
типаMapType
указывает стиль отображения карты. -
Pins
типаIList<Pin>
представляет список меток на карте. -
VisibleRegion
типаMapSpan
возвращает регион карты, который отображается в данный момент.
Эти свойства, за исключением MapElements
, Pins
и VisibleRegion
свойств, поддерживаются объектами BindableProperty, что означает, что они могут быть целевыми объектами привязки данных.
Класс Map также определяет событие MapClicked
, которое запускается при нажатии карты. Объект MapClickedEventArgs
, который сопровождает событие, имеет единственное свойство с именем Location
типа Location
. При срабатывании события свойству Location
присваивается местоположение на карте, в которое произошло касание. Сведения о классе Location
см. в разделе Расположение и расстояние.
Сведения о свойствах ItemsSource
, ItemTemplate
и ItemTemplateSelector
см. в разделе Отображение коллекции закреплений.
Отображение карты
Map можно отобразить, добавив его в макет или страницу:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<maps:Map x:Name="map" />
</ContentPage>
Эквивалентный код C#:
using Map = Microsoft.Maui.Controls.Maps.Map;
namespace WorkingWithMaps
{
public class MapTypesPageCode : ContentPage
{
public MapTypesPageCode()
{
Map map = new Map();
Content = map;
}
}
}
В этом примере вызывается конструктор Map по умолчанию, который располагает карту в центре острова Мауи, Гавайи.
Кроме того, аргумент MapSpan
можно передать в конструктор Map, чтобы задать центральную точку и уровень масштабирования карты при загрузке. Дополнительные сведения см. в разделе Отображение определенного расположения на карте.
Важный
.NET MAUI имеет два типа Map
— Microsoft.Maui.Controls.Maps.Map и Microsoft.Maui.ApplicationModel.Map. Так как пространство имен Microsoft.Maui.ApplicationModel является одной из директив global using
в .NET MAUI, при использовании элемента управления Microsoft.Maui.Controls.Maps.Map из кода необходимо полностью квалифицировать использование Map
или воспользоваться с псевдонимом.
Типы карт
Свойство Map.MapType
можно задать элементом перечисления MapType
, чтобы определить стиль отображения карты. Перечисление MapType
определяет следующие элементы:
-
Street
указывает, что будет отображаться карта улиц. -
Satellite
указывает, что будет отображаться карта, содержащая спутниковые изображения. -
Hybrid
указывает, что будет отображаться карта, объединяющая данные улиц и спутников.
По умолчанию Map будет отображать карту улиц, если свойство MapType
не определено. Кроме того, свойство MapType
можно задать для одного из элементов перечисления MapType
:
<maps:Map MapType="Satellite" />
Эквивалентный код C#:
Map map = new Map
{
MapType = MapType.Satellite
};
Отображение определенного расположения на карте
Область карты, отображаемой при загрузке карты, можно задать путем передачи аргумента MapSpan
конструктору Map:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<x:Arguments>
<maps:MapSpan>
<x:Arguments>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
<x:Double>0.01</x:Double>
<x:Double>0.01</x:Double>
</x:Arguments>
</maps:MapSpan>
</x:Arguments>
</maps:Map>
</ContentPage>
Эквивалентный код C#:
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Location location = new Location(36.9628066, -122.0194722);
MapSpan mapSpan = new MapSpan(location, 0.01, 0.01);
Map map = new Map(mapSpan);
В этом примере создается объект Map, показывающий регион, заданный объектом MapSpan
. Объект MapSpan
сосредоточен на широте и долготе, представленной объектом Location
, и охватывает 0,01 широты и 0,01 градуса долготы. Сведения о классе Location
см. в разделе Расположение и расстояние. Сведения о передаче аргументов в XAML можно найти в разделе Pass arguments in XAML.
Результатом является то, что при отображении карты он сосредоточен на определенном расположении и охватывает определенное количество широт и долгот:
Создание объекта MapSpan
Существует ряд подходов к созданию объектов MapSpan
. Распространенный подход заключается в предоставлении необходимых аргументов конструктору MapSpan
. Это широта и долгота, представленные объектом Location
, и double
значения, представляющие градусы широты и долготы, охватываемые MapSpan
. Сведения о классе Location
см. в разделе Расположение и расстояние.
Кроме того, в классе MapSpan
есть три метода, которые возвращают новые объекты MapSpan
:
-
ClampLatitude
возвращаетMapSpan
с тем жеLongitudeDegrees
, что и экземпляр класса метода, и радиус, который определяется его аргументамиnorth
иsouth
. -
FromCenterAndRadius
возвращаетMapSpan
, определяемый его аргументамиLocation
иDistance
. -
WithZoom
возвращаетMapSpan
с тем же центром, что и экземпляр класса метода, но с радиусом, умноженным на его аргументdouble
.
Сведения о структуре Distance
см. в разделе Расположение и расстояние.
После создания MapSpan
можно получить доступ к следующим свойствам, чтобы получить данные об этом:
-
Center
типаLocation
, представляющий расположение в географическом центреMapSpan
. -
LatitudeDegrees
типаdouble
, который представляет степень широты, охватываемойMapSpan
. -
LongitudeDegrees
типаdouble
, который представляет степень долготы, охватываемойMapSpan
. -
Radius
типаDistance
, который представляет радиусMapSpan
.
Перемещение карты
Метод Map.MoveToRegion
можно вызвать для изменения положения и масштаба карты. Этот метод принимает аргумент MapSpan
, определяющий область отображения карты и его уровень масштабирования.
В следующем коде показан пример перемещения отображаемой области на карте:
using Microsoft.Maui.Maps;
using Microsoft.Maui.Controls.Maps.Map;
...
MapSpan mapSpan = MapSpan.FromCenterAndRadius(location, Distance.FromKilometers(0.444));
map.MoveToRegion(mapSpan);
Масштабирование карты
Уровень масштабирования Map можно изменить, не изменив его расположение. Это можно сделать с помощью пользовательского интерфейса карты или программно путем вызова метода MoveToRegion
с аргументом MapSpan
, который использует текущее расположение в качестве аргумента Location
:
double zoomLevel = 0.5;
double latlongDegrees = 360 / (Math.Pow(2, zoomLevel));
if (map.VisibleRegion != null)
{
map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongDegrees, latlongDegrees));
}
В этом примере метод MoveToRegion
вызывается с аргументом MapSpan
, который указывает текущее расположение карты через свойство Map.VisibleRegion
и уровень масштабирования в виде градусов широты и долготы. Общий результат заключается в том, что уровень масштабирования карты изменяется, но она остаётся на месте. Альтернативный подход к реализации масштабирования карты — использовать метод MapSpan.WithZoom
для управления коэффициентом масштабирования.
Важный
Масштабирование карты с помощью пользовательского интерфейса карты или программы требует, чтобы свойство Map.IsZoomEnabled
было true
. Дополнительные сведения об этом свойстве см. в разделе Отключение масштабирования.
Настройка поведения карты
Поведение Map можно настроить, задав некоторые его свойства и обрабатывая событие MapClicked
.
Заметка
Дополнительная настройка поведения карты может быть достигнута путем настройки обработчика. Дополнительные сведения см. в разделе Настройка элементов управления с помощью обработчиков.
Отображение данных трафика
Класс Map определяет свойство IsTrafficEnabled
типа bool
. По умолчанию это свойство false
, что указывает на то, что данные трафика не будут отображаться на карте. Если для этого свойства задано значение true
, данные трафика накладываются на карту:
<maps:Map IsTrafficEnabled="true" />
Эквивалентный код C#:
Map map = new Map
{
IsTrafficEnabled = true
};
Отключение прокрутки
Класс Map определяет свойство IsScrollEnabled
типа bool
. По умолчанию это свойство true
, указывающее, что карта разрешена для прокрутки. Если для этого свойства задано значение false
, карта не будет прокручиваться:
<maps:Map IsScrollEnabled="false" />
Эквивалентный код C#:
Map map = new Map
{
IsScrollEnabled = false
};
Отключение масштабирования
Класс Map определяет свойство IsZoomEnabled
типа bool
. По умолчанию это свойство true
, указывающее, что масштабирование можно выполнить на карте. Если для этого свойства задано значение false
, карта не может быть увеличена:
<maps:Map IsZoomEnabled="false" />
Эквивалентный код C#:
Map map = new Map
{
IsZoomEnabled = false
};
Отображение расположения пользователя
Класс Map определяет свойство IsShowingUser
типа bool
. По умолчанию это свойство false
, указывающее, что карта не отображает текущее расположение пользователя. Если для этого свойства задано значение true
, на карте отображается текущее расположение пользователя:
<maps:Map IsShowingUser="true" />
Эквивалентный код C#:
Map map = new Map
{
IsShowingUser = true
};
Важный
Для доступа к расположению пользователя требуется разрешение на расположение, которое было предоставлено приложению. Дополнительные сведения см. в конфигурации платформы.
Нажатия на карту
Класс Map определяет событие MapClicked
, которое запускается при нажатии карты. Объект MapClickedEventArgs
, который сопровождает событие, имеет одно свойство с именем Location
типа Location
. При срабатывании события свойство Location
задается расположением карты, по которому было нажато. Сведения о классе Location
см. в разделе Расположение и расстояние.
В следующем примере кода показан обработчик событий для события MapClicked
:
void OnMapClicked(object sender, MapClickedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"MapClick: {e.Location.Latitude}, {e.Location.Longitude}");
}
В этом примере обработчик событий OnMapClicked
выводит широту и долготу, представляющие место на карте, выбранное нажатием. Обработчик событий должен быть зарегистрирован в событии MapClicked
:
<maps:Map MapClicked="OnMapClicked" />
Эквивалентный код C#:
Map map = new Map();
map.MapClicked += OnMapClicked;
Расположение и расстояние
Пространство имен Microsoft.Maui.Devices.Sensors
содержит класс Location
, который обычно используется при расположении карты и её меток. Пространство имен Microsoft.Maui.Maps
содержит структуру Distance
, которую можно использовать по выбору при расположении карты.
Местоположение
Класс Location
инкапсулирует расположение, хранящееся в виде значений широты и долготы. Этот класс определяет следующие свойства:
-
Accuracy
типаdouble?
, представляющая горизонтальную точностьLocation
в метрах. -
Altitude
типаdouble?
, представляющий высоту в метрах в системе отсчета, определяемой свойствомAltitudeReferenceSystem
. -
AltitudeReferenceSystem
типаAltitudeReferenceSystem
, который указывает эталонную систему, в которой предоставляется значение высоты. -
Course
типаdouble?
, указывающее значение градусов относительно истинного севера. -
IsFromMockProvider
типаbool
, который указывает, является ли местоположение от GPS или симулятора местоположения. -
Latitude
типаdouble
, который представляет географическую широту в десятичных градусах. -
Longitude
типаdouble
, представляющий собой долготу местоположения в десятичных градусах. -
Speed
типаdouble?
, который представляет скорость в метрах в секунду. -
Timestamp
типаDateTimeOffset
, представляющий отметку времени, когда был созданLocation
. -
VerticalAccuracy
, типаdouble?
, который указывает вертикальную точностьLocation
в метрах.
Location
объекты создаются с помощью одной из перегрузок конструктора Location
, которые обычно требуют широты и долготы в качестве минимально необходимых аргументов, указанных как значения double
.
Location location = new Location(36.9628066, -122.0194722);
При создании объекта Location
значение широты будет зажато в диапазоне от –90,0 до 90,0, а значение долготы будет зажато в диапазоне от –180,0 до 180,0.
Заметка
Класс GeographyUtils
имеет метод расширения ToRadians
, который преобразует значение double
из градусов в радианы и метод расширения ToDegrees
, который преобразует значение double
из радианов в градусы.
Класс Location
также имеет методы CalculateDistance
, которые вычисляют расстояние между двумя расположениями.
Расстояние
Структура Distance
инкапсулирует расстояние, хранящееся как значение double
, которое представляет расстояние в метрах. Эта структура определяет три доступные только для чтения свойства.
-
Kilometers
типаdouble
, который представляет расстояние в километрах, охватываемыхDistance
. -
Meters
типаdouble
, который представляет расстояние в метрах, охватываемоеDistance
. -
Miles
типаdouble
, который представляет расстояние в милях, охватываемыхDistance
.
Distance
объекты можно создать с помощью конструктора Distance
, который требует аргумента метров, заданного как double
:
Distance distance = new Distance(1450.5);
Кроме того, объекты Distance
можно создавать с помощью методов фабрики FromKilometers
, FromMeters
, FromMiles
и BetweenPositions
.
Distance distance1 = Distance.FromKilometers(1.45); // argument represents the number of kilometers
Distance distance2 = Distance.FromMeters(1450.5); // argument represents the number of meters
Distance distance3 = Distance.FromMiles(0.969); // argument represents the number of miles
Distance distance4 = Distance.BetweenPositions(location1, location2);
Штифты
Элемент управления Map позволяет помечать расположения объектами Pin
.
Pin
— это маркер карты, который открывает окно сведений при нажатии:
Когда объект Pin
добавляется в коллекцию Map.Pins
, значок отображается на карте.
Класс Pin
имеет следующие свойства:
-
Address
типаstring
, который обычно представляет адрес расположения пин-кода. Однако это может быть любое содержимоеstring
, а не только адресом. -
Labelтипа
string
, который обычно представляет заголовок пин-кода. -
Location
типаLocation
, который представляет широту и долготу пин-кода. -
Type
типаPinType
, который представляет тип вывода.
Эти свойства поддерживаются объектами BindableProperty, что означает, что Pin
может быть целью привязки данных. Дополнительные сведения об объектах привязки данных Pin
см. раздел Отображение коллекции закреплений.
Кроме того, класс Pin
определяет события MarkerClicked
и InfoWindowClicked
. Событие MarkerClicked
запускается при нажатии пин-кода и событие InfoWindowClicked
запускается при нажатии окна информации. Объект PinClickedEventArgs
, который сопровождает оба события, имеет одно свойство HideInfoWindow
типа bool
.
Отображение пин-кода
Pin
можно добавить в Map в XAML:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map x:Name="map">
<x:Arguments>
<maps:MapSpan>
<x:Arguments>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
<x:Double>0.01</x:Double>
<x:Double>0.01</x:Double>
</x:Arguments>
</maps:MapSpan>
</x:Arguments>
<maps:Map.Pins>
<maps:Pin Label="Santa Cruz"
Address="The city with a boardwalk"
Type="Place">
<maps:Pin.Location>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
</maps:Pin.Location>
</maps:Pin>
</maps:Map.Pins>
</maps:Map>
</ContentPage>
Этот XAML создает объект Map, показывающий регион, заданный объектом MapSpan
. Объект MapSpan
сосредоточен на широте и долготе, представленных объектом Location
, который охватывает диапазон 0,01 градуса широты и долготы. Объект Pin
добавляется в коллекцию Map.Pins
и рисуется на Map в расположении, указанном свойством Location
. Сведения о классе Location
см. в разделе Расположение и расстояние. Сведения о передаче аргументов в XAML в объекты, которые не имеют конструкторов по умолчанию, см. в статье Передавать аргументы в XAML.
Эквивалентный код C#:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map
{
...
};
Pin pin = new Pin
{
Label = "Santa Cruz",
Address = "The city with a boardwalk",
Type = PinType.Place,
Location = new Location(36.9628066, -122.0194722)
};
map.Pins.Add(pin);
Этот пример кода отображает одну метку на карте.
Взаимодействие с пином
По умолчанию при нажатии Pin
отображается информационное окно.
Касание в другом месте карты закрывает окно сведений.
Класс Pin
определяет событие MarkerClicked
, которое запускается при нажатии Pin
. Для отображения окна сведений не требуется обрабатывать это событие. Вместо этого это событие должно обрабатываться, когда требуется уведомить о том, что определенный пин-код был нажат.
Класс Pin
также определяет событие InfoWindowClicked
, которое запускается при нажатии окна информации. Это событие должно обрабатываться, когда необходимо уведомить о том, что коснулись конкретного окна со сведениями.
В следующем коде показан пример обработки этих событий:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Pin boardwalkPin = new Pin
{
Location = new Location(36.9641949, -122.0177232),
Label = "Boardwalk",
Address = "Santa Cruz",
Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
args.HideInfoWindow = true;
string pinName = ((Pin)s).Label;
await DisplayAlert("Pin Clicked", $"{pinName} was clicked.", "Ok");
};
Pin wharfPin = new Pin
{
Location = new Location(36.9571571, -122.0173544),
Label = "Wharf",
Address = "Santa Cruz",
Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
string pinName = ((Pin)s).Label;
await DisplayAlert("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};
Объект PinClickedEventArgs
, который сопровождает оба события, имеет одно свойство HideInfoWindow
типа bool
. Если для этого свойства задано значение true
внутри обработчика событий, окно сведений будет скрыто.
Типы штырей
Объекты Pin
включают свойство Type
типа PinType
, представляющее тип штыка. Перечисление PinType
определяет следующие элементы:
-
Generic
представляет универсальный пин-код. -
Place
, представляет пин-код для места. -
SavedPin
представляет пин-код для сохраненного расположения. -
SearchResult
представляет пин-код для результата поиска.
Однако установка свойства Pin.Type
на любого участника PinType
не изменяет внешний вид отрисованного значка. Вместо этого необходимо настроить обработчик Pin
для изменения внешнего вида пинов. Дополнительные сведения о настройке обработчика см. в разделе Настройка элементов управления с помощью обработчиков.
Отображение коллекции значков
Класс Map определяет следующие привязываемые свойства:
-
ItemsSource
типаIEnumerable
, который указывает коллекцию элементов для отображения закрепленийIEnumerable
. -
ItemTemplate
типа DataTemplate, который задает DataTemplate для применения к каждому элементу коллекции отображаемых значков. -
ItemTemplateSelector
типа DataTemplateSelector, который указывает DataTemplateSelector, который будет использоваться для выбора DataTemplate для пин-кода во время выполнения.
Важный
Свойство ItemTemplate
имеет приоритет, если заданы свойства ItemTemplate
и ItemTemplateSelector
.
Map можно заполнить элементами, используя привязку данных для связи его свойства ItemsSource
с коллекцией IEnumerable
.
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<Grid>
...
<maps:Map x:Name="map"
ItemsSource="{Binding Positions}">
<maps:Map.ItemTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>
...
</Grid>
</ContentPage>
Данные свойства ItemsSource
привязываются к свойству Positions
подключенного модуля представления, который возвращает ObservableCollection
объектов Position
, который является пользовательским типом. Каждый объект Position
определяет свойства Address
и Description
типа string
, а также свойство Location
типа Location
.
Внешний вид каждого элемента в коллекции IEnumerable
определяется путем задания свойства ItemTemplate
DataTemplate, содержащего объект Pin
, который привязывает данные к соответствующим свойствам.
На следующем снимку экрана показана Map, отображающая коллекцию Pin
с помощью привязки данных:
Выбор внешнего вида элемента во время выполнения
Внешний вид каждого элемента в коллекции IEnumerable
можно выбрать во время выполнения на основе значения элемента, задав для свойства ItemTemplateSelector
значение DataTemplateSelector:
<ContentPage ...
xmlns:templates="clr-namespace:WorkingWithMaps.Templates"
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<ContentPage.Resources>
<templates:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
<templates:MapItemTemplateSelector.DefaultTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</templates:MapItemTemplateSelector.DefaultTemplate>
<templates:MapItemTemplateSelector.SanFranTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="Xamarin!" />
</DataTemplate>
</templates:MapItemTemplateSelector.SanFranTemplate>
</templates:MapItemTemplateSelector>
</ContentPage.Resources>
<Grid>
...
<maps:Map x:Name="map"
ItemsSource="{Binding Positions}"
ItemTemplateSelector="{StaticResource MapItemTemplateSelector}">
...
</Grid>
</ContentPage>
В следующем примере показан класс MapItemTemplateSelector
:
using WorkingWithMaps.Models;
namespace WorkingWithMaps.Templates;
public class MapItemTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate SanFranTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Position)item).Address.Contains("San Francisco") ? SanFranTemplate : DefaultTemplate;
}
}
Класс MapItemTemplateSelector
определяет свойства DefaultTemplate
и SanFranTemplate
DataTemplate, которые задаются различными шаблонами данных. Метод OnSelectTemplate
возвращает SanFranTemplate
, который отображает "Xamarin" в виде метки при нажатии Pin
, когда элемент содержит адрес, содержащий "Сан-Франциско". Если элемент не содержит адрес, содержащий "Сан-Франциско", метод OnSelectTemplate
возвращает DefaultTemplate
.
Заметка
Вариант использования этой функции — привязка свойств подклассированных Pin
объектов к разным свойствам на основе подтипа Pin
.
Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание DataTemplateSelector".
Многоугольники, полилайны и круги
Polygon
, Polyline
и элементы Circle
позволяют выделить определенные области на карте.
Polygon
— это фигура с полностью замкнутым контуром, которая может иметь цвет обводки и заливки.
Polyline
— это линия, которая не полностью ограничивает область.
Circle
выделяет круговую область карты:
Классы Polygon
, Polyline
и Circle
являются производными от класса MapElement
, который предоставляет следующие привязываемые свойства:
-
StrokeColor
— это объект Color, определяющий цвет линии. -
StrokeWidth
— это объектfloat
, определяющий ширину линии.
Класс Polygon
определяет дополнительное привязываемое свойство:
-
FillColor
— это объект Color, определяющий цвет фона многоугольника.
Кроме того, классы Polygon
и Polyline
определяют свойство GeoPath
, которое представляет собой список объектов Location
, указывающих точки фигуры.
Класс Circle
определяет следующие привязываемые свойства:
-
Center
— это объектLocation
, определяющий центр круга в широте и долготе. -
Radius
— это объектDistance
, определяющий радиус круга в метрах, километрах или милях. -
FillColor
— это свойство Color, определяющее цвет в периметре круга.
Создание многоугольника
Объект Polygon
можно добавить на карту, создав его и добавив его в коллекцию MapElements
карты:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Polygon StrokeColor="#FF9900"
StrokeWidth="8"
FillColor="#88FF9900">
<maps:Polygon.Geopath>
<sensors:Location>
<x:Arguments>
<x:Double>47.6458676</x:Double>
<x:Double>-122.1356007</x:Double>
</x:Arguments>
</sensors:Location>
<sensors:Location>
<x:Arguments>
<x:Double>47.6458097</x:Double>
<x:Double>-122.142789</x:Double>
</x:Arguments>
</sensors:Location>
...
</maps:Polygon.Geopath>
</maps:Polygon>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Эквивалентный код C#:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map();
// Instantiate a polygon
Polygon polygon = new Polygon
{
StrokeWidth = 8,
StrokeColor = Color.FromArgb("#1BA1E2"),
FillColor = Color.FromArgb("#881BA1E2"),
Geopath =
{
new Location(47.6368678, -122.137305),
new Location(47.6368894, -122.134655),
...
}
};
// Add the polygon to the map's MapElements collection
map.MapElements.Add(polygon);
Свойства StrokeColor
и StrokeWidth
указываются для задания структуры многоугольника. В этом примере значение свойства FillColor
соответствует значению свойства StrokeColor
, но имеет альфа-значение, указанное для прозрачности, что позволяет базовой карте отображаться через фигуру. Свойство GeoPath
содержит список объектов Location
, определяющих географические координаты точек многоугольника. Объект Polygon
отображается на карте после добавления в коллекцию MapElements
Map.
Заметка
Polygon
— это полностью заключенная фигура. Первые и последние точки будут автоматически соединены, если они не совпадают.
Создание полилайна
Объект Polyline
можно добавить на карту, создав его и добавив его в коллекцию MapElements
карты:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Polyline StrokeColor="Black"
StrokeWidth="12">
<maps:Polyline.Geopath>
<sensors:Location>
<x:Arguments>
<x:Double>47.6381401</x:Double>
<x:Double>-122.1317367</x:Double>
</x:Arguments>
</sensors:Location>
<sensors:Location>
<x:Arguments>
<x:Double>47.6381473</x:Double>
<x:Double>-122.1350841</x:Double>
</x:Arguments>
</sensors:Location>
...
</maps:Polyline.Geopath>
</maps:Polyline>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Эквивалентный код C#:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map();
// instantiate a polyline
Polyline polyline = new Polyline
{
StrokeColor = Colors.Blue,
StrokeWidth = 12,
Geopath =
{
new Location(47.6381401, -122.1317367),
new Location(47.6381473, -122.1350841),
...
}
};
// Add the Polyline to the map's MapElements collection
map.MapElements.Add(polyline);
Свойства StrokeColor
и StrokeWidth
указываются для задания внешнего вида строки. Свойство GeoPath
содержит список объектов Location
, определяющих географические координаты точек полилайна. Объект Polyline
отображается на карте после того, как его добавили в коллекцию MapElements
системы Map.
Создание круга
Объект Circle
можно добавить на карту, создав его и добавив его в коллекцию MapElements
карты:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Circle StrokeColor="#88FF0000"
StrokeWidth="8"
FillColor="#88FFC0CB">
<maps:Circle.Center>
<sensors:Location>
<x:Arguments>
<x:Double>37.79752</x:Double>
<x:Double>-122.40183</x:Double>
</x:Arguments>
</sensors:Location>
</maps:Circle.Center>
<maps:Circle.Radius>
<maps:Distance>
<x:Arguments>
<x:Double>250</x:Double>
</x:Arguments>
</maps:Distance>
</maps:Circle.Radius>
</maps:Circle>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Эквивалентный код C#:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
Map map = new Map();
// Instantiate a Circle
Circle circle = new Circle
{
Center = new Location(37.79752, -122.40183),
Radius = new Distance(250),
StrokeColor = Color.FromArgb("#88FF0000"),
StrokeWidth = 8,
FillColor = Color.FromArgb("#88FFC0CB")
};
// Add the Circle to the map's MapElements collection
map.MapElements.Add(circle);
Расположение Circle
на карте определяется значением свойств Center
и Radius
. Свойство Center
определяет центр круга в широте и долготе, а свойство Radius
определяет радиус круга в метрах. Свойства StrokeColor
и StrokeWidth
указываются для задания контура круга. Значение свойства FillColor
указывает цвет в периметре круга. В этом примере оба значения цвета указывают альфа-канал, что позволяет базовой карте отображаться через круг. Объект Circle
отображается на карте после того, как он был добавлен в коллекцию MapElements
объекта Map.
Заметка
Класс GeographyUtils
имеет метод расширения ToCircumferencePositions
, который преобразует объект Circle
(который определяет значения свойств Center
и Radius
) в список Location
объектов, составляющих координаты широты и долготы периметра круга.
Геокодирование и геолокация
Класс Geocoding
в пространстве имен Microsoft.Maui.Devices.Sensors
можно использовать для геокодирования метки в позиционные координаты и обратного геокодирования координат в метку. См. для получения дополнительной информации по геокодированию.
Класс Geolocation
в пространстве имен Microsoft.Maui.Devices.Sensors
можно использовать для получения текущих координат географического расположения устройства. Дополнительные сведения см. в о геолокации.
Запуск собственного приложения карты
Собственное приложение карты на каждой платформе можно запустить из приложения .NET MAUI с помощью класса Launcher
. Этот класс позволяет приложению открывать другое приложение с помощью пользовательской схемы URI. Функции средства запуска можно вызвать с помощью метода OpenAsync
, передавая string
или Uri
аргумент, представляющий пользовательскую схему URL-адресов для открытия. Дополнительные сведения о классе Launcher
см. в разделе Launcher.
Заметка
Альтернативой использованию класса Launcher
является использование класса Map из пространства имен Microsoft.Maui.ApplicationModel
. Дополнительные сведения см. в разделе Map.
Приложение карт на каждой платформе использует уникальную настраиваемую схему URI. Сведения о схеме URI для карт в iOS см. в секции Ссылки на карты на сайте developer.apple.com. Сведения о схеме URI карт для Android см. в руководстве разработчика карт и интенты Google Maps для Android на сайте developers.android.com. Сведения о схеме URI карт в Windows см. в разделе Запуск приложения "Карты Windows".
Открыть приложение карты в определенной точке
Расположение в приложении собственных карт можно открыть, добавив соответствующие параметры запроса в настраиваемую схему URI для каждого приложения карты:
if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
// https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
await Launcher.OpenAsync("http://maps.apple.com/?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
// opens the Maps app directly
await Launcher.OpenAsync("geo:0,0?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
await Launcher.OpenAsync("bingmaps:?where=394 Pacific Ave San Francisco CA");
}
В этом примере код приводит к запуску стандартного приложения карт на каждой платформе, при этом карта центрируется на метке, представляющей указанное местоположение.
Запуск приложения карты с указаниями
Приложение собственных карт можно запустить, отображая направления, добавив соответствующие параметры запроса в настраиваемую схему URI для каждого приложения карты:
if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
// https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
await Launcher.OpenAsync("http://maps.apple.com/?daddr=San+Francisco,+CA&saddr=cupertino");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
// opens the 'task chooser' so the user can pick Maps, Chrome or other mapping app
await Launcher.OpenAsync("http://maps.google.com/?daddr=San+Francisco,+CA&saddr=Mountain+View");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
await Launcher.OpenAsync("bingmaps:?rtp=adr.394 Pacific Ave San Francisco CA~adr.One Microsoft Way Redmond WA 98052");
}
Этот пример кода приводит к запуску встроенного приложения карты на каждой платформе, с картой, центрированной на маршруте между указанными местоположениями.