Linux 平台下基于Qt 的电子地图的绘制
摘要…………………………………………………………………………………………………………………1
关键词………………………………………………………………………………………………………………2
0 引言………………………………………………………………………………………………………………3
1 电子地图实现总体设计…………………………………………………………………………………………4
2 MITAB 库提取地图数据模块……………………………………………………………………………………5
2.1 读取MIF 格式文件的空间数据………………………………………………………………………………6
3 SQLite 数据库存储地图数据模块 ……………………………………………………………………………7
4 利用Qt 显示地图模块 …………………………………………………………………………………………8
4.1 地图坐标转换…………………………………………………………………………………………………9
4.2 图形对象的显示………………………………………………………………………………………………10
4.4 电子地图的缩放………………………………………………………………………………………………11
4.5 GPS 模块………………………………………………………………………………………………………12
5 结束语……………………………………………………………………………………………………………13
[参考文献 (References) ……………………………………………………………………………………14
-
--------------------------------------------------------------------------------
正文
4.4 电子地图的缩放
QGraphicsView 支持几何变换,当进行视图变换时,QGraphicsView 保持视图的中心,通过应用变换,可以很容易地实现缩放。在视图类中定义一个放大的槽函数和一个缩小的槽函数,将槽和具有autoRepeat 属性的QPushButton 进行连接,就可以实现连续的缩放操作。下面是两个槽函数Public slots:Void zoomIn() {scale(1.5,1.5);}Void zoomOut() {scale(1.5,1.5);}通过以上步骤就可以实现简单的电子地图浏览,最终程序运行的结果如图4,放大之后的结果如图 。其中zoomin 是地图缩小按钮,zoomout 是地图放大按钮。地图数据来源于太原市MapInfo 格式的地图的第一层。图 太原市电子地图的第一层图 放大的电子地图Fig. First Layer of Taiyuan Electrnic Map Fig. Ampplification of The Electrnic Map
5 结束语
该系统 实现电子地图浏览和定位等功能,是嵌入式GPS 定位导航系统的基础。本文详细说明了具体的实现步骤。还有很多功能没有实现,例如导航,值得进一步研究。本方案设计的电子地图,运行速度快,费用低,很适 合用在旅游景点导游,城市路径规划,车辆导航等方面,具有一定的实用价值和经济价值。
摘要…………………………………………………………………………………………………………………1
-
--------------------------------------------------------------------------------
正文
1 电子地图实现总体设计
2 MITAB 库提取地图数据模块
MAPINFO 公司并没有对外公布原始的以矢量形式存储的数据格式,即TAB 格式。但其提供地图交换数据格式(MIF,MapInfo Interchange Fomat)[2]供开发人员作二次开发,这种格式的空间数据以ASCII 格式存储,易生成且可编辑,包含两个文件(*.mif 和 .mid)。其中 .mif 文件保存了该MapInfo 格式地图的结构及空间对象的空间信息,而 .mid 文件顺序保存了空间的所有属性信息。嵌入式Linux 中并没有专门的软件或插件直接支持MIF 格式的电子地图。本文采用开放源码工具MITAB[3]库从MIF 格式地图中提取地图数据。MITAB 提供了两种读取MIF 格式地图的方法:一种是提供 语言应用程序接口,通过调用其中的函数来实现数据的读写操作。MITAB 为 语言应用程序接口提供了很完整的文档资料,编程简单;另一种是提供C++的接口函数库,该函数库可以实现MITAB 的所有功能,但是没有文档资料的支持。本课题采用 语言接口读取地图,图 是用MITAB 的语言接口读取MIF 文件的流程图。图 使用MITAB 提取地图数据流程Fig. Process of using MITAB to obtain map data
2.1 读取MIF 格式文件的空间数据
首先调用mitab_c_open(const char *pzFilename)打开MIF 格式的文件,返回mitab_handle类型的数据,该数据保存了整个mif 文件的所有数据。地图中有很多图形对象 MIF 文件把这些图形对象分为点(point)、直线 line)、折线polyline)、区域 region)、圆弧 arc)、文本 text)、矩形 rectangle)、圆角矩形 rounded rectangle)、椭圆 ellipse)九类。具体提取过程如下:首先,通过调用mitab_c_get_field_count(mitab_handle dataset)函数得到该文件中图形对象的个数,其参数dataset 为打开地图文件时返回的数据。读取图形对象的feature_id(即该图形对象在文件中的标识);其次,通过调用 mitab_c_read_feature(mitab_handle dataset,intfeature_id)获取图形对象,返回值是mitab_feature 类型的数据,该返回数据包含了当前图形对象的所有信息;然后,获取当前图形对象的类型,通过调用 mitab_c_get_type(mitab_featurefeature)函数;最后,调用相应的函数提取对象里面的数据。调用 mitab_c_get_vertex_x()函数提取纬度,mitab_c_get_vertex_y()函数提取经度,调用 mitab_c_get_pen_color()函数提取画笔颜色等。最终就可以把所有的图形对象的数据都提取出来了。读取完一个图形对象必须调用 mitab_c_destroy_feature()函数销毁对象。最后调用mitab_c_close()函数关闭文件。SQLite 数据库存储地图模块
3 SQLite 数据库存储地图数据模块
在Linux 系统下读取地图数据,由于地图数据量大,并且有不断增大的趋势,所以单纯的文件数据读取的效率变得越发的不理想,为了提高数据读取的效率、定位和导航的效 率,我们考虑了采用一个轻量级的数据库系统来检索地图数据。SQLite[4]是2000 年开发出来的一种中小型嵌入式数据库,可以较为方便的运用到嵌入式系统中,它的源代码完全开放,可以免费用于任何用途,包括商业目的。SQLite 提供了对SQL92 的大多数支持:支持多表、索引、事务、视图、触发和一系列的用户接口及驱动,简单易用,速度很快,同时提供了丰富的数据库接口。它的一个重要的特点是体积 非常小,编译后也不过几十KB。根据mif 文件保存图形对象的格式,在SQLite 数据库中设计相应的数据表来存储相应的图形对象。下面以region 对象为例 如表 。表 数据库中的地图数据表Tab. Table of map in database图形对象类型表结构定义表名对应的SQLite 语句区域经度集纬度集节点数画笔宽画笔颜色前景色背景色属性数据regionCREATE TABLE regionTabale(longitude VARCHAR(300),latitude VARCHAR(300),pointnum INTEGER,penwidth INTEGER,pencolor INTERGER,forecolor INTEGER,backcolor INTERGER,property VACHAR(100))QtSql 模块提供了与平台以及数据库种类无关的访问SQL 数据库的接口。Qt 内含SQLite数据库的驱动,Qt 与SQLite 建立连接之后,就可以使用查询类(QSqlQuery)执行底层数据库支持的任何SQL 语句了。利用Qt 数据库查询类里面的INSERT 函数就可以把地图数据导入数据库,利用SELECT 函数可以把地图数据从数据库中导出。然后调用Qt 的绘图类实现地图的显示。
4 利用Qt 显示地图模块
地图显示主要是通过mif 格式地图中的地图数据,结合Qt 中的图形绘图类实现地图的显示。本文中使用的是Qt 中绘图功能强大的Graphics View[5]。Graphics View 提供了用于管理和交互大量定制的2D 图形对象平面以及可视化显示对象的视图widget,并支持缩放和旋转功能。Graphics View 使用BSP(二进制空间划分)树形可以快速地找到对象,因此即使是包含百万个对象的大型场景,也能实时图形化显示。主要用到的类有 QGraphicsItem、QGraphicsView 和QGraphicsScene 这三个类。Graphics View 提供一个QGraphicsScene 充当的场景即是我们添加图形的空间,相当于整个世界;一个QGraphicsView 作为视口,也就是我们观察的窗口,相当于照相机的取景框,这个取景框可以覆盖整个场景,也可以是场景的一部分;一些QGraphicsItem 作为图元,Qt内置了很多图形,比如line、polygon 等,都是继承自QGraphicsItem。其结构图参看图 。图 Graphics View 结构图Fig. Structure of Graphics View
4.1 地图坐标转换
Graphics View 坐标基于笛卡尔坐标系统,一个图元的场景坐标具有 坐标和 坐标。当使用没有变换的视图观察场景时,场景中的一个单元对应屏幕上的一个像素。在GraphicsView 中有三个有效的坐标系统:图元坐标,场景坐标和视图坐标。从地图中提取的经纬度坐标是不能在直接绘制的,需要转换成Graphics View 里的场景坐标才能显示的。所以必须要进行坐标转换。地图文件中的坐标系统采取的是经纬度坐标,显示时采取的是场景(Scene)坐标,因此从地图文件解析 出图元坐标系统时,需要将图元的经纬度坐标转化为场景(Scene)坐标后才能知道在画布的什么位置显示图元。画布的大小是始终固定不变的,但是它表示的 经纬度范围可变,而它表示的经纬度范围就是进行坐标转换,地图缩放,地图平移的基准。为了实现地图坐标的转换,自定义一个类Convert,利用这个类, 所有图元都可以在画布上找到准确的位置显示,最终显示整幅地图。类定义如下:Class Convert{public:convert();double x1;//画布左上角代表的经度double y1;//画布左上角代表的纬度double x2;//画布右下角代表的经度double y2;//画布右下角代表的纬度double x;//当前点的经度double y;//当前点的纬度double w;//当前显示区域的宽度double h;//当前显示区域的高度double wx;//当前显示区域经度的范围double hy;//当前显示区域纬度的范围QPoint *point;//存储坐标转换后的点QPoint *convertfun(double x,double y);//转换函数}转换函数的实现如下:QPointF Convert::convertfun(double x,double y){point=new QPointF(((x-x1)/wx)*w-w/2,((y-y1)/hy)*h-h/2);return *point;}
4.2 图形对象的显示
地图文件中的图形对象就是Graphics View 中的图元。地图显示功能就是把地图数据绘制还原成地图。将经过坐标转换后的图元存储到QGraphicsItem 类对象, 然后在QGraphicsScene 类对象中绘制出来,最后就能在QGraphicsView 类对象中显示出来。下面以读取region 对象为例QPoint *point;//存放图元节点QPen pen;QVectot pointRegion;//存放一个多边形所有节点容器QPointgonF *pPolygonF;//多边形指针QGraphicsPolygonItem *pPolygonItem;/*QGraphicsView 框架下的多边形图元,要把图元封装成QGraphicsItem 才能够在该框架里面显示。 /double brushColor;//存放当前填充颜色double penColor;//存放当前画笔颜色penColor=mitab_c_get_pen_color(feature);//获取当前图形对象的画笔 颜色if(feature_type==7){for(int pointno=0;i4.4 电子地图的缩放
QGraphicsView 支持几何变换,当进行视图变换时,QGraphicsView 保持视图的中心,通过应用变换,可以很容易地实现缩放。在视图类中定义一个放大的槽函数和一个缩小的槽函数,将槽和具有autoRepeat 属性的QPushButton 进行连接,就可以实现连续的缩放操作。下面是两个槽函数Public slots:Void zoomIn() {scale(1.5,1.5);}Void zoomOut() {scale(1.5,1.5);}通过以上步骤就可以实现简单的电子地图浏览,最终程序运行的结果如图4,放大之后的结果如图 。其中zoomin 是地图缩小按钮,zoomout 是地图放大按钮。地图数据来源于太原市MapInfo 格式的地图的第一层。图 太原市电子地图的第一层图 放大的电子地图Fig. First Layer of Taiyuan Electrnic Map Fig. Ampplification of The Electrnic Map
4.5 GPS 模块
由于GPS 定位信息内容较少,因此多用RS-232 串口将定位信息 6][7](NAME0183 语句从GPS 接收机送到计算机中进行信息提取处理。通常采取轮询串口和事件触发两种方式对数据进行接收和处理,本系统采用事件触发方式来提取读取串口信息。事件采用 Qt 类库中的Qtimer 类 8],将Qtimer 的timeout 信号与自定义槽slotReadGPSInfo()连接起来。当时间到时(比如1s)系统就会调用slotReadGPSInfo 函数读取串口信息。对于本文所使用的GPS 接收板,其发送到计算机的数据主要是由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有 $GPGGA“、 $GPGSA“、 GPGSV“[5]以及 $GPRMC“等。每种帧头后的数据也有固定的格式,各帧均以回车符和换行符作为帧尾标识一帧的结束。我们所关心的定位数据如经纬度、速度、时间等均可以 从 $GPRMC“帧中获得。然后把经纬度坐标转换成场景坐标,以图元的形式加载到场景中,就可以实现定位了。5 结束语
该系统 实现电子地图浏览和定位等功能,是嵌入式GPS 定位导航系统的基础。本文详细说明了具体的实现步骤。还有很多功能没有实现,例如导航,值得进一步研究。本方案设计的电子地图,运行速度快,费用低,很适 合用在旅游景点导游,城市路径规划,车辆导航等方面,具有一定的实用价值和经济价值。