地圖

Browse sample. 流覽範例

.NET 多平臺應用程式 UI (.NET MAUI) Map 控件是用於顯示和標註地圖的跨平台檢視。 控件Map會在每個平臺上使用原生地圖控件,並由 Microsoft.Maui.Controls.地圖NuGet 套件

重要

Windows 不支援控件 Map ,因為 WinUI 中缺少地圖控件。 不過,CommunityToolkit.Maui.地圖NuGet 套件可讓您透過 WebView Windows 上的 存取 Bing 地圖。 如需詳細資訊,請參閱 開始使用

設定

控件 Map 會在每個平臺上使用原生地圖控件。 這可為使用者提供快速且熟悉的地圖體驗,但表示需要一些設定步驟才能遵守每個平臺 API 需求。

對應初始化

控件Map是由 Microsoft.Maui.Controls.地圖 提供NuGet 套件,應該新增至 .NET MAUI 應用程式專案。

安裝 NuGet 套件之後,必須在應用程式中UseMauiMap呼叫 類別方法MauiProgram上的 MauiAppBuilderCreateMauiApp 方法,以初始化它:

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設定必要的位置服務要求。 這些通常是下列其中一或多個:

如需詳細資訊,請參閱 選擇要在 developer.apple.com 上要求 的位置服務授權。

Info.plist 中這些索引鍵的 XML 表示如下所示。 您應該更新 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>

然後,當應用程式嘗試存取使用者的位置時,會顯示提示,要求存取:

Screenshot of location permission request on iOS.

Android

在 Android 上顯示及與地圖互動的設定程式是:

  1. 取得Google 地圖 API 金鑰,並將其新增至您的應用程式指令清單。
  2. 在指令清單中指定Google Play服務版本號碼。
  3. [選擇性]在指令清單中指定位置許可權。
  4. [選擇性]在指令清單中指定WRITE_EXTERNAL_STORAGE許可權。
取得Google 地圖 API 金鑰

若要在 Map Android 上使用 控制項,您必須產生 API 金鑰,而 Google 地圖 SDK 會Map取用控件依賴 Android 的 API 金鑰。 若要這樣做,請遵循在Google Cloud Console 中設定和使用 API 金鑰中的指示,developers.google.com。

取得 API 金鑰之後,必須將它新增至 Platform/Android/AndroidManifest.xml 檔案的 元素內<application>,方法是將它指定為元數據的值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 金鑰的建議元資料名稱。 此名稱的金鑰可用來向 Android 上的多個 Google 地圖 API 進行驗證。 為了回溯相容性,com.google.android.maps.v2.API_KEY可以使用元數據名稱,但只允許驗證Android地圖 API v2。 應用程式只能指定其中一個 API 金鑰元資料名稱。

指定Google Play服務版本號碼

在 AndroidManifest.xml元素內<application>新增下列宣告:

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

這會將應用程式編譯的 Google Play 服務版本內嵌到指令清單中。

指定位置許可權

如果您的應用程式需要存取使用者的位置,您必須將 或 ACCESS_FINE_LOCATION 許可權 (或兩者) 新增ACCESS_COARSE_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 使用 WiFi 或行動數據,或兩者來判斷裝置的位置。 許可權 ACCESS_FINE_LOCATION 可讓 API 使用全域定位系統(GPS)、WiFi 或行動數據,盡可能判斷確切的位置。

然後,當應用程式嘗試存取使用者的位置時,會顯示提示,要求存取:

Screenshot of location permission request on Android.

或者,這些許可權可以在 Visual Studio 的 Android 指令清單編輯器中啟用。

指定WRITE_EXTERNAL_STORAGE許可權

如果您的應用程式以 API 22 或更低版本為目標,則必須將許可權新增 WRITE_EXTERNAL_STORAGE 至指令清單,作為專案的子 <manifest> 系:

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

如果您的應用程式以 API 23 或更新版本為目標,則不需要這樣做。

地圖控制項

類別 Map 會定義下列屬性,以控制地圖外觀和行為:

  • IsShowingUserbool別為 的 ,表示地圖是否顯示使用者的目前位置。
  • ItemsSourceIEnumerable別為 的 ,指定要顯示的釘選專案集合 IEnumerable
  • ItemTemplateDataTemplate別為 的 ,指定要 DataTemplate 套用至所顯示釘選集合中每個專案的 。
  • ItemTemplateSelectorDataTemplateSelector別為 的 ,指定 DataTemplateSelector 將在運行時間用來為針腳選擇 DataTemplate 的 。
  • IsScrollEnabledbool別為 的 ,決定是否允許地圖卷動。
  • IsTrafficEnabledbool別為 的 ,表示是否在地圖上覆寫流量數據。
  • IsZoomEnabledbool別為 的 ,決定是否允許地圖縮放。
  • MapElementsIList<MapElement>別為 的 ,代表地圖上的項目清單,例如多邊形和聚合線條。
  • MapTypeMapType別為 的 ,表示地圖的顯示樣式。
  • PinsIList<Pin>別為 的 ,代表地圖上的圖釘清單。
  • VisibleRegionMapSpan別為的 ,會傳回地圖目前顯示的區域。

除了、 PinsVisibleRegion 屬性之外,MapElements這些屬性是由 BindableProperty 物件所支援,這表示這些屬性可以是數據系結的目標。

類別 Map 也會定義 MapClicked 點選地圖時引發的事件。 事件 MapClickedEventArgs 隨附的物件具有名為 Location的單一屬性,類型 Location為 。 引發事件時, Location 屬性會設定為點選的地圖位置。 如需 類別 Location 的相關信息,請參閱 位置和距離

如需、 屬性的相關資訊ItemsSource, 請參閱顯示釘選集合ItemTemplateSelectorItemTemplate

顯示地圖

Map可以藉由將它新增至版面配置或頁面來顯示:

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps">
    <maps:Map x:Name="map" />
</ContentPage>

注意

在 XAML 中, xmlns 應該為控制項新增 Map 命名空間定義。 雖然這不是必要專案,但它可防止和 Polyline 型別之間Polygon發生衝突,這些類型同時存在於 和 Microsoft.Maui.Controls.Shapes 命名空間中Microsoft.Maui.Controls.Maps

<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 建構函式,此建構函式會將地圖置中於夏威夷 Maui:

Screenshot of map control with default location.

或者, MapSpan 自變數可以傳遞至建 Map 構函式,以在載入地圖時設定地圖的中心點和縮放層級。 如需詳細資訊,請參閱 在地圖上顯示特定位置。

重要

.NET MAUI 有兩 Map 種類型 - Microsoft.Maui.Controls.Maps.MapMicrosoft.Maui.ApplicationModel.MapMicrosoft.Maui.ApplicationModel因為命名空間是 .NET MAUI 的global using其中一個指示詞,因此當您從程式代碼使用 Microsoft.Maui.Controls.Maps.Map 控件時,您必須完整限定使用Map方式或使用別名

對應類型

屬性 Map.MapType 可以設定為 MapType 列舉成員,以定義地圖的顯示樣式。 MapType 列舉會定義下列成員:

  • Street 指定會顯示街地圖。
  • Satellite 指定會顯示包含衛星影像的地圖。
  • Hybrid 指定將顯示結合街道和衛星數據的地圖。

根據預設,如果屬性未定義,MapMapType則會顯示街道地圖。 或者, MapType 屬性可以設定為其中 MapType 一個列舉成員:

<maps:Map MapType="Satellite" />

對等的 C# 程式碼為:

Map map = new Map
{
    MapType = MapType.Satellite
};

在地圖上顯示特定位置

將自變數傳遞 MapSpanMap 建構函式,即可設定載入對應時所要顯示的地圖區域:

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map>
        <x:Arguments>
            <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>
            </MapSpan>
        </x:Arguments>
    </maps:Map>
</ContentPage>
<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 中傳遞自變數。

結果是當地圖顯示時,它會以特定位置為中心,並跨越特定數目的緯度和經度度:

Screenshot of map control with specified location.

建立 MapSpan 物件

建立物件的方法有很多 MapSpan 種。 常見的方法是將必要的自變數提供給建 MapSpan 構函式。 這些是由物件表示 Location 的緯度和經度,而 double 值則代表 所 MapSpan跨越的緯度和經度度。 如需 類別 Location 的相關信息,請參閱 位置和距離

或者,類別中有 MapSpan 三種方法會傳回新 MapSpan 物件:

  1. ClampLatitudeMapSpan 回的 ,與方法的類別實例相同 LongitudeDegrees ,以及其 northsouth 自變數所定義的半徑。
  2. FromCenterAndRadiusMapSpan 回其 LocationDistance 自變數所定義的 。
  3. WithZoomMapSpan 回與方法類別實例相同的中心,但半徑乘以其 double 自變數。

如需結構的相關信息 Distance ,請參閱 位置和距離

MapSpan建立 之後,即可存取下列屬性來擷取其相關數據:

  • CenterLocation別為 ,表示 地理中心 MapSpan中的位置。
  • LatitudeDegreesdouble別為 的 ,表示 所 MapSpan跨越的緯度度。
  • LongitudeDegreesdouble別為 的 ,表示 所 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 縮放層級,而不改變其位置。 這可以使用地圖 UI 來完成,或透過使用目前位置做為自變數的Location自變數呼叫 MoveToRegion 方法MapSpan,以程序設計方式完成:

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 方法來控制縮放因數。

重要

無論是透過地圖 UI 還是程式設計方式縮放地圖,都需要 Map.IsZoomEnabled 屬性為 true。 如需此屬性的詳細資訊,請參閱 停用縮放

自定義地圖行為

您可以藉由設定部分屬性,以及處理MapClicked事件,來自定義 的行為Map

注意

自定義其處理程式即可達成其他地圖行為自定義。 如需詳細資訊,請參閱 使用處理程式自定義控件。

顯示流量數據

類別 MapIsTrafficEnabled 定義 型別 bool的屬性。 根據預設,此屬性為 false,表示不會在地圖上覆寫流量數據。 當此屬性設定為 true時,流量數據會覆蓋在地圖上:

<maps:Map IsTrafficEnabled="true" />

對等的 C# 程式碼為:

Map map = new Map
{
    IsTrafficEnabled = true
};

停用捲動

類別 MapIsScrollEnabled 定義 型別 bool的屬性。 根據預設,這個屬性為 true,表示允許卷動地圖。 當此屬性設定為 false時,地圖將不會捲動:

<maps:Map IsScrollEnabled="false" />

對等的 C# 程式碼為:

Map map = new Map
{
    IsScrollEnabled = false
};

停用縮放

類別 MapIsZoomEnabled 定義 型別 bool的屬性。 根據預設,這個屬性為 true,表示可以在地圖上執行縮放。 當此屬性設定為 false時,無法縮放地圖:

<maps:Map IsZoomEnabled="false" />

對等的 C# 程式碼為:

Map map = new Map
{
    IsZoomEnabled = false
};

顯示使用者的位置

類別 MapIsShowingUser 定義 型別 bool的屬性。 根據預設,此屬性為 false,表示地圖未顯示使用者的目前位置。 當此屬性設定為 true時,地圖會顯示使用者的目前位置:

<maps:Map IsShowingUser="true" />

對等的 C# 程式碼為:

Map map = new Map
{
    IsShowingUser = true
};

重要

存取使用者的位置需要已授與應用程式的位置許可權。 如需詳細資訊,請參閱 平台設定

地圖點選

類別 MapMapClicked 定義點選地圖時所引發的事件。 事件 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

類別 Location 會封裝儲存為緯度和經度值的位置。 這個類別會定義下列屬性:

  • Accuracydouble?別為 的 ,以公尺表示的水平精確度 Location
  • Altitudedouble?別為 ,表示 屬性所 AltitudeReferenceSystem 指定參考系統中公尺的高度。
  • AltitudeReferenceSystemAltitudeReferenceSystem別為 的 ,指定提供高度值的參考系統。
  • Coursedouble?別為 ,表示相對於 true north 的度值。
  • IsFromMockProviderbool別為 ,表示位置是否來自 GPS 或模擬位置提供者。
  • Latitudedouble別為 的 ,表示小數點位置的緯度。
  • Longitude,屬於 類型 double,表示小數點位置的經度。
  • Speed,類型 double?為 ,表示每秒以公尺為單位的速度。
  • TimestampDateTimeOffset別為 的 ,表示建立 時的 Location 時間戳。
  • VerticalAccuracydouble?別為 的 ,以公尺為單位,指定的 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跨越的公里距離。
  • Metersdouble別為 的 ,表示所 Distance跨越公尺的距離。
  • Milesdouble別為 的 ,表示所 Distance跨越的英哩距離。

Distance 物件可以使用建 Distance 構函式來建立,這需要指定為 的 double計量自變數:

Distance distance = new Distance(1450.5);

或者,Distance可以使用 、FromMetersFromMilesBetweenPositions Factory 方法來建立FromKilometers物件:

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是點選時開啟資訊視窗的地圖示記:

Screenshot of a map pin and its information window.

Pin當物件加入至集合時Map.Pins,圖釘會在地圖上轉譯。

類別 Pin 具有下列屬性:

  • Addressstring別為 的 ,這通常代表針腳位置的位址。 不過,它可以是任何 string 內容,而不只是位址。
  • Labelstring別為 的 ,通常代表釘選標題。
  • LocationLocation別為 的 ,表示針腳的緯度和經度。
  • TypePinType別為 的 ,表示針腳的類型。

這些屬性是由 BindableProperty 物件所支援,這表示 Pin 可以是數據系結的目標。 如需數據系結 Pin 對象的詳細資訊,請參閱 顯示釘選集合

此外,類別 PinMarkerClicked 定義和 InfoWindowClicked 事件。 點 MarkerClicked 選釘選時會引發事件,並在 InfoWindowClicked 點選資訊視窗時引發事件。 PinClickedEventArgs同時同時伴隨這兩個事件的物件具有單HideInfoWindow一屬性,類型為 bool

顯示釘選

Pin可以在 XAML 中新增 至 Map

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map x:Name="map">
        <x:Arguments>
            <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>
            </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>
<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集合,並在 其 Location 屬性所指定的位置上Map繪製。 如需 類別 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);

此範例程式代碼會導致在地圖上轉譯單一釘選:

Screenshot of a map pin.

與釘選互動

根據預設, Pin 點選時會顯示其資訊視窗:

Screenshot of a map pin and its information window.

點選地圖上的其他地方會關閉信息視窗。

類別 PinMarkerClicked 定義事件,該事件會在點選 時 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 外觀。 如需處理程式自定義的詳細資訊,請參閱 使用處理程式自定義控件。

顯示 PIN 集合

類別 Map 會定義下列可繫結屬性:

重要

設定 ItemTemplateItemTemplateSelector 屬性時ItemTemplate,屬性會優先使用。

Map可以使用資料系結將其ItemsSource屬性系結至IEnumerable集合,以釘選填入 :

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.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>
<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連接的 viewmodel 屬性,該屬性會ObservableCollectionPosition傳回 物件的 ,這是自定義型別。 每個Position物件都會Address定義 型string別 的 和 Description 屬性,以及 Location 型別 Location的屬性。

集合中 IEnumerable 每個項目的外觀都是藉由將 屬性設定 ItemTemplateDataTemplatePin ,其中包含數據系結至適當屬性之 物件的 。

下列螢幕快照顯示 Map 使用資料系結來 Pin 顯示集合:

Screenshot of map with data bound pins.

選擇運行時間的項目外觀

您可以藉由將 屬性設定ItemTemplateSelectorDataTemplateSelector,在執行時間根據專案值選擇集合中IEnumerable每個項目的外觀:

<ContentPage ...
             xmlns:templates="clr-namespace:WorkingWithMaps.Templates"
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.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>
<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;
    }
}

類別 MapItemTemplateSelectorDefaultTemplate 定義 和 SanFranTemplateDataTemplate 屬性,這些屬性會設定為不同的數據範本。 當專案具有包含 「San Francisco」 的位址時,此方法 OnSelectTemplateSanFranTemplate傳回 ,當點選 時 Pin ,會將 「Xamarin」 顯示為標籤。 當項目沒有包含 「San Francisco」 的位址時, OnSelectTemplate 此方法會傳 DefaultTemplate回 。

注意

這項功能的使用案例是根據Pin子類型,將子類別Pin化對象的屬性系結至不同的屬性。

如需數據範本選取器的詳細資訊,請參閱 建立 DataTemplateSelector

多邊形、聚合線條和圓形

PolygonPolylineCircle 元素可讓您在地圖上醒目提示特定區域。 Polygon是可以具有筆觸和填滿色彩的完整封閉圖形。 Polyline是未完全封入區域的線條。 醒 Circle 目提示地圖的圓形區域:

Polygon and polyline on a map.Circle on a map.

PolygonPolylineCircle 類別衍生自 MapElement 類別,其會公開下列可系結屬性:

  • StrokeColorColor是決定線條色彩的物件。
  • StrokeWidthfloat是決定線條寬度的物件。

類別 Polygon 會定義額外的可系結屬性:

  • FillColorColor是決定多邊形背景色彩的物件。

此外, PolygonPolyline 類別都會定義 GeoPath 屬性,這是指定圖形點的物件清單 Location

類別 Circle 會定義下列可繫結屬性:

  • CenterLocation是 對象,定義圓形的中心,以緯度和經度為單位。
  • Radius 是對象 Distance ,定義以公尺、公里或英哩為單位的圓形半徑。
  • FillColorColor是決定圓形周邊色彩的屬性。

建立多邊形

Polygon物件可以具現化並新增至地圖的MapElements集合,以新增至地圖:

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.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>
<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);

StrokeColorStrokeWidth 屬性是指定來設定多邊形的外框。 在此範例中 FillColor ,屬性值會比對 StrokeColor 屬性值,但已指定Alpha值使其透明,讓基礎地圖可以透過圖形顯示。 屬性 GeoPath 包含定義多邊形點地理座標的物件清單 Location 。 一 Polygon 旦物件加入 至 MapElementsMap集合,物件就會在地圖上呈現。

注意

Polygon是完全封閉的圖形。 如果第一個點和最後一個點不相符,則會自動連接。

建立聚合線條

Polyline物件可以具現化並新增至地圖的MapElements集合,以新增至地圖:

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.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>
<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 旦物件加入 至 MapElementsMap集合,物件就會在地圖上呈現。

建立圓形

Circle物件可以具現化並新增至地圖的MapElements集合,以新增至地圖:

<ContentPage ...
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.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>
                    <Distance>
                        <x:Arguments>
                            <x:Double>250</x:Double>
                        </x:Arguments>
                    </Distance>
                </maps:Circle.Radius>
            </maps:Circle>             
        </maps:Map.MapElements>
    </maps:Map>
</ContentPage>
<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取決於 和 Radius 屬性的值Center。 屬性 Center 會以緯度和經度定義圓形的中心,而 Radius 屬性則以公尺定義圓形的半徑。 和 StrokeColorStrokeWidth 屬性是指定來設定圓形的外框。 FillColor屬性值會指定圓形周邊內的色彩。 在此範例中,這兩個色彩值都會指定Alpha色板,讓基礎地圖可以透過圓形可見。 一旦物件加入 至 MapElementsMap集合,物件Circle就會在地圖上呈現。

注意

類別GeographyUtils具有ToCircumferencePositions擴充方法,可將物件 (定義 CenterRadius 屬性值) 轉換成Circle組成圓形周邊緯度和經度座標的物件清單Location

地理編碼和地理位置

Geocoding命名空間中的 Microsoft.Maui.Devices.Sensors 類別可用來將地標記地理編碼為定位座標,並將地理編碼座標反向編碼為地標記。 如需詳細資訊,請參閱 地理編碼

Geolocation命名空間中的 Microsoft.Maui.Devices.Sensors 類別可用來擷取裝置目前的地理位置座標。 如需詳細資訊,請參閱 地理位置

啟動原生對應應用程式

每個平臺上的原生對應應用程式都可以由 Launcher 類別從 .NET MAUI 應用程式啟動。 這個類別可讓應用程式透過其自定義 URI 配置開啟另一個應用程式。 您可以使用 方法叫用 OpenAsync 啟動器功能,傳入 stringUri 自變數,代表要開啟的自定義 URL 配置。 如需 類別 Launcher 的詳細資訊,請參閱 Launcher

注意

使用 Launcher 類別的替代方法是使用 Map 命名空間中的 Microsoft.Maui.ApplicationModel 類別。 如需詳細資訊,請參閱 對應

每個平臺上的地圖應用程式都會使用唯一的自定義 URI 配置。 如需 iOS 上地圖 URI 配置的相關信息,請參閱 developer.apple.com 上的地圖連結 。 如需 Android 上地圖 URI 配置的相關信息,請參閱 地圖 開發人員指南Google 地圖 Android developers.android.com 意圖。 如需 Windows 上地圖 URI 配置的相關信息,請參閱啟動 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");
}

此範例程式代碼會導致在每個平台上啟動原生地圖應用程式,地圖會以指定位置之間的路線為中心。