原文:Windows phone 8 学习笔记(8) 定位地图导航

Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式、视图等。bing地图的定位误差比较大,在模拟器中测试新地图貌似比较理想。本节主要讲解下位置服务以及新地图控件的使用。

快速导航:

    一、定位服务

    二、地图和导航

一、定位服务

通过手机定位服务可以开发利用手机地理位置的应用。我们可以通过应用监视手机行踪,配合地图使用可以用于导航等。定位服务可以及时取得手机地理位置,也可以持续跟踪手机移动,还可以在后台运行。

1. 立即获取当前位置

我们可以通过一次操作获取当前位置,下面的代码演示了实现的方法。

[C#]

 private async void OneShotLocation_Click(object sender, RoutedEventArgs e)
{
//地理位置访问服务
Geolocator geolocator = new Geolocator();
//定义精度,米为单位
geolocator.DesiredAccuracyInMeters = 1; try
{
//开始获取当前位置的经纬度
Geoposition geoposition = await geolocator.GetGeopositionAsync();
LatitudeTextBlock.Text = "经度:" + geoposition.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = "纬度:" + geoposition.Coordinate.Longitude.ToString("0.00");
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x80004004)
{
StatusTextBlock.Text = "系统设置关闭了位置服务.";
} }
}

2. 持续跟踪位置信息

如果开启持续跟踪手机位置,当手机移动距离超出设定距离时,就会触发位置改变事件,这个时候我们就可以通过环境信息计算出手机的行动轨迹,速度方向等。下面演示了如何持续跟踪。

[C#]

Geolocator geolocator = null;
bool tracking = false; private void TrackLocation_Click(object sender, RoutedEventArgs e)
{ if (!tracking)
{
//地理位置访问服务
geolocator = new Geolocator();
//精度级别
geolocator.DesiredAccuracy = PositionAccuracy.High;
//超过多少米引发位置改变事件
geolocator.MovementThreshold = 100; //功能状态改变时
geolocator.StatusChanged += geolocator_StatusChanged;
//位置改变时
geolocator.PositionChanged += geolocator_PositionChanged; tracking = true;
TrackLocationButton.Content = "停止跟踪";
}
else
{
geolocator.PositionChanged -= geolocator_PositionChanged;
geolocator.StatusChanged -= geolocator_StatusChanged;
geolocator = null; tracking = false;
TrackLocationButton.Content = "跟踪位置";
StatusTextBlock.Text = "停止";
}
} void geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
string status = ""; switch (args.Status)
{
case PositionStatus.Disabled:
status = "位置服务设置被禁用";
break;
case PositionStatus.Initializing:
status = "正在初始化";
break;
case PositionStatus.NoData:
status = "无数据";
break;
case PositionStatus.Ready:
status = "已准备";
break;
case PositionStatus.NotAvailable:
status = "无法使用";
break;
case PositionStatus.NotInitialized:
break;
}
Dispatcher.BeginInvoke(() =>
{
StatusTextBlock.Text = status;
});
} void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
LatitudeTextBlock.Text = "经度:" + args.Position.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = "纬度:" + args.Position.Coordinate.Longitude.ToString("0.00");
});
}

3. 在后台持续跟踪

位置跟踪可以作为服务在后台运行,这个时候我们不需要更新UI,为了使我们的应用可以作为服务运行,我们需要右键打开清单文件,选择用XML文本编辑器的方式,替换DefaultTask节点为如下信息:

[XML]

      <DefaultTask Name="_default" NavigationPage="MainPage.xaml">
<BackgroundExecution>
<ExecutionType Name="LocationTracking" />
</BackgroundExecution>
</DefaultTask>

然后我们需要注册RunningInBackground事件,打开App.xaml添加事件Application_RunningInBackground,代码如下:

[XAML]

        <!--处理应用程序的生存期事件所需的对象-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"
RunningInBackground="Application_RunningInBackground"/>

在App.xaml.cs中添加静态变量RunningInBackground和Geolocator,当Application_RunningInBackground事件时RunningInBackground为true,当Application_Activated事件时,RunningInBackground为false。代码如下:

[C#]

//确定应用是否在后台运行
public static bool RunningInBackground { get; set; }
//提供对当前地理位置的访问
public static Geolocator Geolocator { get; set; } // 激活应用程序(置于前台)时执行的代码
// 此代码在首次启动应用程序时不执行
private void Application_Activated(object sender, ActivatedEventArgs e)
{
RunningInBackground = false;
} private void Application_RunningInBackground(object sender, RunningInBackgroundEventArgs args)
{
RunningInBackground = true;
}

在mainpage中添加如下代码:

[C#]

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (App.Geolocator == null)
{
App.Geolocator = new Geolocator();
App.Geolocator.DesiredAccuracy = PositionAccuracy.High;
App.Geolocator.MovementThreshold = 100;
App.Geolocator.PositionChanged += geolocator_PositionChanged;
}
} void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
if (!App.RunningInBackground)
{
Dispatcher.BeginInvoke(() =>
{
LatitudeTextBlock.Text = "经度:" + args.Position.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = "纬度:" + args.Position.Coordinate.Longitude.ToString("0.00");
});
}
else
{
Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast();
toast.Content = args.Position.Coordinate.Latitude.ToString("0.00") + "," + args.Position.Coordinate.Longitude.ToString("0.00");
toast.Title = "位置:";
toast.NavigationUri = new Uri("/Page1.xaml", UriKind.Relative);
toast.Show(); }
}

二、地图和导航

要用到新地图控件,需要先注册,在phone:PhoneApplicationPage注册标识。

[XAML]

xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"

1.引入地图控件

在XAML中添加如下代码即可引入控件。我们看到Center就是指当前地图中心点的经纬度;ZoomLevel就是缩放级别; LandmarksEnabled 属性设置为 true 以在 Map 控件上显示地标; PedestrianFeaturesEnabled 设置为 true,以显示步行街构造。

[XAML]

        <!--ContentPanel - 在此处放置其他内容-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<!--地图控件-->
<maps:Map x:Name="MyMap" Center="30.5473, 114.2922" ZoomLevel="10" LandmarksEnabled="true" PedestrianFeaturesEnabled="true" />
<Button Foreground="Red" Content="指定位置" HorizontalAlignment="Left" Margin="295,530,0,0" VerticalAlignment="Top" Click="Button_Click_1" Width="151"/>
<Button Foreground="Red" Content="制图模式" HorizontalAlignment="Left" Margin="10,530,0,0" VerticalAlignment="Top" Click="Button_Click_2"/>
<Button Foreground="Red" Content="颜色模式" HorizontalAlignment="Left" Margin="134,530,0,0" VerticalAlignment="Top" Click="Button_Click_3"/>
<Button Foreground="Red" Content="我的位置" HorizontalAlignment="Left" Margin="10,602,0,0" VerticalAlignment="Top" Click="Button_Click_4"/>
</Grid>

2.设置制图模式

在制图模式中有四个选项,分别如下:

    Road:显示正常的默认二维地图。

    Aerial:显示航测图。


    Hybrid:显示与道路和标签重叠的地图的“航测”视图。


    Terrain:为显示的高地和水域构造(例如高山和河流)显示自然地形图像。

下面看看如何切换。

[C#]

//切换制图模式
private void Button_Click_2(object sender, RoutedEventArgs e)
{
switch (MyMap.CartographicMode)
{
case MapCartographicMode.Aerial:
MyMap.CartographicMode = MapCartographicMode.Hybrid;
break;
case MapCartographicMode.Hybrid:
MyMap.CartographicMode = MapCartographicMode.Road;
break;
case MapCartographicMode.Road:
MyMap.CartographicMode = MapCartographicMode.Terrain;
break;
case MapCartographicMode.Terrain:
MyMap.CartographicMode = MapCartographicMode.Aerial;
break;
}
}

3.设置颜色模式

颜色分为明和暗两种,我们看看如何实现。

[C#]

//切换颜色模式
private void Button_Click_3(object sender, RoutedEventArgs e)
{
if (MyMap.ColorMode == MapColorMode.Light)
MyMap.ColorMode = MapColorMode.Dark;
else MyMap.ColorMode = MapColorMode.Light;
}

4.指定新视角位置

我们可以通过编程方式切换视角位置到新的经纬度,并可以指定切换时的过渡效果,这里指定的是抛物线的方式。

[C#]

private void Button_Click_1(object sender, RoutedEventArgs e)
{
//以抛物线的方式,把视角定位到光谷软件园中心湖上空。
MyMap.SetView(new GeoCoordinate(30.476724, 114.406563), 16, MapAnimationKind.Parabolic);
}

5.定位我的位置并标记

把地图定位到我的当前位置。这个时候就需要借助定位的功能,通过定位功能获取到的经纬度实例类型不一样,需要预先做一个转换。转换类CoordinateConverter如下。

[C#]

public static class CoordinateConverter
{
/// <summary>
/// 把定位位置转换为地图位置
/// </summary>
/// <param name="geocoordinate"></param>
/// <returns></returns>
public static GeoCoordinate ConvertGeocoordinate(Geocoordinate geocoordinate)
{
return new GeoCoordinate
(
geocoordinate.Latitude,
geocoordinate.Longitude,
geocoordinate.Altitude ?? Double.NaN,
geocoordinate.Accuracy,
geocoordinate.AltitudeAccuracy ?? Double.NaN,
geocoordinate.Speed ?? Double.NaN,
geocoordinate.Heading ?? Double.NaN
);
}
}

然后,我们需要在地图上画一个小正方形标记我的当前位置,并把地图定位到这里。

[C#]

//添加其他控件到地图,标识我的当前位置
private async void Button_Click_4(object sender, RoutedEventArgs e)
{
//获取我的地理位置
Geolocator myGeolocator = new Geolocator();
//精度
myGeolocator.DesiredAccuracyInMeters = 1;
Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();
Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
//转换经纬度GeoCoordinate
GeoCoordinate myGeoCoordinate = CoordinateConverter.ConvertGeocoordinate(myGeocoordinate); //MessageBox.Show(myGeoCoordinate.ToString()); //定位地图到我的位置
MyMap.SetView(myGeoCoordinate, 16, MapAnimationKind.Parabolic); //画一个正方形,然后渲染在地图的我的当前位置上
Rectangle MyRectangle = new Rectangle();
MyRectangle.Fill = new SolidColorBrush(Colors.Black);
MyRectangle.Height = 20;
MyRectangle.Width = 20; MapOverlay MyOverlay = new MapOverlay();
MyOverlay.Content = MyRectangle;
MyOverlay.GeoCoordinate = myGeoCoordinate;
MyOverlay.PositionOrigin = new Point(0, 0.5); MapLayer MyLayer = new MapLayer();
MyLayer.Add(MyOverlay);
MyMap.Layers.Add(MyLayer); }

6.获取行车路线

我们还可以通过定位和地图实现导航的功能,下面演示了,从我的当前位置(光谷软件园)到指定的位置(光谷创业街)如何行车。

[XAML]

    <phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="RouteListTemplate">
<TextBlock Text="{Binding}" FontSize="{StaticResource PhoneFontSizeMedium}" Margin="5,5,0,0"/>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot 是包含所有页面内容的根网格-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="地图导航" Grid.Row="0" FontSize="{StaticResource PhoneFontSizeLarge}" Margin="0,0,0,20"/>
<maps:Map x:Name="MyMap" Grid.Row="1" Center="30.476724, 114.406563" ZoomLevel="13"/>
<TextBlock Text="驾车路线" Grid.Row="2" FontSize="{StaticResource PhoneFontSizeLarge}" Margin="0,10,0,20"/>
<phone:LongListSelector x:Name="RouteLLS" Grid.Row="3" Background="Transparent" ItemTemplate="{StaticResource RouteListTemplate}" LayoutMode="List"
IsGroupingEnabled="False"/>
</Grid>

[C#]

    public partial class Page1 : PhoneApplicationPage
{
public Page1()
{
InitializeComponent();
this.GetCoordinates();
} RouteQuery MyQuery = null;
GeocodeQuery Mygeocodequery = null; List<GeoCoordinate> MyCoordinates = new List<GeoCoordinate>(); private async void GetCoordinates()
{
Geolocator MyGeolocator = new Geolocator();
MyGeolocator.DesiredAccuracyInMeters = 5;
Geoposition MyGeoPosition = null;
try
{
MyGeoPosition = await MyGeolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(10));
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("系统设置已关闭位置服务。");
}
catch (Exception ex)
{
}
MyCoordinates.Add(new GeoCoordinate(MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude)); Mygeocodequery = new GeocodeQuery();
Mygeocodequery.SearchTerm = "光谷创业街";
Mygeocodequery.GeoCoordinate = new GeoCoordinate(MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude); Mygeocodequery.QueryCompleted += Mygeocodequery_QueryCompleted;
Mygeocodequery.QueryAsync(); }
void Mygeocodequery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
MyQuery = new RouteQuery();
MyCoordinates.Add(e.Result[0].GeoCoordinate);
MyQuery.Waypoints = MyCoordinates;
MyQuery.QueryCompleted += MyQuery_QueryCompleted;
MyQuery.QueryAsync();
Mygeocodequery.Dispose();
}
} void MyQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
{
if (e.Error == null)
{
//获取具体的行程路线
Route MyRoute = e.Result;
MapRoute MyMapRoute = new MapRoute(MyRoute);
MyMap.AddRoute(MyMapRoute);
List<string> RouteList = new List<string>();
foreach (RouteLeg leg in MyRoute.Legs)
{
foreach (RouteManeuver maneuver in leg.Maneuvers)
{
RouteList.Add(maneuver.InstructionText);
}
} RouteLLS.ItemsSource = RouteList;
MyQuery.Dispose();
}
} }
作者:[Lipan]
出处:[http://www.cnblogs.com/lipan/]
版权声明:本文的版权归作者与博客园共有。转载时须注明原文出处以及作者,并保留原文指向型链接,不得更改原文内容。否则作者将保留追究其法律责任。

Windows phone 8 学习笔记(8) 定位地图导航的更多相关文章

  1. Windows phone 8 学习笔记(8) 定位地图导航(转)

    Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式.视图等.bing地图的定位误差比较大,在模拟器中测试新地图貌似比较理想.本节主要讲解下位置服务以及新地图控件的 ...

  2. Windows phone 8 学习笔记

    Windows phone 8 学习笔记(1) 触控输入  http://www.apkbus.com/android-138547-1-1.html Windows phone 8 学习笔记(2) ...

  3. Windows phone 8 学习笔记(9) 集成

    原文:Windows phone 8 学习笔记(9) 集成 本节整理了之前并没有提到的Windows phone 8 系统相关集成支持,包括选择器.锁定屏幕的.联系人的访问等.选择器列举了若干内置应用 ...

  4. Windows phone 8 学习笔记(7) 设备

    原文:Windows phone 8 学习笔记(7) 设备 本节主要涉及到 Windows phone 8 手机支持的各类设备,包括相机.设备状态,振动装置等.还有各类感应器,包括磁力计.加速度器和陀 ...

  5. Windows phone 8 学习笔记(1) 触控输入

    原文:Windows phone 8 学习笔记(1) 触控输入 Windows phone 8 的应用 与一般的Pc应用在输入方式上最大的不同就是:Windows phone 8主要依靠触控操作.因此 ...

  6. Windows phone 8 学习笔记(5) 图块与通知(转)

    基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认图块,还可以有若干个次要图块.另外,通知与图块的关系比较密切,我们 ...

  7. Windows phone 8 学习笔记(2) 数据文件操作(转)

    Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方.本节主要讲解它们的用法以及相关限制性.另外包括本地数据库的使用方式 ...

  8. Windows phone 8 学习笔记(6) 多任务

    原文:Windows phone 8 学习笔记(6) 多任务 Windows phone 8 是一个单任务操作系统,任何时候都只有一个应用处于活跃状态,这里的多任务是指对后台任务的支持.本节我们先讲讲 ...

  9. Windows phone 8 学习笔记(5) 图块与通知

    原文:Windows phone 8 学习笔记(5) 图块与通知 基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认 ...

随机推荐

  1. catalan 数——卡特兰数(转)

    Catalan数——卡特兰数 今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来后来查了下,原来是Catalan数.悲剧啊,现在整理一下 一.Catalan数的定义令h(1) ...

  2. TCP/IP笔记 二.网络层(2)——ICMP,RIP,OSPF,BGP

    1. ICMP ICMP (Internet Control Message Protocol) 作用:提高 IP 数据报交付成功的机会. 1.1 特点 ICMP 允许主机或路由器报告差错情况和提供有 ...

  3. CSipSimple最新版本号

    要使用CSipSimple有两种方法:第一种是不编译jni,另外一种是编译jni. 这里介绍的是第一种:不编译jni. 首先,用SVNclient检出CSipSimple源代码:svn checkou ...

  4. 让XP系统支持GPT硬盘

    转自 http://article.pchome.net/content-1324506-all.html 1XP系统还不过时 教你完美征服3TB硬盘回顶部 原作者:沈洁 随着高清1080p片源的普及 ...

  5. delphi 网页提交按钮执行点击事件

    遍历即可实现,下列代码仅供参考: var i: integer; T: OleVariant; begin T := WebBrowser1.Document; do begin if T.all.i ...

  6. 与众不同 windows phone (2) - Control(控件)

    原文:与众不同 windows phone (2) - Control(控件) [索引页][源码下载] 与众不同 windows phone (2) - Control(控件) 作者:webabcd介 ...

  7. CAS (1) —— Mac下配置CAS到Tomcat(服务端)(转)

    tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 cas版本: cas4.1.2cas-client-3.4.1 参考来源: CAS实现单点登录(SSO)经典完整教 ...

  8. 14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器

    14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器 当InnoDB 被开发, 内分配齐 提供了与操作系统和运行库往往缺乏 ...

  9. data URI scheme及其应用

    data URI scheme通俗的来讲就是将一张图片直接塞到HTML中而不是通过HTTP请求去获取.这样从表面上看会降低一次HTTP的请求,实现了对于网页的优化(只是看了其它一些文章data URI ...

  10. WM_PARENTNOTIFY的作用(不完全)

    VCL里源码如下: procedure TWinControl.WMParentNotify(var Message: TWMParentNotify); begin with Message do ...