徐曉宇,魏巍,宗亞輝,李富忠
(山西農(nóng)業(yè)大學(xué) 軟件學(xué)院,山西 太谷 030801)
基于MiniGUI的嵌入式電子地圖引擎開發(fā)
徐曉宇,魏巍,宗亞輝,李富忠*
(山西農(nóng)業(yè)大學(xué) 軟件學(xué)院,山西 太谷 030801)
[目的]為了提高電子地圖的開發(fā)效率,減輕開發(fā)人員負(fù)擔(dān),本文研究不針對特定操作系統(tǒng)、基于MiniGUI的嵌入式電子地圖引擎,并處理TAB格式的地圖數(shù)據(jù)。[方法]首先設(shè)計一個基于MiniGUI的自定義控件,利用與操作系統(tǒng)無關(guān)的接口設(shè)計相應(yīng)的類,實現(xiàn)地圖源數(shù)據(jù)讀取、繪制、漫游、縮放和測距等功能。[結(jié)果]使用該引擎開發(fā)電子地圖應(yīng)用程序,利用該程序?qū)σ孢M行功能性驗證。結(jié)果表明,該引擎各項功能均能正確執(zhí)行。[結(jié)論]該電子地圖引擎功能正常,使用方便,操作簡單,具有一定的可移植性。
MiniGUI; 嵌入式電子地圖; 引擎開發(fā)
MiniGUI, Embedded Electronic Map, Development of Engine
隨著嵌入式技術(shù)的快速發(fā)展,嵌入式電子地圖已經(jīng)滲透到農(nóng)業(yè)、軍事、工業(yè)、醫(yī)療等各個領(lǐng)域。由于嵌入式設(shè)備資源平臺有限,不能像PC機一樣安裝主流的桌面地理信息系統(tǒng)軟件,因此需要技術(shù)人員根據(jù)實際需要進行開發(fā)。
目前已有不少國內(nèi)外公司(如ESRI,Pocket Systems Ltd)研發(fā)出了嵌入式電子地圖[1],但多數(shù)只適用于某個特定的嵌入式操作系統(tǒng)(如linux、uC/OS—II、VxWorks等)[2]。在這種情況下,開發(fā)人員使用電子地圖二次開發(fā)工具,即使用電子地圖引擎來開發(fā)電子地圖,將大大減輕工作負(fù)擔(dān),縮短開發(fā)周期,提高開發(fā)效率。
因此,本文基于輕量級、可移植性高的MiniGUI,開發(fā)不針對特定操作系統(tǒng)的嵌入式電子地圖引擎,用來處理TAB格式的地圖數(shù)據(jù)。具體開發(fā)流程為:先設(shè)計一個基于MiniGUI的自定義控件MGC;再設(shè)計相應(yīng)的類,以完成地圖源數(shù)據(jù)的讀取、繪制、漫游、縮放和測距等功能。由于開發(fā)時全部使用與操作系統(tǒng)無關(guān)的接口,所以該引擎可以適應(yīng)各種MiniGUI環(huán)境。
1.1 MapInfo數(shù)據(jù)文件
開發(fā)過程中所處理數(shù)據(jù)的格式為MapInfo中的TAB格式。在TAB格式文件中,地圖屬性數(shù)據(jù)存儲在兩種屬性表中,主要是屬性數(shù)據(jù)的表結(jié)構(gòu)文件.TAB和屬性數(shù)據(jù)文件.DAT中[3,4]??臻g數(shù)據(jù)則保存在空間數(shù)據(jù)文件.MAP中。通過索引文件(.ID文件)將.TAB文件和.DAT文件的數(shù)據(jù)有機結(jié)合在一起[5]。
1.2 OGR/GDAL
GDAL(Geospatial Data Abstraction Library)是一個開源的、符合X/MIT協(xié)議、利用抽象數(shù)據(jù)模型及其它工具來進行數(shù)據(jù)轉(zhuǎn)換和解析的柵格空間數(shù)據(jù)轉(zhuǎn)換庫[6]。OGR庫是GDAL庫下的一個可以讀取、寫入和處理多種矢量數(shù)據(jù)格式的C++開源庫[7],可以處理ESRI Shapefiles、SDTS、PostGIS、MapInfo TAB、MapInfo mid/mif等類型的數(shù)據(jù)[8],并且是按照Open GIS對矢量數(shù)據(jù)格式而定義的[9]。
1.3 MiniGUI的消息機制
MiniGUI是靠消息驅(qū)動的系統(tǒng),所有的運作都是圍繞消息而進行的。系統(tǒng)對輸入事件會產(chǎn)生消息,對應(yīng)用程序的響應(yīng)也會產(chǎn)生消息,應(yīng)用程序通過接收消息來完成某個動作,也可以同其他應(yīng)用程序的窗口進行通信[10]。MiniGUI在處理消息的過程中,窗口管理器會維護主窗口的消息隊列,當(dāng)外設(shè)有某些動作,比如鼠標(biāo)左鍵被按下時,窗口管理器會將該消息放入主窗口的消息隊列并進入消息循環(huán)中,接收該消息的窗口會根據(jù)相應(yīng)的窗口過程來處理這條消息。
1.4 雙緩沖技術(shù)實現(xiàn)快速繪圖
為了地圖的快速顯示,以及避免地圖繪制過程中的閃爍現(xiàn)象,采用雙緩沖技術(shù)的繪圖模式[11,12]。
第一次緩沖要求用戶將地圖數(shù)據(jù)繪制在一個大于屏幕顯示范圍的內(nèi)存區(qū)域上,這個內(nèi)存區(qū)域稱為緩沖區(qū)1,當(dāng)用戶進行漫游時,可以直接從該內(nèi)存區(qū)域中讀取數(shù)據(jù)并顯示,而不必在整個地圖數(shù)據(jù)庫中再尋找,加快了地圖的顯示速度。
第二次緩沖要求從緩沖區(qū)1中將需要顯示的數(shù)據(jù)拷貝到緩沖區(qū)2中,緩沖區(qū)2是一個和屏幕顯示區(qū)域大小一致的內(nèi)存區(qū)域之后可以給緩沖區(qū)2上面再繪制一些其他信息,如文字等。繪制完成后再將緩沖區(qū)2中的數(shù)據(jù)一次性拷貝到屏幕顯示區(qū)域。
2.1 系統(tǒng)開發(fā)環(huán)境
設(shè)計實現(xiàn)的電子地圖引擎MiniGUIGISController的開發(fā)環(huán)境配置如表1所示。
表1 系統(tǒng)開發(fā)環(huán)境配置
安裝MiniGUI時需要打開幀緩沖,并使用qvfb(qt virtual framebuffer)在X window下模擬出frame buffer環(huán)境,以節(jié)省時間。使用qvfb時,需對MiniGUI.cfg 文件進行配置。在MiniGUI安裝完成后還需要依次安裝Proj和GDAL。
2.2 系統(tǒng)類設(shè)計
系統(tǒng)中共設(shè)計了47個類來完成既定功能,圖1給出了其中最主要的20個類及其關(guān)系。
圖1 MiniGUIGISController頂層類圖Fig.1 The top class diagram of MiniGUIGISController
圖1中的類主要包括:ViewState類及其子類提供對地圖的控制功能,主要用來處理鼠標(biāo)事件;Map類結(jié)合Layer、Feature類以及這些類的子類為地圖數(shù)據(jù)讀取提供支持,還包含了打開地圖、設(shè)置過濾器、設(shè)置地圖顯示中心等;MiniGUIDC類、DrawContext類、Env類CS類以及IniFile類屬于工具類,提供坐標(biāo)轉(zhuǎn)換、配置信息讀取、矢量圖形的繪制等功能。除了ViewState類,圖1中的其他類全部參與到地圖的繪制與顯示過程中,尤其是Style類和Geometry類,負(fù)責(zé)圖元繪制的細(xì)節(jié)問題。
2.3 自定義控件MGC的實現(xiàn)
MGC是MiniGUI上的自定義控件,該控件中定義了很多關(guān)于地圖操作的消息,對電子地圖的任何操作都會以消息的形式發(fā)送給MGC,并在MGC的過程函數(shù)中得到處理。
開發(fā)MGC步驟如下:
(1)控件注冊。在注冊過程中需要對控件類的樣式、擴展風(fēng)格、背景色、控件的過程處理函數(shù)等信息進行賦值。其中,最重要的是控件的過程處理函數(shù)_on_message(),該函數(shù)將MGC接收到的所有消息轉(zhuǎn)發(fā)給View類的對象。
(2)消息處理。由于最終的消息處理需要在View類的對象中進行,將該對象的指針作為MGC控件的一個附加數(shù)據(jù)來保存,以后所有對地圖的操作都要依附于該對象。所以,_on_message()函數(shù)接收到消息之后,首先會判斷當(dāng)前窗口的附加數(shù)據(jù)中是否包含一個View類型對象的指針,如果包含,則直接將消息轉(zhuǎn)發(fā)給該對象的_on_message()函數(shù),如果沒有包含,則要新建一個View類的對象,然后再將消息發(fā)送給該對象的_on_message()函數(shù)。
(3)控件卸載。在應(yīng)用程序退出時要對注冊的控件進行卸載,此時調(diào)用了MiniGUI的UnregisterWindowClass()函數(shù)。
2.4 讀取源數(shù)據(jù)模塊的實現(xiàn)
讀取源數(shù)據(jù)功能通過Map類的open()函數(shù)來完成。
open()函數(shù)在創(chuàng)建Map類的對象map之后,將地圖數(shù)據(jù)的部分信息保存在map對象的對應(yīng)屬性中,包括地圖名以及地圖源數(shù)據(jù)的存放目錄。之后根據(jù)地圖源數(shù)據(jù)配置文件,通過load_from_gstfile()函數(shù)讀取地圖源數(shù)據(jù)。
load_from_gstfile()函數(shù)根據(jù).gst文件中的配置信息讀取地圖源數(shù)據(jù),同時保存對應(yīng)圖層的配置信息。在該函數(shù)中首先要創(chuàng)建一個IniFile類的對象gst_file,用來保存從.gst文件中讀取到的地圖配置信息,然后根據(jù)gst_file對象中的內(nèi)容依次讀取每一層地圖數(shù)據(jù)。在讀取某一層地圖源數(shù)據(jù)時,需要創(chuàng)建OGR數(shù)據(jù)源對象ds,然后再獲取該圖層的OGRLayer對象layer。通過layer創(chuàng)建一個MapLayer類的對象,其指針保存在layer_ptr對象中,然后將當(dāng)前圖層的配置信息保存在MapLayer類的對象中。最終,ds、圖層名稱以及l(fā)ayer_ptr會被保存在map對象的對應(yīng)屬性中,而且layer_ptr在map中的存放次序和配置文件中定義的圖層顯示次序一致。
2.5 地圖繪制模塊的實現(xiàn)
電子地圖在接收到繪制消息后,首先會調(diào)用view對象的on_paint()函數(shù),該函數(shù)用來完成緩沖區(qū)1的重繪以及緩沖區(qū)2、結(jié)果層和文字層的繪制。
當(dāng)需要重繪緩沖區(qū)1時,調(diào)用draw_background()函數(shù),該函數(shù)內(nèi)部需要完成過濾器和繪圖上下文的設(shè)置,之后調(diào)用MapLayer對象中的draw()函數(shù),依次繪制每一個圖層,并保存當(dāng)前的地圖狀態(tài),包括像素、比例尺以及緩沖區(qū)1在地圖正投影坐標(biāo)系中的位置。
(1)設(shè)置過濾器函數(shù)。設(shè)置過濾器函數(shù)的作用是設(shè)置緩沖區(qū)1中能顯示的地圖球面坐標(biāo)的范圍。以緩沖區(qū)1的左上角在正投影坐標(biāo)系統(tǒng)中的位置為參考,根據(jù)緩沖區(qū)1的尺寸和像素比例尺,經(jīng)過坐標(biāo)轉(zhuǎn)換,計算出緩沖區(qū)1所對應(yīng)區(qū)域的球面坐標(biāo)范圍。
(2)圖層繪制。首先要確定當(dāng)前比例尺下需要顯示的圖層,然后調(diào)用MapFeature::draw()函數(shù)依次繪制需要顯示的圖層中能通過過濾器的各個地圖要素。get_next_feature()函數(shù)返回下一個需要繪制的地圖要素的指針。獲得一個需要繪制的要素之后,通過MapFeature::draw()函數(shù)來繪制該要素。
2.6 地圖漫游模塊的實現(xiàn)
地圖進入漫游狀態(tài)后,控件要接收鼠標(biāo)左鍵被按下、移動以及左鍵抬起的消息,之后會按照接收到的消息來完成不同的動作。
鼠標(biāo)左鍵被按下時,需要設(shè)置鼠標(biāo)的按下狀態(tài),同時記錄當(dāng)前的鼠標(biāo)位置,每一次接收到鼠標(biāo)移動事件,都會調(diào)用on_mouse_move()函數(shù),在該函數(shù)中計算鼠標(biāo)的移動距離,之后調(diào)用InvalidateRect()函數(shù)設(shè)置無效區(qū)域并重繪,該函數(shù)會引起MSG_PAINT消息的發(fā)送,這時需要在Roaming::on_paint()函數(shù)中來處理該消息,完成漫游過程中地圖的繪制。
鼠標(biāo)左鍵抬起時進入on_mouse_up()函數(shù),設(shè)置鼠標(biāo)的抬起狀態(tài)后,調(diào)用move_viewport()函數(shù)來保存當(dāng)前顯示窗口的位置信息。
2.7 地圖縮放模塊的實現(xiàn)
縮放功能包括對地圖的點擊放大、矩形放大、點擊縮小,這里以點擊放大為例,該過程涉及到3個函數(shù)。
(1)Zoom::on_mouse_down()函數(shù)
進入點擊放大狀態(tài)并獲取到了鼠標(biāo)左鍵被按下消息后,調(diào)用Zoom::on_mouse_down()函數(shù)來保存當(dāng)前鼠標(biāo)位置以及鼠標(biāo)左鍵的按下狀態(tài)。
(2)ZoomIn::on_mouse_up()函數(shù)
當(dāng)接收到鼠標(biāo)左鍵抬起的消息時,會調(diào)用ZoomIn::on_mouse_up()函數(shù),該函數(shù)根據(jù)鼠標(biāo)左鍵被點擊之前的像素比例尺和預(yù)先定義的放大因子,計算并設(shè)置放大后的像素比例尺,同時還要用點擊點的位置設(shè)置為緩沖區(qū)1的中心位置,最后需要調(diào)用Zoom::on_mouse_up()函數(shù)進行重繪。
(3)Zoom::on_mouse_up()函數(shù)
該函數(shù)設(shè)置鼠標(biāo)左鍵的抬起狀態(tài),設(shè)置窗口無效區(qū)域,引起重繪操作,并根據(jù)放大操作之后的像素比例尺和緩沖區(qū)1的位置,進行重繪操作。
2.8 測距模塊的實現(xiàn)
在測距功能中,采用Distance::on_mouse_down()函數(shù)和Distance::on_mouse_dbclick()函數(shù)。二者分別實現(xiàn)了如何處理鼠標(biāo)左鍵彈起以及接收到鼠標(biāo)左鍵雙擊消息后的動作。
測距狀態(tài)下,鼠標(biāo)左鍵被按下時調(diào)用on_mouse_down()函數(shù)。該函數(shù)首先判斷用戶是否是第一次點擊鼠標(biāo),如果是,則只標(biāo)記該點;反之則需要判斷是否屬于鼠標(biāo)左鍵被雙擊,若屬于,則意味著標(biāo)記結(jié)束,此時調(diào)用on_mouse_dbclick()函數(shù)來計算各點之間的距離之和,并調(diào)用用戶設(shè)置好的回調(diào)函數(shù),將測距結(jié)果反饋給用戶。
利用MiniGUIGISController開發(fā)電子地圖應(yīng)用程序MgisTest,通過MgisTest對MiniGUIGISController的功能進行驗證。
3.1 MgisTest的實現(xiàn)步驟
(1)創(chuàng)建主窗口。
(2)在主窗口中創(chuàng)建工具欄、Menu菜單以及地圖控件。工具欄用來提供改變地圖狀態(tài)的操作:漫游、放大、縮小、測距。Menu菜單主要提供地圖的打開、關(guān)閉功能。地圖控件用來顯示地圖以及完成對地圖的所有操作。
(3)設(shè)置各個UI元素的過程處理函數(shù),完成相應(yīng)的操作。
(4)設(shè)置測距回調(diào)函數(shù)用來反饋測距結(jié)果。
3.2 驗證過程及結(jié)果
(1)打開電子地圖后如圖2所示,地圖源數(shù)據(jù)被讀取并繪制在窗口中,地圖正常顯示,說明MiniGUIGISController的讀取源數(shù)據(jù)及地圖繪制功能正常。
圖2 讀取源數(shù)據(jù)、地圖繪制功能測試結(jié)果Fig.2 The testing results of reading data and drawing function
(2)向左拖動鼠標(biāo),使得整個地圖向左進行漫游,如圖3所示。經(jīng)過漫游動作,原本在右邊位置的“兒童公園南門”的標(biāo)注移動到了該圖的中心位置,說明MiniGUIGISController的漫游功能正常。
(3)點擊“縮小”按鈕,使地圖進入縮小狀態(tài),如圖4所示。從圖4中可以看出,河流寬度變窄,各部分區(qū)域也相應(yīng)縮小,而且與圖3相比,五角星的標(biāo)注消失,說明MiniGUIGISController的縮小功能正常。
(4)點擊“放大”按鈕,使地圖進入放大狀態(tài),如圖5所示。與圖2相比,河流寬度增加,各部分區(qū)域變大,說明MiniGUIGISController的放大功能正常。
圖3 地圖漫游功能測試結(jié)果Fig.3 The testing results of roaming function
圖4 地圖縮小功能測試結(jié)果Fig.4 The testing results of zooming-out function
圖5 地圖放大功能測試結(jié)果Fig.5 The testing results of zooming-in function
(5)點擊“測距”按鈕,并用鼠標(biāo)標(biāo)注出想要測量的點,系統(tǒng)會自動生成兩點間的直線,通過雙擊鼠標(biāo)左鍵完成標(biāo)注,之后屏幕上會彈出一個標(biāo)識測距結(jié)果的對話框,在此對話框中顯示整個距離為1.2 km,如圖6所示。這說明MiniGUIGISController的測距功能正常。
圖6 測距功能測試結(jié)果Fig.6 The testing results of measuring distance function
通過對MiniGUIGISController基礎(chǔ)上的電子地圖MgisTest進行各種操作,驗證了MiniGUIGISController能正常執(zhí)行地圖源數(shù)據(jù)讀取、繪制、漫游、縮放、測距等功能。
論文設(shè)計實現(xiàn)了基于MiniGUI、針對MapInfo的TAB格式數(shù)據(jù)的電子地圖引擎MiniGUIGISController,該引擎有地圖源數(shù)據(jù)讀取、繪制、漫游、縮放、測距等功能,使用方便、操作簡單,具有一定的可移植性,今后可以從以下幾方面繼續(xù)完善:增加搜索及定位功能;增加對三維地圖數(shù)據(jù)的繪制與顯示功能;設(shè)計針對特定機型的電子地圖引擎。
[1]龍柏宇.基于ARM的數(shù)字船用雷達顯控軟件的設(shè)計與實現(xiàn)[D].成都:電子科技大學(xué),2013.
[2]龔峰.基于Geocoding和瓦片地圖引擎的生活信息服務(wù)系統(tǒng)的開發(fā)[D].上海:上海交通大學(xué),2012.
[3]Shoba B, Rasappan K. Application of GIS in Solid Waste Management for Coimbatore City[J]. International Journal of Scientific and Research Publications,2013,3(10):1-4.
[4]李樂,毛之琳.MapInfo二次開發(fā)在坐標(biāo)轉(zhuǎn)換中的應(yīng)用[J].測繪通報,2011(12):58-60.
[5]Hou D-y, Zhang S-b. Research the Coordinate Transformation Method about MapInfo Data[J]. Geomatics & Spatial Information Technology,2011(1):065.
[6]崔虎平,江南.基于OGR的通用地理數(shù)據(jù)格式轉(zhuǎn)換研究[J].測繪通報,2012(s1):579-581.
[7]Warmerdam F. The Geospatial Data Abstraction Library[M].Open Source Approaches in Spatial Data Handling,2008:87-104.
[8]黃健,宋巧紅,吳延海,等.嵌入式Linux下MiniGUI皮膚引擎設(shè)計[J].計算機應(yīng)用與軟件,2011(10):114-116.
[9]Zhao S, Yu T, Meng Q, et al. GDAL-based extend ArcGIS Engine’s support for HDF file format[C]//2010 18th International Conference on Geoinformatics. IEEE, 2010:1-3.
[10]韓飛,黃賢武,張慶峰.MiniCUI在車載導(dǎo)航終端中的應(yīng)用[J].單片機與嵌入式系統(tǒng)應(yīng)用,2005(6):61-63.
[11]安曉博,陳蜀宇,劉小威.嵌入式GIS地圖快速顯示方法的應(yīng)用[J].計算機系統(tǒng)應(yīng)用,2012(10):204-207.
[12]趙松.跨平臺導(dǎo)航電子地圖顯示引擎的研究與構(gòu)建[D]:重慶大學(xué),2008.
(編輯:李曉斌)
[Objective]In order to improve the efficiency of the development of electronic map, and reduce the burden of developer’s, the thesis developed an electronic map engine which could deal with the data of TAB format, based on MiniGUI, and the engine was not for a specific operating system. [Methods]Firstly, the thesis designed a controller on MiniGUI. Then, used interface which was independent of operate system to design the corresponding class. The engine provided functions of reading map data, drawing map, roaming, zooming, measuring distance and others.[Results]The thesis developed an electronic map application based on the engine, which could be used to test and verify the engine. The result showed that the functions provided by the engine were normal, and could meet the expectation. [Conclusion]The electronic map engine works normally, easy operating and has good portability.
2016-09-27
2016-11-24
徐曉宇(1987-),女(漢),山西陽泉人,助教,碩士,研究方向:軟件工程
*通信作者:李富忠,教授,博士生導(dǎo)師。Tel:13734008985;E-mail:sxaulfz@126.com
山西農(nóng)業(yè)大學(xué)科技創(chuàng)新基金(2016009)
TP311
A
1671-8151(2017)03-0223-06
Development of Embedded Electronic Map Engine Based on MiniGUI
Xu Xiaoyu, Wei Wei, Zong Yahui, Li Fuzhong*
(CollegeofSoftware,ShanxiAgriculturalUniversity,Taigu030801,China)