Categories

Posts Tagged ‘GPS’

Windows Mobile平台获取GPS信息

Windows Mobile(以下简称WM)的开发相对于iPhone来说简单的多, Apple在界面上明显略胜一筹,但是在实际应用的开发方面还是微软做的更到位。就像在iPhone上如果要想获取GPS信息是个不容易办到的事儿, 虽然开放了CLLocationManager类,但是所获得的GPS信息只是过期的cache, 要开发者自己写代码去获得最新的GPS信息, 还有可能不响应。 相比之下在WM系统就简单的多, WM5 Pocket SDk5 以后提供了叫做中间媒介驱动的一套函数,可以方便的访问GPS硬件及读取GPS定位信息,其实只有4个函数,他们分别是
GPSOpenDevice, GPSGetPosition, GPSGetDeviceState, GPSCloseDevice. 怎么样,简单吧

你只需要在文件中包含头文件

1
#include <Gpsapi.h>

以及链接Gpsapi.lib库文件即可,接下来就是在开始定位的地方打开设备

1
2
3
4
5
6
7
// global vars
static HANDLE   hGPSEvents[2] = {0};
 
//
hGPSEvents[0] = CreateEvent(NULL,TRUE,FALSE,"NewLocationDataEvent");
hGPSEvents[1] = CreateEvent(NULL,TRUE,FALSE,"DeviceStateChanged");
HANDLE	 hGPSDevice = GPSOpenDevice( hGPSEvents[0], hGPSEvents[1],NULL,0);

两个由CreateEvent创建的事件对象分别在收到新的gps数据和gps硬件设备有变化的时候通知宿主, 比如当hGPSEvents[0]被触发的时候你可能会调用GPSGetPosition来获取最新的GPSGetPosition数据信息, 同样当hGPSEventsEvents[1]被触发时会使用GPSGetDeviceState获得设备当前状态以便控制程序。

在打开设备后, 如果卫星信号接收正常,而且接收到数据时会触发数据接收事件,在数据事件被触发时只要调用GPSGetPosition就可以读取最新GPS数据

1
2
3
GPS_POSITION  gpsPos = {0};
gpsPos.dwSize = sizeof(GPS_POSITION);
DWORD dwRet = GPSGetPosition( hGPSDevice, &gpsPos, 3000,0 );

以上表示读取3秒钟之内的有效数据, gpsPos返回的是gps数据信息,其结构为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
typedef struct _GPS_POSITION {
   DWORD dwVersion;			// 中间驱动的版本号,始终为GPS_VERSION_1
   DWORD dwSize;			// 该结构字节大小,必须在传入前赋值
 
   DWORD dwValidFields;		//标明返回的该结构中的哪些字段有效,比如经纬度,速度等, 不是所有GPSGetPosition硬件设备都支持
 
   DWORD dwFlags;			//数据状态, 始终为1
 
   SYSTEMTIME stUTCTime;	//卫星时间
 
   double dblLatitude;		//维度
   double dblLongitude;		//精度
   float  flSpeed;			//速度,以节为单位
   float  flHeading;		//卫星角度, 正北 为0
   double dblMagneticVariation;		//磁偏角度,由地理北极和磁北极误差所致
   float  flAltitudeWRTSeaLevel;	//海拔高度
   float  flAltitudeWRTEllipsoid;	//相对于地心的高度,这里使用WGS_84椭球做参考
 
   GPS_FIX_QUALITY     FixQuality;	// 误差修正质量
   GPS_FIX_TYPE        FixType;		//修正类型
   GPS_FIX_SELECTION   SelectionType;	//二维、三维选择类型
   float flPositionDilutionOfPrecision;	// 有卫星方位所造成的误差,数值越小越精确,1.0表示误差最小,50 精度最差
   float flHorizontalDilutionOfPrecision;// 水平方向误差
   float flVerticalDilutionOfPrecision; // 垂直方向误差
 
   DWORD dwSatelliteCount; //读取该数据时卫星数量
   DWORD rgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];//相应卫星的伪随机数
 
   DWORD dwSatellitesInView;		// GPS设备可覆盖的卫星数量
   DWORD rgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES]; // 伪随机数
   DWORD rgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];// 卫星仰角
   DWORD rgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES]; //卫星方位角
   DWORD rgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];// 卫星信号强度
} GPS_POSITION, *PGPS_POSITION;

只要在线程或者消息队列里处理数据接收消息再读取数据即可完成定位及轨迹记录。

最后别忘了调用GPSCloseDevice关闭GPS设备, 实际上GPS中间驱动采用的是计数的方式来开关设备,当你调用GPSOpenDevice时如果设备处于关闭状态就将其打开, 否则如果已经被其它程序打开就只把计数加1, 关闭时如果计数为0,就关闭硬件设备,否则只是减少计数。