Windows Mobile手機GPS定位

轉載自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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章