轉載自devdiv論壇,原作者爲:yinzl0211
http://www.devdiv.net/viewthread.php?tid=12491&page=1&authorid=14949
帶GPS功能的Windows Mobile手機定位可以通過GPS獲取手機所在的詳細地址,民用一般誤差在5米到50米之間的範圍內。通過使用GPSApi頭文件中包含的一下四個函數,由GPS中層驅動程序(GPSID)提供,可以通過它使用GPS設備並實時更新手機所在位置的信息。注意包含GPSAPI.h頭文件與GPAAPI.lib靜態鏈接庫。
#include <gpsapi.h>
#pragma comment(lib,"gpsapi.lib")
GPSOpenDevice
GPSGetPosition
GPSGetDeviceState
GPSCloseDevice
一、下面分別介紹各個函數的功能,參數以及具體怎樣實現使用這些函數。
1.GPS_POSITION結構
在介紹各個函數之前,要先介紹GPS_POSITION數據結構,他用來存放GPS定位所需要的各種信息。
typedef struct _GPS_POSITION {
DWORD dwVersion; //GPSID的版本號,在調用GPSGetPosition之前賦值,暫時必須被賦值爲GPS_VERSION_1
DWORD dwSize; //GPS_POSITION結構的大小,同樣應先用sizeof給它賦值
DWORD dwValidFields;// 結構實例中的有效空間標記,標記結構中哪些值有效
DWORD dwFlags; //在調用GPSGetPosition函數時修改過的數據的狀態
SYSTEMTIME stUTCTime; //根據GPS衛星提供的信息獲得的宇宙時間
double dblLatitude; //緯度,單位”度”,正數表示北
double dblLongitude; //經度,單位”度”,正數表示東
float flSpeed; //移動速度,單位“KNOTS”(海里),估計是海里/小時
float flHeading; //移動方向,單位“度”,數值爲偏北往順時針的度數
double dblMagneticVariation; //正北與地磁北極角度差,整數表示往東的度數
float flAltitudeWRTSeaLevel; //距海平面高度
float flAltitudeWRTEllipsoid;//距橢球面高度
GPS_FIX_QUALITY FixQuality;
GPS_FIX_TYPE FixType;
GPS_FIX_SELECTION SelectionType;
float flPositionDilutionOfPrecision;
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;
通過以上可以知道,要獲取GPS定位信息,必須定位一個GPS_POSITION變量保存其信息,且在使用GPSGetPosition函數前要將其前兩個參數分別賦好值。
2.GpsOpenDevice
函數原型如下:
HANDLE GPSOpenDevice(
HANDLE hNewLocationData,
HANDLE hDeviceStateChange,
const WCHAR *szDeviceName,
DWORD dwFlags
);
函數功能:建立程序同GPS中間驅動的連接,獲得句柄。
前兩個參數爲HANDLE型,都通過CreateEvent的返回值給它們賦值。如:
HANDLE s_hNewLocationData = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE s_hDeviceStateChange = CreateEvent(NULL, FALSE, FALSE, NULL);
第1個參數: HANDLE hNewLocationData
CreateEvent生成的句柄或者爲NULL。
當有新的GPS定位信息時,這個事件被GPS中間驅動設置爲信號態。
第2個參數: HANDLE hDeviceStateChange
CreateEvent生成的句柄或者爲NULL。
當GPS設備位置發生改變時,驅動將其設置爲信號態。
第3個參數:必須爲NULL。
第4個參數:必須爲0。
返回值:成功則返回GPS中間驅動句柄。失敗則爲NULL。
3.GPSGetPosition
DWORD GPSGetPosition(
HANDLE hGPSDevice,
GPS_POSITION *pGPSPosition,
DWORD dwMaximumAge,
DWORD dwFlags
);
函數功能:返回本地位置信息。
第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
DWORD GPSCloseDevice(
HANDLE hGPSDevice
);
函數功能:關閉GPS設備句柄。
參數:HANDLE hGPSDevice:GPSOpenDevice打開的GPS設備句柄。
返回值:成功:ERROR_SUCCESS。 錯誤:錯誤信息。
二、GPS具體實現細節
1> 首先用CreateEvent生成3個接受消息的句柄,兩個上述以說明,第三個用來接受置關閉GPS設備結束線程
HANDLE s_hExitThread = CreateEvent(NULL, FALSE, FALSE, NULL);
2> 打開GPS設備並聲明線程函數
HANDLE s_hGPS_Device = GPSOpenDevice(s_hNewLocationData, s_hDeviceStateChange, NULL, NULL);
DWORD GPSThreadProc(__opt LPVOID lpParameter);
3> 定義線程函數
DWORD GPSThreadProc(__opt LPVOID lpParameter)
{
GPS_POSITION gps_Position = {0}; //不用說了,放數據的
DWORD dwRet = 0; //表狀態的,具體狀態幹具體的事
GPS_DEVICE gps_Device = {0}; //存放GPS設備信息,在GPSGetDeviceState前要賦值,如下
HANDLE gpsHandles[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[])
{
DWORD m_dwThreadID; //創建線程
HANDLE m_hThread = CreateThread(NULL, NULL, GPSThreadProc, NULL, NULL, &m_dwThreadID);
GPSThreadProc(NULL); //運行線程
return 0;
}