Share via



2017 年 5 月

第 32 卷,第 5 期

此文章由机器翻译。

新式應用程式 - 地圖控制項的深度剖析

Frank La La

Frank La Vigne在我的專欄上個月,我示範了通用 Windows 平台 (UWP) 應用程式和新增對應到您的 UWP 應用程式是多麼的 Bing 地圖控制項的基本功能。本月我將示範如何運用一些更進階的功能,可讓您的應用程式真的突顯出來,並為使用者提供絕佳的體驗。我也將探討如何內嵌豐富的圖像和 3D 經驗的 Bing 地圖服務,直接將您的應用程式。

入門

深入了解如何將地圖控制項加入和取得 MapServiceToken,請參閱我上個月的專欄 (msdn.com/magazine/mt797655)。基於本專欄的目的,建立新的空白 UWP 專案在 Visual Studio 中從 [檔案] 功能表中選擇 [新的專案。接著展開已安裝的範本 |Windows |空白的應用程式 (Windows 通用)。將專案命名為 DCTourismMap,然後按一下 [確定]。立即之後,會出現對話方塊,詢問您的應用程式應將目標設的 Windows 版本。此專案中,預設選項是將沒問題,因此您只要按一下 [確定]。在 MainPage.xaml 檔案中,加入頁面標記中的下列命名空間宣告︰

xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"

接下來,將地圖控制項加入頁面上,在頁面上的方格控制項中加入下列 XAML (確定插入您從 Bing 地圖入口網站,在接收到的 MapServiceToken 值 bingmapsportal.com):

<maps:MapControl x:Name="mapControl" MapServiceToken="{Insert Key Here}" >
</maps:MapControl>

現在,您就可以執行方案,您應該會看到地圖控制項涵蓋整個應用程式的螢幕。使用此控制項中的位置,您現在可以開始利用所有 UWP 的 Bing 地圖控制項所提供。

自訂地圖標記

在我的上一篇專欄中我提到將標記加入至對應。標記只是找出地圖上的位置。不過,UWP 地圖控制項也可讓開發人員將對應至自訂的 XAML 控制項,XAML 控制項,以及提供增強的互動性。目標是要建立的地圖,展示了各種地標居於華府。在地圖上的標記會各自映像的位置,並按一下它時,便會出現其相關的網站。最後,對應圖應該看起來像**[圖 1**。

具有自訂的按鈕控制項放在對應指定的位置
[圖 1 對應,加上自訂的按鈕控制項放在指定的位置

若要達成此目的,地圖控制項必須 MapItemsControl、 一個 DataTemplate,還有一些新增其他屬性。首先,修改 [地圖控制項中的 mainpage.xaml 檔案,如下所示的 XAML [圖 2

[圖 2 修改地圖控制項 MainPage.xaml 中的 XAML

<maps:MapControl x:Name="mapControl" Loaded="mapControl_Loaded"
  MapServiceToken="[Insert Key Here]">
  <maps:MapItemsControl x:Name="sitesMapItemsControl" >
    <maps:MapItemsControl.ItemTemplate>
      <DataTemplate>
        <Button Click="itemButton_Click"
          maps:MapControl.Location="{Binding Location}" >
          <StackPanel>
            <Border Background=
              "{ThemeResource ApplicationPageBackgroundThemeBrush}">
              <TextBlock Text="{Binding Name}"/>
            </Border>
            <Image Source="{Binding ImageUri}" Width="100" Height="50"
              Stretch="UniformToFill">
            </Image>
          </StackPanel>
        </Button>
      </DataTemplate>
    </maps:MapItemsControl.ItemTemplate>
  </maps:MapItemsControl>
</maps:MapControl>

請仔細閱讀 XAML,並記下 [MapItemsControl DataTemplate 繫結具有數個屬性的物件。下一個步驟是建立包含這些屬性的模型。在 [方案總管專案上按一下滑鼠右鍵、 按一下 [新增],然後按一下 [新增資料夾] 在後續的功能表。將的資料夾命名為模型,然後按 enter 鍵。[模型] 資料夾上按一下滑鼠右鍵、 按一下 [新增],然後選擇新項目。在後續的對話方塊中,選擇 [從範本清單中的 [類別]。將新的類別檔案 POI.cs,然後按一下 [確定] (POI 代表感興趣的點)。

修改 POI.cs 檔案,使其與類似下列的程式碼的內容︰

using System;
using Windows.Devices.Geolocation;
namespace DCTourismMap.Model
{
  public class POI
  {
    public string Name { get; set; }
    public Geopoint Location { get; set; }
    public Uri ImageUri { get; set; }
    public Uri InformationUri { get; set; }
  }
}

接下來,開啟 MainPage.xaml.cs 檔案,並加入事件處理常式中所示**[圖 3**置華盛頓特區的對應,並設定縮放層級的重點在於國家購物中心周圍的區域。LoadPointsOfInterest 方法會建立並填入清單 < POI >。MapControl_Loaded 方法的最後一行會將 MapItemsControl ItemsSource 設這份清單。

[圖 3 置中在華盛頓特區的對應,並建立要擴展觀光點的事件處理常式

private void mapControl_Loaded(object sender, RoutedEventArgs e)
{
  this.mapControl.Center = new Geopoint(
    new BasicGeoposition() { Latitude = 38.889906, Longitude = -77.028634 });
  this.mapControl.ZoomLevel = 16;
  sitesMapItemsControl.ItemsSource = LoadPointsOfInterest();
}
private List<POI> LoadPointsOfInterest()
{
  List<POI> pointsOfInterest = new List<POI>();
  pointsOfInterest.Add(new POI()
  {
    Name ="Washington Monument",
    ImageUri= new Uri(
      "https://upload.wikimedia.org/wikipedia/commons/e/ea/
      Washington_October_2016-6_%28cropped%29.jpg"),
    InformationUri = new Uri("https://www.nps.gov/wamo/index.htm"),
    Location = new Geopoint(
      new BasicGeoposition() { Latitude = 38.8895, Longitude = -77.0353 })
  });
pointsOfInterest.Add(new POI()
{
  Name = "White House",
  ImageUri = new Uri(
    "http://www.publicdomainpictures.net/pictures/20000/nahled/white-house.jpg"),
  InformationUri = new Uri("https://www.whitehouse.gov"),
  Location = new Geopoint(
    new BasicGeoposition() { Latitude = 38.897734, Longitude = -77.036535 })
});
pointsOfInterest.Add(new POI()
{
  Name = "The US Capitol",
  ImageUri = new Uri(
    "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/US_
    Capitol_west_side.JPG/320px-US_Capitol_west_side.JPG"),
  InformationUri = new Uri("https://www.capitol.gov/"),
  Location = new Geopoint(
    new BasicGeoposition() { Latitude = 38.889892, Longitude = -77.009341 })
});
return pointsOfInterest;
}

加入互動功能

現在,新增下列事件處理常式程式碼的 DataTemplate 中指定的按鈕控制項︰

private void itemButton_Click(object sender, RoutedEventArgs e)
{
var buttonSender = sender as Button;
POI poi = buttonSender.DataContext as POI;
Launcher.LaunchUriAsync(poi.InformationUri);
}

事件處理常式會擷取控制項觸發交給 LaunchURIAsync 啟動器類別方法的 InformationURI 屬性與事件相關聯的 POI 物件。Uri 的網站,這會啟動系統上的預設瀏覽器,並載入傳送給它的 URI。啟動器類別位於 Windows.System 命名空間。您可以選擇加入命名空間,以手動方式與使用陳述式或讓 Visual Studio 處理詳細資料。啟動器類別可以做更多事比只需開啟瀏覽器。閱讀更多關於在啟動器類別 bit.ly/2n4Zx0F

現在就執行方案,並看起來應該像**[圖 1**。按一下任何標記會顯示有關地標的網站。

三個維度中的對應

Bing 地圖 UWP 控制項更吸引人的層面之一是它能夠呈現 3D 影像的世界各地許多位置。若要開始,建立新的專案使用入門 」 一節所述的步驟。此時,不過,命名方案 3DMaps。請務必要將命名空間宣告加入至 MainPage.xaml 檔案,以包含對應的命名空間。插入顯示的 XAML [圖 4 MainPage.xaml 地圖控制項和按鈕,可控制 3D 檢視對應的一系列的頁面節點中。

[圖 4 XAML 來建立 3D 地圖應用程式的介面

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <Grid.RowDefinitions>
    <RowDefinition Height="30*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="549*"/>
  </Grid.RowDefinitions>
  <StackPanel Orientation="Horizontal"  Grid.Row="0">
    <Button Name="btn3DView" Content="3D View" Click="btn3DView_Click" />
  </StackPanel>
  <StackPanel Orientation="Vertical" Grid.Row="1">
    <TextBlock FontWeight="Bold">Heading: </TextBlock>
    <TextBlock Text="{Binding ElementName=mapControl,Path=Heading,
      Mode=OneWay}"></TextBlock>
    <TextBlock FontWeight="Bold">Pitch: </TextBlock>
    <TextBlock Text="{Binding ElementName=mapControl,Path=ActualCamera.Pitch,
      Mode=OneWay}"></TextBlock>
  </StackPanel>
  <maps:MapControl x:Name="mapControl" Grid.Row="2"
    MapServiceToken="[Insert Token Here]">
  </maps:MapControl>
</Grid>

操作 3D Map

3D 模式中檢視地圖很簡單,而且我接觸到的簡短在我的專欄上個月。不過,所有從該資料行的範例應用程式未被切換到 3D 檢視。現在,我們來看看如何以程式設計方式操作 3D 地圖。新增 [btn3Dview] 按鈕的事件處理常式中所示**[圖 5**。

[圖 5 程式碼,以切換到著重於較低的曼哈頓 3D 地圖檢視

private async void btn3DView_Click(object sender, RoutedEventArgs e)
{
  if (this.mapControl.Is3DSupported)
  {
    this.mapControl.Style = MapStyle.Aerial3DWithRoads;
    BasicGeoposition nycDowntownLatLong = new BasicGeoposition()
    {
      Latitude = 40.712929,
      Longitude = -74.018291
    };
    double radius = 550;
    double heading = 90;
    double pitch = 80;
    MapScene nycDowntownScene = MapScene.CreateFromLocationAndRadius(
      new Geopoint(nycDowntownLatLong), radius, heading, pitch );
    await mapControl.TrySetSceneAsync(nycDowntownScene);
  }
}

立即,您會發現切換至 Aerial3DWithRoads 地圖控制項樣式屬性的程式碼。此外,我想要能夠控制檢視相關的特定詳細資料。在此範例中,我想要顯示的較低的曼哈頓 skyline。若要這樣做,我需要 「 框架擷取 「 非常攝影師會藉由設定攝影機和點的特定位置和指定之的角度的 3D 空間中,選取位置的方式相同。在圖表**[圖 6**提供概觀。

MapScene 的概念圖
[圖 6 的 MapScene 的概念圖

若要設定所需的圖片,開始緯度和經度定義位置。然後定義變數 radius、 標題及字距等性質來控制相機的檢視。接下來,建立使用 MapScene.CreateFromLocationAndRadius 方法 MapScene。這會建立場景,在指定的緯度和經度從離開以公尺為單位 (radius) 在一定距離上置中。標題是指相機所面臨的方向。這個值可以從 0 到 360,代表羅盤點的任何位置。如需參考,90 值代表東部。值為零北、 180 是南,而且 270 可以西部。音調指的是面前的相機角度。零是由上而下檢視,90 會相交。

一旦建立 MapScene 物件時,使用 TrySetSceneAsync 方法會將它套用到地圖控制項。現在執行專案。按一下 3D 檢視,您的應用程式應該會顯示較低的曼哈頓的 3D 檢視。請注意,您可以控制透過滑鼠和鍵盤對應。如果您的裝置支援觸控功能,您也可以使用觸控筆勢控制標題、 縮放層級和地圖控制項的點數。

雖然 having 滑鼠、 鍵盤和筆勢內建於地圖控制項的控制項是很好,那就天下太平了以程式設計方式操作 3D 地圖檢視區。

關閉應用程式,然後返回 [Visual Studio 中的 MainPage.xaml 檔案中的程式碼。Btn3DView 按鈕之後,StackPanel 控制項中加入下列 XAML:

<Button Name="btnRotateCameraLeft" Content="Rotate Left"
  Click="btnRotateCameraLeft_Click" />
<Button Name="btnRotateCameraRight" Content="Rotate Right"
  Click="btnRotateCameraRight_Click" />
<Button Name="btnTiltCameraDown" Content="Tilt Down"
  Click="btnTiltCameraDown_Click" />
<Button Name="btnTiltCameraUp" Content="Tilt Up"
  Click="btnTiltCameraUp_Click" />

此 XAML 會建立四個按鈕來控制地圖檢視區。兩個控制標題是︰ 其中一個權限和其他開啟左邊。兩個是用來控制越大,音調︰ 傾斜向上一個,以向下傾斜另一個。現在,加入事件處理常式中所示**[圖 7**,MainPage.xaml.cs 檔案。

[圖 7 控制 MapScene 相機的 UI 按鈕的事件處理常式

private async void btnRotateCameraLeft_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryRotateAsync(-30);
}
private async void btnRotateCameraRight_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryRotateAsync(30);
}
private async void btnTiltCameraUp_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryTiltAsync(15);
}
private async void btnTiltCameraDown_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryTiltAsync(-15);
}

方法 TryRotateAsync 和 TryTiltAsync 都採取 double,代表旋轉或分別傾斜角度類型的參數。負值會向左旋轉,向下傾斜。正值會向右旋轉並向上傾斜。現在執行應用程式。按一下 [3D 檢視,並試試我們現在有按鈕在地圖上的控制項。您的應用程式應該看起來像**[圖 8**。

按一下旋轉右數次後應用程式
[圖 8 按一下旋轉右數次後的應用程式

StreetSide 檢視

Bing 地圖服務的其他強大功能是 StreetSide 檢視中,可讓使用者瀏覽互動式全景,一系列的位置。UWP 地圖控制項,您的應用程式現在有了可以在其中內嵌這項功能。

如果應用程式已在執行中,將它停止,並回到 Visual Studio。若要加入按鈕,以啟用 StreetSide 檢視 MainPage.xaml 檔案中加入下列 XAML:

<Button Name="btnStreetSide" Content="StreetSide" Click="btnStreetSide_Click" />

現在加入事件處理常式中的**[圖 9**啟用 StreetSide 檢視。

[圖 9 設定,並顯示較低的曼哈頓的 StreetSide 檢視

if (mapControl.IsStreetSideSupported)
{
  BasicGeoposition nycDowntownLatLong = new BasicGeoposition()
  {
    Latitude = 40.712929,
    Longitude = -74.018291
  };
  Geopoint nycDowntownPoint = new Geopoint(nycDowntownLatLong);
  StreetSidePanorama panoramaNearDowntownNYC =
    await StreetSidePanorama.FindNearbyAsync(nycDowntownPoint);
  if (panoramaNearDowntownNYC != null)
  {
    var nycSSE = new StreetSideExperience(panoramaNearDowntownNYC);
    mapControl.CustomExperience = nycSSE;
  }
  }
}

第一個步驟是檢查應用程式是否要依不是每個裝置都會支援它支援 StreetSide] 檢視中,在裝置上執行。下一個步驟是建立 GeoPoint 從 latitiude/經度座標。現在,將該 GeoPoint 傳遞至 FindNearbyAsync 方法,以找出具有 StreetSide 圖像可用的鄰近位置。如果沒有圖像接近該位置存在,此方法會傳回 null。

所有就是建立 StreetSide 經驗 StreetSide 全景物件傳遞給 StreetSide 經驗建構函式。若要切換 StreetSide 檢視地圖控制項,設定新建立的 StreetSide 經驗物件地圖控制項自訂經驗的屬性。

現在就執行方案,然後按一下 [StreetSide] 按鈕。按一下傾斜及傾斜縮小,應用程式應顯示的全球財務中心和自由塔 StreetSide 檢視。請注意,控制項回應鍵盤、 滑鼠和觸控。控制項甚至可讓您放大及探索環境。以下 StreetSide 檢視中,沒有概觀圖,可讓使用者瀏覽更進一步的區域。正在使用的應用程式,您可能已經注意到開啟左右,開啟按鈕無法再運作。

關閉應用程式並回到 Visual Studio 並修改 [關閉] 按鈕的事件處理常式。若要變更 StreetSide 檢視的標題,必須直接變更地圖控制項的標題屬性。若要偵測是否已啟用 StreetSide 檢視,請檢查自訂經驗屬性不是 null。開啟剩餘的修改事件處理常式,並開啟右邊的按鈕,讓它們看起來像是中的程式碼圖 10

[圖 10 更新支援 StreetSide 檢視旋轉的事件處理常式

private async void btnRotateCameraLeft_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryRotateAsync(-30);
  if (mapControl.CustomExperience != null)
  {
    mapControl.Heading = mapControl.Heading - 30;
  }
}
private async void btnRotateCameraRight_Click(object sender, RoutedEventArgs e)
{
  await mapControl.TryRotateAsync(30);
  if (mapControl.CustomExperience != null)
  {
    mapControl.Heading = mapControl.Heading + 30;
  }
}

再次執行此方案,然後按一下 [StreetSide] 按鈕,若要啟用 StreetSide 檢視。開啟左右,開啟按鈕現在可以運作。值得注意的是,在 3D 檢視中,設定地圖控制項的 [標題] 屬性,事實上,旋轉相機的檢視。不過,它沒有建立動畫的點之間,進行粗略的轉換。

總結

上個月有提到我在專欄中,對應的真正的行動裝置更是不可或缺的功能之一。利用轉換到數位的對應,對應會變得不只是可自訂,但互動式和沈浸式。在本專欄中,您會看到地圖控制項隨附 UWP 如何提供這些豐富的互動式功能和 3D 的圖像。在大部分情況下,存取對應服務和圖像來參加免費開發人員的您。


Frank La Vigne是主要的推廣經理 DataLeader.io,他可協助客戶運用搜尋化為存放區資料科學。定期在他的部落格 FranksWorld.com 和已製作成 YouTube 頻道呼叫的 Frank 世界電視 (FranksWorld.TV)。

感謝下列 Microsoft 技術專家來檢閱這份文件︰ Rachel Appel