.NET 多平臺應用程式 UI (.NET MAUI) Map 控件是用於顯示和標註地圖的跨平台檢視。 控件 Map 會在每個平臺上使用原生地圖控件,並由 Microsoft.Maui.Controls.Maps NuGet 套件提供。
這很重要
Windows 不支援控件 Map ,因為 WinUI 中缺少地圖控件。 不過, CommunityToolkit.Maui.Maps NuGet 套件可讓您透過 WebView Windows 上的 存取 Bing 地圖服務。 如需詳細資訊,請參閱 開始使用。
設定
控件 Map 會在每個平臺上使用原生地圖控件。 這可為使用者提供快速且熟悉的地圖體驗,但表示需要一些設定步驟才能遵守每個平臺 API 需求。
地圖初始化
控件 Map 是由 Microsoft.Maui.Controls.Maps NuGet 套件所提供,該套件應該新增至 .NET MAUI 應用程式專案。
安裝 NuGet 套件之後,必須在 MauiProgram 類別的 CreateMauiApp 方法中,透過在 MauiAppBuilder 物件上呼叫 UseMauiMaps 方法來初始化它。
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 上的 選擇位置服務授權。
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>
然後,當應用程式嘗試存取使用者的位置時,會顯示提示,要求存取:
安卓
在 Android 上顯示及與地圖互動的設定程式是:
- 取得 Google Maps API 金鑰,並將其新增至您的應用程式指令清單。
- 在指令清單中指定Google Play服務版本號碼。
- [選擇性]在指令清單中指定位置許可權。
- [選擇性]在指令清單中指定WRITE_EXTERNAL_STORAGE許可權。
取得Google Maps API 金鑰
若要在 Android 平台上使用 Map 控制項,您必須產生 API 金鑰,此金鑰將由 Google Maps SDKMap 所依賴的控件在 Android 上取用。 若要進行此操作,請遵循 developers.google.com 上 Google Cloud Console 設定 和 使用 API 金鑰 中的指示。
取得 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 Maps 型 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_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 使用 WiFi 或行動數據,或兩者來判斷裝置的位置。 許可權 ACCESS_FINE_LOCATION 可讓 API 使用全域定位系統(GPS)、WiFi 或行動數據,盡可能判斷確切的位置。
然後,當應用程式嘗試存取使用者的位置時,會顯示提示,要求存取:
或者,這些許可權可以在 Visual Studio 的 Android 指令清單編輯器中啟用。
指定“WRITE_EXTERNAL_STORAGE”存取權限
如果您的應用程式針對 API 22 或更低版本,則必須在 manifest 中新增 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類型會回傳地圖的目前顯示區域。
除了、 Pins和 VisibleRegion 屬性之外,MapElements這些屬性是由 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 建構函式,此建構函式會將地圖置中於夏威夷 Maui:
或者, MapSpan 自變數可以傳遞至建 Map 構函式,以在載入地圖時設定地圖的中心點和縮放層級。 如需詳細資訊,請參閱 在地圖上顯示特定位置。
這很重要
.NET MAUI 有兩 Map 種類型 - Microsoft.Maui.Controls.Maps.Map 和 Microsoft.Maui.ApplicationModel.Map。
Microsoft.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
};
在地圖上顯示特定位置
將參數 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 物件:
-
ClampLatitude返回一個具有與該方法的類別實例相同LongitudeDegrees的MapSpan,其半徑由north和south參數所定義。 -
FromCenterAndRadius回傳由其Location和Distance參數所定義的MapSpan。 -
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 縮放層級,而不改變其位置。 這可以使用地圖 UI 來完成,或者通過程式調用 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 方法來控制縮放因數。
這很重要
無論是透過地圖 UI 還是程式設計方式縮放地圖,都需要 Map.IsZoomEnabled 屬性為 true。 如需此屬性的詳細資訊,請參閱 停用縮放。
自定義地圖行為
您可以藉由設定其部分屬性,以及處理MapClicked事件,來自定義Map的行為。
備註
自定義其處理程式即可達成其他地圖行為自定義。 如需詳細資訊,請參閱 使用處理程式自定義控件。
顯示流量資料
類別 Map 定義了一個型別為 bool 的屬性 IsTrafficEnabled。 根據預設,此屬性為 false,表示不會在地圖上覆寫流量數據。 當此屬性設定為 true時,流量數據會覆蓋在地圖上:
<maps:Map IsTrafficEnabled="true" />
對等的 C# 程式代碼為:
Map map = new Map
{
IsTrafficEnabled = true
};
停用捲動
類別 Map 定義了一個型別為 bool 的屬性IsScrollEnabled。 根據預設,這個屬性為 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);
或者,可以使用 FromKilometers、FromMeters、FromMiles 和 BetweenPositions 工廠方法來建立Distance物件:
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可以在 XAML 中新增 至 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集合,並在 其 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);
此範例程式代碼會導致在地圖上轉譯單一釘選:
與釘選互動
根據預設, 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");
};
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 DisplayAlertAsync("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 DisplayAlertAsync("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,指定在運行時用於為引腳選擇DataTemplate的DataTemplateSelector。
這很重要
當設定 ItemTemplate 和 ItemTemplateSelector 屬性時,ItemTemplate 屬性會優先。
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 x:DataType="models:Position">
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>
...
</Grid>
</ContentPage>
屬性ItemsSource數據會綁定到連接的 viewmodel 的Positions屬性,該屬性會返回一個包含Position物件的ObservableCollection,這是自定義類型。 每個Position物件都定義了Address和Description型別為string的屬性,以及Location型別為Location的屬性。
集合中 IEnumerable 每個項目的外觀都是藉由將 屬性設定 ItemTemplate 為 DataTemplatePin ,其中包含數據系結至適當屬性之 物件的 。
下列螢幕快照顯示 Map 使用資料系結顯示 Pin 集合。
在運行時選擇項目外觀
您可以在執行時,根據項目值選擇IEnumerable集合中每個項目的外觀,藉由將ItemTemplateSelector屬性設定為DataTemplateSelector。
<ContentPage ...
xmlns:templates="clr-namespace:WorkingWithMaps.Templates"
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:viewmodels="clr-namespace:WorkingWithMaps.ViewModels"
x:DataType="viewmodels:PinItemsSourcePageViewModel">
<ContentPage.Resources>
<templates:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
<templates:MapItemTemplateSelector.DefaultTemplate>
<DataTemplate x:DataType="models:Position">
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</templates:MapItemTemplateSelector.DefaultTemplate>
<templates:MapItemTemplateSelector.SanFranTemplate>
<DataTemplate x:DataType="models:Position">
<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>
The following example shows the MapItemTemplateSelector class:
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 和 SanFranTemplateDataTemplate 屬性,這些屬性已設定為不同的資料模板。 當項目的地址包含「San Francisco」時,OnSelectTemplate 方法會返回 SanFranTemplate,當點擊 Pin 時,會顯示「Xamarin」作為標籤。 當項目沒有包含 「San Francisco」 的位址時, OnSelectTemplate 此方法會傳 DefaultTemplate回 。
備註
這項功能的使用案例是根據Pin子類型,將子類別Pin化對象的屬性系結至不同的屬性。
如需有關資料模板選擇器的更多資訊,請參閱建立資料模板選擇器。
多邊形、聚合線條和圓形
Polygon、 Polyline和 Circle 元素可讓您在地圖上醒目提示特定區域。
Polygon是可以具有筆觸和填滿色彩的完整封閉圖形。
Polyline是無法完全圍住一個區域的線。 地圖的圓形區標示為Circle。
Polygon、 Polyline和 Circle 類別衍生自 MapElement 類別,其會公開下列可系結屬性:
-
StrokeColorColor是決定線條色彩的物件。 -
StrokeWidthfloat是決定線條寬度的物件。
類別 Polygon 會定義額外的可系結屬性:
-
FillColorColor是決定多邊形背景色彩的物件。
此外, Polygon 和 Polyline 類別都會定義 GeoPath 屬性,這是指定圖形點的物件清單 Location 。
類別 Circle 會定義下列可繫結屬性:
-
Center是一個Location對象,定義了圓形的中心,並以緯度和經度表示。 -
Radius是對象Distance,定義以公尺、公里或英哩為單位的圓形半徑。 -
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);
StrokeColor 和 StrokeWidth 屬性被指定用來設定多邊形的外框。 在此範例中,FillColor 屬性值與 StrokeColor 屬性值相同,但指定了一個透明的 Alpha 值,使圖形下方的地圖可以顯示出來。 屬性 GeoPath 包含定義多邊形點地理座標的物件清單 Location 。 物件一加入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 。 物件一旦加入 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屬性值會指定圓形周邊內的色彩。 在此範例中,這兩個色彩值都指定了透明度通道,讓基礎地圖可以透過圓形顯示。 一旦物件加入 至 MapElements 的Map集合,物件Circle就會在地圖上呈現。
備註
類別GeographyUtils具有ToCircumferencePositions擴充方法,可以將定義Center和Radius屬性值的Circle物件轉換成Location物件的清單,這些物件構成圓形周邊的緯度和經度座標。
地理編碼和地理位置
Geocoding命名空間中的 Microsoft.Maui.Devices.Sensors 類別可用來將地標記地理編碼為定位座標,並將地理編碼座標反向編碼為地標記。 如需詳細資訊,請參閱 地理編碼。
Geolocation命名空間中的 Microsoft.Maui.Devices.Sensors 類別可用來擷取裝置目前的地理位置座標。 如需詳細資訊,請參閱 地理位置。
啟動原生對應應用程式
.NET MAUI 應用程式可使用 Launcher 類別啟動每個平臺上的原生地圖應用程式。 這個類別可讓應用程式透過其自定義 URI 配置開啟另一個應用程式。 您可以使用 方法叫用 OpenAsync 啟動器功能,傳入 string 或 Uri 自變數,代表要開啟的自定義 URL 配置。 如需 類別 Launcher 的詳細資訊,請參閱 Launcher。
每個平臺上的地圖應用程式都會使用唯一的自定義 URI 配置。 如需 iOS 上地圖 URI 配置的相關信息,請參閱 developer.apple.com 上的 地圖連結 。 如需 Android 上地圖 URI 配置的相關信息,請參閱地圖 開發人員指南 和 Android developers.android.com 上的 Google Maps 意圖 。 如需 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");
}
此範例程式代碼會導致在每個平台上啟動原生地圖應用程式,地圖會以指定位置之間的路線為中心。
瀏覽範例