徐晓宇,魏巍,宗亚辉,李富忠
(山西农业大学 软件学院,山西 太谷 030801)
基于MiniGUI的嵌入式电子地图引擎开发
徐晓宇,魏巍,宗亚辉,李富忠*
(山西农业大学 软件学院,山西 太谷 030801)
[目的]为了提高电子地图的开发效率,减轻开发人员负担,本文研究不针对特定操作系统、基于MiniGUI的嵌入式电子地图引擎,并处理TAB格式的地图数据。[方法]首先设计一个基于MiniGUI的自定义控件,利用与操作系统无关的接口设计相应的类,实现地图源数据读取、绘制、漫游、缩放和测距等功能。[结果]使用该引擎开发电子地图应用程序,利用该程序对引擎进行功能性验证。结果表明,该引擎各项功能均能正确执行。[结论]该电子地图引擎功能正常,使用方便,操作简单,具有一定的可移植性。
MiniGUI; 嵌入式电子地图; 引擎开发
MiniGUI, Embedded Electronic Map, Development of Engine
随着嵌入式技术的快速发展,嵌入式电子地图已经渗透到农业、军事、工业、医疗等各个领域。由于嵌入式设备资源平台有限,不能像PC机一样安装主流的桌面地理信息系统软件,因此需要技术人员根据实际需要进行开发。
目前已有不少国内外公司(如ESRI,Pocket Systems Ltd)研发出了嵌入式电子地图[1],但多数只适用于某个特定的嵌入式操作系统(如linux、uC/OS—II、VxWorks等)[2]。在这种情况下,开发人员使用电子地图二次开发工具,即使用电子地图引擎来开发电子地图,将大大减轻工作负担,缩短开发周期,提高开发效率。
因此,本文基于轻量级、可移植性高的MiniGUI,开发不针对特定操作系统的嵌入式电子地图引擎,用来处理TAB格式的地图数据。具体开发流程为:先设计一个基于MiniGUI的自定义控件MGC;再设计相应的类,以完成地图源数据的读取、绘制、漫游、缩放和测距等功能。由于开发时全部使用与操作系统无关的接口,所以该引擎可以适应各种MiniGUI环境。
1.1 MapInfo数据文件
开发过程中所处理数据的格式为MapInfo中的TAB格式。在TAB格式文件中,地图属性数据存储在两种属性表中,主要是属性数据的表结构文件.TAB和属性数据文件.DAT中[3,4]。空间数据则保存在空间数据文件.MAP中。通过索引文件(.ID文件)将.TAB文件和.DAT文件的数据有机结合在一起[5]。
1.2 OGR/GDAL
GDAL(Geospatial Data Abstraction Library)是一个开源的、符合X/MIT协议、利用抽象数据模型及其它工具来进行数据转换和解析的栅格空间数据转换库[6]。OGR库是GDAL库下的一个可以读取、写入和处理多种矢量数据格式的C++开源库[7],可以处理ESRI Shapefiles、SDTS、PostGIS、MapInfo TAB、MapInfo mid/mif等类型的数据[8],并且是按照Open GIS对矢量数据格式而定义的[9]。
1.3 MiniGUI的消息机制
MiniGUI是靠消息驱动的系统,所有的运作都是围绕消息而进行的。系统对输入事件会产生消息,对应用程序的响应也会产生消息,应用程序通过接收消息来完成某个动作,也可以同其他应用程序的窗口进行通信[10]。MiniGUI在处理消息的过程中,窗口管理器会维护主窗口的消息队列,当外设有某些动作,比如鼠标左键被按下时,窗口管理器会将该消息放入主窗口的消息队列并进入消息循环中,接收该消息的窗口会根据相应的窗口过程来处理这条消息。
1.4 双缓冲技术实现快速绘图
为了地图的快速显示,以及避免地图绘制过程中的闪烁现象,采用双缓冲技术的绘图模式[11,12]。
第一次缓冲要求用户将地图数据绘制在一个大于屏幕显示范围的内存区域上,这个内存区域称为缓冲区1,当用户进行漫游时,可以直接从该内存区域中读取数据并显示,而不必在整个地图数据库中再寻找,加快了地图的显示速度。
第二次缓冲要求从缓冲区1中将需要显示的数据拷贝到缓冲区2中,缓冲区2是一个和屏幕显示区域大小一致的内存区域之后可以给缓冲区2上面再绘制一些其他信息,如文字等。绘制完成后再将缓冲区2中的数据一次性拷贝到屏幕显示区域。
2.1 系统开发环境
设计实现的电子地图引擎MiniGUIGISController的开发环境配置如表1所示。
表1 系统开发环境配置
安装MiniGUI时需要打开帧缓冲,并使用qvfb(qt virtual framebuffer)在X window下模拟出frame buffer环境,以节省时间。使用qvfb时,需对MiniGUI.cfg 文件进行配置。在MiniGUI安装完成后还需要依次安装Proj和GDAL。
2.2 系统类设计
系统中共设计了47个类来完成既定功能,图1给出了其中最主要的20个类及其关系。
图1 MiniGUIGISController顶层类图Fig.1 The top class diagram of MiniGUIGISController
图1中的类主要包括:ViewState类及其子类提供对地图的控制功能,主要用来处理鼠标事件;Map类结合Layer、Feature类以及这些类的子类为地图数据读取提供支持,还包含了打开地图、设置过滤器、设置地图显示中心等;MiniGUIDC类、DrawContext类、Env类CS类以及IniFile类属于工具类,提供坐标转换、配置信息读取、矢量图形的绘制等功能。除了ViewState类,图1中的其他类全部参与到地图的绘制与显示过程中,尤其是Style类和Geometry类,负责图元绘制的细节问题。
2.3 自定义控件MGC的实现
MGC是MiniGUI上的自定义控件,该控件中定义了很多关于地图操作的消息,对电子地图的任何操作都会以消息的形式发送给MGC,并在MGC的过程函数中得到处理。
开发MGC步骤如下:
(1)控件注册。在注册过程中需要对控件类的样式、扩展风格、背景色、控件的过程处理函数等信息进行赋值。其中,最重要的是控件的过程处理函数_on_message(),该函数将MGC接收到的所有消息转发给View类的对象。
(2)消息处理。由于最终的消息处理需要在View类的对象中进行,将该对象的指针作为MGC控件的一个附加数据来保存,以后所有对地图的操作都要依附于该对象。所以,_on_message()函数接收到消息之后,首先会判断当前窗口的附加数据中是否包含一个View类型对象的指针,如果包含,则直接将消息转发给该对象的_on_message()函数,如果没有包含,则要新建一个View类的对象,然后再将消息发送给该对象的_on_message()函数。
(3)控件卸载。在应用程序退出时要对注册的控件进行卸载,此时调用了MiniGUI的UnregisterWindowClass()函数。
2.4 读取源数据模块的实现
读取源数据功能通过Map类的open()函数来完成。
open()函数在创建Map类的对象map之后,将地图数据的部分信息保存在map对象的对应属性中,包括地图名以及地图源数据的存放目录。之后根据地图源数据配置文件,通过load_from_gstfile()函数读取地图源数据。
load_from_gstfile()函数根据.gst文件中的配置信息读取地图源数据,同时保存对应图层的配置信息。在该函数中首先要创建一个IniFile类的对象gst_file,用来保存从.gst文件中读取到的地图配置信息,然后根据gst_file对象中的内容依次读取每一层地图数据。在读取某一层地图源数据时,需要创建OGR数据源对象ds,然后再获取该图层的OGRLayer对象layer。通过layer创建一个MapLayer类的对象,其指针保存在layer_ptr对象中,然后将当前图层的配置信息保存在MapLayer类的对象中。最终,ds、图层名称以及layer_ptr会被保存在map对象的对应属性中,而且layer_ptr在map中的存放次序和配置文件中定义的图层显示次序一致。
2.5 地图绘制模块的实现
电子地图在接收到绘制消息后,首先会调用view对象的on_paint()函数,该函数用来完成缓冲区1的重绘以及缓冲区2、结果层和文字层的绘制。
当需要重绘缓冲区1时,调用draw_background()函数,该函数内部需要完成过滤器和绘图上下文的设置,之后调用MapLayer对象中的draw()函数,依次绘制每一个图层,并保存当前的地图状态,包括像素、比例尺以及缓冲区1在地图正投影坐标系中的位置。
(1)设置过滤器函数。设置过滤器函数的作用是设置缓冲区1中能显示的地图球面坐标的范围。以缓冲区1的左上角在正投影坐标系统中的位置为参考,根据缓冲区1的尺寸和像素比例尺,经过坐标转换,计算出缓冲区1所对应区域的球面坐标范围。
(2)图层绘制。首先要确定当前比例尺下需要显示的图层,然后调用MapFeature::draw()函数依次绘制需要显示的图层中能通过过滤器的各个地图要素。get_next_feature()函数返回下一个需要绘制的地图要素的指针。获得一个需要绘制的要素之后,通过MapFeature::draw()函数来绘制该要素。
2.6 地图漫游模块的实现
地图进入漫游状态后,控件要接收鼠标左键被按下、移动以及左键抬起的消息,之后会按照接收到的消息来完成不同的动作。
鼠标左键被按下时,需要设置鼠标的按下状态,同时记录当前的鼠标位置,每一次接收到鼠标移动事件,都会调用on_mouse_move()函数,在该函数中计算鼠标的移动距离,之后调用InvalidateRect()函数设置无效区域并重绘,该函数会引起MSG_PAINT消息的发送,这时需要在Roaming::on_paint()函数中来处理该消息,完成漫游过程中地图的绘制。
鼠标左键抬起时进入on_mouse_up()函数,设置鼠标的抬起状态后,调用move_viewport()函数来保存当前显示窗口的位置信息。
2.7 地图缩放模块的实现
缩放功能包括对地图的点击放大、矩形放大、点击缩小,这里以点击放大为例,该过程涉及到3个函数。
(1)Zoom::on_mouse_down()函数
进入点击放大状态并获取到了鼠标左键被按下消息后,调用Zoom::on_mouse_down()函数来保存当前鼠标位置以及鼠标左键的按下状态。
(2)ZoomIn::on_mouse_up()函数
当接收到鼠标左键抬起的消息时,会调用ZoomIn::on_mouse_up()函数,该函数根据鼠标左键被点击之前的像素比例尺和预先定义的放大因子,计算并设置放大后的像素比例尺,同时还要用点击点的位置设置为缓冲区1的中心位置,最后需要调用Zoom::on_mouse_up()函数进行重绘。
(3)Zoom::on_mouse_up()函数
该函数设置鼠标左键的抬起状态,设置窗口无效区域,引起重绘操作,并根据放大操作之后的像素比例尺和缓冲区1的位置,进行重绘操作。
2.8 测距模块的实现
在测距功能中,采用Distance::on_mouse_down()函数和Distance::on_mouse_dbclick()函数。二者分别实现了如何处理鼠标左键弹起以及接收到鼠标左键双击消息后的动作。
测距状态下,鼠标左键被按下时调用on_mouse_down()函数。该函数首先判断用户是否是第一次点击鼠标,如果是,则只标记该点;反之则需要判断是否属于鼠标左键被双击,若属于,则意味着标记结束,此时调用on_mouse_dbclick()函数来计算各点之间的距离之和,并调用用户设置好的回调函数,将测距结果反馈给用户。
利用MiniGUIGISController开发电子地图应用程序MgisTest,通过MgisTest对MiniGUIGISController的功能进行验证。
3.1 MgisTest的实现步骤
(1)创建主窗口。
(2)在主窗口中创建工具栏、Menu菜单以及地图控件。工具栏用来提供改变地图状态的操作:漫游、放大、缩小、测距。Menu菜单主要提供地图的打开、关闭功能。地图控件用来显示地图以及完成对地图的所有操作。
(3)设置各个UI元素的过程处理函数,完成相应的操作。
(4)设置测距回调函数用来反馈测距结果。
3.2 验证过程及结果
(1)打开电子地图后如图2所示,地图源数据被读取并绘制在窗口中,地图正常显示,说明MiniGUIGISController的读取源数据及地图绘制功能正常。
图2 读取源数据、地图绘制功能测试结果Fig.2 The testing results of reading data and drawing function
(2)向左拖动鼠标,使得整个地图向左进行漫游,如图3所示。经过漫游动作,原本在右边位置的“儿童公园南门”的标注移动到了该图的中心位置,说明MiniGUIGISController的漫游功能正常。
(3)点击“缩小”按钮,使地图进入缩小状态,如图4所示。从图4中可以看出,河流宽度变窄,各部分区域也相应缩小,而且与图3相比,五角星的标注消失,说明MiniGUIGISController的缩小功能正常。
(4)点击“放大”按钮,使地图进入放大状态,如图5所示。与图2相比,河流宽度增加,各部分区域变大,说明MiniGUIGISController的放大功能正常。
图3 地图漫游功能测试结果Fig.3 The testing results of roaming function
图4 地图缩小功能测试结果Fig.4 The testing results of zooming-out function
图5 地图放大功能测试结果Fig.5 The testing results of zooming-in function
(5)点击“测距”按钮,并用鼠标标注出想要测量的点,系统会自动生成两点间的直线,通过双击鼠标左键完成标注,之后屏幕上会弹出一个标识测距结果的对话框,在此对话框中显示整个距离为1.2 km,如图6所示。这说明MiniGUIGISController的测距功能正常。
图6 测距功能测试结果Fig.6 The testing results of measuring distance function
通过对MiniGUIGISController基础上的电子地图MgisTest进行各种操作,验证了MiniGUIGISController能正常执行地图源数据读取、绘制、漫游、缩放、测距等功能。
论文设计实现了基于MiniGUI、针对MapInfo的TAB格式数据的电子地图引擎MiniGUIGISController,该引擎有地图源数据读取、绘制、漫游、缩放、测距等功能,使用方便、操作简单,具有一定的可移植性,今后可以从以下几方面继续完善:增加搜索及定位功能;增加对三维地图数据的绘制与显示功能;设计针对特定机型的电子地图引擎。
[1]龙柏宇.基于ARM的数字船用雷达显控软件的设计与实现[D].成都:电子科技大学,2013.
[2]龚峰.基于Geocoding和瓦片地图引擎的生活信息服务系统的开发[D].上海:上海交通大学,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二次开发在坐标转换中的应用[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的通用地理数据格式转换研究[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皮肤引擎设计[J].计算机应用与软件,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在车载导航终端中的应用[J].单片机与嵌入式系统应用,2005(6):61-63.
[11]安晓博,陈蜀宇,刘小威.嵌入式GIS地图快速显示方法的应用[J].计算机系统应用,2012(10):204-207.
[12]赵松.跨平台导航电子地图显示引擎的研究与构建[D]:重庆大学,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-),女(汉),山西阳泉人,助教,硕士,研究方向:软件工程
*通信作者:李富忠,教授,博士生导师。Tel:13734008985;E-mail:sxaulfz@126.com
山西农业大学科技创新基金(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)