MapX在VC++中实现军用标图系统的研究及应用

为适应军队信息化发展的要求,开发一个C3I系统,首先要解决的问题就是开发一套适用于军事应用的标图系统。本文分析了GIS组件--MapX的特性,阐述了将MapX集成于VC++ 6.0中绘制军用图形的基本方法,并给出了实现军用标图系统的一种解决方案。
关键词 MapX;VC++;程序设计;集成;军用标图系统
Keywords : MapX; VC++; programming; Integration; Military drawing system

1 引 言
无论战时或平时,一切军事活动通常都在军用地图上进行描绘。为适应军队信息化发展的要求,开发一个C3I系统,首先要解决的问题就是开发一套适用于军事应用的标图系统。根据军事应用系统对实时性的要求,以及硬件设备的配置情况,一般采用以下二种方法:
一是独立开发,即从空间数据的采集、编辑到数据的处理、分析及结果的输出,所有的算法都由开发者独立设计,然后,选用某种程序设计语言编程实现。
二是集成二次开发。该方法目前主要有两种方式:1)OLE/DDE,指用软件开发工具开发前台可执行应用程序,以OLE自动化方式或DDE方式启动GIS工具软件在后台执行,利用回调技术动态获取其返回信息,实现应用程序中的地理信息处理功能;2)GIS控件,指利用建立在OCX技术基础上的GIS功能组件,如MapInfo公司的MapX,在Visual C++等编制的应用程序中,直接嵌入GIS功能,而后进一步开发出地理信息系统的各种功能。由于对大多数开发者来说,能力、时间、财力方面的限制使其独立开发出来的产品很难在功能上与商业化GIS工具软件相比,因此结合GIS工具软件与当今可视化开发语言的集成二次开发方式就成为GIS应用开发的主流。与利用OLE/DDE技术相比,GIS控件开发速度快,占用资源少,而且易实现许多底层的编程和开发功能。
本文提出在VC++环境下,集成MapX控件,实现军用标图系统的一种解决方案。

2 MapX特性分析
MapX是MapInfo公司向用户提供的具有强大地图分析功能的ActiveX控件产品。由于它是一种基于Windows操作系统的标准控件,因而能支持绝大多数标准的可视化开发环境如Visual C++、Visual Basic、Delphi、PowerBuilder等。利用MapX,编程人员可以选用自己最熟悉的开发语言简单快速地在系统应用中嵌入地图化功能,增强系统应用的空间分析能力,实现系统应用的增值,并且可以脱离MapInfo的软件平台运行。MapX采用基于MapInfo Professional的相同的地图化技术,可以实现MapInfo Professional具有的绝大部分地图编辑和空间分析功能。
2.1 MapX的空间数据结构
从横向分析,MapX采用基于空间实体与空间索引相结合的一种结构。空间实体是地理图形的抽象模型,主要包括点、线、面三种类型。任何点、线、面实体都可以用直角坐标点x、y来表示。点可以表示成一组坐标(x,y),对于线和面,则均被表示成多组坐标(x1,y1,x2,y2,...,xn,yn);空间索引是查询空间实体的一种机制,通过空间索引,就能够以尽量快的速度查询到给定坐标范围内的空间实体及其所对应的数据;从纵向分析,MapX的空间数据结构是一种分层存放的结构。如图1。
2.2 MapX的模型结构
MapX组件的基本构成单元是Object(单个对象)和Collection(集合)。其中,集合包括对象,是多个对象的组合。每种对象和集合负责处理地图某一方面的功能。位于顶层的是Map对象本身,其它均由Map对象继承。Layers、DataSets、Annotations是Map对象下面的三个重要的分支。其中Layer主要用于操作地图的图层,DataSet用于访问空间数据表,Annotation用于在地图上增加文本或者符号。
2.3 MapX与标图系统相关的主要特性
(1)注解 可提供方向、加亮显示特殊数据,还可加入文本、符号、表格使地图信息更加丰富直观;
(2)图层显示和控制 图层的缩放、使用或创建无缝地图、还可支持一些特殊的应用,比如可绘制特殊图形的用户自定义图层(如logo图案);
(3)选择 可在地图上拖动鼠标以在圆、矩形或特定的点上选择一个或多个对象或记录以供分析;
(4)对象库 可以使用FeatureFactory对象,创建、联接或删除点、线、区域图形对象;
(5)工具 使用MapX的标准工具或根据需要自己创建的自定义工具,用户可通过点击或拖拽对地图直接进行操作;
(6)地图编辑 允许用户添加、修改、删除地图上的文本、编辑区域、点等特殊对象;
(7)外部数据支持 MapX支持多种外部数据的访问方式,如Oracle8i、ADO、DAO等,还可以通过ODBC使用更广泛的数据。

3 MapX在VC++中集成实现标图的基本方法
对于常用图形的绘制,如绘制符号、直线、多点线、区域及其格式,还有放大、缩小、漫游、选择等功能,MapX控件提供了接口,开发者只需调用CmapX::SetCurrentTool(...)即可实现。
对于军用图形,如舰船、指挥所、集结地域等的绘制,则要采用自定义方法,其步骤如下:
3.1 创建自定义工具
其函数为CmapX::CreateCustomTool(...)。
3.2 定义槽事件
在VC应用程序中利用ON_EVENT(the Class,id,dispid,pfnHandler,vtsParams)定义系列槽事件,如鼠标按下事件(DISPID_MOUSEDOWN),鼠标弹起事件(DISPID_MOUSEUP),工具被使用事件(MapX_DISPID_TOOLUSED)等来实现控件事件的触发。
3.3 使用自定义工具进行绘图
3.3.1 图形的绘制 首先,获取军用图形的关键点坐标:将鼠标在屏幕上按下,触发MapX控件窗口的MouseDown事件,记下按点坐标(x1,y1),并拖动后再弹起,触发MouseUp事件,记下弹起点坐标(x2,y2)。接着,利用CmapX3ConvertCoord(...)函数将屏幕坐标转换成经纬度坐标(x'1,y'1),(x'2,y'2),再利用(x'1,y'1),(x'2,y'2)组成矩形,在此矩形内选取绘制图形的关键点坐标;然后将关键点连成线、弧或区域,利用如下函数实现:
CmapX::GetFeatureFactory().CreateArc(...);
CmapX::GetFeatureFactory().CreateRegion(...);
CmapX::GetFeatureFactory().CreateLine(...);
最后利用CmapX3GetFeatureFactory().CombineFeatures(...)将线、弧等组合成一个实体图形,取出实体图形的中心坐标(x0,y0),并转化为屏幕坐标(x'0,y'0)。
3.3.2 图形的移动、放大、缩小 对于图形的移动、放大、缩小,只需用Select工具选中拖动即可。
3.3.3 图形的旋转 首先,选取图形绘制时在矩形框内选取的关键点坐标,利用ConvertCoord(...)函数,将这些关键点经纬度坐标转换为屏幕坐标,然后进行坐标平移变换,变成以图形实体中心点(x'0,y'0)为原点的坐标,再利用旋转变换公式:
x' = xcosθ - ysinθ
y' = xsinθ + ycosθ
进行旋转变换,得到新的以中心点为原点的坐标,接着进行坐标逆平移变换,得到新的关键点屏幕坐标,再将这些关键点屏幕坐标转化为经纬度坐标,重新进行图形绘制,并通过void CMapXLayer::DeleteFeature(...)来删除初始图形。

4 军用标图系统的实现
4.1 系统的功能
军用标图系统要实现的主要功能包括:绘图功能这由基本标图、陆军常用标图、海军常用标图、空军常用标图四部分实现,包括图形的绘制、复制、删除、旋转以及图形的注解等;信息处理功能:它包括图形实体属性信息的录入、查询、删除,该功能通过外挂数据库来实现;地图输出功能:它包括地图的打印输出、文件输出、剪贴板输出,其中文件输出的图形格式包括Metafile、Bitmap、JPEG image、GIF Image、Portable Network Graphics、PhotoShop、TIF Image;其它功能:它包括图形的选择、地图的缩放、视图的选择、图层控制、距离测量、标语、鹰眼图等。
4.2 实现步骤
(1) 利用MFC AppWizard(exe)新建一工程MapTest,并将MapX.h和MapX.cpp文件加入到该工程;
(2) 在CmapTestView3OnCreate()中通过CmapX3Create(...)创建两个MapX控件窗口,分别加载地图,一个作为主图,另一个作为鹰眼图。然后新建一可编辑图层,置于顶层,以便在该图层上绘图;
(3) 建立一事件槽(eventsink),在视图头文件中加入DECLARE EVENTSINK MAP()
在视图实现文件中加入
BEGIN EVENT SINK MAP(CmapXTestView,Cview)
END EVENT SINK MAP()
然后在两行代码中加入要处理的槽事件;
(4) 绘图功能模块,定义绘图函数基类:
class CDrawObject:public Cobject
{
public:
CMapX *m_ctrlMapX; float r; float c[3][3]; void clone();
void rotate(float theta); void clear();
float affinex(float x,float y,float d);
float affiney(float x,float y,float d);
void SetLineFeatureStyle();
......
CDrawObject();
virtual ~CDrawObject();
};
所有的绘图函数类均继承这个类,并实现了所有绘图函数类的封装;在CMapTestView3OnCreate()中创建自定义工具,然后使用标准工具或自定义工具通过对绘图函数类的调用进行绘图;在绘图过程中,记录下所绘图性的FeatureID值,并利用SQL命令将其存入Access外部数据库;
(5) 信息处理功能模块,利用图形的FeatureID值作为关联字段创建Access外部数据库,通过创建和使用自定义工具,利用MFC ODBC和SQL语句实现图形实体属性信息的录入、查询、修改、删除功能。其中录入的SQL语句为:
CString strSQL.Format("insert into[Table]values(%d, '%s', '%s', '%s', '%s', '%s')",[FeatureID],NULL,NULL,NULL,NULL,NULL);
CDatabase::ExecuteSQL(strSQL);
(6) 地图输出模块:对于文件和剪贴版输出,只需利用函数CmapX::ExportMap(...)即可;对于打印预览和输出只需利用函数CmapX::PrintMap(...)即可。
4.3 系统界面
系统界面如图2。

5 结束语
本文是笔者在军用标图系统开发中运用技巧和方法的总结,对开发其它数字标图系统具体一定的参考价值。基于MapX组件的集成开发在GIS中的应用非常广泛。笔者运用MapX在VC++6.0中集成开发的军用标图系统经初步运用,获得了较满意的效果。

参考文献
[1] 刘光,地理信息系统二次开发教程--组件篇[M],北京:清华大学出版社,2002.
[2] 邬伦、刘瑜,地理信息系统--原理,方法和应用[M],北京:科学出版社,2001.
[3] 李兰友,VC++.NET图形图像编程[M],北京:电子工业出版社,2002.1.
[4] 刘刀桂、孟繁晶,VisualC++实践与提高--数据库篇[M],北京:中国铁道出版社,2001.

作者简介:梁日辉,硕士,主研领域:信息管理,自动化指挥。