带GPS功能的Windows Mobile手机定位可以通过GPS获取手机所在的详细地址,民用一般误差在5米到50米之间的范围内。通过使用GPSApi头文件中包含的一下四个函数,由GPS中层驱动程序(GPSID)提供,可以通过它使用GPS设备并实时更新手机所在位置的信息。注意包含GPSAPI.h头文件与GPAAPI.lib静态链接库。(在做gps方面开始时可以参照sdk的几个Demo)
GPSOpenDevice
GPSGetPosition
GPSGetDeviceState
GPSCloseDevice
一、下面分别介绍各个函数的功能,参数以及具体怎样实现使用这些函数。
1.GPS_POSITION结构
在介绍各个函数之前,要先介绍GPS_POSITION数据结构,他用来存放GPS定位所需要的各种信息。
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
typedef
struct
_GPS_POSITION{
DWORDdwVersion; // GPSID的版本号,在调用GPSGetPosition之前赋值,暂时必须被赋值为GPS_VERSION_1
DWORDdwSize; // GPS_POSITION结构的大小,同样应先用sizeof给它赋值
DWORDdwValidFields; // 结构实例中的有效空间标记,标记结构中哪些值有效
DWORDdwFlags; // 在调用GPSGetPosition函数时修改过的数据的状态
SYSTEMTIMEstUTCTime; // 根据GPS卫星提供的信息获得的宇宙时间
double dblLatitude; // 纬度,单位”度”,正数表示北
double dblLongitude; // 经度,单位”度”,正数表示东
float flSpeed; // 移动速度,单位“KNOTS”(海里),估计是海里/小时
float flHeading; // 移动方向,单位“度”,数值为偏北往顺时针的度数
double dblMagneticVariation; // 正北与地磁北极角度差,整数表示往东的度数
float flAltitudeWRTSeaLevel; // 距海平面高度
float flAltitudeWRTEllipsoid; // 距椭球面高度
GPS_FIX_QUALITYFixQuality;
GPS_FIX_TYPEFixType;
GPS_FIX_SELECTIONSelectionType;
float flPositionDilutionOfPrecision;
float flHorizontalDilutionOfPrecision;
float flVerticalDilutionOfPrecision;
DWORDdwSatelliteCount; // 获取以上信息使用到的卫星数量
DWORDrgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];
DWORDdwSatellitesInView; // GPS硬件设备可见范围内的卫星数量
DWORDrgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];
}GPS_POSITION, * PGPS_POSITION;
DWORDdwVersion; // GPSID的版本号,在调用GPSGetPosition之前赋值,暂时必须被赋值为GPS_VERSION_1
DWORDdwSize; // GPS_POSITION结构的大小,同样应先用sizeof给它赋值
DWORDdwValidFields; // 结构实例中的有效空间标记,标记结构中哪些值有效
DWORDdwFlags; // 在调用GPSGetPosition函数时修改过的数据的状态
SYSTEMTIMEstUTCTime; // 根据GPS卫星提供的信息获得的宇宙时间
double dblLatitude; // 纬度,单位”度”,正数表示北
double dblLongitude; // 经度,单位”度”,正数表示东
float flSpeed; // 移动速度,单位“KNOTS”(海里),估计是海里/小时
float flHeading; // 移动方向,单位“度”,数值为偏北往顺时针的度数
double dblMagneticVariation; // 正北与地磁北极角度差,整数表示往东的度数
float flAltitudeWRTSeaLevel; // 距海平面高度
float flAltitudeWRTEllipsoid; // 距椭球面高度
GPS_FIX_QUALITYFixQuality;
GPS_FIX_TYPEFixType;
GPS_FIX_SELECTIONSelectionType;
float flPositionDilutionOfPrecision;
float flHorizontalDilutionOfPrecision;
float flVerticalDilutionOfPrecision;
DWORDdwSatelliteCount; // 获取以上信息使用到的卫星数量
DWORDrgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];
DWORDdwSatellitesInView; // GPS硬件设备可见范围内的卫星数量
DWORDrgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
DWORDrgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];
}GPS_POSITION, * PGPS_POSITION;
2.GpsOpenDevice
函数原型如下:
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
HANDLEGPSOpenDevice(
HANDLEhNewLocationData,
HANDLEhDeviceStateChange,
const WCHAR * szDeviceName,
DWORDdwFlags
);
HANDLEhNewLocationData,
HANDLEhDeviceStateChange,
const WCHAR * szDeviceName,
DWORDdwFlags
);
前两个参数为 HANDLE 型,都通过 CreateEvent 的返回值给它们赋值。如:
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
HANDLEs_hNewLocationData
=
CreateEvent(NULL,FALSE,FALSE,NULL);
HANDLEs_hDeviceStateChange = CreateEvent(NULL,FALSE,FALSE,NULL);
HANDLEs_hDeviceStateChange = CreateEvent(NULL,FALSE,FALSE,NULL);
第 2 个参数: HANDLE hDeviceStateChange CreateEvent 生成的句柄或者为 NULL 。 当 GPS 设备位置发生改变时,驱动将其设置为信号态。
第 3 个参数:必须为 NULL 。
第 4 个参数:必须为 0 。
返回值:成功则返回 GPS 中间驱动句柄。失败则为 NULL 。
3.GPSGetPosition
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
DWORDGPSGetPosition(
HANDLEhGPSDevice,
GPS_POSITION * pGPSPosition,
DWORDdwMaximumAge,
DWORDdwFlags
);
HANDLEhGPSDevice,
GPS_POSITION * pGPSPosition,
DWORDdwMaximumAge,
DWORDdwFlags
);
函数功能:返回本地位置信息。
第 1 个参数: HANDLE hGPSDevice GPS 设备句柄。 GPSOpenDevice 函数打开的设备句柄。 这个参数可以为 NULL ,此时函数不会启动 GPS 设备。 但函数会返回其他程序调用 GPS 驱动后保留的数据。 这个数据满足 dwMaximumAge 设置的时间值。第 2 个参数: GPS_POSITION *pGPSPosition GPS_POSITION 结构指针。函数将填充这个结构。 用户必须输入结构版本和大小参数值。
第3个参数:DWORD dwMaximumAge规定了本地GPS信息的最长有效期。在有效期内可以使用这个数据。
第 4 个参数: DWORD dwFlags 保留值为 0 。返回值:成功: ERROR_SUCCESS 。 失败:错误信息。
GPSGetDeviceState
DWORD GPSGetDeviceState(
GPS_DEVICE *pGPSDevice
);
函数功能:获取 GPS 硬件设备的当前状态信息。
参数: GPS_DEVICE *pGPSDevice : GPS_DEVICE 结构体指针。
返回值:成功: ERROR_SUCCESS 。 错误:错误编号。
4.GPSCloseDevice
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
DWORDGPSCloseDevice(
HANDLEhGPSDevice
);
HANDLEhGPSDevice
);
参数: HANDLE hGPSDevice : GPSOpenDevice 打开的 GPS 设备句柄。
返回值:成功: ERROR_SUCCESS 。 错误:错误信息。
二、 GPS 具体实现细节
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
1
>
首先用CreateEvent生成3个接受消息的句柄,两个上述以说明,第三个用来接受置关闭GPS设备结束线程
HANDLEs_hExitThread = CreateEvent(NULL,FALSE,FALSE,NULL);
2 > 打开GPS设备并声明线程函数
HANDLEs_hGPS_Device = GPSOpenDevice(s_hNewLocationData,s_hDeviceStateChange,NULL,NULL);
DWORDGPSThreadProc(__optLPVOIDlpParameter);
3 > 定义线程函数
DWORDGPSThreadProc(__optLPVOIDlpParameter)
{
GPS_POSITIONgps_Position = { 0 }; // 不用说了,放数据的
DWORDdwRet = 0 ; // 表状态的,具体状态干具体的事
GPS_DEVICEgps_Device = { 0 }; // 存放GPS设备信息,在GPSGetDeviceState前要赋值,如下
HANDLEgpsHandles[GPS_CONTROLLER_EVENT_COUNT] = {s_hNewLocationData,s_hDeviceStateChange,s_hExitThread};
gps_Position.dwSize = sizeof (gps_Position); // POSITION结构的第一个参数
gps_Position.dwVersion = GPS_VERSION_1; // POSITION结构的第二个参数
gps_Device.dwVersion = GPS_VERSION_1; // DEVICE结构的第二个参数
gps_Device.dwSize = sizeof (gps_Device); // DEVICE结构的第一个参数
while ( 1 ) // 循环获取
{
dwRet = WaitForMultipleObjects(GPS_CONTROLLER_EVENT_COUNT,gpsHandles,FALSE, 100 );
switch (dwRet)
{
case WAIT_OBJECT_0: // 有数据,获取并输出
dwRet = GPSGetPosition(s_hGPS_Device, & gps_Position,MAX_AGE, 0 );
break ;
case WAIT_OBJECT_0 + 1 : // 设备状态变化,获取状态信息
dwRet = GPSGetDeviceState( & gps_Device);
ZeroMemory( & gps_Device, sizeof (gps_Device));
gps_Device.dwVersion = GPS_VERSION_1;
if (ERROR_SUCCESS == dwRet)
{ // 状态获取成功,则获取定位信息
dwRet = GPSGetPosition(s_hGPS_Device, & gps_Position,MAX_AGE, 0 );}
break ;
case WAIT_OBJECT_0 + 2 : // 结束线程事件,关闭GPS设备
GPSCloseDevice(s_hGPS_Device);
return 1 ;
default :
break ;
}
// 获取间断时间
Sleep(MAX_WAIT);
}
return 0 ;
}
4 > _tmain函数
int _tmain( int argc,_TCHAR * argv[])
{
DWORDm_dwThreadID; // 创建线程
HANDLEm_hThread = CreateThread(NULL,NULL,GPSThreadProc,NULL,NULL, & m_dwThreadID);
GPSThreadProc(NULL); // 运行线程
return 0 ;
}
HANDLEs_hExitThread = CreateEvent(NULL,FALSE,FALSE,NULL);
2 > 打开GPS设备并声明线程函数
HANDLEs_hGPS_Device = GPSOpenDevice(s_hNewLocationData,s_hDeviceStateChange,NULL,NULL);
DWORDGPSThreadProc(__optLPVOIDlpParameter);
3 > 定义线程函数
DWORDGPSThreadProc(__optLPVOIDlpParameter)
{
GPS_POSITIONgps_Position = { 0 }; // 不用说了,放数据的
DWORDdwRet = 0 ; // 表状态的,具体状态干具体的事
GPS_DEVICEgps_Device = { 0 }; // 存放GPS设备信息,在GPSGetDeviceState前要赋值,如下
HANDLEgpsHandles[GPS_CONTROLLER_EVENT_COUNT] = {s_hNewLocationData,s_hDeviceStateChange,s_hExitThread};
gps_Position.dwSize = sizeof (gps_Position); // POSITION结构的第一个参数
gps_Position.dwVersion = GPS_VERSION_1; // POSITION结构的第二个参数
gps_Device.dwVersion = GPS_VERSION_1; // DEVICE结构的第二个参数
gps_Device.dwSize = sizeof (gps_Device); // DEVICE结构的第一个参数
while ( 1 ) // 循环获取
{
dwRet = WaitForMultipleObjects(GPS_CONTROLLER_EVENT_COUNT,gpsHandles,FALSE, 100 );
switch (dwRet)
{
case WAIT_OBJECT_0: // 有数据,获取并输出
dwRet = GPSGetPosition(s_hGPS_Device, & gps_Position,MAX_AGE, 0 );
break ;
case WAIT_OBJECT_0 + 1 : // 设备状态变化,获取状态信息
dwRet = GPSGetDeviceState( & gps_Device);
ZeroMemory( & gps_Device, sizeof (gps_Device));
gps_Device.dwVersion = GPS_VERSION_1;
if (ERROR_SUCCESS == dwRet)
{ // 状态获取成功,则获取定位信息
dwRet = GPSGetPosition(s_hGPS_Device, & gps_Position,MAX_AGE, 0 );}
break ;
case WAIT_OBJECT_0 + 2 : // 结束线程事件,关闭GPS设备
GPSCloseDevice(s_hGPS_Device);
return 1 ;
default :
break ;
}
// 获取间断时间
Sleep(MAX_WAIT);
}
return 0 ;
}
4 > _tmain函数
int _tmain( int argc,_TCHAR * argv[])
{
DWORDm_dwThreadID; // 创建线程
HANDLEm_hThread = CreateThread(NULL,NULL,GPSThreadProc,NULL,NULL, & m_dwThreadID);
GPSThreadProc(NULL); // 运行线程
return 0 ;
}