顯示地圖的 2D、3D 和 Streetside 檢視
重要
針對企業用 Bing 地圖服務淘汰
UWP MapControl 和 Windows.Services.Maps 命名空間的地圖服務都是依賴 Bing 地圖服務。 針對企業用 Bing 地圖服務已遭到取代且即將淘汰,屆時 MapControl 及服務將不再接收資料。
如需詳細資訊,請參閱 Bing 地圖服務開發人員中心和 Bing 地圖服務文件。 您可以在可關閉的輕量型視窗中顯示地圖,這稱為地圖地點卡片,或是在功能齊全的地圖控制項中顯示。
下載地圖範例,以試用本指南中所述的一些功能。
在地點卡片中顯示地圖
您可以在使用者觸碰的 UI 元素或應用程式區域的上方、下方或側邊,顯示輕量型快顯視窗,裡面包含地圖。 地圖可以顯示與您的應用程式相關的城市或地址資訊。
這個地點卡片會顯示西雅圖市。
這是讓西雅圖出現在按鈕下方的地點卡片中的程式碼。
private void Seattle_Click(object sender, RoutedEventArgs e)
{
Geopoint seattlePoint = new Geopoint
(new BasicGeoposition { Latitude = 47.6062, Longitude = -122.3321 });
PlaceInfo spaceNeedlePlace = PlaceInfo.Create(seattlePoint);
FrameworkElement targetElement = (FrameworkElement)sender;
GeneralTransform generalTransform =
targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);
Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
(targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));
spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}
這個地點卡片顯示西雅圖 Space Needle 的位置。
這是讓 Space Needle 出現在按鈕下方的地點卡片中的程式碼。
private void SpaceNeedle_Click(object sender, RoutedEventArgs e)
{
Geopoint spaceNeedlePoint = new Geopoint
(new BasicGeoposition { Latitude = 47.6205, Longitude = -122.3493 });
PlaceInfoCreateOptions options = new PlaceInfoCreateOptions();
options.DisplayAddress = "400 Broad St, Seattle, WA 98109";
options.DisplayName = "Seattle Space Needle";
PlaceInfo spaceNeedlePlace = PlaceInfo.Create(spaceNeedlePoint, options);
FrameworkElement targetElement = (FrameworkElement)sender;
GeneralTransform generalTransform =
targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);
Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
(targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));
spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}
在控制項中顯示地圖
使用地圖控制項,在您的應用程式中顯示豐富且可自訂的地圖資料。 地圖控制項可以顯示道路地圖、空照圖、3D 視圖、行駛路線、搜尋結果和交通資訊。 在地圖上,您可以顯示使用者的位置、方向和興趣點。 地圖也可以顯示空中的 3D 視圖、街景、交通狀況、大眾運輸資訊以及當地商家。
當您想要應用程式內的地圖可讓使用者檢視應用程式特定或一般地理資訊時,請使用地圖控制項。 在您的應用程式中擁有地圖控制項,表示使用者不需要離開應用程式即可取得該資訊。
注意
如果您不介意使用者在應用程式之外,請考慮使用 Windows 地圖應用程式來提供該資訊。 您的應用程式可以啟動 Windows 地圖應用程式,顯示特定的地圖、路線和搜尋結果。 如需詳細資訊,請參閱啟動 Windows 地圖應用程式。
將地圖控制項新增至應用程式
藉由新增 MapControl,在 XAML 頁面上顯示地圖。 若要使用 MapControl,您必須在 XAML 頁面或程式碼中宣告 Windows.UI.Xaml.Controls.Maps 命名空間。 如果您從工具箱拖曳控制項,則會自動新增此命名空間宣告。 如果您手動將 MapControl 新增至 XAML 頁面,則必須手動在頁面頂端新增命名空間宣告。
下列範例會顯示基本的地圖控制項,並設定地圖來顯示縮放和傾斜控制項,以及接受觸控輸入。
<Page
x:Class="MapsAndLocation1.DisplayMaps"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MapsAndLocation1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
mc:Ignorable="d">
<Grid x:Name="pageGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Maps:MapControl
x:Name="MapControl1"
ZoomInteractionMode="GestureAndControl"
TiltInteractionMode="GestureAndControl"
MapServiceToken="EnterYourAuthenticationKeyHere"/>
</Grid>
</Page>
如果您在程式碼中新增地圖控制項,則必須在程式碼檔案頂端手動宣告命名空間。
using Windows.UI.Xaml.Controls.Maps;
...
// Add the MapControl and the specify maps authentication key.
MapControl MapControl2 = new MapControl();
MapControl2.ZoomInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.TiltInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.MapServiceToken = "EnterYourAuthenticationKeyHere";
pageGrid.Children.Add(MapControl2);
取得和設定地圖驗證金鑰
您必須先將地圖驗證金鑰指定為 MapServiceToken 屬性的值,才能使用 MapControl 和地圖服務。 在上述範例中,將 EnterYourAuthenticationKeyHere
取代為您從 Bing 地圖服務開發人員中心取得的金鑰。 「警告:未指定的 MapServiceToken」文字會繼續顯示在控制項下方,直到您指定地圖驗證金鑰為止。 如需取得和設定地圖驗證金鑰的詳細資訊,請參閱要求地圖驗證金鑰。
設定地圖的位置
將地圖指向您想要的任何位置或使用使用者的目前位置。
設定地圖的起始位置
藉由在程式碼中指定 MapControl 的 Center 屬性,或在 XAML 標記中繫結屬性,來設定要在地圖上顯示的位置。 下列範例會顯示以西雅圖市為中心的地圖。
注意
由於字串無法轉換成 Geopoint,因此除非使用資料繫結,否則您無法在 XAML 標記中指定 Center 屬性的值。 (此限制也適用於 MapControl.Location 附加屬性。)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Specify a known location.
BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 47.604, Longitude = -122.329 };
Geopoint cityCenter = new Geopoint(cityPosition);
// Set the map location.
MapControl1.Center = cityCenter;
MapControl1.ZoomLevel = 12;
MapControl1.LandmarksVisible = true;
}
設定地圖的目前位置
您的應用程式必須先呼叫 RequestAccessAsync 方法,才能存取使用者的位置。 此時,您的應用程式必須在前景,且 RequestAccessAsync 必須是從 UI 執行緒呼叫。 在使用者授與您的應用程式存取其位置的權限之前,您的應用程式將無法存取位置資料。
使用 Geolocator 類別的 GetGeopositionAsync 方法來取得裝置的目前位置 (如果有位置可用)。 若要取得對應的 Geopoint,請使用地理位置地理座標的 Point 屬性。 如需詳細資訊,請參閱取得目前的位置。
// Set your current location.
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
// Get the current location.
Geolocator geolocator = new Geolocator();
Geoposition pos = await geolocator.GetGeopositionAsync();
Geopoint myLocation = pos.Coordinate.Point;
// Set the map location.
MapControl1.Center = myLocation;
MapControl1.ZoomLevel = 12;
MapControl1.LandmarksVisible = true;
break;
case GeolocationAccessStatus.Denied:
// Handle the case if access to location is denied.
break;
case GeolocationAccessStatus.Unspecified:
// Handle the case if an unspecified error occurs.
break;
}
當您在地圖上顯示裝置的位置時,請考慮顯示圖形,並根據位置資料的正確性來設定縮放層級。 如需詳細資訊,請參閱定位感知應用程式的指導方針。
變更地圖的位置
若要變更出現在 2D 地圖中的位置,請呼叫 TrySetViewAsync 方法的其中一個多載。 使用該方法指定 Center、ZoomLevel、Heading 和 Pitch 的新值。 您也可以藉由提供 MapAnimationKind 列舉中的常數,指定當檢視變更時要使用的選擇性動畫。
若要變更 3D 地圖的位置,請改用 TrySetSceneAsync 方法。 如需詳細資訊,請參閱顯示空照 3D 檢視。
呼叫 TrySetViewBoundsAsync 方法,在地圖上顯示 GeoboundingBox 的內容。 例如,使用這個方法,在地圖上顯示路線或部分路線。 如需詳細資訊,請參閱在地圖上顯示路線和路線指引。
變更地圖的外觀
若要自訂地圖的外觀和風格,請將地圖控制項的 StyleSheet 屬性設定為任何現有的 MapStyleSheet 物件。
myMap.StyleSheet = MapStyleSheet.RoadDark();
您也可以使用 JSON 來定義自訂樣式,然後使用該 JSON 來建立 MapStyleSheet 物件。
使用地圖樣式表編輯器應用程式,能夠以互動方式建立樣式表 JSON。
myMap.StyleSheet = MapStyleSheet.ParseFromJson(@"
{
""version"": ""1.0"",
""settings"": {
""landColor"": ""#FFFFFF"",
""spaceColor"": ""#000000""
},
""elements"": {
""mapElement"": {
""labelColor"": ""#000000"",
""labelOutlineColor"": ""#FFFFFF""
},
""water"": {
""fillColor"": ""#DDDDDD""
},
""area"": {
""fillColor"": ""#EEEEEE""
},
""political"": {
""borderStrokeColor"": ""#CCCCCC"",
""borderOutlineColor"": ""#00000000""
}
}
}
");
如需完整的 JSON 項目參考,請參閱 地圖樣式表參考。
您可以從現有的樣式表開始,然後使用 JSON 覆寫任何您想要的元素。 此範例從現有的樣式開始,並使用 JSON 只變更水域的色彩。
MapStyleSheet \customSheet = MapStyleSheet.ParseFromJson(@"
{
""version"": ""1.0"",
""elements"": {
""water"": {
""fillColor"": ""#DDDDDD""
}
}
}
");
MapStyleSheet builtInSheet = MapStyleSheet.RoadDark();
myMap.StyleSheet = MapStyleSheet.Combine(new List<MapStyleSheet> { builtInSheet, customSheet });
注意
您在第二個樣式表中定義的樣式會覆寫第一個樣式。
設定方向和視角
放大、縮小、旋轉和傾斜地圖攝影機,以取得您想要效果的正確角度。 試試看這些屬性。
- 藉由設定 Center 屬性,將地圖的中心設定為地理點。
- 將 ZoomLevel 屬性設定為介於 1 到 20 之間的值,以設定地圖的縮放層級。
- 設定 Heading 屬性來設定地圖的旋轉角度,其中 0 或 360 度 = 北、90 = 東、180 = 南、270 = 西。
- 將 DesiredPitch 屬性設定為介於 0 到 65 度之間的值,以設定地圖的傾斜度。
顯示和隱藏地圖功能
藉由設定 MapControl 的下列屬性值,顯示或隱藏道路和地標等地圖功能。
啟用或停用 LandmarksVisible 屬性,在地圖上顯示建築物和地標。
注意
您可以顯示或隱藏建築物,但無法防止它們以三維形式出現。
啟用或停用 PedestrianFeaturesVisible 屬性,在地圖上顯示行人設施,如公共樓梯。
啟用或停用 TrafficFlowVisible 屬性,在地圖上顯示交通流量。
將 WatermarkMode 屬性設定為其中一個 MapWatermarkMode 常數,以指定是否在地圖上顯示浮水印。
將 MapRouteView 新增至地圖控制項的 Routes 集合,在地圖上顯示駕駛或步行路線。 如需詳細資訊和範例,請參閱在地圖上顯示路線和路線指引。
如需如何在 MapControl 中顯示圖釘、圖形和 XAML 控制項的資訊,請參閱在地圖上顯示興趣點 (POI)。
顯示街景
街景是出現在地圖控制項上方的位置的街道層級視角。
請考慮將「街景」檢視中的體驗與最初顯示在地圖控制項中的地圖分開。 例如,在街景中變更位置不會改變街景下方地圖的位置或外觀。 當您關閉街景 (透過按一下控制項右上角的 X) 後,原始地圖保持不變。
顯示街景
- 檢查 IsStreetsideSupported,判斷裝置是否支援街景功能。
- 如果支援街景功能,請呼叫 FindNearbyAsync,在指定的位置附近建立 StreetsidePanorama。
- 藉由檢查 StreetsidePanorama 是否不為 Null,來判斷是否找到附近全景
- 如果找到附近的全景,請為地圖控制項的 CustomExperience 屬性建立 StreetsideExperience。
此範例示範如何顯示類似上一個影像的街景。
注意
如果地圖控制項的大小太小,則不會顯示概觀圖。
private async void showStreetsideView()
{
// Check if Streetside is supported.
if (MapControl1.IsStreetsideSupported)
{
// Find a panorama near Avenue Gustave Eiffel.
BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 48.858, Longitude = 2.295};
Geopoint cityCenter = new Geopoint(cityPosition);
StreetsidePanorama panoramaNearCity = await StreetsidePanorama.FindNearbyAsync(cityCenter);
// Set the Streetside view if a panorama exists.
if (panoramaNearCity != null)
{
// Create the Streetside view.
StreetsideExperience ssView = new StreetsideExperience(panoramaNearCity);
ssView.OverviewMapVisible = true;
MapControl1.CustomExperience = ssView;
}
}
else
{
// If Streetside is not supported
ContentDialog viewNotSupportedDialog = new ContentDialog()
{
Title = "Streetside is not supported",
Content ="\nStreetside views are not supported on this device.",
PrimaryButtonText = "OK"
};
await viewNotSupportedDialog.ShowAsync();
}
}
顯示空照 3D 檢視
使用 MapScene 類別指定地圖的 3D 視角。 地圖場景代表了地圖中呈現的 3D 檢視。 MapCamera 類別代表顯示這樣檢視畫面的攝影機的位置。
若要讓地圖表面的建築物和其他特徵以 3D 的形式出現,請將地圖控制項的 Style 屬性設定為 MapStyle.Aerial3DWithRoads。 這是具有 Aerial3DWithRoads 樣式的 3D 檢視範例。
顯示 3D 檢視
- 檢查 Is3DSupported,判斷裝置是否支援 3D 檢視。
- 如果支援 3D 檢視,請將地圖控制項的 Style 屬性設定為 MapStyle.Aerial3DWithRoads。
- 使用其中一個 CreateFrom 方法建立 MapScene 物件,例如 CreateFromLocationAndRadius 和 CreateFromCamera。
- 呼叫 TrySetSceneAsync 以顯示 3D 檢視。 您也可以藉由提供 MapAnimationKind 列舉中的常數,指定當檢視變更時要使用的選擇性動畫。
此範例示範如何顯示 3D 檢視。
private async void display3DLocation()
{
if (MapControl1.Is3DSupported)
{
// Set the aerial 3D view.
MapControl1.Style = MapStyle.Aerial3DWithRoads;
// Specify the location.
BasicGeoposition hwGeoposition = new BasicGeoposition() { Latitude = 43.773251, Longitude = 11.255474};
Geopoint hwPoint = new Geopoint(hwGeoposition);
// Create the map scene.
MapScene hwScene = MapScene.CreateFromLocationAndRadius(hwPoint,
80, /* show this many meters around */
0, /* looking at it to the North*/
60 /* degrees pitch */);
// Set the 3D view with animation.
await MapControl1.TrySetSceneAsync(hwScene,MapAnimationKind.Bow);
}
else
{
// If 3D views are not supported, display dialog.
ContentDialog viewNotSupportedDialog = new ContentDialog()
{
Title = "3D is not supported",
Content = "\n3D views are not supported on this device.",
PrimaryButtonText = "OK"
};
await viewNotSupportedDialog.ShowAsync();
}
}
取得位置的相關資訊
呼叫 MapControl 的下列方法,以取得地圖上位置的相關資訊。
- TryGetLocationFromOffset 方法 - 取得對應至地圖控制項檢視區中指定點的地理位置。
- GetOffsetFromLocation 方法 - 取得對應至指定地理位置的地圖控制項檢視區。
- IsLocationInView 方法 - 判斷地圖控制項的檢視區中目前是否顯示指定的地理位置。
- FindMapElementsAtOffset 方法 - 取得位於地圖控制項檢視區中指定點的地圖元素。
處理互動和變更
處理 MapControl 的下列事件,以處理地圖上的使用者輸入手勢。 藉由檢查 MapInputEventArgs 的 Location 和 Position 屬性的值,取得地圖上地理位置的相關資訊,以及檢視區中發生手勢的實體位置。
藉由處理控制項的 LoadingStatusChanged 事件,判斷地圖是否正在載入或已完成載入。
處理 MapControl 的下列事件,處理使用者或應用程式變更地圖設定時所發生的變更。
最佳做法建議
使用充足的螢幕空間 (或整個螢幕) 來顯示地圖,讓使用者不必過度平移和縮放,即可檢視地理資訊。
如果地圖僅用於呈現靜態、資訊性的檢視,那麼使用較小的地圖可能更合適。 如果您選擇較小的靜態地圖,請根據可用性來確定其尺寸:要夠小以節省螢幕空間,但又要夠大以確保清晰可讀。
將地圖場景中的興趣點嵌入地圖元素中;任何額外資訊可以顯示為暫時性的 UI,覆蓋在地圖場景上。