張良紅, 楊 豪, 黃 雯, 彭振宇
(浙江省地質(zhì)調(diào)查院,杭州 311203)
航點(diǎn)航跡圖是物化探野外調(diào)查質(zhì)量監(jiān)控的重要資料,包括航跡和點(diǎn)位信息(點(diǎn)號(hào)、坐標(biāo)、日期和時(shí)間),一般要求制作成A4版面[1-2],上部分為航點(diǎn)航跡圖,下部分為點(diǎn)位信息。野外調(diào)查獲得的航點(diǎn)航跡數(shù)據(jù)一般為GPX格式,為制作、輸出可編輯且與地理底圖匹配的航點(diǎn)航跡圖及點(diǎn)位信息,通??衫肕apsource[3-4]、Global Mapper[5-6]等軟件及二次開(kāi)發(fā)[7-8]將航點(diǎn)航跡數(shù)據(jù)投影轉(zhuǎn)換為Excel及MapGIS文件格式,然后在MapGIS中輸出航點(diǎn)航跡圖,并在Excel下編輯和整理點(diǎn)位信息,這些方法比較繁瑣,使用起來(lái)需要對(duì)坐標(biāo)轉(zhuǎn)換方法比較熟悉。
近幾年,浙江各縣市土地質(zhì)量地球化學(xué)調(diào)查工作陸續(xù)開(kāi)展,快速制作航點(diǎn)航跡圖成為地質(zhì)人員急需解決的問(wèn)題。為了避免手工轉(zhuǎn)換過(guò)程中每次打開(kāi)軟件時(shí)重復(fù)設(shè)置投影轉(zhuǎn)換和圖形參數(shù),以及手工創(chuàng)建和編輯航點(diǎn)點(diǎn)位信息。筆者在前人研究基礎(chǔ)上,利用VC基于MapGIS、Excel、MSXML二次開(kāi)發(fā),實(shí)現(xiàn)了航點(diǎn)航跡圖的批量繪制并同時(shí)輸出Excel格式點(diǎn)位信息,為編制航點(diǎn)航跡圖冊(cè)提供了便利。
本系統(tǒng)為Visual C++6.0開(kāi)發(fā)的MFC多文檔應(yīng)用程序,二次開(kāi)發(fā)實(shí)現(xiàn)的功能模塊主要包括存取投影及圖形參數(shù)、讀取GPX數(shù)據(jù)、坐標(biāo)轉(zhuǎn)換、生成點(diǎn)線文件、輸出點(diǎn)位信息等部分,各模塊之間的關(guān)系及系統(tǒng)工作流程如圖1所示。
圖1 系統(tǒng)工作流程Fig.1 The flow chart
本系統(tǒng)操作的主要數(shù)據(jù)為航點(diǎn)和航跡數(shù)據(jù),一條航跡包括多個(gè)航跡點(diǎn),每個(gè)航點(diǎn)包括時(shí)間、位置、點(diǎn)名等信息。為了讀取數(shù)據(jù)、坐標(biāo)轉(zhuǎn)換、圖形繪制等的方便和航點(diǎn)航跡圖輸出成果的需要,系統(tǒng)設(shè)置航點(diǎn)和航跡數(shù)據(jù)結(jié)構(gòu),航點(diǎn)結(jié)構(gòu)存放航點(diǎn)點(diǎn)名、時(shí)間、坐標(biāo)等信息,所有測(cè)點(diǎn)組成一個(gè)數(shù)組,數(shù)組采用MFC提供的模板類CArray;航跡僅需包含航跡名稱和航跡坐標(biāo)信息,點(diǎn)名和時(shí)間信息不使用故不用存儲(chǔ)。航點(diǎn)信息和航跡信息數(shù)據(jù)結(jié)構(gòu)定義如下:
//航點(diǎn)信息
typedef struct
{
CString Name;//點(diǎn)名
CString Time;//時(shí)間
D_DOT xy;//坐標(biāo),MapGIS點(diǎn)線實(shí)體類型數(shù)據(jù)結(jié)構(gòu)
}WAYPT;
typedef CArray
//航跡信息
typedef struct
{
CString Name;//航跡名稱
CArray
}TRACK;
為了避免每次打開(kāi)軟件時(shí)重復(fù)設(shè)置投影轉(zhuǎn)換及圖形參數(shù),可以將參數(shù)保存起來(lái),程序運(yùn)行后先讀取將其作為默認(rèn)參數(shù),為批量制作航點(diǎn)航跡圖提供便利。參數(shù)可以存儲(chǔ)在外部文件(如INI文件9-10])中,也可存儲(chǔ)在程序自身文件內(nèi)。為了減少文件數(shù)量和交流的方便,本程序?qū)?shù)數(shù)據(jù)附加在可執(zhí)行文件(PE)[11]尾部,附加數(shù)據(jù)偏移和大小可通過(guò)讀取PE文件最后一個(gè)節(jié)表中的PointerToRawData和SizeOfRawData數(shù)值來(lái)確定[12-13],具體實(shí)現(xiàn)方法如編程1。
編程1:獲取PE文件附加數(shù)據(jù)偏移和大小
//成功返回附加數(shù)據(jù)偏移,失敗返回0
DWORD GetOverlaySize(HANDLE hFile, PLARGE_INTEGER lpOverlaySize)
{
IMAGE_DOS_HEADER DosHeader;
DWORD dwOffset = 0, dwRead;
if (lpOverlaySize != NULL) lpOverlaySize->QuadPart = 0;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);//移到文件頭
ReadFile(hFile, &DosHeader, sizeof(DosHeader), &dwRead, NULL);
if (DosHeader.e_magic == IMAGE_DOS_SIGNATURE)//MZ
{
IMAGE_NT_HEADERS NtHeaders;
SetFilePointer(hFile, DosHeader.e_lfanew, NULL, FILE_BEGIN);
ReadFile(hFile, &NtHeaders, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), &dwRead, NULL);
if (NtHeaders.Signature == IMAGE_NT_SIGNATURE)//PE