2017 年 5 月
第 32 卷,第 5 期
此文章由机器翻译
新式应用 - 深入了解地图控件
通过 Frank La La
在我的专栏上个月,我演示了有关通用 Windows 平台 (UWP) 应用程序和添加映射到 UWP 应用程序是多么容易为必应地图控件的基本功能。本月我将向您展示如何利用一些更高级的功能,可使您的应用程序真正脱颖而出,并为您的用户提供出色的体验。我还将探讨如何嵌入丰富的图像和 Bing Maps 的直接插入您的应用程序的 3D 体验。
开始使用
有关如何添加地图控件并获得 MapServiceToken 深入探讨,请参阅我上个月的专栏 (msdn.com/magazine/mt797655)。出于本专栏,通过从文件菜单中选择新的项目创建在 Visual Studio 中的新的空白 UWP 项目。然后展开到已安装的模板 |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 Maps 控件所能提供。
自定义映射标记
在上期专栏里,我编写了有关将标记添加到映射。标记只是找出在地图上的位置。但是,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。右键单击 Models 文件夹,单击添加,然后选择新建项。在随后的对话框框中,选择从模板列表中的类。命名新的类文件 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要居中华盛顿 (哥伦比亚特区) 上的地图,并将重点介绍 National 购物中心周围的区域的缩放级别设置。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);
}
事件处理程序检索与触发事件并将 InformationURI 属性设为启动程序类的 LaunchURIAsync 方法将该控件关联的 POI 对象。对于 Uri 的 Web 站点,这将启动默认浏览器在系统上的,并加载发送给它的 URI。启动器类驻留在 Windows.System 命名空间中。必须添加手动具有 using 语句,或者让 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 Maps
以三维形式查看地图很简单,我简要谈及的简要在我的专栏上个月。但是,该示例应用程序从该列所做的只是切换到 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概述。
图 6 的 MapScene 的概念图
若要设置所需图片的步骤,请使用纬度和经度定义位置启动。然后定义的变量半径、 标题和 pitch 可以控制到摄像机的视图。接下来,创建使用 MapScene.CreateFromLocationAndRadius 方法 MapScene。这将创建一个场景,来在指定的纬度和经度一段距离某些消失以米为单位 (radius) 上居中。标题是指照相机所面临的方向。此值可以介于 0 到 360 之间,表示指南针点的任意位置。有关参考,值为 90 东表示。值为零是北、 180 南部,且 270 西部。俯仰是指从该处面向相机的角度。零是自上而下的视图,90 会垂直。
一旦创建 MapScene 对象时,它即使用 TrySetSceneAsync 方法应用于地图控件。现在运行该项目。单击 3D 视图,您的应用程序应显示较低的曼哈顿的 3D 视图。请注意,您可以控制通过鼠标和键盘映射。如果您的设备支持触控,你可能会使用触摸手势来控制标题、 缩放级别和音调地图控件。
尽管遇到鼠标,直接内置地图控件的键盘和手势控件很好,那就更好,以编程方式操作 3D 视区的映射。
关闭应用程序,并返回到 Visual Studio 中的 MainPage.xaml 文件中的代码。将以下 XAML 添加到 StackPanel 控件 btn3DView 按钮之后︰
<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 这些方法都采用双精度值,表示的角度旋转或倾斜,分别类型的参数。负值将向左旋转,向下倾斜。正值右转和向上倾斜。现在,运行该应用程序。单击 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 按钮。单击倾斜向上和向下倾斜,应用程序应显示的世界 Financial 中心和自由立式 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并且具有通道调用的 Frank 世界电视 YouTube (FranksWorld.TV)。
衷心感谢以下 Microsoft 技术专家对本文的审阅: Rachel Appel