本文主要内容是讲述如何创建基于 Windows Universal App 的Windows 10 3D地图应用,涉及的Windows 10新特性包括 Bing Maps 控件、Compiled data bindings (x:Bind),SplitView 和Hamburger。
本文中的示例源代码已在github 上共享( https://github.com/gaoxuesong/navigado )。
获取Bing Maps密钥
在 Universal Windows App 中使用必应地图需要从 Bing Maps Developer Center 获取地图验证密钥,并将其添加到应用中。
创建新密钥:
- 在浏览器中登陆 Bing Maps Developer Center ( https://www.bingmapsportal.com ),建议以您的 Microsoft 账户登陆。首次登陆选择要与必应地图帐户关联的帐户。如果你想要使用自己的 Microsoft 帐户,请单击"是"。否则,请单击"使用其他帐户登录"。
- 创建必应地图帐户。依次输入"帐户名称"、"联系人姓名"、"公司名称"、"电子邮件地址"和"电话号码"。在接受使用条款后,单击"创建"。
- 在"我的帐户"菜单下,单击"创建或查看密钥"。
- 单击用于创建"新密钥"的链接。
-
创建新密钥。完成"创建密钥"表格,然后单击"创建"。
- 应用程序名称:此信息仅供你作参考之用,以将其与其他密钥区分开来。
- 应用程序 URL(可选):此信息仅供你作参考之用。
- 密钥类型:选择Basic 或者 Enterprise。
- 应用程序类型:选择Universal App以便在你的 Universal Windows App 中使用。
将创建的密钥复制到安全位置,在下面的步骤中我们会将其加入到Universal Windows App 中。
创建基于 Universal Windows App的地图应用
在Visual Studio 2015中创建新工程
打开 Visual Studio 2015(目前最新版为 Visual Studio 2015 RC),选择File > New Project。
展开Installed > Templates ,选择 Windows Universal > Blank App ( Windows Universal),如下图所示。
设定工程的名称即在 Name 中输入应用的名称,本例为"navigado"。Navigado是世界语导航的意思。
设定工程保存的目录,即在 Location 中设定工程保存的目录。
点击 OK 即创建新的Windows 10 Universal App。
添加地图控件和绑定密钥
在 XAML 页面或代码中,MapControl 需要 Windows.UI.Xaml.Controls.Maps 命名空间的命名空间声明。
本例中是手动将 MapControl 添加到 MainPage.XAML 页面,并在该页面顶部手动添加命名空间声明:
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
若要在你的 Universal Windows App 中使用 MapControl 和地图服务 (Windows.Services.Maps),则需要地图验证密钥。将该密钥添加到地图控件和地图服务对象(如果适用)。
若要验证 MapControl,请使用该密钥来设置 MapServiceToken 属性值。你可以在代码中设置该属性,也可以在 XAML 标记中设置。
在本例中采用 Compiled data bindings (x:Bind) 的方式将必应地图的密钥绑定至 XAML 文件中的 MapControl,代码如下:
File: MainPage.xaml
x:Name="myMapControl"
MapServiceToken="{x:Bind BingMapsToken, Mode=OneWay}"
Loaded="MapControlLoaded"/>
在 MainPage.xaml.cs中的 MainPage 类中设定 BingMapsToke 的值,BingMapsToken的值即是在第一步骤中获取的 Bing Maps的密钥。代码如下:
File: MainPage.xaml.cs
private String BingMapsToken = "BingMapsToken by Bing Maps dev center ";
显示3D地图和设定地图中心
在MainPage.xmal.cs代码文件的顶部手动添加命名空间声明。
using Windows.UI.Xaml.Controls.Maps;
using Windows.Devices.Geolocation;
在 MapControl 类的 MapControlLoaded方法中添加如下的代码,显示3D地图并设定地图中心:
File: MainPage.xaml.cs
public BasicGeoposition seattleLocation = new BasicGeoposition()
{
//Geopoint for Seattle
Latitude = 47.604,
Longitude = -122.329
};
public BasicGeoposition spaceNeedlePosition = new BasicGeoposition()
{
//Geopoint for Seattle
Latitude = 47.6204,
Longitude = -122.3491
};
private async void MapControlLoaded(object sender, RoutedEventArgs e)
{
myMapControl.Center = new Geopoint(seattleLocation);
myMapControl.ZoomLevel = 12;
if (myMapControl.Is3DSupported)
{
this.myMapControl.Style = MapStyle.Aerial3DWithRoads;
Geopoint spaceNeedlePoint = new Geopoint(seattleLocation);
MapScene spaceNeedleScene = MapScene.CreateFromLocationAndRadius(spaceNeedlePoint,
400, /* show this many meters around */
135, /* looking at it to the south east*/
60 /* degrees pitch */);
await myMapControl.TrySetSceneAsync(spaceNeedleScene);
}
else
{
//string status = "3D views are not supported on this device.";
this.myMapControl.Style = MapStyle.Aerial;
}
}
可使用MapControl 的 Is3DSupported 方法判断设备是否支持3D地图显示,代码
this.myMapControl.Style = MapStyle.Aerial3DWithRoads;
实现了地图的切换至3D模式。调用MapControl.TrySetSceneAsync 方法切换地图场景。
其中 使用BasicGeoposition 类实例化两个演示地点 seattleLocation 和 spaceNeedlePosition。
在地图上显示图钉、图像和地理空间形状
可通过将图钉、图像和形状添加到 MapElements 集合,在 MapControl 上显示集合中的图钉或者图像。
- 通过使用 MapIcon 类显示图像(例如,图钉)和文本(可选)。使用 Image 属性设定自定义图像。
- 定义和显示 MapPolygon 或 MapPolyline。
提示 在 XAML 标记中,无法以声明方式绑定到 MapElements 集合。
以下是未对 Title 属性指定任何值的MapIcon默认图像。
下面的示例显示了 Seattle 的地图并添加了自定义图像和标题的 MapIcon,来指示 Space Needle 的位置。您可以更具您应用的逻辑在需要的时候添加图钉,比如在OnNavigatedTo 方法中设定。本例中在MainPage.xmal.cs代码文件中的 MapControlLoaded 方法中添加图钉。
File: MainPage.xaml.cs
MapIcon seattleMapIcon = new MapIcon();
seattleMapIcon.Location = new Geopoint(seattleLocation);
seattleMapIcon.NormalizedAnchorPoint = new Point(0.5, 1.0);
seattleMapIcon.Title = "Parking here";
seattleMapIcon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/mappin.png"));
myMapControl.MapElements.Add(seattleMapIcon);
SplitView 和Hamburger
在Windows 10 应用设计的典型特征就是 SplitView 和 Hamburger,本文当然不会漏过此新特性。
在 MainPage.xaml 中添加如下代码:
IsItemClickEnabled="True" ItemClick="NavLinksList_ItemClick" ItemsSource="{x:Bind NavLinks}" ItemTemplate="{StaticResource NavLinkItemTemplate}"/> Margin="14,40,0,0" VerticalAlignment="Top" x:Name="Hamburger" FontFamily="Segoe MDL2 Assets" Glyph="" Foreground="Green" PointerPressed="Button_Click" /> 在 MainPage.xaml 中添加代码设定ListView 的ItemTemplate: ListView 的ItemsSource 以x:Bind方式绑定,绑定的数据源在 MainPage.xaml.cs 中设定: private ObservableCollection { new NavLink() { Label = "Map", Symbol = Windows.UI.Xaml.Controls.Symbol.Map }, new NavLink() { Label = "MapDrive", Symbol = Windows.UI.Xaml.Controls.Symbol.MapDrive }, new NavLink() { Label = "MapPin", Symbol = Windows.UI.Xaml.Controls.Symbol.MapPin }, new NavLink() { Label = "Camera", Symbol = Windows.UI.Xaml.Controls.Symbol.Camera }, }; public ObservableCollection { get { return _navLinks; } } 我们在ListView 中的ItemClick 事件可响应用户的交互。在MainPage.xaml.cs中实现 NavLinksList_ItemClick 方法,通过判断 ListView 中Item的 Lable 可知用户究竟点击了哪一个Item,即可执行不同的业务逻辑。在本例中,我们添加Lable为"Map"的响应切换地图显示模式,其代码如下: private void NavLinksList_ItemClick(object sender, ItemClickEventArgs e) { String label = (e.ClickedItem as NavLink).Label; switch (label) { case "Map": if (myMapControl.Is3DSupported) { if ( this.myMapControl.Style == MapStyle.Aerial3DWithRoads) { this.myMapControl.Style = MapStyle.Road; } else { this.myMapControl.Style = MapStyle.Aerial3DWithRoads; } MapIcon seattleMapIcon = new MapIcon(); seattleMapIcon.Location = new Geopoint(seattleLocation); seattleMapIcon.NormalizedAnchorPoint = new Point(0.5, 1.0); seattleMapIcon.Title = "Parking here"; seattleMapIcon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/mappin.png")); myMapControl.MapElements.Add(seattleMapIcon); } break; default: break; } } 在前面的代码中我们将FontIcon的x:Name 属性设定为Hamburger,现在 MainPage.xaml.cs 中添加PointerPressed 事件响应Button_Click 即实现了Windows 10 的Hamburger。 private void Button_Click(object sender, RoutedEventArgs e) { Splitter.IsPaneOpen = (Splitter.IsPaneOpen == true) ? false : true; //StatusBorder.Visibility = Visibility.Collapsed; } 代码运行效果如下: 如果您的设备支持多点手势触控,则旋转地图,效果超酷。旋转后可清晰看到图钉的文字"Parking here"。 点击 Hamburger 的 "Map"按钮切换地图显示模式,如下图所示。 使用 Visual Studio 2015 开发 Windows 10 应用时,您会看到下图的提示,提醒您激活开发者模式。 那么如何激活开发者模呢? 如果您的Windows 10已经升级至 Pro Insider Preview Evaluation Copy. Build 10130 以上,或者您看此文时Windows 10 正式版已经发布,那么在 Settings 选择 Update & security > For developers ,选择 Developer Mode 激活开发者模式。 在 Settings 选择 Update & security,然后选择 For developers 。 Windows 10 desktop 作者:雪松 Microsoft MVP -- Windows Platform Development, Hortonworks Certified Apache Hadoop 2.0 Developer 激活设备的开发者模式
Windows 10 Phones
Use gpedit to enable your device
Use regedit to enable your device
Use PowerShell to enable your device