1 引言
MapInfo 作为一个功能强大的地理信息系统(GIS) 开发工具,被广泛应用在统计、测绘、水利、军事、环保等领域。它为用户提供了先进的数据可视化、信息地图化技术,并且提供了集成数字地图开发方式,方便用户在其他应用程序中利用MapInfo 的地图元素进行集成数字地图编程开发。通过在VC++环境下完成MapInfo 的集成数字地图开发功能,详细介绍了在集成数字地图环境下应用C++和MFC 的编程过程。这种在VC++环境下的集成开发方式,极大地发挥了VC++和MapInfo 两种应用软件的优点,为数字地图信息系统的应用提供了广阔的平台。
2 开发环境要求
目前计算机技术发展迅速,大多数计算机软硬件性能都能满足应用软件开发要求。这里不失一般性地构建编程环境如下:在Windows 2000/XP 操作系统下安装Visual C++6.0 和MapInfo 6.0 软件, 另外需安装MapBasic 开发软件获取mapbasic.h 文件,在开发中便于使用;硬件要求必须有足够的内存可以同时运行客户程序和MapInfo,客户程序采用OLE 自动控制。
3 集成数字地图开发实例
本软件采用VC++面向对象编程语言实现,主要步骤如下:
(1) 创建框架程序,实现OLE 自动化客户支持。
1) 启动Visual C++,利用MFC AppWizard 应用程序向导创建一个单(多) 文档应用程序projectname。创建过程中各选项可保留默认选择,创建完成后按如下步骤在程序中加入自动化支持代码:
①在stdafx.h 中原有#include 后加入代码:

#include <afxdisp.h>
②在projectname.cpp 文件中InitInstance 函数里加入代码:
if (! AfxOleInit ()) {AfxMessageBox (" OLE 初始化失败!") ;return FALSE;}
2) 利用MFC 添加MapInfo 支持类,为该类创建一个对
象,并获取存放当前可执行文件的完全路径。
①选择“View”->“ClassWizard”菜单,再选择“AddClass”标签下的“From a type library”,弹出“import a typelibrary”对话框,在查找范围选项里打开MapInfo 安装路径下的“professional”文件夹下的“mapinfow.tlb”文件, 单击“OK”按钮确定所选中的类,这样创建的类将允许通过OLE自动界面访问MapInfo。
②打开projectname.cpp 文件,添加如下代码:
在原有的#include 代码后添加:#include " mapinfow.h"
在声明“CprojectnameApp theApp;”后,添加变量声明:
DMapInfo m_map;
定义存放当前可执行文件的完全路径名:
CString sPath;
在InitInstance 函数中OLE 初始化成功之后添加代码:
m_map.CreateDispatch (" MapInfo.Application") ;
获取当前可执行文件的完全路径名:

char cPath [512] ;
CString sTempPath;
GetModuleFileName (NULL,cPath,sizeof (cPath)) ;
sTempPath.Format (" %s" ,cPath) ;
int nPos = sTempPath.ReverseFind ('\\') ;
sPath = sTempPath.Left (nPos) ;
③为满足程序通用性,先将mapbasic.h 文件拷贝到工程
文件夹下,打开mapinfow.h 文件,在该文件尾部加上如下代
码:
extern DMapInfo m_map;
#include " mapbasic.h"
此时,已经成功添加了MapInfo,并可访问OLE 自动化对象。
(2) 创建含有MapInfo 数字地图元素的子窗口,获取该子窗口标识及句柄,实现应用程序与该子窗口的交互。
1) 在类视图头文件(projectnameView.h) 中加入成员变量:
protected:
unsigned long m_lwindowID;
HWND m_hwndWindow;
2) 在工程debug 文件夹下创建map 文件夹,将待装入的数字地图文件(假设文件名为ditu) 存放在其中,在类视图实现文件(projectnameView.cpp) 中添加如下代码:
①在原有的#include 代码后加上:
#include " mapinfow.h"
②在构造函数中,对变量进行初始化:
m_lwindowID=atol (m_map.Eval (" WindowID (0)")) ;
m_hwndWindow=0;
③在OnInitialUpdate 方法中,装入数字地图文件,并获得其标识及句柄。
CString strCommand;
m_map.Do ( " Open Table \" " + sPath + " \\map\\ditu\"
Interactive") ;//装载数字地图
strCommand.Format ( " Set Next Document Parent % lu
Style 1 Map From China_bt" , (long) m_hWnd) ;
m_map.Do (strCommand) ;
m_lwindowID=atol (m_map.Eval (" WindowID (0)")) ;
strCommand.Format ( " WindowInfo (% lu, % u) " ,
m_lwindowID,WIN_INFO_WND) ;
m_hwndWindow = ( HWND) atol ( m_map.Eval
(strCommand)) ;
④在析构函数中,释放成员变量,终止Mapinfo。
if (m_hwndWindow) {
::DestroyWindow (m_hwndWindow) ;
m_hwndWindow=NULL;
m_lwindowID=0L;}
(3) 添加Mapinfo 的数字地图编辑工具,这里添加“选
择”、“拖动”、“放大”、“缩小”4 个工具。
1) 创建4 个菜单命令项:Selector、Grabber、Zoom-In、
Zoom -Out。定义它们的ID 号为ID_TOOLS_SELECTOR、ID_TOOLS_RECENTER、ID_TOOLS_EXPAND 和ID_TOOLS_SHRINK。对于每个工具命令,在MapBasic.h 中有相应的状态定义标识M_TOOLS_SELECTOR、M_TOOLS_RECENTER、M_TOOLS_EXPAND 和M_TOOLS_SHRINK。

2) 为跟踪当前选择的每个工具,在CprojectnameView 中定义一个私有成员变量:
int m_eMouseMode;
3) 在构造器中初始化该变量,将数字地图工具的初始状态定义为“选择”。
m_eMouseMode=M_TOOLS_SELECTOR;
4) 利用ClassView 向导为每个工具添加COMMAND 和UPDATE_COMMAND_UI 函数,下面以Selector 工具为例进行添加,其他类似。
void CMessView::OnToolbarSelector () {
m_eMouseMode = M_TOOLS_SELECTOR;
//设置当前工具
m_map.RunMenuCommand (M_TOOLS_SELECTOR) ;
}
void CMessView::OnUpdateToolbarSelector ( CCmdUI*
pCmdUI) {
pCmdUI->SetRadio (m_eMouseMode ==
M_TOOLS_SELECTOR) ;//更新用户界面
pCmdUI->Enable (m_lwindowID) ;
}
(4) 编译并运行程序。成功之后MapInfo 在VC++环境下的集成开发平台就搭建好了,用户可以根据自己的需要添加各种算法实现数字地图应用功能,如路径规划、地理信息查询等。
如图1 所示是一个路径规划的例子,为其添加了路径规划按钮G 和保存按钮S,在路径规划按钮响应函数中添加路径规划算法。这里以北京到呼和浩特的飞机航线示例,规划好的路径可以通过保存按钮保存成Mapinfo 数字地图文件,方便二次开发和利用。

4 结语
从实用性出发,详细介绍了在应用广泛的VC++环境下完成MapInfo 集成数字地图的开发过程,该开发过程通用性较以得到压缩四叉树。P 的压缩四叉树表示为ZT (P)。四叉树中的一个叶结点对应一个正规正方形,一条被压缩的边(更准确地说是这条边最顶端的顶点) 对应2 个正规正方形的集合差所形成的环形区,这个环形区被称为平铺区。如图3 所示。一棵压缩四叉树将单位正方形分隔为一些平铺区。

2 算法描述
选择P 中各点的一个随机排列〈P〉=〈p1,…,pn〉。Ti 为Pi= {p1,…,pi} 的压缩四叉树。在Ti 中对应ZT (Pi) 中的一个平铺区f 的每个结点存储一个列表cl (f),该列表包含f 中的所有点。这样P 中的每个点都存储在Ti 中。cl (f) 称为f 的冲突列表。对于P 中每个点都有一个指针指向包含它的Ti 中的结点。在第i 次迭代中,找到Ti-1=ZT (Pi-1) 中存储pi的结点vi,将pi插入vi。这种插入最多导致创建3 个新结点。因为只有压缩四叉树的叶结点才能包含插入点。这样会加入一个新结点存储新点Pi。将这个新叶结点悬挂在四叉树上要求一条已有的压缩边Ti-1,加入一个新的顶点。插入pi的叶结点已经存储了一个插入点,不仅为了pi,也是为了这个叶结点上以前存储的点而引入一个新叶结点。如果这2 个点之间的距离相对f的直径靠近的话将引入新的压缩边。这样得到的结果树Ti 就是Pi 的压缩四叉树。将vi 中存储的所有点移到Ti 中正确的位置。对vi中存储的所有点,检查是否要存储到新结点中,如果是将它移动至新结点。如果vi 的冲突列表中有k 个点,则本次循环花费O (1+k) 时间。由此得到压缩四叉树Tn。
3 算法分析
定义3:设Y 为P 的任意子集,平铺区f∈ZT (Y)。如果集合,f∈ZT (X),并且X 是具有这种属性的最小子集,即:不存在X 的真子集具有平铺区f,则称X 是f 的定义集。

引理1:如果X 是平铺区f∈ZT (P) 的定义集,则│X│≤4。
与传统随机化增量构建方法不同,这种情况下的定义集不唯一。
引理2:对平铺区f∈ZT (Pi),第i 次迭代创建f 的概率≤
4/i,即:证明:设D1,…,Dm Pi 为f 的所有不同的定义集。Z=D1∩D2∩…∩Dm。仅当pi∈Z 时f 在第i 次迭代时创建。如果,则存在f 的定义集Dt, 。同时,由于,f也是ZT (Pi-1) 的一个平铺区,这个平铺区在第i 次迭代时被创建的概率为零。

根据引理1,所有定义集的基数最大为4,│Z│≤4。要求的概率受到pi在Z 中的概率的限制。考虑Pi上所有可能的排列。Z 中的4 个点之一在这i 个点排列中排在最后的最大概率是4/i。根据引理2,创建一个平铺区f 的概率与它的冲突列表的大小无关。
引理3:第i 次迭代的期望工作量是O (1+n/i)。
证明:对于f∈ZT (Pi),在第i 次迭代时创建中花费的工作量与它的冲突列表cl (f) 的长度成正比。设Xi是表示本算法第i 次迭代的工作量的随机变量。因为Ti 的冲突列表长度
为n,根据引理2,第i 次迭代的期望工作上限为:这里的期望是对Pi所有可能的排列。因此,E [Xi] =E [E[Xi│Pi]] =O (1+n/i)。
定理1:对于位于单位正方形内的平面上的n 点集合P,可以在时间O (nlogn) 内构造一颗压缩四叉树。
证明: 根据引理3, 上述算法的总计花费时间为。
4 结语
这种构造四叉树的方法对于多维空间内的点依然适用。Eppstein 的算法是一种懒惰随机化增量四叉树构造算法。Eppstein 的算法略为复杂,但支持插入和删除操作,而本算法只支持构建压缩四叉树。

原创文章,转载请注明: 转载自MapInfo中文网

本文链接地址: MapInfo 在VC++环境下的集成开发实例

文章的脚注信息由WordPress的wp-posturl插件自动生成

作者:
该日志由 admin 于2012年02月26日发表在未分类分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。 | +复制链接
转载请注明: MapInfo 在VC++环境下的集成开发实例
关键字:
【上一篇】
【下一篇】

您可能感兴趣的文章:

发表评论

[请申请gravatar头像,木有头像的评论可能不会被回复|头像相关帮助]

插入图片