30 Days of .NET [Windows Mobile Applications] - Day 03: GPS Compass(GPS指南针)

原文见Day 03: GPS Compass

需求

使用GPS信息显示指南针。

实现

GPS指南针就是在UI上显示当前位置的方位(azimuth),GPS receiver输出的NMEA里就包含了这个信息。存放在GPRMC的第八个字段。

$GPRMC,015834,A,3749.8448,S,14459.6697,E,000.0,136.8,120908,011.7,E*63

上述例子中136.8为方位角。基于NMEA的分析,我写过一篇文章.NET Compact Framework下的GPS NMEA data数据分析

作者提出进行GPS的开发有三种选择,1.直接使用串口连接GPS receiver。2.使用OpenNETCF GPS Library。3.使用GPS Intermediate Driver
作者最终选择了GPS Intermediate Driver,这个库支持Windows Mobile 5以上系统。MS宣称GPS Intermediate Driver可以屏蔽所有硬件的差异,说实在,屏蔽了所有硬件的差异意味着这个库只是支持通用的NMEA,厂商的NMEA就不能解析出来了。凡事都是有优缺点,技术选型主要取决于需求。对这个指南针的需求比较简单,只是需要取出方位角信息,使用GPS Intermediate Driver可以提高开发效率。

进行GPS Intermediate Driver的开发,可以从参考Windows Mobile 6的事例代码C:\Program Files\Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS。MS把GPS Intermediate Driver封装到Microsoft.WindowsMobile.Samples.Location里面,进行Compatct Framework的开发,我们只需要使用Microsoft.WindowsMobile.Samples.Location就可以了。

GpsDeviceState device = null;
GpsPosition position 
= null;
Gps gps 
= new Gps();

private void Form1_Load(object sender, System.EventArgs e)
{
    gps.DeviceStateChanged 
+= new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
    gps.LocationChanged 
+= new LocationChangedEventHandler(gps_LocationChanged);
}

private void startGpsMenuItem_Click(object sender, EventArgs e)
{
    
if (!gps.Opened)
    {
        gps.Open();
    }
}

private void stopGpsMenuItem_Click(object sender, EventArgs e)
{
    
if (gps.Opened)
    {
        gps.Close();
    }
}

上面是使用Microsoft.WindowsMobile.Samples.Location的核心代码,GpsDeviceState device定义GPS设备的状态,设备的具体状态可以参考GpsDeviceState.cs里面的enum定义

public enum GpsServiceState : int
{
    Off 
= 0,
    On 
= 1,
    StartingUp 
= 2
    ShuttingDown 
= 3,
    Unloading 
= 4,
    Uninitialized 
= 5,
    Unknown 
= -1
}

GpsPosition position定义了位置信息,其实这个类是大而全的类,把通用的NMEA可以分析的信息全部放到这个类里面。

有类图定义可见,我们不仅仅可以得到方位角信息,而且可以在这个类里面得到经纬度,海拔,UTC时间,速度,卫星状态,误差值等等。

Gps对象表示一台Gps的设备,gps.Open();为打开设备,开始接受GPS信息,gps.Close();为关闭该设备。gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);和gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);表示订阅设备状态变化信息和位置变化信息。从GpsPosition的类定义知道,当位置发生变化,也就是回调gps_LocationChanged的时候,可以取出经纬度,海拔等多方面的信息。因此只要订阅该消息就可以完成几乎所有的GPS开发。

使用假GPS(FakeGPS)设备测试程序


作者提供了一个测试方法,使得没有GPS receiver的设备也可以进行测试,FakeGPS 可以在C:\Program Files\Windows Mobile 6 SDK\Tools\GPS找到。FakeGPS可以参考  施炯 同学的 A Windows Mobile GPS Application Sample – Using Fake GPS

设置Share Folder。

安装FakeGPS.CAB。

配置FakeGPS。


使用FakeGPS测试GpsCompass,请在Window Mobile 6 Professional下测试,我在Window Mobile 6 Classic下测试,打开GPS设备失败。

 

安装程序: gpsCompass.cab

源代码: gpsCompass.zip
 

.NET Compact Framework, WinCE, Windows Mobile开发系列

Jake's Blog in 博客园 -- 精简开发 无线生活

作者:Jake LinJake's Blog on 博客园
出处:http://procoder.cnblogs.com

作品Jake Lin创作,采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。 任何转载必须保留完整文章,在显要地方显示署名以及原文链接。如您有任何疑问或者授权方面的协商,请给我留言
posted @ 2009-05-25 12:55 Jake Lin 阅读(3795) 评论(19) 编辑 收藏

 回复 引用 查看   
#1楼 2009-05-25 12:45 施炯      
这个指南针界面好看多了
 回复 引用 查看   
#2楼 2009-05-25 14:53 汉广      
不错:)


问一个离题的问题,
我上周写了一个文章<<(Tips &Tricks)如何为Windows Mobile 创建拨号连接--C# >>,你评论说"直接导入注册表"创建拨号连接。
是怎么做的呢?需要导入什么信息?可不可以分享下……

 回复 引用 查看   
#3楼 2009-05-25 15:21 小罗      
好贴顶一个,工作中GPS没涉及过。
 回复 引用 查看   
#4楼[楼主] 2009-05-25 18:41 Jake.NET      
@施炯
图片是wikipedia里面的,在Chris Craft的blog里面有说明。http://commons.wikimedia.org/wiki/Compass_rose

 回复 引用 查看   
#5楼[楼主] 2009-05-25 18:44 Jake.NET      
@汉广
谢谢,你的文章写得很好,我用的机器的厂商为各个运营商的链接配置了注册表项,我可以直接把这个注册表文件在安装的时候导入到wince的注册表,这样ras就能用了。

你的方式是通用的,我也在找一个通用的方式,过几天试一下,然后告诉你是否可以用到所有机器上。

 回复 引用 查看   
#6楼[楼主] 2009-05-25 18:46 Jake.NET      
@小罗
谢谢,GPS开发可以选择NMEA或者GPS Intermediate Driver,如果只是取出GPS receiver的信息,难度不大。

 回复 引用   
#7楼 2009-05-26 17:47 daysun[未注册用户]
下载不了,能不能发一份给我。
shanhx@163.com

 回复 引用 查看   
#8楼[楼主] 2009-05-26 18:37 Jake.NET      
@daysun
我测试了一下,可以下载,点击左上角的“Download”链接,谢谢!

 回复 引用   
#9楼 2009-08-15 00:13 Lawliet[未注册用户]
楼主,下载不了
 回复 引用 查看   
#10楼[楼主] 2009-08-17 06:55 Jake.NET      
@Lawliet
项目的page。
http://30daysofdotnet.codeplex.com/

 回复 引用 查看   
#11楼[楼主] 2009-08-17 06:58 Jake.NET      
上面的项目链接,作者还没有上传代码,而且作者的网站http://www.cjcraft.com/不知道出于什么原因不能访问了
 回复 引用 查看   
#12楼[楼主] 2009-08-18 19:13 Jake.NET      
@Lawliet
我已经发邮件为原作者了。

 回复 引用 查看   
#13楼[楼主] 2009-08-19 07:53 Jake.NET      
@Lawliet
Chris 的网站 ok了。

 回复 引用 查看   
#14楼 2009-12-02 10:40 wangxm      
我有个问题想问下,使用GPS Intermediate Driver的方式,屏蔽了硬件间的差异,难道连端口号和波特率都不用指定了?猜想难道它是遍历的方式?在已知端口号和波特率的情况下,可以自己指定吗?来提高性能。
 回复 引用 查看   
#15楼[楼主] 2009-12-02 14:15 Jake Lin      
@wangxm
不需要手工配置,其实这些信息在注册表里面有的。

 回复 引用 查看   
#16楼 2009-12-31 13:45 egmkang      
我看的第一篇GPS相关的文章就是你写的这个
当时应该是五六月了..

 回复 引用 查看   
#17楼 2010-04-29 10:46 余锦峰      
我在htc 900c里面运行了上面的例子,但是发现无法获取正确的坐标。sdk里面的例子也在机子上运行过,同样无法获取坐标。设备是可以打开的。
 回复 引用 查看   
#18楼[楼主] 2010-05-12 20:05 Jake Lin      
@余锦峰
不好意思,回复晚了,你先确认你的手机GPS功能是否正常工作,然后检查GPS Intermediate Driver,你可以下载我的程序NavsGO试试,里面有检查GPS端口的程序。

 回复 引用 查看   
#19楼[楼主] 2010-05-12 20:07 Jake Lin      
@余锦峰
请看
Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发
http://www.cnblogs.com/procoder/archive/2009/08/21/1551155.html
Windows Mobile下GPS管理软件NavsGo之GPS监控功能的开发
http://www.cnblogs.com/procoder/archive/2009/08/19/1549453.html