陈建臣
(陕西长岭电子科技有限责任公司产品开发部,宝鸡,721006)
摘要 MapInfo是目前较为常用的一种电子地图,输出数据文件格式为MIF格式,包括mif文件和mid文件。Mitab库是一个动态链接库,可以调用库文件读取MIF格式的地图文件。利用QT的画图函数来实现电子地图的绘制,并且绘制所要求的移动和可缩放大小的地图。
关键词:电子地图,Mitab,MIF,电子地图显示
1概述
QT5是一个用于开发GUI的C++类库,提供了一个完整的GUI程序解决方案以及上百个功能强大的窗口部件,支持可视化开发。
Mitab库基于GIS协会关于简单要素的规范实力OGR开发,同时它是一个开源的C++库,主要用于读写MapInfo输出的TAB文件和mif/mid格式文件。可从Mitab官网下载该开源库,最新版本是1.7。
MIF格式文件是MapInfo用来向外交换数据的一种中间交换文件。MapInfo是一种数据可视化、信息地图化的桌面地理信息系统软件,该软件所采用的地图格式主要包括TAB格式和MIF格式。
2 MIF地图读取
MIF格式的文件包含了地理位置信息和空间图形信息文本文件,由mif和mid2个文件组成。mif文件保存了MapInfo表的表结构及表中所有空间对象的空间信息,mid文件则按记录顺序保存了每个对象的所有属性信息。
2.1地图数据读取
使用mitab库的mitab_c_open()函数打开MIF文件,并使用mitab_c_field_count()和mitab_c_get_field_name()获取空间对象的数量和对象名称数组,使用mitab_c_field_type()来获取对象的类型。通过不同的对象类型,调用不同的函数来读取数据。例如区域Polygon对象的画笔颜色、样式、宽度等,调用mitab_c_get_parts()、mitab_c_get_vertex_counts()、mitab_c_get_vertex_x()和mitab_c_get_vertex_y()读取地图经纬度点。
MapInfo的一个Mif文件对应电子地图的一个图层,读取数据的同时根据图层名称不同添加到不同的链表中。
流程如下:开始---读图层文件---区域数据/折线数据/点文本数据---添加到对应的链表中。
2.2经纬度坐标转换
将经纬度坐标转换成QT中画布Scene中的坐标,坐标转换程序如下:
double x_lon_L = 73.33;//地图经度左边界
double x_lon_R = 135.05;//地图经度右边界
double y_lat_D = 3.51;//地图纬度下边界
double y_lat_U = 53.33;//地图纬度上边界
x = ((x-x_lon_L)/wx) * width_w –width_w/2;
y = height_h/2 - ((y – y_lat_D)/hy) * height_h;
其中等式右边x,y为用mitab库函数读取的经纬度坐标。
3QT显示
QT提供了图形视图框架、动画框架和状态机框架。
图形视图框架提供了一个基于图形项的模型视图编程方法,它主要有场景、视图和图形项3个部分组成,这3个部分分别由QGraphicsScene、QGraphicesView和QGraphicsItem这3个类来表示。
图形视图框架可以管理数量庞大的自定义2D图形项,并且可以与他们进行交互。使用视图部件可以使这些图形项可视化,视图支持缩放和移动、旋转。这些为电子地图的显示控制提供了方便。
场景QGraphicsScene是图形项QGraphicsItem对象的容器,电子地图每个图层就是一个图形项Item。
视图QGraphicsView使场景可视化,场景的绘制从背景层开始,然后是图形项层,最后是前景层。
图形视图框架是基于笛卡尔坐标系统的,一个图形项在场景中的位置和几何形状由x坐标和y坐标来表示。图形项试验自己的本地坐标系统,坐标通常是以他们的中心为原点,这也是所有变换的中心。场景坐标是所有图形项的基础坐标系统,场景坐标描述了每一个顶层图形项的位置,也形成了所有从视图传到场景上的事件的基础。视图的坐标就是部件的坐标,所有鼠标事件和拖放事件最初都是使用视图坐标被接受的。
利用QT5进行电子地图显示时,QT5的鼠标键盘缩放、拖放触发事件函数。一个图层的全部数据显示时不现实的,可以进行数据点缩减处理。缩放移动不同的View视图窗口坐标范围对应的Scene场景坐标范围不同,只处理当前窗口对应的Scene坐标范围内的坐标点。对象为折线或者区域时,判断区域边界是否在Scene范围内。这样能大量减少当前要显示的坐标点,提高刷新率。
画点程序如下:
if(factor <=pointData.zoom_max && factor>= pointData.zoom_min)
//判断图层是否显示
{
foreach(font_pont pointf,pointData.point_list)
{
if(pointf.point.x() < left_top.x() ||
pointf.point.y() < left_top.y() ||
pointf.point.x() > right_buttom.x() ||
pointf.point.y() > right_buttom.y()
)//判断当前点是否在视图窗口对应的场景范围内
continue;
else
{
…//画场景范围内的点坐标
}
}
}
地图显示时同一图层点文本显示时,文本信息显示可能会发生遮挡。MapInfo有专门的overlap函数进行处理,QT5没有专门函数,可以利用QGraphicsItem碰撞检测功能进行处理。电子地图处理结束、显示之前可以进行重叠隐藏。
场景QGraphicsScene管理着大量的图像项Item,可以获取当前视图窗口对应的Scene范围内的Items。利用collidingItems()函数进行碰撞检测,图形项zValue值低的选择隐藏。
4结论
本文给出了基于QT5使用MIF格式输出进行电子地图显示的过程,并进行QT5显示时数据点缩减、遮挡等处理。非海量区域数据处理时使用此方法简单方便,可以有效的实现电子地图的显示效果。