摘要:MapBasic是Mapinfo自带的二次开发语言,它是一种类似Basic的解释性语言,利用MapBasic编程生成的*.mbx文件能在Mapinfo软件平台上运行,早期的Mapinfo二次开发都是基于MapBasic进行的。MapBasic学起来容易,用起来却束缚多多,无法实现较复杂的自定义功能,用它来建立用户界面也很麻烦,从现在角度看,MapBasic比较适合用于扩展Mapinfo功能。

一、利用MapBasic开发

MapBasic是Mapinfo自带的二次开发语言,它是一种类似Basic的解释性语言,利用MapBasic编程生成的*.mbx文件能在Mapinfo软件平台上运行,早期的Mapinfo二次开发都是基于MapBasic进行的。MapBasic学起来容易,用起来却束缚多多,无法实现较复杂的自定义功能,用它来建立用户界面也很麻烦,从现在角度看,MapBasic比较适合用于扩展Mapinfo功能。

二、利用OLE自动化开发

1. 建立Mapinfo自动化对象

基于OLE自动化的开发就是编程人员通过标准化编程工具如VC、VB、Delphi、PB等建立自动化控制器,然后通过传送类似MapBasic语言的宏命令对Mapinfo进行操作。实际上是将Mapinfo用作进程外服务器,它在后台输出OLE自动化对象,供控制器调用它的属性和方法。

OLE自动化开发的首要一步就是建立Mapinfo自动化对象,以Delphi为例(后面都是如此),你可设定一个Variant类型的全程变量代表OLE自动化对象,假设该变量名为olemapinfo,那么有:

oleMapinfo := CreateOleObject('Mapinfo.Application')

一旦OLE自动化对象建立,也就是后台Mapinfo成功启动,你就可以使用该对象的Do方法向Mapinfo发送命令,如:

oleMapinfo.Do('Set Next Document Parent' + WinHand + 'Style 1')

这一命令使Mapinfo窗口成为应用程序的子窗口,WinHand是地图窗口句柄,style 1 是没有边框的窗口类型。你还可以使用自动化对象的Eval方法返回MapBasic表达式的值,如下面语句返回当前所打开的表数:

TablesNum:=olemapinfo.eval('NumTables()')

你也可以直接调用Mapinfo菜单或按钮命令对地图窗口进行操作,如地图放大显示:

oleMapinfo.RunMenuCommand(1705)

2. 建立客户自动化对象触发CallBack

基于OLE自动化开发的难点在于所谓的CallBack,Mapinfo服务器对客户程序地图窗口的反应叫CallBack,假如你在地图窗口中移动地图目标,Mapinfo能返回信息告诉你地图目标当前的坐标位置,这就是CallBack功能。如果你想定制自己的地图操作工具或菜单命令,你必须依靠CallBack。但是想捕获CallBack信息,你的客户程序必须具备接收CallBack信息的能力,为此需要在客户程序中定义自己的OLE自动化对象,如:

//定义界面

IMyCallback = interface(IDispatch)

['{2F4E1FA1-6BC7-11D4-9632-913682D1E638}']

function WindowContentsChanged(var WindowID: Integer):SCODE;safecall;

function SetStatusText(var StatusText: WideString): SCODE; safecall;

//定义界面实现

TMyCallback = class(TAutoObject, IMyCallback)

function SetStatusText(var StatusText: WideString): SCODE; safecall;

function WindowContentsChanged(var WindowID: Integer): SCODE;safecall;

其中WindowContentsChanged函数用于返回变化窗口的ID号,即当地图窗口变化时(如放大、缩小),让Mapinfo将地图窗口的ID号返回给客户程序; 另一个SetStatusText函数返回Mapinfo状态条变化信息。编程人员不能随意定义这些函数,因为只有在三种情况下Mapinfo服务器的CallBack才会被触发:(1)地图窗口发生变化,触发函数为WindowContentsChanged;(2)Mapinfo状态条信息改变,触发函数为SetStatusText;(3)用户选择自定义工具或菜单命令在地图窗口上操作,如用户定制的画线工具,当用户在地图窗口画线时触发Mapinfo的CallBack返回线的坐标位置。

建立客户自动化对象后,调用MapInfo自动化对象的SetCallback方法将客户自己定义的自动化对象告诉Mapinfo,只要程序一运行,客户自动化对象就会自动在注册表中注册,然后就能收到CallBack信息了,如:

My:=MyCallBack.Create

oleMapInfo.SetCallBack(My)

这里打一个比方我想会有助于理解上述机制,客户程序与Mapinfo之间的交互就像舞台指挥与木偶演员的交流,客户程序中的地图窗口或说Mapinfo子窗口只不过是一个牵线木偶,后台的Mapinfo才是真正操纵木偶的演员,所以客户程序必须与后台Mapinfo建立正向、反向的联系机制,才能操纵地图窗口中的图形目标。

三、利用MapX开发

1. 掌握使用MapX

MapX是Mapinfo公司最新推出的ActiveX控件产品,目前已经发展到MapX4.5。由于MapX是基于Windows操作系统的标准控件,因而能支持VC、VB、Delphi、PB等标准化编程工具,使用时只需将控件装入开发环境,装入控件后,开发环境ActiveX工具条上会增加一个控件按钮Map,把它拖放到窗体上就可建立一个TMap类型的ActiveX地图对象Map,通过设置或访问该Map对象的属性、调用该Map对象的方法及事件,便能快捷地将地图操作功能溶入到你的应用程序中。

MapX由一系列Object(对象)和Collection(对象集合)组成,Map是最基本的对象,每个Map由Layer(层)、Dataset(数据集)和Annotation(标注)这三个对象及对象集合(Layers、Datasets、Annotations)来定义, 其中Layer用于操作地图图层,Dataset用于访问空间对象的属性数据,Annotation用于在地图上添加文本、符号等标注,掌握上述三个主要对象的特征后,再顺藤摸瓜掌握下一级对象的特征,如每个Layer又由Feature(点、线、面、文本图形目标)对象及对象集合(Features)定义,每个Dataset由Field(属性数据域)对象及对象集合(Fields)定义......,这样很快就能把MapX学到手。

2. 定义地图坐标系

在MapX开发中需要特别注意地图坐标系问题,MapX地图坐标系分为地图显示坐标系和内部计算坐标系,两者互为独立,在GIS应用开发中根据应用需要设置好这两种坐标系非常重要,因为坐标系一方面影响软件系统的内部坐标处理,另一方面影响地图的外观显示。Map对象的坐标系及投影通过CoordSys对象的Set方法定义:

Set(Type, [Datum], [Units], [OriginLongitude], [OriginLatitude],

[StandardParallelOne], [StandardParallelTwo], [Azimuth], [ScaleFactor],

[FalseEasting], [FalseNorthing], [Range], [Bounds], [AffineTransform])

其中主要参数:Type表示投影类型,Type为1时地图坐标以经纬度表示,后面都为可选参数,其中Datum为地球基准面;Units为坐标单位,如Units为7表示以米为单位;OriginLongitude、OriginLatitude分别为起始经度和纬度;StandardParallelOne、StandardParallelTwo为第一、第二标准纬线,该参数与地图投影相关。

通过设置Map对象的DisplayCoordSys和NumericCoordSys属性返回的CoordSys对象,就可设定地图显示坐标系和内部计算坐标系。举例如下:

procedure TMain.DefineMapParam();

var

MapDatum: Variant;//地球基准面

begin

try

MapDatum := CreateOleObject('MapX.Datum.4'); //建立基准面对象

//定义北京54坐标系基准面

// (Ellipsoid, ShiftX, ShiftY, ShiftZ, RotateX, RotateY, RotateZ, ScaleAdjust, PrimeMeridian)

MapDatum.set(3, 24, -123, -94, -0.02, 0.25, 0.13, 1.1, 0);

//定义北京54坐标系经纬度作为内部计算坐标系

Map1.NumericCoordSys.Set_(1, MapDatum);

//定义北京54坐标系30度标准纬线麦卡托投影作为显示坐标系,单位为米

Map1.DisplayCoordSys.Set_(26,MapDatum,7,0,0,30);

finally

VarClear(MapDatum);

end;

坐标系是GIS系统的基石,正确设置坐标系是系统成败的关键。

3. 操纵地图对象

你可以简单地加载一个GeoSet文件,给Layers对象集合赋予具体的内容,随之在Map对象中就能看到地图显示,GeoSet文件类似MapInfo中的工作空间,MapX中带有Geoset文件的编辑器GeosetMangater.exe,用户可在编辑器中组合及设置图层,然后保存生成一个 *.gst 文件直接调入Map对象,这样可以节省时间。你也可以通过Layers对象的Add 或 Remove 方法添加或移走地图图层,如:

Map.layers.Add(FileName); // 添加图层,FileName为文件全路径名

Map.Layers.Remove(3); // 移走地图第三层

Layers对象由一组Layer对象组成,通过Layer对象的Features和Selection对象集合你可以操纵和选择图层上的图形目标,如:

Map.Layers.Item(1).AddFeature(Newobj); //将新建对象Newobj添加到图层一

4. 地图数据捆绑

数据捆绑是将不同来源的数据对应到地图层的过程,捆绑结果会产生一个Dataset对象,Dataset对象的集合组成Datasets Collection,它定义了Map对象的数据集属性。 你可以通过Datasets将不同来源的数据捆绑到地图上实现图文互动,或创建专题图,如下例ODBC Access数据的捆绑及专题分析:

procedure TMapForm.ODBC1Click(Sender: TObject);

var

param: ODBCQueryInfo ;

ds: Dataset; //定义数据集

Datafields: Fields; //定义数据域

begin

param.SqlQuery := 'select * from China'; //选择Access数据库中的China表

param.DataSource := 'MapChina'; //ODBC 数据源名

param.ConnectString := 'ODBC;'; //或是user = ... Pwd = ... , 定义ODBC连接

Datafields.Add('GEONAME','GEONAME', miAggregationAuto,miTypeString); //添加数据域GEONAME

Datafields.Add('POPU','POPU', miAggregationAuto,miTypeNumeric); //添加数据域POPU

//将Access数据捆绑到Mapinfo China表

ds := Map.Datasets.Add(miDataSetODBC, param, unassigned, unassigned, unassigned, 'CHINA', Datafields, unassigned);

ds.Themes.Add(miThemeRanged, 'POPU', 'MyTheme'); //添加一个范围专题图

end;

5. 建立客户定制工具

你还可以定制自己的地图操作工具,下面通过定制一个名为Info的信息按钮工具简述方法步骤:

(1)定义客户工具常量

Const CUSTOM_INFO_TOOL = 1

(2)利用Map对象的CreateCustomTool方法定义客户工具,方法为:

CreateCustomTool (ToolNumber, Type, Cursor, [ShiftCursor] , [CtrlCursor], [InfoTips])

其中ToolNumber为工具号,即上面定义的常量;Type为工具类型;Cursor为光标形状,其他参数可选。

//定义Info工具为十字光标点触发工具

Map.CreateCustomTool(CUSTOM_INFO_TOOL, miToolTypePoint, miCrossCursor, miArrowCursor, miArrowCursor, unassigned)

(3)在Map对象事件ToolUsed中编写工具的Handler(操作内容)

procedure TMain.MapToolUsed(Sender: TObject; ToolNum: Smallint; X1, Y1, X2, Y2, Distance: Double;

Shift, Ctrl: WordBool; var EnableDefault: WordBool);

begin

Case ToolNumber of

CUSTOM_INFO_TOOL : //信息工具Info

try

……

end;

(4)定义信息按钮的Click事件

procedure TMain.InfoClick(Sender: TObject);

begin

Map.CurrentTool:=CUSTOM_INFO_TOOL;

end

四、小结

基于MapBasic的开发简单但受限制较多,比较适合Mapinfo功能扩展编程。而基于OLE自动化的开发比较繁琐,因为需要来回向后台的Mapinfo发送MapBasic字符串命令,所建立的应用程序运行速度也相对较慢,但这种开发方法能随心所欲制作出美观友好的界面,将地理操作与非地理操作溶为一体,并且能实现几乎100%的Mapinfo功能,这是目前的MapX4.5也不能比拟的。与传统GIS专业性开发环境相比,像MapX这类组件式GIS系统的出现可说是一种质的飞跃,它小巧灵活,开发简捷,价格便宜,以后会越来越大众化。 用MapX开发的GIS系统运行速度快,因为它不需要在Mapinfo软件平台上运行。但从目前MapX4.5看,MapX并没能实现所有的Mapinfo功能(据称95%以上),使用过程中发现其生成或编辑地图能力及地理分析能力不足,而且里面Bug也不少,当然随着今后新版的推出,MapX会越来越稳定、完美。

tmap的使用_MapInfo教程--二次开发入门相关推荐

  1. Flow-3D二次开发入门 教程

    Flow-3D二次开发入门 教程 加载体热源 (默认的,没有任何热源) General Physics Fluid设定 Meshing & Geometry Geometry meshing ...

  2. Revit二次开发入门教程一(工具篇)

    对BIM开发感兴趣的读者可以关注我的BIM开发系列教程 什么是BIM开发?这篇文章可以告诉你 Revit二次开发教程提纲 Revit二次开发编程入门一(工具篇) 前言 BIM诞生的背景 Revit在B ...

  3. Revit二次开发入门秘籍 01如何入门

    关于入门 我想在开始学习之前大家应该更需要知道如何入门,对比一下我们在学校的学习,我们需要书.老师-书上呢,是有所有的知识点,有重要的,有不重要的,而老师呢,会知道哪些是重点,也就是我们考试要考的,教 ...

  4. Revit二次开发入门捷径_升维学习、降维打击

    问题 入门Revit二次开发有捷径吗? 答案 量子力学:有也没有.(皮一下:叠加态) 没有:目的地只有一个,路只有一条,学习没有捷径. 有:虽然路只有一条,但我们可以借助交通工具,缩短时间就是捷径. ...

  5. Revit二次开发入门关键

    学会学习 什么是学习? 学得:通过学,获得的知识. 假会!眼睛:我会了!脑子:我会了!手:不,你不会!!! 习得:通过练习,获得的知识. 真会!手:我会了!基本不用经过太多的思考! 没意识到:好运~! ...

  6. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件

    第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...

  7. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第六章:数据存储

    第 6 章 数据存储 本章介绍Android 4种存储方式的用法,包括共享参数SharedPreferences.数据库SQLite.存储卡文 件.App的全局内存,另外介绍Android重要组件-应 ...

  8. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第五章:中级控件

    第 5 章 中级控件 本章介绍App开发常见的几类中级控件的用法,主要包括:如何定制几种简单的图形.如何使用几种选择按钮.如何高效地输入文本.如何利用对话框获取交互信息等,然后结合本章所学的知识,演示 ...

  9. Revit二次开发入门相关安装和配置

    Revit二次开发入门相关安装和配置 最近一周,由于项目需要,需要做一个基于Revit的二次开发项目,也特意初步自学了Revit二次开发的相关知识.由于学习时间过短,了解到的只是皮毛,所有还希望大家能 ...

最新文章

  1. 纯 Git 实现前端 CI/CD
  2. 为什么分布式一定要有延时任务?
  3. 我酸了!又是别人家公司!百度新年发 U 奖金鼓励员工
  4. 火星上的甲烷从哪里来,科学家用算法给出了答案
  5. 程序员面试拼多多,来看看这些面试题你掌握的有多少呢?
  6. android c 电话联系人,Android 联系人按中文拼音排序
  7. linux jetty 安装目录结构,Linux下Jetty 9安装部署
  8. 计算机组装与维修单招,单招职二 计算机组装与维修试卷.doc
  9. 安卓应用安全指南 5.6.2 密码学 规则书
  10. 基于win32的windows画板程序
  11. Vue3.0 + Ts 项目框架搭建四:配置 Svg-Icon、Icon图标
  12. 职称英语与计算机考试试题,2020年职称计算机考试模拟选择试题及答案.doc
  13. 必备9种能力、9种手段、9种心态
  14. SATI阅读重点有哪些?
  15. wifi信号满格无法连接服务器,wifi正常为什么不能上网_一招解决wifi信号满格不能上网的方法...
  16. 各运营商虚拟主机对比_满足您需求的最佳虚拟主机提供商
  17. 计算机硬盘正常的使用步骤,500g的硬盘的电脑合理分区方法
  18. vue 父组件重新加载子组件
  19. Protel99SE添加泪滴焊盘
  20. 2t3ik与ddgs挖矿病毒处理

热门文章

  1. boost::variant2模块实现默认构造相关的测试程序
  2. boost::replace_copy_if相关的测试程序
  3. boost::::adaptors::indexed::indexed相关的测试程序
  4. boost::coroutine模块实现power的测试程序
  5. Boost:宏BOOST_TEST_CSTR_EQ的使用实例
  6. DCMTK:根据DICOM第11部分媒体存储应用程序配置文件制作DICOMDIR
  7. OpenCV FLANN在数据集中搜索查询图片的实例(附完整代码)
  8. OpenCV自定义CN跟踪器
  9. OpenCV添加(混合)两个图像
  10. OpenCV在矩阵上进行Mask 运算operations