|
|
|
|

基于OLE自动化的MapInfo集成开发

摘要:本文以Delphi应用程序为例,比较详细的介绍了如何利用OLE自动化技术集成开发MapInfo应用程序。介绍了OLE调用、回叫等功能的使用方法。最后,以一个例子说明了如何在实际应用程序中用到本文所讲的方法。 关键词:OLE自动化;MapInfo;地图集成化 ...

作者:江崇礼 马振涛 董明来源:GIS空间站论坛|2006年12月14日
摘要:本文以Delphi应用程序为例,比较详细的介绍了如何利用OLE自动化技术集成开发MapInfo应用程序。介绍了OLE调用、回叫等功能的使用方法。最后,以一个例子说明了如何在实际应用程序中用到本文所讲的方法。
关键词:OLE自动化;MapInfo;地图集成化
 
1        概述
 
MapInfo Professionnal 6.0是美国MapInfo公司开发的一种桌面地理信息系统开发平台,因为它小巧玲珑、易学易用,同时对空间数据具有强大的采集、存贮、分析等功能,所以成为世界上最为流行的桌面地理信息系统。目前利用MapInfo开发应用程序主要有三种方式。分别是单纯利用MapBasic开发、利用可视化编程工具集成二次开发和利用MapX开发。
在这三种方法中,单纯MapBasic编程由于缺乏可视化编程环境的支持,开发周期过长而较少采用,后两种是实际应用中比较常用的方法。
利用MapX开发的应用程序因为不需要后台MapInfo的支持,所以运行速度快,小巧灵活,是目前比较流行的开发方法,然而MapX并没有实现所有的MapInfo功能,而且其生成和编辑地图的能力尚有欠缺。相信随着更高版本的MapX的推出,这种开发方法将会越来越流行。
利用可视化编程工具集成开发是在前台利用可视化编程工具(VC、VB、Delphi等)开发与地理信息功能无关的用户界面,在涉及到地理信息功能时在后台调用MapInfo。实际上是将地图窗口集成到其它编程语言开发的应用程序中,用其它编程语言通过向MapInfo传送命令来控制MapInfo。这种方法能随心所欲制造出美观友好的界面并且能实现几乎所有的MapInfo功能,尤其是需要在原有成熟的应用系统中增加地理信息管理功能时,这种方法是非常有效的。
 
2        OLE调用方法介绍
 
应用程序向MapInfo传送命令主要通过有两种途径:
一种是利用DDE技术建立MapInfo和应用程序之间的通信。DDE会话是两个Windows应用程序交换信息的过程。只有当两个支持DDE的应用程序运行时,它们之间才可以进行DDE会话。在一个会话中,只有一个应用程序是主动的,成为客户,被动的应用程序成为服务器。实际运行时,MapInfo充当服务器的角色,被客户应用程序调用。
另一种向MapInfo传送命令的方法是OLE自动化技术。MapInfo允许其他支持OLE功能的应用程序把MapInfo作为一个对象加以调用,MapInfo作为一个OLE服务器向其他应用程序提供它的对象,而客户应用程序则使用它的对象,其他应用程序通过调用OLE自动化对象的方法、属性来操作MapInfo。
实际应用中,利用OLE是较为常用的方法,因为它比DDE稳定可靠,同时它还能报告MapInfo的运行错误,而DDE不能获取MapInfo的错误代码。本文主要讨论基于OLE自动化的集成开发。
 
以Delphi集成MapInfo为例,利用OLE自动化集成开发方法如下:
 
a)        启动MapInfo
 
在客户程序中启动MapInfo用如下语句来实现:
var oleMapInfo : Variant;     //在Delphi应用程序中声明OLE Variant类型的变量
oleMapInfo := CreateOLEObject('MapInfo.Application');
CreateOLEObject()函数用来创建MapInfo自动化服务器的一个实例,上述语句同时把该函数的返回值赋给Variant类型的变量oleMapInfo,通过上述语句,oleMapInfo对象被定义为MapInfo的一个实例,在以后的操作中,oleMapInfo就相当于一个MapInfo服务器,Delphi应用程序通过对oleMapInfo的调用,就相当于对MapInfo的进行管理和操作。
 
b)        调用MapInfo实例的方法和属性
 
OleMapInfo对象拥有以下方法和属性
对象
方法
属性
Application
Do、Eval、RunCommand、SetCallBack 、RunMenuCommand、DataObject、
Name、Application、Parent、Version、Visible、LastErrorCode等
在应用程序中调用不同的方法和属性可以实现不同的功能,其中经常用到的有:
1)        Do方法—向MapInfo传送指令
启动MapInfo后就可以向它传送MapBasic指令,让其实现相应MapBasic语句对应的功能。例如下述语句打开并调入一幅地图:
MsgString := ‘Open Table “D:\Map\Map1.Tab” Interactive’;
oleMapInfo.Do(MsgString);
MsgString := ‘Map From Map1’;
oleMapInfo.Do(MsgString);
Do方式是集成开发用到最多的一种方法,基本上一些重要的功能都要用它来实现。下面列举一些。
重生成MapInfo窗口
当启动MapInfo之后,通常要做的第一步是重生成MapInfo窗口:
MsgString := 'Set Next Document Parent ' + sWinHand + ' Style 1';
//sWinHand是Delphi容纳MapInfo窗口的控件的句柄
oleMapInfo.Do(MsgString);
当执行完上述语句后,MapInfo的对话框和错误信息就为客户程序所拥有。
直接运行Mapbasic程序
有的时候,需要在二次开发中调用现成的MapBasic程序实现特定的功能,用Do方法实现如下:
MsgString := 'Run Application " D:\MapBasic\DrawArc.MBX"';
oleMapInfo.Do(MsgString);
重定义MapInfo右键菜单
这是一项很有实际意义的功能,开发者可以根据实际需要增加或者修改MapInfo地图窗口的右键菜单,甚至完全屏蔽MapInfo的右键菜单:
MsgString := 'Create Menu "MapperShortcut" ID 17 As "(-"';   //屏蔽右键菜单
oleMapInfo.Do(MsgString);
2)        Eval方法—从MapInfo获得返回值
oleMapInfo的Eval方法可以从MapInfo中返回值给客户程序。当客户程序需要得到某些地图信息时,需要应用此方法。下面的语句将地图中心的横、纵坐标返回给客户程序:
MsgString := 'MapperInfo(WindowID(0), 3)';
CenterLongitude := oleMapInfo.Eval(MsgString);
MsgString := 'MapperInfo(WindowID(0), 4)';
CenterLatitude := oleMapInfo.Eval(MsgString);
//MapperInfo是MapInfo内部函数
3)        RunMenuCommand方法—调用MapInfo菜单
利用RunMenuCommand方法可以方便的实现MapInfo的菜单功能。在MapInfo中,每一个菜单功能都对应着一个ID号,在MapBasic安装目录下的MENU.DEF文件中可以查询到每个菜单对应的ID号。例如当希望客户程序的某一个按钮按下后弹出MapInfo的Change View对话框(对应MapInfo中Map菜单的Change View菜单项),只需要响应在这个按钮的OnClick事件,在其中调用oleMapInfo的RunMenuCommand方法:
procedure TFormMap.cmdChangeViewClick(Sender: TObject);
begin
  oleMapInfo.RunMenuCommand(805);
  //805是MEMU.DEF中对应M_MAP_CHANGE_VIEW的值
end;
利用同样的方法,MapInfo的Main工具栏中对应的按钮同样可以集成到应用程序中。工具栏按钮对应的ID号同样可以在MENU.DEF中找到。
 
3 利用回叫机制从MapInfo中获取信息
 
在集成二次开发中,通常采用回叫机制从MapInfo中获取信息。所谓回叫,是指当集成客户程序的MapInfo地图窗口中有事件发生时,MapInfo通过OLE自动化对象自动向客户应用程序发送消息的机制。
利用回调机制,在如下情况下MapInfo可以向客户程序发送信息:
1)  apInfo中执行菜单栏或者工具按钮的命令。
2)  图窗口发生变化。
3)  MapInfo状态条发生改变(用户在地图上移动鼠标)。
而客户程序可以接收相应的信息,在自己定义的方法中进行处理。所以可以利用回叫机制在应用程序中实现下面的功能:
1)  定义MapInfo右键菜单。
2)  过用户自定义工具同MapInfo交互。
3)  控制发生变化的地图。
4)  自定义客户程序状态栏显示的内容。
回叫是利用OLE自动化集成二次开发的难点所在,其核心思想是MapInfo服务器向客户程序发送消息。以自定义客户程序的状态栏为例,回调机制的使用方法如下:
1)  建一个类,定义SetStatusText方法。此方法带一个WideString类型的参数StatusText。这个参数是MapInfo向客户程序传递过来的。
在Delphi6.0中选择File|New|ActiveX|Automation Object,通过启动Automation Object向导打开“Type Library”编辑器来实现。这里假设创建的类名为TmyCallBack。
2)  应用程序窗体中添加状态栏。
3)  使用第一步中定义的类创建一个对象。
varCallBack := TMyCallBack.Create;
4)调用自动OLE对象的SetCallBack方法传递参数。
oleMapInfo.SetCallback(varCallBack As IMyCallBack);
5)在SetStatusText方法中处理由MapInfo传递的StatusText参数,控制状态栏的显示。
procedure TMyCallBack.SetStatusText(const StatusText: WideString);
begin
MainForm.StatusBar1.Panels[0].Text := StatusText;
//MainForm是容纳地图组件的窗体
end;
 
4 应用实例
 
笔者在为某单位开发的EMC(电磁兼容)预测与分析系统中应用了OLE自动化技术,从实际应用来看,达到了满意的效果。
系统对分布在不同站位的发射机和接收机进行电磁兼容的分析,作为其中的一个子系统,地理信息功能由Delphi 6.0和MapInfo 6.5相结合开发而成。数据库选用MS SQL Server。应用程序主要用Delphi开发完成,当需要直观的显示地图、站位、发射机、接受机、发射信号等地理信息时调用MapInfo的功能来实现。利用OLE自动化技术实现二者的交互。
站位坐标、参数,发射机接受机参数、所在站位等信息存储在SQL Server的表中。首先利用一个MapBasic程序连接SQL Server数据库,获取信息存入MapInfo的表中,载入基本地图并为站位、发射机、接受机、信号等分别创建图层。
Delphi首先启动MapInfo服务器,然后运行MapBasic程序载入地图,接着通过OLE自动化和MapInfo服务器交互。系统结构如下图所示:
系统运行界面如下:
 
 
其中
隐藏、显示图层由oleMapInfo的do方法调用MapBasic语句实现。
放大、缩小、漫游按钮由oleMapInfo的RunMenuCommand方法实现。
试图设置中获取地图中心坐标通过oleMapInfo的Eval方法实现。
状态栏的更新通过OLE回叫实现。
 
5        结束语
 
实践表明,利用OLE自动化技术开发MapInfo应用程序节省了开发周期,能有灵活有效的控制MapInfo,实现MapInfo的地理信息系统功能。它的缺点是需要在后台调用MapInfo故程序运行速度受到限制。然而在MapX控件应用成熟以前,OLE调用、回叫仍然将会是普遍应用的开发方法。
 
参考文献
1 王晓武,陈宗敏,杜兴国. MapBasic程序设计. 北京:电子工业出版社,2000
2 三味工作室. MapInfo6.0应用开发指南[M]. 北京:人民邮电出版社,2001.1
3 赫晓峰,鲜明,谢晓霞,肖顺平. MapInfo二次开发中回叫机制的应用. 微计算机信息,2002(5):72-74
摘要:本文以Delphi应用程序为例,比较详细的介绍了如何利用OLE自动化技术集成开发MapInfo应用程序。介绍了OLE调用、回叫等功能的使用方法。最后,以一个例子说明了如何在实际应用程序中用到本文所讲的方法。
关键词:OLE自动化;MapInfo;地图集成化
 
1        概述
 
MapInfo Professionnal 6.0是美国MapInfo公司开发的一种桌面地理信息系统开发平台,因为它小巧玲珑、易学易用,同时对空间数据具有强大的采集、存贮、分析等功能,所以成为世界上最为流行的桌面地理信息系统。目前利用MapInfo开发应用程序主要有三种方式。分别是单纯利用MapBasic开发、利用可视化编程工具集成二次开发和利用MapX开发。
在这三种方法中,单纯MapBasic编程由于缺乏可视化编程环境的支持,开发周期过长而较少采用,后两种是实际应用中比较常用的方法。
利用MapX开发的应用程序因为不需要后台MapInfo的支持,所以运行速度快,小巧灵活,是目前比较流行的开发方法,然而MapX并没有实现所有的MapInfo功能,而且其生成和编辑地图的能力尚有欠缺。相信随着更高版本的MapX的推出,这种开发方法将会越来越流行。
利用可视化编程工具集成开发是在前台利用可视化编程工具(VC、VB、Delphi等)开发与地理信息功能无关的用户界面,在涉及到地理信息功能时在后台调用MapInfo。实际上是将地图窗口集成到其它编程语言开发的应用程序中,用其它编程语言通过向MapInfo传送命令来控制MapInfo。这种方法能随心所欲制造出美观友好的界面并且能实现几乎所有的MapInfo功能,尤其是需要在原有成熟的应用系统中增加地理信息管理功能时,这种方法是非常有效的。
 
2        OLE调用方法介绍
 
应用程序向MapInfo传送命令主要通过有两种途径:
一种是利用DDE技术建立MapInfo和应用程序之间的通信。DDE会话是两个Windows应用程序交换信息的过程。只有当两个支持DDE的应用程序运行时,它们之间才可以进行DDE会话。在一个会话中,只有一个应用程序是主动的,成为客户,被动的应用程序成为服务器。实际运行时,MapInfo充当服务器的角色,被客户应用程序调用。
另一种向MapInfo传送命令的方法是OLE自动化技术。MapInfo允许其他支持OLE功能的应用程序把MapInfo作为一个对象加以调用,MapInfo作为一个OLE服务器向其他应用程序提供它的对象,而客户应用程序则使用它的对象,其他应用程序通过调用OLE自动化对象的方法、属性来操作MapInfo。
实际应用中,利用OLE是较为常用的方法,因为它比DDE稳定可靠,同时它还能报告MapInfo的运行错误,而DDE不能获取MapInfo的错误代码。本文主要讨论基于OLE自动化的集成开发。
 
以Delphi集成MapInfo为例,利用OLE自动化集成开发方法如下:
 
a)        启动MapInfo
 
在客户程序中启动MapInfo用如下语句来实现:
var oleMapInfo : Variant;     //在Delphi应用程序中声明OLE Variant类型的变量
oleMapInfo := CreateOLEObject('MapInfo.Application');
CreateOLEObject()函数用来创建MapInfo自动化服务器的一个实例,上述语句同时把该函数的返回值赋给Variant类型的变量oleMapInfo,通过上述语句,oleMapInfo对象被定义为MapInfo的一个实例,在以后的操作中,oleMapInfo就相当于一个MapInfo服务器,Delphi应用程序通过对oleMapInfo的调用,就相当于对MapInfo的进行管理和操作。
 
b)        调用MapInfo实例的方法和属性
 
OleMapInfo对象拥有以下方法和属性
对象
方法
属性
Application
Do、Eval、RunCommand、SetCallBack 、RunMenuCommand、DataObject、
Name、Application、Parent、Version、Visible、LastErrorCode等
在应用程序中调用不同的方法和属性可以实现不同的功能,其中经常用到的有:
1)        Do方法—向MapInfo传送指令
启动MapInfo后就可以向它传送MapBasic指令,让其实现相应MapBasic语句对应的功能。例如下述语句打开并调入一幅地图:
MsgString := ‘Open Table “D:\Map\Map1.Tab” Interactive’;
oleMapInfo.Do(MsgString);
MsgString := ‘Map From Map1’;
oleMapInfo.Do(MsgString);
Do方式是集成开发用到最多的一种方法,基本上一些重要的功能都要用它来实现。下面列举一些。
重生成MapInfo窗口
当启动MapInfo之后,通常要做的第一步是重生成MapInfo窗口:
MsgString := 'Set Next Document Parent ' + sWinHand + ' Style 1';
//sWinHand是Delphi容纳MapInfo窗口的控件的句柄
oleMapInfo.Do(MsgString);
当执行完上述语句后,MapInfo的对话框和错误信息就为客户程序所拥有。
直接运行Mapbasic程序
有的时候,需要在二次开发中调用现成的MapBasic程序实现特定的功能,用Do方法实现如下:
MsgString := 'Run Application " D:\MapBasic\DrawArc.MBX"';
oleMapInfo.Do(MsgString);
重定义MapInfo右键菜单
这是一项很有实际意义的功能,开发者可以根据实际需要增加或者修改MapInfo地图窗口的右键菜单,甚至完全屏蔽MapInfo的右键菜单:
MsgString := 'Create Menu "MapperShortcut" ID 17 As "(-"';   //屏蔽右键菜单
oleMapInfo.Do(MsgString);
2)        Eval方法—从MapInfo获得返回值
oleMapInfo的Eval方法可以从MapInfo中返回值给客户程序。当客户程序需要得到某些地图信息时,需要应用此方法。下面的语句将地图中心的横、纵坐标返回给客户程序:
MsgString := 'MapperInfo(WindowID(0), 3)';
CenterLongitude := oleMapInfo.Eval(MsgString);
MsgString := 'MapperInfo(WindowID(0), 4)';
CenterLatitude := oleMapInfo.Eval(MsgString);
//MapperInfo是MapInfo内部函数
3)        RunMenuCommand方法—调用MapInfo菜单
利用RunMenuCommand方法可以方便的实现MapInfo的菜单功能。在MapInfo中,每一个菜单功能都对应着一个ID号,在MapBasic安装目录下的MENU.DEF文件中可以查询到每个菜单对应的ID号。例如当希望客户程序的某一个按钮按下后弹出MapInfo的Change View对话框(对应MapInfo中Map菜单的Change View菜单项),只需要响应在这个按钮的OnClick事件,在其中调用oleMapInfo的RunMenuCommand方法:
procedure TFormMap.cmdChangeViewClick(Sender: TObject);
begin
  oleMapInfo.RunMenuCommand(805);
  //805是MEMU.DEF中对应M_MAP_CHANGE_VIEW的值
end;
利用同样的方法,MapInfo的Main工具栏中对应的按钮同样可以集成到应用程序中。工具栏按钮对应的ID号同样可以在MENU.DEF中找到。
 
3 利用回叫机制从MapInfo中获取信息
 
在集成二次开发中,通常采用回叫机制从MapInfo中获取信息。所谓回叫,是指当集成客户程序的MapInfo地图窗口中有事件发生时,MapInfo通过OLE自动化对象自动向客户应用程序发送消息的机制。
利用回调机制,在如下情况下MapInfo可以向客户程序发送信息:
1)  apInfo中执行菜单栏或者工具按钮的命令。
2)  图窗口发生变化。
3)  MapInfo状态条发生改变(用户在地图上移动鼠标)。
而客户程序可以接收相应的信息,在自己定义的方法中进行处理。所以可以利用回叫机制在应用程序中实现下面的功能:
1)  定义MapInfo右键菜单。
2)  过用户自定义工具同MapInfo交互。
3)  控制发生变化的地图。
4)  自定义客户程序状态栏显示的内容。
回叫是利用OLE自动化集成二次开发的难点所在,其核心思想是MapInfo服务器向客户程序发送消息。以自定义客户程序的状态栏为例,回调机制的使用方法如下:
1)  建一个类,定义SetStatusText方法。此方法带一个WideString类型的参数StatusText。这个参数是MapInfo向客户程序传递过来的。
在Delphi6.0中选择File|New|ActiveX|Automation Object,通过启动Automation Object向导打开“Type Library”编辑器来实现。这里假设创建的类名为TmyCallBack。
2)  应用程序窗体中添加状态栏。
3)  使用第一步中定义的类创建一个对象。
varCallBack := TMyCallBack.Create;
4)调用自动OLE对象的SetCallBack方法传递参数。
oleMapInfo.SetCallback(varCallBack As IMyCallBack);
5)在SetStatusText方法中处理由MapInfo传递的StatusText参数,控制状态栏的显示。
procedure TMyCallBack.SetStatusText(const StatusText: WideString);
begin
MainForm.StatusBar1.Panels[0].Text := StatusText;
//MainForm是容纳地图组件的窗体
end;
 
4 应用实例
 
笔者在为某单位开发的EMC(电磁兼容)预测与分析系统中应用了OLE自动化技术,从实际应用来看,达到了满意的效果。
系统对分布在不同站位的发射机和接收机进行电磁兼容的分析,作为其中的一个子系统,地理信息功能由Delphi 6.0和MapInfo 6.5相结合开发而成。数据库选用MS SQL Server。应用程序主要用Delphi开发完成,当需要直观的显示地图、站位、发射机、接受机、发射信号等地理信息时调用MapInfo的功能来实现。利用OLE自动化技术实现二者的交互。
站位坐标、参数,发射机接受机参数、所在站位等信息存储在SQL Server的表中。首先利用一个MapBasic程序连接SQL Server数据库,获取信息存入MapInfo的表中,载入基本地图并为站位、发射机、接受机、信号等分别创建图层。
Delphi首先启动MapInfo服务器,然后运行MapBasic程序载入地图,接着通过OLE自动化和MapInfo服务器交互。系统结构如下图所示:
系统运行界面如下:
 
 
其中
隐藏、显示图层由oleMapInfo的do方法调用MapBasic语句实现。
放大、缩小、漫游按钮由oleMapInfo的RunMenuCommand方法实现。
试图设置中获取地图中心坐标通过oleMapInfo的Eval方法实现。
状态栏的更新通过OLE回叫实现。
 
5        结束语
 
实践表明,利用OLE自动化技术开发MapInfo应用程序节省了开发周期,能有灵活有效的控制MapInfo,实现MapInfo的地理信息系统功能。它的缺点是需要在后台调用MapInfo故程序运行速度受到限制。然而在MapX控件应用成熟以前,OLE调用、回叫仍然将会是普遍应用的开发方法。
 
参考文献
1 王晓武,陈宗敏,杜兴国. MapBasic程序设计. 北京:电子工业出版社,2000
2 三味工作室. MapInfo6.0应用开发指南[M]. 北京:人民邮电出版社,2001.1
3 赫晓峰,鲜明,谢晓霞,肖顺平. MapInfo二次开发中回叫机制的应用. 微计算机信息,2002(5):72-74

上一篇:GIS技术在特色数据库项目建设中的应用研究

下一篇:用VC开发Mapinfo程序