关键词 MapX;VC程序设计;专题图制作
1 引言
MapInfo MapX是一个用来做地图化工作的OCX控件,它可以很容易地在您的应用程序中加入强大的制图功能。它可以把您的数据用地图的形式显示出来,更易于理解。地图形式可以比简单的图表、图形提供更多的信息,而且描述地图比描述数据表更加简单迅速。
专题图是按照特定专题渲染地图的过程,以图形的形式在地图上表示数据。通常使用数据集中的一组或多组数据,利用颜色渲染、填充图案、符号、直方和饼图等方式表示数据。根据数据中的特定值指派这些颜色、图案或符号,创建不同的专题地图。
微软的Visual C++6.0技术成熟、应用广泛、影响巨大,在应用软件的开发方面是首选的开发环境之一。而MapX编程的教程通常是以VB为基础的。利用VC编译MapX程序比利用VC编写MapX程序要相对复杂一些,兼容性也要差一点。因此利用VC编写MapX程序的可供参考的教程和示例代码相对较少。但因为大量的应用软件采用VC编写、大量的软件公司采用VC作为开发工具,因此在VC环境中引入MapX控件进行MapX功能开发就非常重要。本文的目的在于具体阐述VC环境下基于MapX控件创建专题地图的方法。
2 VC下MapX开发环境的建立
2.1 MapX控件的引入
要在VC下使用MapX的各个功能来编写程序,首先必须要确保MapX控件已经在系统中安装并注册。在 MapX Web 站点 <http://www.mapx.com> 上找到最新的示例应用程序。该示例应用程序的源代码文件夹中包含MapX.h和MapX.cpp两个文件,这两个文件实际上分别就是MapX控件的类层次定义文件和COM接口实现文件。把这两个文件拷贝到应用程序所在的文件夹。或者将MapX安装目录下“\MapInfo\MapX 5.0\Samples50\C++\Cpp”文件夹下的MAPX.H和MAPX.CPP文件,拷贝到VC应用程序的工程目录下。然后再在VC++6.0集成开发环境的“Project”菜单中点击“Add To Project”→“Files”,弹出“Insert File Into Project”对话框。在文件列表框中列出了项目中的文件。按住“Control”键的同时选中MapX.h和MapX.cpp两个文件,然后点击对话框中的“OK”按钮,完成MapX控件的插入。
2.2 Doc/View下MapX控件的使用
MAPX是一个窗口控件,要想在Doc/View中使用就必须动态创建,一般遵从这样的步骤:
(1)添加资源ID,需要在工程的资源视图下的String Table下增加一个ID。
(2) 添加MAPX控件头文件的引用,可以直接把MAPX头文件的引用添加到工程的StdAfx.h文件中,这样就不必在其他的很多文件中添加这个引用了。
(3)声明CMapX类型变量,在视图类中写入形如CMapX m_ctrlMapX的声明。
(4)使用MAPX的Creat方法,在工程中视图类创建的时候创建MAPX控件,其代码为:
int C**View::OnCreate(LPCREATESTRUCT lpCreateStruct) // (视图类的WM_CREATE消息响应函数)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
RECT windRect; GetClientRect(&windRect);
//取得视图区域
if (!m_ctrlMapX.Create(NULL, WS_VISIBLE, windRect, this,IDS_MAPX1)) return -1;
//以当前视图窗口为父窗口,以IDS_MAPX1为标识,创建一个可见的、无窗口名称的、
//覆盖整个视图区域的MAPX控件窗口。
return 0;
}
(5)设定控件的初始状态, 如果简单的创建了MAPX控件在显示的时候会显示美国的地图,这样就需要在视图出现前改变MAPX的基本设置,改变默认地图以及改变地图中心、缩放率、是否可编辑、是否可选择以及添加一些新图层等操作。
(6)添加MAPX控件的事件响应。给动态生成的MAPX控件添加事件需要槽事件处理宏来处理消息映射。首先要在视图类的头文件H文件中声明宏DECLARE_EVENTSINK_ MAP();然后在视图类的CPP文件中加入MapX事件处理函数映射宏
BEGIN_EVENTSINK_MAP(CHWDView, CView)
//CPP文件中消息映射
END_EVENTSINK_MAP()
其中BEGIN_EVENTSINK_MAP带有两个参数,第一个参数当前类、第二个参数是当前类的基类。BEGIN_ EVENTSINK_MAP和END_EVENTSINK_MAP()是一对定义事件映射的宏,其间可以插入自定义的MapX控件消息映射。
3 基于MapX创建专题图
3.1 数据绑定与专题地图
数据绑定是将数据源中的数据导入 MapX 的过程。为了增强GIS系统数据处理的灵活性,系统分开存储涉及的图形矢量数据及空间属性数据。MapX通过数据集集合(Datasets)对象,可以将用户的属性数据与地图的空间数据连接起来,属性数据与几何数据的关联是通过数据绑定实现的。数据绑定的数据源可以是ODBC数据源、MapInfo Table文件、安全数组等。要绑定一个数据源,首先要指定所绑定的图层,然后需要指定与图层中地图对象相匹配的关键字段。将自己的数据绑定到地图上主要有以下两个优点:一是可以将数据作为地图上的图元查看;二是可以将属性数据绑定到地图上,然后使用该绑定创建基于数据的专题地图。
数据绑定的实现是通过Datasets.Add方法实现的。DataSets.add方法原型为DataSets.Add (Type, SourceData, [Name], [Geofield], [SecondaryGeofield], [BindLayer], [Fields], [Dynamic])。对大多数数据绑定类型, SourceData其实是一种OLE接口。MapX通过这个接口直接从数据源中访问数据,数据并没有真正传递给DataSets.Add。
当绑定时数据包含经度和纬度,且要在新的图层相应的位置上创建这些点时需使用BindLayer 对象。通过数据绑定,可以将BindLayer对象作为一个参数,使用Datasets.Add方法将自己的数据转变为一个DataSet。
在 MapX中有Field对象和Fields对象。在数据绑定时,MapX 对绑定的每个数据列均需要开销,通过Field对象和Fields对象只绑定地图中需要的数据。使用Datasets.Add 的Fields 参数建立要绑定到地图上的字段。字段集合对象的Add方法的原型为[Field=]OBJECT.Add (DataSourceCol, [Name], [AggregateFunction], [Type]) // DataSourceCol取值为数据源中字段名或索引值。
数据绑定事件:一旦数据源的某列被定义为地理列,并且确定了绑定数据的图层,则绑定就开始进行。数据源的每一行都和一个图元相匹配且数据将会带入地图。如果某行有不匹配发生,则DataMismatch事件被激活。当数据源发生变化时,MapX通过调用DataSet.Refresh来刷新数据。但数据源有新行时,此方法并不添加新图元。
3.2 专题地图的制作
MapX中使用Themes集合与Theme对象来实现对专题图的支持,每个Themes集合中可以包含多个Theme对象,也就是说,针对一个Dataset,可以创建多幅不同的专题地图。每个Dataset都拥有一个Themes集合,并以其属性的形式存在,即Dataset.Themes。使用Themes的Add、Remove、RemoveAll等方法可以控制专题的添加和删除。
在创建专题图的过程中,有几个关键因素,包括专题图变量的确定、属性数据的获取以及专题图层的显示与控制。
在进行专题图规划时,首先要确定专题图变量。在专题图中显示的数据就是专题图变量。一个专题变量可以是一个字段或表达式。取决于专题图的类型,在一张地图上可以显示一个或多个专题图变量。范围值、等级符号、点密度和独立值地图都只检查一个变量。可以利用饼图或直方图一次显示多个专题变量。也可以创建双变量专题地图,其中一个地图对象可代表两个不同的数据,用符号的颜色代表一个专题变量,符号的大小代表另一个专题变量。
在创建专题地图之前,必须确定需要显示何种信息,信息存储在什么位置。它可以在创建地图时所基于的表中,也可以在ODBC支持的外部数据库中。数据来源于Field对象或Field集合,在Themes.Add方法中通过Fields参数传递。
具体在创建专题图时,首先应将某个产生专题图数据的dataset通过数据绑定引入地图中,之后使用Themes.Add方法创建一个Theme对象。代码为:curmap.Datasets(1).Themes. Add(miThemeRanges,‘TotPop’,‘’),函数的语法为Themes. Add([Type], [Field], [Name])。Type用于定义要创建的专题图的类型,它的取值范围是ThemeTypeConstants,该参数可选,如果没有定义或者定义为 miThemeAuto,MapX会根据字段数以及已经存在的专题图类型自动在ThemeTypeConstants中选择一个。如果MapX无法自行确定专题类型,就会产生一个错误。Field(s)定义在专题图中使用的一个或多个字段,可以通过字段名、字段索引或字段对象来引用。当创建多变量专题图时,可以使用数组表示。该字段是可选的,若不特意指定,MapX会使用DataSet中的第一个数字型字段。Name,即专题图的名称,String类型参数,若不指定,MapX会自动生成一个名字。
专题图创建好后,有两种方法可以控制专题地图。一是使用Theme.ThemeDlg方法。该方法显示一个对话框,用户可以直接修改专题图特性。语句如下为curmap.Datasets(1).Themes(1).ThemeDlg;这种方法虽然简单,但是很难与自己的程序风格相一致,用户界面不友好,而且在这个默认的对话框中,用户可以随意改变任何设置,使得程序的控制难度加大。二是改变ThemeProperties对象属性。通过设置ThemeProperties对象属性,可以使用自己定制的界面,给用户有限的修改能力,实现起来也非常简单,而且对用户的操作有全部的控制权。ThemeProperties对象是Themes集合中的一员,主要用于定义专题地图的显示,包括颜色、符号等。ThemeProperties对象的属性中有许多又属于其他对象,如RangeCategory、Individualvalue、Style等,可进行更深层次的设定。
3.3 专题图实例
图1是以中国各省(区、市)的人口密度为专题图变量绘制的范围专题图。从图1中可以看出,我国西北地区人口密度最小,东南区域人口密度相对较大;江苏、台湾、河南、山东人口密度较大,西藏人口密度最小。
图1 中国各省(区、市)人口密度专题图
4 结束语
使用专题渲染在地图上显示数据时,可以清晰地展现在数据列表中几乎无法显现的样式和趋势,为用户的决策支持提供依据。本文实现了VC环境下基于MapX控件创建专题图,为在VC环境下开发MapX程序做了初步探索和有益启示。