1. 引言
与传统的纸质地图相比,电子地图具有信息载负量大,阅读方便,具有动态显示功能,可显示大区域详情避免图幅拼接,可进行各种内容叠加,可进行更广泛的信息共享,具有更丰富的色彩,生产周期短,更新及时等特点,在各个行业领域都具有广泛的应用 [1] [2]。
在航空装备模拟训练领域,电子地图也是不可或缺的功能之一。它不仅是构建战场想定编辑系统、作战态势显示系统的基础,而且目前大部分军用飞机模拟训练系统的建设也需要构建具有电子地图显示、浏览功能的机载电子地图仿真模块,因此无论是海军航空兵模拟仿真训练体系建设的要求,还是具体的飞机模拟训练系统建设、应用的具体需求,都需要针对此类应用设计和构建一个数据来源多样、运行稳定可靠、产品自主可控的电子地图模块。
2. 矢量电子地图Shapefile格式简介
目前随着地理信息系统技术的发展,各公司、机构都发布了自己的电子地图数据格式,这些电子地图格式各有特点。考虑到地理信息数据获取和交换的难易程度,我们选取Shapefile格式作为矢量数据格式。
2.1. Shapefile地图格式
Figure 1. Structure and composition of Shapefile
图1. Shapefile文件结构和组成
Shapefile文件是一种地理空间数据开发格式,由美国环境系统研究所(简称ESRI)制定,目前该文件格式已经作为一个开放式的标准广泛应用于地理信息软件界,基本上诸如MAPINFO、ARCGIS之类的绝大部分地理信息系统软件都能够支持导入、导出该格式的矢量地图数据 [3] [4] [5]。
一个基本的Shapefile至少包含以下三个文件:分别是“.SHP”、“.SHX”、“.DBF”,其结构如图1所示。
.SHP文件是图形格式文件。它用于保存地图特征的空间坐标信息(例如X,Y,Z,通常X对应经度值,Y对应纬度值,Z对应高度值)。图1为.SHP文件的结构及组成。一个.SHP文件由一个固定长度基本信息头部和多个地图特征信息组成,其中基本信息包括文件大小、特征数量、特征类型(点、线、面)等要素,地图特征由特征ID、部件数量、部件数组、顶点数组等要素组成。
.SHP文件的地图特征类型有三类:点特征、线特征、面特征。点特征比较简单,通常直接由点的位置,也就是经纬度描述。线特征则是由一组点坐标串组成的;面特征由多个子环构成,所谓子环是一个至少有四个顶点构成的封闭且无自交现象的环,并且环上的第一个顶点必须和最后一个顶点重合,且顶点的顺序表示了面的方向(逆时针方向为正)。如图2所示的面特征,由三个子环即V1→V6,V7→V13,V14→V17组成,其中V1→V6,V7→V13两个子环分别以逆时针方向顶点分别描述了两个多边形面,而V14→V17则以顺时针顺序的顶点描述了一个被剔除的空洞。
Figure 2. Face features described by Shapefile
图2. Shapefile描述的面特征
.DBF文件是属性数据格式,它存储在由xBase数据库处理系统产生的数据库文件中,其中存储着每个地图特征的属性数据,如特征名称、特征的国标分类码等属性信息。
.SHX文件是图形索引格式,在地图渲染中不使用该文件,所以不做过多介绍。
2.2. Shapefile地图数据读取
Shapefile作为一种在90年代初就已被应用的文件格式,有着良好的操作性和可交换性,大部分GIS软件都能够支持SHAPE FILE格式地理数据的导入、导出,但是依照Shapefile文件格式定义编程读取Shapefile文件中的地图特征数据仍然是一项繁琐的工作,幸运的是我们找到了一个可以进行Shapefile文件读写的开源库SHAPELIB。
SHAPELIB (全称是Shapefile C Library)目前的版本是1.5.2,它是一个用于读写ESRI公司的Shapefile格式文件的C语言底层类开源库,它为Shapefile文件的读写提供了一组C接口的API函数,用于从Shapefile读取或者写入地图特征信息,它便于集成且使用简单,可以降低在其它应用程序中读写Shapefile地图特征信息的编程工作量,使用SHAPELIB从Shapefile文件中读取地图特征的空间位置信息和特征属性信息的代码如下:
3. 基于OpenGL的电子地图绘制技术
地图作为客观世界与地理信息的显示载体,地图符号是描述地图信息的重要部分,在电子地图中,符号信息对于确定地图中的物体、地标和区域具有重要的作用,因此选用合适的矢量图元绘制样式将对电子地图的信息展示效果至关重要 [6]。与Shapefile中的点、线、面三种特征相对应,地图符号通常也分为点符号、线符号和面符号,此外每种类型的符号都可能需要通过文字对其进行标注。
3.1. 点特征的绘制
点符号适合显示如机场、雷达、城市、村庄、飞机、舰船等具体的地图点特征,实践中可以采用栅格图片对地图中的点特征进行表示,首先我们建立并制作了栅格点符号图库。如图3所示,该符号图库是一张底色透明、前景色为白色的PNG图片,图片大小为64 × 64像素,包含4行 × 4列共计16个栅格点符号,每个栅格点符号的大小都是16 × 16像素。
Figure 3. Grid point symbol library example
图3. 栅格点符号图库示例
在绘制上述符号时,首先根据符号类型计算符号在栅格图片中的纹理坐标,然后使用OpenGL纹理在屏幕上,以特征所在位置为中心绘制一个16 × 16的小矩形,部分绘制代码如下。
上述代码中,spotColor指的是栅格点符号的混合颜色、spotStyle指的是栅格点符号的样式,上述两个值由用户读取Shapefile后额外设置。程序执行过程为:首先设置符号颜色,并绑定符号库对应的纹理ID;然后根据符号的spotStyle值计算栅格点符号在符号库中的相对位置(用纹理坐标表示);最后依次绑定纹理坐标并将纹理贴到其对应的小正方形区域。
3.2. 线特征的绘制
线符号是通过定义图元样式如线宽、线型、颜色来表达河流、道路、边界、航线等地图线特征,在OpenGL中绘制时即线符号除顶点信息外,还要具备颜色lineColor、线宽lineWidth、线型lineStyle等三个要素。在OpenGL中,先特征的绘制比较简单,其代码如下:
对于部分铁路、公路等负责线特征,可以通过两次绘制方法进行。
3.3. 面特征的绘制
面符号主要通过填充颜色、透明度等表达陆地、水域、绿地、空域等地图面特征,采用OpenGL进行颜色填充面符号的绘制时,OpenGL能够直接支持的只有简单的凸多边形,如图4(a)所示,而从Shapefile中读取的面特征通常是一个复杂的面,大概率出现图4(b)凹多边形或者图4(c)带有空洞的多边形等情况,这种复杂面如果不经处理直接在OpenGL中绘制通常都很难得到预期正确结果。
Figure 4. Simple faces in OpenGL and complex faces in Shapefile
图4. OpenGL中的简单面和Shapefile中的复杂面
从Shapefile中读取的面特征(使用多边形表示)有可能是非凸多边形,需要将其分解成更小的凸多边形(如三角形),再组合起来显示。OpenGL工具函数库(即GLU)提供了一组函数来完成这个操作,这个分解的过程叫做分格化(Tessellation)。使用GLU函数库进行多边形分格化的代码如下:
通过上述代码将面特征的所有子环以及子环的顶点信息输入到分格化器,分格化器在结束面特征绘制之后,就会根据我置的分格化缠绕规则进行分格化计算并将结果通过设置的回调函数通知我们。在回调函数中可以得到分格化后的结果,即复杂的非凸多边形被分格化成一组三角形,如图5所示。
Figure 5. Schematic diagram of polygon meshing results
图5. 多边形分格化结果示意图
多边形分格化完成以后对于颜色填充面符号的绘制,可以使用多边形风格化得到的一组三角面片来代替,代码如下:
3.4. 文字符号的绘制
在绘制地图矢量特征时,通常需要使用文字对特征进行标注,这就需要在OpenGL中显示和输出字体符号。OpenGL绘制字体有两种方式:栅格方式和纹理方式,前者使用OpenGL的栅格图像函数glRasterPos进行定位,然后将字体图片通过glBitmap函数直接绘制到OpenGL颜色缓冲区内;后者将需要绘制的字体图片制作成纹理,然后通过纹理贴图的方式将字体显示到世界坐标系中的某个方块上 [7]。这两者各有优缺点,我们选用栅格方式进行绘图,共有三个阶段。
绘制准备阶段的主要内容是初始化字体引擎。字体引擎用于将文字转换成对应的文字图片,OpenGL本身并没有内置字体引擎,在Windows下可以使用GDI的字体引擎来完成此功能。字体引擎的初始化主要有三个参数:字体类型,字体高度和是否粗体。字体创建完毕后,字体绘制的流程如图6。
当用户指定一个起始位置绘制一个字符串时,首先需要将字符串由多字节字符集转换成Unicode字符集,这样使得字符串中每个字符都占用两个字节,长度相等便于索引。然后依次从Unicode字符串中取出字符,并检查该字符是否已经绘制过,如果没有绘制过则调用GDI生成该字符对应的图片、获取图片宽度、生成对应纹理并存入字符缓冲区;否则在字符缓冲区中查找该字符的缓冲数据,并使用缓冲的字符图片和纹理进行纹理贴图绘制。最后绘制完成一个字符后,起始位置会根据该字符图片的宽度改变,这样便能够从左至右绘制整个字符串。
Figure 6. Text string drawing process
图6. 文本字符串绘制的流程
4. 电子地图模块的总体设计
基于Shapefile和OpenGL的电子地图模块结构如图7所示,由地图编辑工具和地图绘制两部分组成。
Figure 7. Structure of electronic map module
图7. 电子地图模块总体结构
地图编辑工具是一个可视化的编辑工具,其界面如图8所示,它负责加载Shapefile文件并通过可视化的编辑环境设置特征的绘制样式、可见性,并且在输出时对地图中的面特征进行分格化处理,对地图矢量特征进行瓦片切割以便生成指定区域的矢量瓦片,最终处理结果保存成一个地图数据包文件。
Figure 8. The Interface of Map’s visual editing tool
图8. 地图可视化编辑工具界面
地图绘制模块负责加载地图数据包并基于OpenGL渲染显示指定区域的地图图像,该模块提供SDK以便集成到其它程序中,使用该模块制作的某二次雷达程序、机载电子地图仿真程序实现效果如图9所示,该电子地图模块具有支持平移、旋转和无级缩放,支持不同的地图投影方式,可以通过可视化编辑工具修改地图的显示样式等功能特点,能够满足机载地图显示仿真、作战推演仿真、二维战场态势等系统对地图显示的要求,且其数据来源广泛,数据交互较容易,具有一定的应用价值。
Figure 9. Application example of electronic map module
图9. 电子地图模块应用示例
5. 结束语
无论是海军航空兵模拟仿真训练体系建设的要求,还是军机仿真电子地图显示的具体应用需求,考虑到地图数据获取和交换的便捷性,基于Shapefile电子地图格式和OpenGL图形渲染引擎,实现了通用的二维电子地图模块及可视化的地图编辑工具,该模块在硬件配置为Intel Core i7-6700HQ处理器,英伟达GeForce 940MX显卡,8GB DDR4 2133MHz内存的硬件环境中,实测该地图模块的刷新率稳定保持在50到60赫兹。表明该地图模块可以维持较高的渲染效率,其数据易于获取、显示内容丰富、操作界面友好、信息直观立体,因此在航空装备仿真等方面具有一定的应用价值。