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

原文: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 学习笔记 设备
系列目录
下一篇:Windows phone 8 学习笔记 集成》

时间: 2024-09-17 04:24:48

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

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

原文:Windows phone 8 学习笔记(9) 集成  本节整理了之前并没有提到的Windows phone 8 系统相关集成支持,包括选择器.锁定屏幕的.联系人的访问等.选择器列举了若干内置应用提供的相关支持:锁定屏幕展示了我们可以对锁定屏幕提供背景图像,屏幕通知等功能:联系人访问演示了对联系人的管理维护和只读访问. 快速导航:     一.选择器     二.锁定屏幕     三.联系人访问 一.选择器 选择器为手机内置应用对您的开发提供的相关支持,通过选择器你可以直接调用相机应用捕获

ArcGIS JS 学习笔记4 实现地图联动

原文:ArcGIS JS 学习笔记4 实现地图联动 1.开篇       守望屁股实在太好玩了,所以最近有点懒,这次就先写个简单的来凑一下数.这次我的模仿目标是天地图的地图联动. 天地的地图联动不仅地图有联动,而且鼠标也有联动,我就照着这个目标进行山寨. 2.准备       地图联动其实就是当一张的extent发生了变化,另一张图的extent也要同步变化,这样就可以两张图的范围同步了.同理,这样就可以扩展到N张图进行联动.所以这次的目标就是实现添加任意的地图都要可以联动.首先依然是先看一下官

Windows phone 8 学习笔记(4) 应用的启动

原文:Windows phone 8 学习笔记(4) 应用的启动 Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开.照片中心.音乐+视频中心提供扩展支持应用从此启动.另外,我们还可以通过文件关联.URI关联的方式启动应用. 快速导航:     一.扩展音乐+视频中心     二.扩展照片中心     三.文件关联以及SD卡访问     四.URI关联     五.启动我的其他应用和启动内置应用 一.扩展音乐+视频中心 1)在音乐+视频中心

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

原文:Windows phone 8 学习笔记(5) 图块与通知 基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认图块,还可以有若干个次要图块.另外,通知与图块的关系比较密切,我们可以通过在接受到消息时动态更新图块来达到适时的效果.我们本节把图块和通知放在一起讲. 快速导航:    一.图块    二.图块更新计划    三.本地通知    四.推送通知 一.图块 1)定义默认图块 默认图块只能在清单文件中定义

Windows phone 8 学习笔记(3) 通信

原文:Windows phone 8 学习笔记(3) 通信 Windows phone 8 可利用的数据通信方式比较广泛,在硬件支持的前提下,我们可以利用WiFi.蓝牙.临近感应等多种方式.数据交互一般通过套接字来完成,我们将在本文详细的分析. 快速导航:     一.WP8套接字     二.蓝牙     三.NFC     四.获取网络状态     五.访问web的几种方式 一.WP8套接字 1)创建套接字客户端 Windows phone 8中的套接字并不支持发布服务端,我们只能利用它在手

Windows录音API学习笔记--转

Windows录音API学习笔记 结构体和函数信息  结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct {     WORD      wMid; 用于波形音频输入设备的设备驱动程序制造商标识符.     WORD      wPid; 声音输入设备的产品识别码.     MMVERSION vDriverVersion; 用于波形音频输入设备的设备驱动程序的版本号.高位字节是主版本号,低字节是次版本号.     CHAR      szPna

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

原文:Windows phone 8 学习笔记(2) 数据文件操作 Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方.本节主要讲解它们的用法以及相关限制性.另外包括本地数据库的使用方式. 快速导航:     一.分析各类数据文件存储方式     二.安装文件夹     三.本地文件夹(独立存储空间)     四.媒体库操作     五.本地数据库 一.分析各类数据文件存储方式 1)安装文件夹 安装文件夹即应用安装

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

原文:Windows phone 8 学习笔记(6) 多任务 Windows phone 8 是一个单任务操作系统,任何时候都只有一个应用处于活跃状态,这里的多任务是指对后台任务的支持.本节我们先讲讲应用程序的运行状态,然后看看支持的后台任务,包括:后台代理.后台音频.后台文件传输.后台辅助线程等. 快速导航:     一.应用的状态     二.后台代理     三.后台音频     四.后台文件传输     五.后台辅助线程 一.应用的状态 1)应用的运行状态 我们通过图解来分析应用的运行状

《Advanced Windows Debugging》学习笔记

看完了很久,也一直没有完成这篇博客,在项目使用中,大多数还是用到其中的一些命令去解析,目前没有太多机会,可以让自己用基本命令去锻炼一下"遍历堆链表"等高级调试技巧.看完这本书给我最大的感觉是: 当你觉得你有些比较难解决的调试或检测问题的时候,不妨查一查是不是有相应的工具.开发过程中需要的各种分析.检测.调试工具,这本书上都有或多或少的讲解. WinDbg 堆栈解析能力天生比vs强很多.每当程序宕掉,发现Visual studio 的[Call Stack]窗口全是汇编地址的时候,我会果