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


Карта

Просмотрите пример. Обзор примера

Элемент управления многоплатформенный пользовательский интерфейс приложения .NET (.NET MAUI) Map — это кроссплатформенное представление для отображения и аннотирования карт. Элемент 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 его необходимо инициализировать в приложении, вызвав UseMauiMap метод в объекте 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();
    }
}

После добавления и инициализации Map пакета NuGet api можно использовать в проекте.

Конфигурация платформы

Дополнительная конфигурация требуется в Android, прежде чем карта будет отображаться. Кроме того, в iOS, Android и Mac Catalyst доступ к расположению пользователя требует предоставления приложению разрешений на расположение.

IOS и Mac Catalyst

Отображение и взаимодействие с картой в iOS и Mac Catalyst не требует дополнительной настройки. Однако для доступа к службам расположения необходимо задать необходимые запросы служб расположения в Info.plist. Обычно они будут одним или несколькими из следующих:

Дополнительные сведения см. в разделе Выбор авторизации служб расположения для запроса по 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>

Затем появится запрос, когда приложение пытается получить доступ к расположению пользователя, запрашивая доступ:

Снимок экрана: запрос на разрешение расположения в iOS.

Android

Процесс конфигурации для отображения и взаимодействия с картой в Android — это:

  1. Получите ключ API Google Maps и добавьте его в манифест приложения.
  2. Укажите номер версии служб Google Play в манифесте.
  3. [необязательно] Укажите разрешения расположения в манифесте.
  4. [необязательно] Укажите разрешение 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 можно использовать имя метаданных, но только разрешает проверку подлинности в API Карт Android версии 2. Приложение может указать только одно из имен метаданных ключа 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.

Кроме того, эти разрешения можно включить в редакторе манифестов Android в Visual Studio.

Укажите разрешение WRITE_EXTERNAL_STORAGE

Если приложение предназначено для API 22 или ниже, необходимо добавить WRITE_EXTERNAL_STORAGE разрешение в манифест в качестве дочернего <manifest> элемента:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Это не обязательно, если приложение предназначено для API 23 или более поздней версии.

Элемент управления Карта

Класс Map определяет следующие свойства, управляющие внешним видом и поведением карты:

  • IsShowingUserboolТип , указывает, отображает ли карта текущее расположение пользователя.
  • ItemsSourceТип IEnumerable, который указывает коллекцию отображаемых элементов пин-кода IEnumerable .
  • ItemTemplateтип DataTemplate, который указывает DataTemplate , что применяется к каждому элементу в коллекции отображаемых закреплений.
  • ItemTemplateSelectorТип DataTemplateSelector, который указывает DataTemplateSelector , что будет использоваться для выбора DataTemplate пин-кода во время выполнения.
  • IsScrollEnabledboolТип , определяет, разрешено ли прокручивать карту.
  • IsTrafficEnabledboolТип , указывает, наложены ли данные трафика на карту.
  • IsZoomEnabledboolТип , определяет, разрешено ли масштабирование карты.
  • MapElementsIList<MapElement>Тип , представляет список элементов на карте, таких как многоугольники и многолинейные линии.
  • MapTypeMapTypeТип , указывает стиль отображения карты.
  • PinsIList<Pin>Тип , представляет список закреплений на карте.
  • VisibleRegion, типа MapSpan, возвращает отображаемую в данный момент область карты.

Эти свойства, за исключением MapElementsсвойств и PinsVisibleRegion свойств, поддерживаются объектами, что означает, что они могут быть целевыми BindableProperty объектами привязки данных.

Класс Map также определяет MapClicked событие, которое запускается при нажатии карты. Объект MapClickedEventArgs , который сопровождает событие, имеет одно свойство с именем Locationтипа Location. Когда событие запускается, Location свойство задается в расположении карты, которое было касалось. Сведения о классе см. в Location разделе "Расположение и расстояние".

Сведения о свойствах ItemTemplateи свойствах см. в ItemsSourceразделе "Отображение коллекции закрепления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 Так как пространство имен является одной из директив MAUI global using .NET, при использовании 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 см. в разделе "Передача аргументов" в XAML.

Результатом является то, что при отображении карты он сосредоточен на определенном расположении и охватывает определенное количество широт и долгот:

Снимок экрана: элемент управления картой с указанным расположением.

Создание объекта MapSpan

Существует ряд подходов к созданию MapSpan объектов. Распространенный подход — предоставление необходимых аргументов конструктору MapSpan . Это широта и долгота, представленные Location объектом, и double значения, представляющие градусы широты и долготы, охватываемые объектом MapSpan. Сведения о классе см. в Location разделе "Расположение и расстояние".

Кроме того, в MapSpan классе есть три метода, возвращающие новые MapSpan объекты:

  1. ClampLatitude возвращает объект MapSpan с таким же LongitudeDegrees , как экземпляр класса метода, и радиус, определенный его north и south аргументами.
  2. FromCenterAndRadius возвращает объект, определенный MapSpan его Location и Distance аргументами.
  3. WithZoomMapSpan возвращает значение с тем же центром, что и экземпляр класса метода, но с радиусом, умноженным на его double аргумент.

Сведения о структуре см. в Distance разделе "Расположение и расстояние".

MapSpan После создания можно получить доступ к следующим свойствам, чтобы получить данные об этом:

  • Centerтипа Location, который представляет расположение в географическом центре объекта MapSpan.
  • LatitudeDegrees, тип double, представляющий степень широты, охватываемой MapSpan.
  • LongitudeDegrees, тип double, представляющий градусы долготы, охватываемые элементом MapSpan.
  • RadiusDistanceтип, представляющий 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 инкапсулирует расположение, хранящееся в виде значений широты и долготы. Этот класс определяет приведенные ниже свойства.

  • Accuracydouble?типа, который представляет горизонтальную точность Location, в метрах.
  • Altitudedouble?тип, представляющий высоту в метрах в эталонной системе, указанной свойствомAltitudeReferenceSystem.
  • AltitudeReferenceSystemтип AltitudeReferenceSystem, который указывает эталонную систему, в которой предоставляется значение высоты.
  • Courseтип double?, указывающий значение градусов относительно истинного севера.
  • IsFromMockProvider, тип bool, который указывает, находится ли расположение от GPS или от поставщика макетного расположения.
  • Latitudedoubleтип, представляющий широту расположения в десятичных градусах.
  • Longitudedoubleтип, представляющий долготу расположения в десятичных градусах.
  • Speeddouble?типа, который представляет скорость в метрах в секунду.
  • 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 значения, которое представляет расстояние в метрах. Эта структура определяет три свойства только для чтения:

  • Kilometersdoubleтип , который представляет расстояние в километрах, охватываемых Distance.
  • Meters, тип double, который представляет расстояние в метрах, охватываемом Distance.
  • Miles, типа double, который представляет расстояние в милях, охватываемых Distance.

Distance Объекты можно создавать с помощью конструктора Distance , для которого требуется аргумент счетчиков, указанный doubleв качестве:

Distance distance = new Distance(1450.5);

Кроме того, Distance объекты можно создавать с FromMilesFromKilometersFromMetersпомощью методов , и 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 имеет следующие свойства:

  • AddressstringТип , который обычно представляет адрес для расположения пин-кода. Однако это может быть любое string содержимое, а не только адрес.
  • Labelтипа string, который обычно представляет заголовок пин-кода.
  • LocationLocationтип, представляющий широту и долготу закрепления.
  • Typeтип, представляющий тип PinTypeпин-кода.

Эти свойства поддерживаются BindableProperty объектами, что означает Pin , что это может быть целевым объектом привязок данных. Дополнительные сведения о объектах привязки Pin данных см. в разделе "Отображение коллекции закреплений".

Кроме того, Pin класс определяет MarkerClicked и InfoWindowClicked события. Событие MarkerClicked запускается при нажатии пин-кода, и InfoWindowClicked событие запускается при нажатии окна сведений. Объект PinClickedEventArgs , сопровождающий оба события, имеет одно HideInfoWindow свойство типа bool.

Отображение пин-кода

В XAML можно добавить следующее Pin 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: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 элементы позволяют выделить определенные области на карте. A Polygon — это полностью заключенная фигура, которая может иметь цвет штриха и заливки. Строка Polyline , которая не полностью заключена в область. Выделена Circle круговая область карты:

Многоугольник и многоугольник на карте.Круг на карте.

PolylineCircle КлассыPolygon, производные от MapElement класса, предоставляют следующие привязываемые свойства:

  • StrokeColor — это объект, определяющий Color цвет линии.
  • StrokeWidth — это объект, определяющий float ширину линии.

Класс Polygon определяет дополнительное привязываемое свойство:

  • FillColor — это объект, определяющий Color цвет фона многоугольника.

Кроме того, Polygon и Polyline классы определяют GeoPath свойство, которое представляет собой список Location объектов, которые указывают точки фигуры.

Класс Circle определяет следующие привязываемые свойства:

  • CenterLocation— это объект, определяющий центр круга в широте и долготе.
  • RadiusDistance— это объект, определяющий радиус круга в метрах, километрах или милях.
  • FillColorColor— это свойство, определяющее цвет в периметре круга.

Создание многоугольника

Объект 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);

StrokeWidth Свойства StrokeColor задаются для задания структуры многоугольника. В этом примере FillColor значение свойства соответствует StrokeColor значению свойства, но имеет альфа-значение, указанное для прозрачности, что позволяет базовой карте отображаться через фигуру. Свойство GeoPath содержит список объектов, определяющих Location географические координаты точек многоугольника. Объект Polygon отображается на карте после добавления MapElements в коллекцию Mapобъекта.

Примечание.

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

StrokeWidth Свойства StrokeColor задаются для задания внешнего вида строки. Свойство 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 свойство определяет радиус круга в метрах. StrokeWidth Свойства StrokeColor задаются для задания контура круга. Значение FillColor свойства указывает цвет в периметре круга. В этом примере оба значения цвета указывают альфа-канал, что позволяет базовой карте отображаться через круг. Объект Circle отображается на карте после добавления MapElements в коллекцию Mapобъекта.

Примечание.

Класс GeographyUtils имеет ToCircumferencePositions метод расширения, который преобразует Circle объект (который определяет Center и значения свойств) в список объектов, составляющих Location координаты широты и Radius долготы периметра круга.

Геокодирование и геолокация

Класс 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 пространства имен. Дополнительные сведения см. в разделе "Карта".

Приложение карт на каждой платформе использует уникальную настраиваемую схему 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");
}

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