GPS数据格式解析源代码举例
本文轉(zhuǎn)自:http://norke.blog.163.com/blog/static/2765720820116185028104/
GPS數(shù)據(jù)格式解析源代碼舉例
?
隨著內(nèi)置GPS的手機越來越多,GPS相關(guān)的應(yīng)用也越來越廣泛,GPS已經(jīng)不僅僅只是得到一個經(jīng)緯度的信息,可以通過GPS開發(fā)出更多的應(yīng)用,比如位置圖片,比如好友位置顯示,比如跟蹤等等,TimeSyncPPC就是可以使用GPS的時鐘來進行時間同步的。
????
????所有這些功能都需要知道GPS的數(shù)據(jù)格式并能夠解析出自己需要的數(shù)據(jù)出來。下面就以TimeSyncPPC中如何得到GPS的日期和時間為例來說明如何解析GPS數(shù)據(jù)。
????
????TimeSyncPPC是用于Pocket PC上的時間同步工具,因此得到GPS的時間和日期,使用的GPS的指令是$GPRMC,其指令格式如下:
????
????$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>?
??????1) 標準定位時間(UTC time)格式:時時分分秒秒.秒秒秒(hhmmss.sss)。?
??????2) 定位狀態(tài),A = 數(shù)據(jù)可用,V = 數(shù)據(jù)不可用。?
??????3) 緯度,格式:度度分分.分分分分(ddmm.mmmm)。?
??????4) 緯度區(qū)分,北半球(N)或南半球(S)。?
??????5) 經(jīng)度,格式:度度分分.分分分分。
??????6) 經(jīng)度區(qū)分,東(E)半球或西(W)半球。?
??????7) 相對位移速度, 0.0 至 1851.8 knots?
??????8) 相對位移方向,000.0 至 359.9度。實際值。?
??????9) 日期,格式:日日月月年年(ddmmyy)。?
??????10) 磁極變量,000.0 至180.0。?
??????11) 度數(shù)。?
??????12) Checksum.(檢查位)?
????從數(shù)據(jù)格式中可以看出,我們需要得到1和9兩個字段的數(shù)據(jù)即可。
????
????當然,使用GPS首先要打開GPS的串口,代碼如下:??
HANDLE OpenCom(CString strCom, DWORD BaudRate, BYTE ByteSize, BYTE StopBits, BYTE Parity, int FlowControl)
{
????HANDLE??hCommPort;
????CString strTemp;
????if((hCommPort = CreateFile(strCom, GENERIC_READ | GENERIC_WRITE, 0,
????????????????????????NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
????{
????????return NULL;
????}
????
????DCB??????????commDCB;
????CString??????strWinText;
????GetCommState(hCommPort, &commDCB);
????commDCB.BaudRate????= BaudRate;
????commDCB.ByteSize????= ByteSize;
????commDCB.StopBits????= StopBits;
????commDCB.fParity????????= (NOPARITY == Parity) ? FALSE : TRUE;
????commDCB.Parity????????= Parity;
????commDCB.fDsrSensitivity = FALSE;
????commDCB.fDtrControl???? = DTR_CONTROL_ENABLE;
????if(FlowControl == 1)????// Hardware
????{
????????// Enable RTS/CTS Flow Control
????????commDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
????????commDCB.fOutxCtsFlow = 1;
????????commDCB.fOutX = 0;
????????commDCB.fInX = 0;
????}
????else if(FlowControl == 0)????// Software
????{
????????// Enable XON/XOFF Flow Control
????????commDCB.fRtsControl = RTS_CONTROL_ENABLE;
????????commDCB.fOutxCtsFlow = 0;
????????commDCB.fOutX = 1;
????????commDCB.fInX??= 1;??
????}
????else
????{
????????commDCB.fRtsControl = RTS_CONTROL_ENABLE;
????????commDCB.fOutxCtsFlow = 0;
????????commDCB.fOutX = 0;
????????commDCB.fInX??= 0;
????}
????SetCommState(hCommPort, &commDCB);
????return hCommPort;
}????
????串口打開后需要得到一行GPS數(shù)據(jù),GPS數(shù)據(jù)是以結(jié)束,代碼如下:
// 返回值為-1:超時,其他值為數(shù)據(jù)長度
int GetGPSLineData(HANDLE hCommPort, char *ReadBuf, int Length)
{
????// 讀一行GPS數(shù)據(jù)
????DWORD nBytes;
????int i = 0;
????DWORD TimeOut = 0;
????while(i < Length)
????{
????????if(g_isQuit)
????????????return i;
????????TimeOut ++;
????????if(TimeOut >= 100)
????????????return -1;
????????ReadFile(hCommPort, (LPVOID)&ReadBuf[i], 1, &nBytes, NULL);
????????if(nBytes == 0)
????????{
????????????Sleep(1);
????????????continue;
????????}
????????TimeOut = 0;
????????if(ReadBuf[i] == 0x0d)
????????{
????????????ReadBuf[i] = 0;
????????????break;
????????}
????????if(ReadBuf[i] == 0x0a)
????????{
????????????continue;
????????}
????????i ++;
????}
????return i;
}????
????下面是解析一行GPS數(shù)據(jù),將數(shù)據(jù)結(jié)果存儲在一個數(shù)組中,代碼如下:
// 解析一行GPS數(shù)據(jù)
int AnalyzeGPSData(char *GPSData, int Length, char Command[][100])
{
????int i = 0;
????int j = 0, k = 0;
????while(i < Length)
????{
????????if(GPSData[i] == ',')
????????{
????????????Command[j][k] = 0;
????????????j ++;
????????????k = 0;
????????????i ++;
????????????continue;
????????}
????????Command[j][k] = GPSData[i];
????????k ++;
????????i ++;
????}
????return j;
}
解析之后的GPS數(shù)據(jù)包含命令和參數(shù),下面就是判斷是否是我們需要的命令,如果是得到第一個和第九個參數(shù)即可。不過要注意,GPS時間是世界標準時間,因此要轉(zhuǎn)換成本地時間,代碼如下:
DWORD WINAPI GetGPSTime(LPVOID lpParameter)
{
????char ReadBuf[1000];
????DWORD TimeOut = 0;
????
????char Command[40][100];
????HANDLE hCommPort = OpenCom(g_strComPort, g_BaudRate);
????if(hCommPort == NULL)
????{
????????MessageBox(NULL, _T("Can not open COM port!"), NULL, MB_OK | MB_TOPMOST);
????????goto GPSExit;
????}
????while(1)
????{????
????????if(g_isQuit)
????????????break;
????????// 讀一行GPS數(shù)據(jù)
????????int Length = GetGPSLineData(hCommPort, ReadBuf, 999);
????????if(Length == -1)
????????{
????????????TimeOut ++;
????????????if(TimeOut < 100)
????????????????continue;
????????}
????????if(TimeOut >= 100)
????????{
????????????MessageBox(NULL, _T("Read GPS data timeout!"), NULL, MB_OK | MB_TOPMOST);
????????????goto GPSExit;
????????}
????????TimeOut = 0;
????????AnalyzeGPSData(ReadBuf, Length, Command);
????????
????????if(strcmp(Command[0], "$GPRMC") == 0)
????????{
????????????SYSTEMTIME st, LocalSt;
????????????st.wHour = (Command[1][0] - '0') * 10 + (Command[1][1] - '0');
????????????st.wMinute = (Command[1][2] - '0') * 10 + (Command[1][3] - '0');
????????????st.wSecond = (Command[1][4] - '0') * 10 + (Command[1][5] - '0');
????????????st.wMilliseconds = (Command[1][7] - '0') * 100 + (Command[1][8] - '0') * 10 +??(Command[1][9] - '0');
????????????st.wDay = (Command[9][0] - '0') * 10 + (Command[9][1] - '0');
????????????st.wMonth = (Command[9][2] - '0') * 10 + (Command[9][3] - '0');
????????????st.wYear = (Command[9][4] - '0') * 10 + (Command[9][5] - '0') + 2000;
????????????FILETIME FileTime, LocalFileTime;
????????????SystemTimeToFileTime(&st, &FileTime);
????????????FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
????????????FileTimeToSystemTime(&LocalFileTime, &LocalSt);
????????????g_GPSDateCtrl->SetTime(LocalSt);
????????????g_GPSTimeCtrl->SetTime(LocalSt);
????????????if(strcmp(Command[2], "A") == 0)
????????????{
????????????????BOOL ret = SetSystemTime(&st);
????????????????MessageBox(NULL, _T("SyncTime Success!"), _T(""), MB_OK | MB_TOPMOST);
????????????????strGPSButton = _T("Get GPS Time");
????????????????g_ThisDlg->SetDlgItemText(IDC_GETGPSTIME, strGPSButton);
????????????????g_ThisDlg->GetDlgItem(IDC_SETGPSTIME)->EnableWindow(0);
????????????????break;
????????????}
????????????else
????????????{
????????????????TimeOut ++;
????????????}
????????}
????????
????}
GPSExit:
????if(hCommPort != NULL)
????????CloseHandle(hCommPort);
????g_GetGPSTimeThread = NULL;
????strGPSButton = _T("Get GPS Time");
????g_ThisDlg->SetDlgItemText(IDC_GETGPSTIME, strGPSButton);
????g_ThisDlg->GetDlgItem(IDC_SETGPSTIME)->EnableWindow(0);
????
????return TRUE;
}????
????如果需要解析其他指令,可以參考函數(shù)DWORD WINAPI GetGPSTime(LPVOID lpParameter)的實現(xiàn)方法,其實還是比較簡單的。
????
????這些代碼已經(jīng)在TimeSyncPPC中測試過,可以直接使用,開發(fā)環(huán)境為VS2005,Windows Mobile 6.1 for PPC。如有疑問請在下方留言
總結(jié)
以上是生活随笔為你收集整理的GPS数据格式解析源代码举例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 位图和矢量图
- 下一篇: grapher中文版 附序列号