一、 前言
電子地圖應(yīng)用作為一門新興學(xué)科,已不僅限于地圖制作中。本文利用VC++和OLE(Object Linking and Embedding, 對象連接和嵌入)編程技術(shù),實現(xiàn)了實時信息在矢量地圖背景上的顯示。
程序應(yīng)用于顯示處理終端,接收并處理網(wǎng)絡(luò)信息的部分在不同的系統(tǒng)中有不同的要求,這里不再贅述。
MapInfo矢量地圖用圖層方式進(jìn)行存儲和管理,每個圖層對應(yīng)地圖上的一類要素(如居民地,水系,鐵路,公路等),對于每個包含圖形信息的圖層,需要有4個文件(.dat, .tab, .map, .id)支持。
MapInfo地圖允許嵌入一個地圖窗口到任何能接受OLE對象的應(yīng)用程序中。從服務(wù)器(如MapInfo)插入一個OLE對象到容器應(yīng)用程序(如Microsoft Word),并在該應(yīng)用程序中對這個對象進(jìn)行處理。被嵌入的對象是來自服務(wù)器應(yīng)用程序的對象的一個副本。對象一旦位于容器中,它將不再被鏈接到源對象。
在VC++應(yīng)用程序中用OLE方式嵌入MapInfo進(jìn)程,需定義了一個MapInfo對象(DMapInfo類),DMapInfo類在MapInfo類型庫(Mapinfow.tlb)中定義。MapInfo軟件提供了自己的編程語言MapBasic, VC++對地圖進(jìn)程的操作主要通過發(fā)送MapBasic命令來實現(xiàn)。
二、 創(chuàng)建程序框架
程序框架是用MFC實現(xiàn)的,MFC 應(yīng)用程序向?qū)ВˋppWizard)生成了大部分的代碼,然后加入MapInfo進(jìn)程。步驟如下:
1. 創(chuàng)建一個新項目,項目類型選擇MFC AppWizard(exe),項目名稱設(shè)為MapApp,其它按照提示進(jìn)行設(shè)置即可。應(yīng)用程序向?qū)ё詣由闪巳齻€類:
CmapAppApp 應(yīng)用程序類
CmapAppDoc 文檔類
CmapAppView 視圖類
CmainFrame 主框架類
2. 添加MapInfo類型庫
運行類向?qū)?,單擊增加類按鈕(Add Class …),選擇“From a type library”,找到“Mapinfow.tlb”文件并打開,在“Confirm Classes”中選擇“DMapInfo”類,單擊OK確認(rèn)輸入并關(guān)閉對話框。現(xiàn)在MapApp應(yīng)用程序中已添加了DMapInfo類,并增加了"mapinfow.h"和"mapinfow.cpp"兩個源文件。
3. 用OLE方式嵌入MapInfo進(jìn)程
在"mapApp.cpp"中CMapAppApp theApp語句下面加入下面的語句:
DMapInfo mapinfo; file://mapinfo對象
在CMapAppApp::InitInstance() 函數(shù)中增加OLE的初始化,代碼如下:
程序清單1 MapApp.cpp文件
將"mapbasic.h"文件拷貝到本項目的目錄中,在“stdafx.h”中增加以下代碼,把mapinfo說明為全局變量:
4. 顯示地圖窗口
為CmapAppView類增加地圖窗口的標(biāo)識和句柄變量,在MapAppView.h文件中添加如下代碼:
打開類向?qū)Т翱?,在Class Name下拉列表框中選擇類CmapAppView,Object Ids列表框中選擇CmapAppView,Messages列表框中選擇OnInitialUpdate,單擊Add Function為CmapAppView重載OnInitialUpdate()函數(shù),然后在函數(shù)中添加顯示地圖窗口的代碼。
程序清單2 MapAppView.cpp文件
5. 編譯運行軟件,將屏幕顯示分辨率設(shè)置為1600′1024,則在右半屏出現(xiàn)地圖窗口?,F(xiàn)在剩下的工作只是加入接收目標(biāo)數(shù)據(jù)并轉(zhuǎn)換為經(jīng)緯度后進(jìn)行實時顯示,這里只給出同地圖窗口有關(guān)的部分,假設(shè)正在不斷接收目標(biāo)數(shù)據(jù),寫入全局變量中,并向CmapAppView類發(fā)送消息,調(diào)用CmapAppView類的ShowMapLine()函數(shù)。在MapApp.cpp文件中添加全局變量定義:
在MapApp.h文件中添加全局變量說明:
在CmapAppView::OnInitialUpdate()函數(shù)的結(jié)束部分添加如下代碼:
/////////////////定義mapinfo中所用的變量
在CmapAppView:: ShowMapLine()函數(shù)代碼如下:
程序清單3 MapAppView.cpp文件
6. 編譯運行軟件,顯示界面如下:
要保存plane表,可在CmapAppView類的析構(gòu)函數(shù)中添加下面的代碼:
程序清單4 MapAppView.cpp文件
左屏顯示內(nèi)容的構(gòu)造,可根據(jù)各軟件系統(tǒng)的要求,顯示數(shù)據(jù),圖表等,由VC++編程實現(xiàn)。
三、 其它說明
上面程序清單2中
sprintf(str,"Add Map Window %lu Layer plane Animate",m_lWindowid);
語句中的Animate屬性一定要有,這表示將plane圖層設(shè)置為動態(tài)(Animate)圖層,每個地圖窗口只能有一個動態(tài)圖層,當(dāng)這個圖層上的對象變化時,地圖窗口只刷新此圖層,以便可以實現(xiàn)快速刷新。
在應(yīng)用OLE技術(shù)嵌入地圖窗口的應(yīng)用中,還可根據(jù)需要加入多種工具,用于地圖信息的修改和查詢,如標(biāo)尺窗口,信息窗口,圖層控制,圖層選擇編輯等,但在實時接收數(shù)據(jù)并顯示的狀態(tài)下,有些功能的使用將會導(dǎo)致訪問沖突,以致程序出錯,如圖層控制、圖層編輯等,原因是實時數(shù)據(jù)正在對plane表進(jìn)行編輯,此時再改變其它圖層,就與mapInfo一次只能編輯一個圖層的原則產(chǎn)生了沖突。