夏 江 常海軍
[摘要]提出一種在Windce5.0下用EVC和Max mobile結合GPS全球定位系統定位信息加語音的錄制和回放的技術,實現電子地圖作業過程中,POI采集和更新程序的實現方法。
[關鍵詞]MapX- MobileEVC NEMA0183語音 POI
中圖分類號:TP2文獻標識碼:A文章編號:1671-7597(2009)0710076-03
電子地圖應用的飛速發展已逐漸在地圖行業中占有越來越大的比重、同時城市范圍也在不斷的擴大,新修的道路和各種設施比比皆是,電子地圖的更新問題已逐漸成了電子地圖應用的一種難言之痛,GPS導航成為了一種普遍采用的導航定位技術,并在精度、實時性、全天候等方面取得了長足進步。本文就針對利用前比較普及的GPS系統,實現電子地圖中POI更新的一種方法。
一、MapInfo MapX Mobile簡介
MapX Mobile是一個可以用在Pocket PC的MapX平臺,用MapX Mobile
建立的軟件可以單獨在設備上運行,并能夠和Pocket PC的Windows CE操作系統兼容,不需要無線連接。
二、定位信息的接收
通常GPS定位信息接收系統主要由GPS接收天線、變頻器、信號通道、微處理器、存儲器以及電源等部分組成。由于GPS定位信息內容較少,因此多用RS-232串口將定位信息(NEMA0183語句)從GPS接收機傳送到PDA中進行信息提取處理。從串口讀取數據有多種方法,在此直接使用 Win32 API函數對其進行編程處理。在Wince5.0下不允許直接對硬件端口進行控制操作,所有的端口均被視為“文件”,因此在對串口進行偵聽之前需要通過打開文件來打開串口,并對其進行相關參數配置:
m_nPortNr=portNo;
wsprintf(szPort, L"COM%d:", portNo); //設置串口名
m_hComm = CreateFile(//打開串口
szPort,
GENERIC_READ | GENERIC_WRITE, //允許讀和寫
0, //獨占方式
NULL,OPEN_EXISTING, //打開而不是創建
0, NULL );
// 設置串口的超時特性為立即返回。
if (!GetCommState(m_hComm,&m_dcb))
{
return FALSE;
}
m_dcb.BaudRate = baud; // 設置波特率
m_dcb.ByteSize = databits; // 數據位,范圍:4-8
m_dcb.Parity = NOPARITY; // 校驗模式
m_dcb.StopBits = stopbits; // 停止位
//設置串口讀寫時間
GetCommTimeouts (m_hComm, &m_CommTimeouts);
m_CommTimeouts.ReadIntervalTimeout = 1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
m_pPortOwner = pPortOwner;
//指定端口監測的事件集
SetCommMask (m_hComm, EV_RXCHAR | EV_CTS);
//創建讀串口線程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&
m_dwRThreadID);
return TRUE;
}
在成功創建讀串口線程后,可采取輪詢串口和事件觸發兩種方式對數據進行接收處理,本文在此采取效率比較高的事件觸發方式進行接收處理,通過等待EV_RXCHAR事件的發生來啟動ReadFile函數完成對GPS定位信息的接收:
ReadThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;
DWORD evtMask;
BYTE * readBuf = NULL;//讀取的字節
DWORD actualReadLen=0;//實際讀取的字節數
DWORD willReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
// 清空緩沖,并檢查串口是否打開。
ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);
//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{
ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
readBuf = new BYTE[willReadLen];
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
//如果讀取的數據大于0,
if (actualReadLen>0)
{
::SendMessage((ceSeries->m_pPortOwner)->m_hWnd, WM_COMM_RXCHAR,
(WPARAM) readBuf, (LPARAM) ceSeries->m_nPortNr);
}
}
}
return 0;
}
三、提取定位數據
GPS接收機處于正常工作狀態時,GPS導航定位信息通過串口按設定的時間間隔傳送到PDA中。前面的程序代碼只是從串口接收數據以字節流的方式放置于指定緩存中,必須通過程序將字節流中的相關信息提取出來,將其格式化為符合程序需要的定位信息數據。同其他通訊協議類似,NMEA 0183信息自有其完善幀結構描述體系。對于本文中其發送到PDA的幀信息主要由幀頭、幀尾和幀內數據組成,根據數據幀的不同,幀頭也不相同,主要有:
“$GPRMC” 、“$GPGGA”、“$GPGSA” 以及“$GPGSV”等。這些幀頭標識了后續幀內數據的組成結構,各幀均以回車符和換行符標識一幀的結束。
對于通常的情況,定位數據如經緯度、速度、時間、等均可以從“$GPRMC”幀中獲取得到,而關于定位時間、緯度、經度、高度、定位所用的衛星數、DOP值、差分狀態和校正時段等相關信息可從“$GPGGA”幀中獲取得,下面這兩種幀結構的相關描述:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
<1>UTC時間,hhmmss(時分秒)格式
<2>定位狀態,A=有效定位,V=無效定位
<3>緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)
<4>緯度半球N(北半球)或S(南半球)
<5>經度dddmm.mmmm(度分)格式(前面的0也將被傳輸)
<6>經度半球E(東經)或W(西經)
<7>地面速率(000.0~999.9節,前面的0也將被傳輸)
<8>地面航向(000.0~359.9度,以真北為參考基準,前面的0也將被傳輸)
<9>UTC日期,ddmmyy(日月年)格式
<10> 磁偏角(000.0~180.0度,前面的0也將被傳輸)
<11> 磁偏角方向,E(東)或W(西)
<12> 模式指示
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx
<1>UTC時間,格式為hhmmss.sss
<2>緯度,格式為ddmm.mmmm(第一位是零也將傳送)
<3>緯度半球,N或S(北緯或南緯)
<4>經度,格式為dddmm.mmmm(第一位零也將傳送)
<5>經度半球,E或W(東經或西經)
<6>定位質量指示,0=定位無效,1=定位有效
<7>使用衛星數量,從00到12(第一個零也將傳送)
<8>水平精確度,0.5到99.9
<9>天線離海平面的高度,-9999.9到9999.9米
<10> 大地水準面高度,-9999.9到9999.9米
<11> 差分GPS數據期限(RTCM SC-104),最后設立RTCM傳送的秒數量
<12> 差分參考基站標號,從0000到1023(首位0也將傳送)
M 指單位米
至于其他幾種幀格式,除了特殊用途外,平時并不常用,雖然接收機也在源源不斷地向主機發送各種數據幀,但在處理時一般先通過對幀頭的判斷而只對"$GPRMC"和$GPGGA幀進行數據處理。如果情況特殊,需要從其他幀獲取數據,處理方法與之也是完全類似的。由于幀內各數據段由逗號分割,因此在處理緩存數據時一般是通過搜尋ASCII碼"$"來判斷是否是幀頭,在對幀頭的類別進行識別后再通過對所經歷逗號個數的計數來判斷出當前正在處理的是哪一種定位導航參數,并做出相應的處理。下面就是對緩存數據中的"$GPRMC"和$GPGGA進行解幀處理的主要代碼:
$GPRMC:
class CRMCResponse
{
NMEA_TIMEm_Time; // UTC時間
NMEA_DATEm_Date; // UTC日期
BOOL m_IsDataValid;// 定位狀態
NMEA_LATITUDEm_Latitude; // 緯度
NMEA_LONGITUDE m_Longitude;// 經度
double m_Bearing;// 地面航向
//提取出相應的數據項
BOOL Parse(const CNmeaSentence& sentence);
};
BOOL CRMCResponse:: Parse(const CNmeaSentence& sentence)
{
// 校驗接收到GPS數據是否有效,無效則返回
NMEA_BOOLEAN check = sentence.IsChecksumBad(12);
m_Time = sentence.Time(1);
m_Date = sentence.Date(9);
m_Latitude = sentence.Latitude(3, 4);
m_Longitude= sentence.Longitude(5, 6);
return TRUE;
}
$GPGGA:
class CGGAResponse
{
int m_GPSQuality; //GPS信號質量
int m_nSatellites;//使用衛星數量
//提取出相應的數據項
BOOL Parse(const CNmeaSentence& sentence);
};
BOOL CGGAResponse::Parse(const CNmeaSentence& sentence)
{
// 校驗接收到GPS數據是否有效,無效則返回
if (sentence.IsChecksumBad(15) == True)
{
return FALSE;
}
m_GPSQuality= sentence.Integer(6);
m_nSatellites = sentence.Integer(7);
return TRUE;
}
現在已將所需信息提取了出來,主要有經緯度、地面速率、地面航向、天線離海平面的高度、使用衛星數量、是否差分、時間、日期等分別提取到了相應變量中,本程序把經緯度作為坐標信息以點的形式保存在實際的程序數據中,而其它相關變量則作為相應點的屬性進行保存。應用中往往要根據需要對其做進一步的運算處理,而且GPS使用的WGS-84坐標系也與我國采用的坐標系不同,有時也要對此加以變換。
四、語音的錄制和回放部分的實現
POI采集和更新涉及到的內容較多,這就對采集到的信息描述提出較高的要求,在保證地理空間位置相對準確的情況下,也要保證采集到的相關信息的準確性,比較通用的一些做法是同時采取多種手段來滿足要求,主要有下幾種方式:
現場記錄紙的方式:詳細記錄每一個信息點相關信息,回到內業把相關信息整理出來,這種做法效率較低,本程序不采取這種方法作為輔助手段。
直接錄入程序方式:本文采取的方式是在現場直接把相關信息的描述寫入程序中,這種做法效率較高,但同時也增加錯誤的幾率,這就需要采取一種輔助手段來幫助修正錯誤,常用的有現場錄音和拍照的方式,本文主要介紹錄音程序的程序實現,下面是語音文件讀寫主要程序代碼。
class CWaveFile
{
public:
/* 文件內部定位 */
unsigned int wave_getpos(wave_file *wf);
char wave_setpos(wave_file *wf, unsigned int pos);
//保存和釋放語音文件占用的內存
void wave_free(wave_file *wf);
char wave_save(wave_file *wf);
//保存語音文件
DWORD m_dwFlags;
long Write(char* pData, long nLength);
//打開語音文件
BOOL Open(LPCTSTR szFileName,DWORD dwFlags);
void Close();
//讀取語音數據
long Read(char* pData, long nLength);
long GetLength() {return m_nLength;}
protected:
FILE* m_pFile; //文件指針
long m_nLength;//讀取或寫入文件的數據段長度
};
通過以上程序代碼,可以作為輔助手段的語音文件可以非常方便地進行讀寫,在進行內業數據整理的時候,利用采集現場記錄數據和相應錄音可以進一步提高信息描述的準確性。
上面是本文中提到的程序的主要實現模塊,具體的環境有不同的應用要求,實現細節也可能不同,但此種做業方式對電子地圖數據的采集和更新來說,經過實際工作的檢驗,還是比較實用的。
五、小結
本文結合主要的相關程序代碼對電子地圖數據的采集和更新進行了模塊說明,包括NMEA 0183格式說明、串口的程序設計、語音模塊作了簡要的講述。通過本文的設計方法可提高電子地圖數據的采集和更新效率和數據質量。本文程序在Windows xp下,由EVC++ 4.0編譯通過。
參考文獻:
[1]李勝樂,MapInfo地理信息系統二次開發實例,電子工業出版社.
[2]汪兵、李存斌、陳鵬等,EVC高級編程及其應用開發(EMBEDDED VISUAL C++嵌入式編程),中國水利水電出版社.
[3]譚思亮、鄒超群,Visual C++串口通信工程開發實例導航,人民郵電出版社.
[4]MapX 開發人員指南,MapInfo Corporation Troy,NY.
[5]Programming Microsoft Windows CE.NET,Third Edition,Douglas Boling Microsoft Press.
[6]NMEA-0183 Protocol Description, Mihai, www.remember.ro.
作者簡介:
夏江,女,53歲,工程師,河北省地礦局測繪院制圖分院副院長、技術負責,從事測繪工作34年;常海軍,河北省地礦局測繪院制圖分院,工程師。