APP下载

基于MapInfo的线对象剪断功能探讨*

2012-12-23高自强

地矿测绘 2012年2期
关键词:子句断线折线

高自强

(河北省地勘局测绘院,河北廊坊 065000)

基于MapInfo的线对象剪断功能探讨*

高自强

(河北省地勘局测绘院,河北廊坊 065000)

将MapInfo软件的线剪断功能和MapGIS软件的线剪断功能进行比较,指出MapInfo的线剪断功能单一的问题。为此,介绍了一种利用MapBasic编译生成线对象剪断工具的方法,较好地解决了这一问题。

MapGIS;MapInfo;线对象;剪断功能

0 引言

MapInfo提供了一些点线面及注记工具,能进行图形对象的基本编辑操作。然而,在地质测绘行业中,大多数电子地图数据生产的从业人员由于用惯了其他图形编辑软件,总感觉MapInfo的图形操作工具过于单调。例如,熟悉MapGIS的人就对Map-Info的线剪断功能心存芥蒂。为此,笔者设计了一种MapInfo环境下的线剪断模型,较好地解决了这一问题。

1 MapGIS与MapInfo环境下线剪断功能的比较

在MapGIS中,软件为用户提供了多种剪断线工具,主要有:“线编辑”菜单下的“剪断线”功能(高版本MapGIS提供3种方式:有剪断点、无剪断点和定比剪断);“线编辑”菜单下的“相交线剪断”功能(2种方式:剪断母线和不剪断母线);“其他”菜单下的“自动剪断线”——对全图作完全线剪断处理。这些方式几乎穷尽了剪断线的所有方式,使用也相当方便。

MapInfo软件也为用户提供了剪断线的功能,一般做法是:

1)首先置当前表为“可编辑”,选中要剪断的线。

2)点击“对象/设置目标”菜单,将选中的线对象设置为当前目标。

3)选中另一个线对象,此线对象应满足两点:一是必须与目标对象相交,二是两对象之交点就是准备剪断的位置。如果没有这样的线对象存在,则需要利用输入折线工具增加一个。

4)点击“对象/折线分割”菜单,完成目标对象的切割。

5)如果切割器是临时生成的,最后还要将其删除。

很显然,与MapGIS相比,MapInfo中的剪断线功能单一、操作繁琐。

2 利用MapBasic生成Mbx工具的模型及基本思路

MapInfo提供一种名为MapBasic开发工具,它是一种类似Basic的解释性语言,语法规则和函数与通用Basic语言极其相似,有一定Basic基础的人员能很快学会使用。利用MapBasic编译生成的*.mbx文件能在MapInfo环境下直接运行,因而可以用MapBasic生成Mbx用以扩展MapInfo的功能。下面分析用MapBasic生成MapInfo环境下线剪断工具的基本模型:

第一,该工具应能作为菜单项或工具箱项于启动MapInfo时即自动运行并驻留至MapInfo退出,以便随时调用。

第二,使用时不进行更多的操作,只须选中该工具后在地图窗口中单击线对象需要剪断的部位即可将原来的对象一分为二。

第三,被剪断后形成的新对象保留原对象的样式和属性,而且其任何片断均能保留原对象相应片断的走向(延伸方向)。

第四,不必进行任何其他操作就可以无限次地重复使用。

上述第一项和第四项,利用MapBasic提供的Alter Menu语句和Create ButtonPad语句就可实现。

利用MapBasic建立新的线对象的一般做法是:先用Create pline语句创建一个节点数为0的空对象,再依次向其增加节点,最后用Insert语句将这个新对象插入文件。为说明方便,把需要剪断的原始线对象称为L0,把剪断后的两个线对象称为L1和L2,把单击位置的坐标定义为(x,y)。L1应包含L0从首节点开始的若干节点,其末节点就是(x,y);相应的,L2以(x,y)为首节点,并且包含L0除L1已经用到的节点之外的所有节点。

但是,存在问题是:虽然从地图窗口中取得坐标是可以实现的,但这个坐标究竟位于L0的哪一个片断中,L1(或L2)究竟包含L0的哪几个节点。由于用MapInfo的选择工具选择一个对象并不要求单击位置一定要位于对象之上,当单击发生于对象附近一定范围内时,该对象就能被选中,因而仅以单击位置作为(x,y)加入对象中,必然会有一定偏差,L1的最后一个片断和L2的第一个片断实际上已经偏离了原来的走向。

3 如何定位剪断点

3.1 坐标的确定

如图1所示,L0就是前述的原始线对象(图中只画了它的一部分),圆O的圆心就是鼠标单击位置,其半径为一个定长d,圆O与L0的一个片断——线段AB交于M点和N点,直线OP为AB的垂线,P点为垂足。显然,P点就是将L0分为L1和L2的分割点。

图1 剪断点的定位示意图Fig.1 Positioning schematic of snipped point

求P点坐标的过程是:把圆O看作一个线对象Obj1,然后以A(x1,y1)和B(x2,y2)为节点构造一个新的折线对象Obj2,用MapBasic提供的函数IntersectNodes可以返回一个线对象Obj3,代码如下:

Obj3=IntersectNodes(Obj1,Obj2,INCL_ALL)

这个新对象包含两个节点,其首节点为M,末节点为N,坐标分别为:

线段MN的中分点P的坐标公式为:

3.2 具体实验

为了给前文提到的圆O的半径d定义一个合理的值,笔者进行了一个实验,实验代码如下:

执行以上代码需要建立一个名称为“实验”的MapInfo表文件,在该表中画一条竖直的折线对象。将上述代码复制粘贴至MapBasic文档中,编译后执行,程序将在MapInfo中添加一个有ToolButton按钮的工具箱,点击该按钮,在折线对象左侧距离折线稍远一点的位置单击,此时MapInfo没有任何反应,接着,慢慢向折线移动鼠标并单击,当单击点很接近折线时,屏幕右下方出现一个消息框,报告一个数字。继续从折线左侧趋近折线,不断有数字报告。重复多次后,改为从折线右侧趋近折线。结果如图2所示。

图2 实验结果Fig.2 Experiment result

如果把那条竖直线改为水平线,把上面代码中的print d/(x1-x)改为print d/(y1-y),结果基本相同。

上面代码中“d=MapperInfo(i_win_id,MAPPER_INFO_SCALE)”将当前地图窗口的显示比例赋给变量d。这段代码的执行结果说明,当点击位置与对象的距离约为窗口显示比例分母的1/30或更近时,该对象即可被选中。

3.3 圆半径的确定

根据以上的分析和测试,当d取值不小于当前窗口显示比例的1/30时,圆O就会与折线相交。为弥补测试误差,把d的值定为窗口显示比例的1/20。

4 剪断线工具代码的编写与编译执行

4.1 向MapInfo添加工具按钮

代码如下:

主过程Main向MapInfo界面中加入一个标题为“线工具”的工具箱,并向工具箱放入一个ToolButton按钮,该功能由Create ButtonPad语句完成。MapBasic允许定义如下3种类型的按钮:

第一种:ToolButton工具按钮。当用户单击ToolButton工具按钮时,它处于激活状态直到选择了另一个工具。当一个工具按钮处于激活状态时,如果用户在某种MapInfo窗口单击,将调用由Calling子句指定的处理程序。ToolButton的Icon子句指定按钮的显示图案。MapBasic的安装目录下有一“SAMPLESMAPBASICICONDEMO”子目录,双击其下的 ICONDEMO.MB文件,在打开的MapBasic窗口下编译并执行,它将为MapInfo添加一个Icon Sampler菜单项,依次选取其下的子菜单打开各种工具箱,单击合适的按钮出现对话框(见图3)。把Constant项下的文本内容复制粘贴到ToolButton的Icon子句中即可完成按钮图案的定义(直接在该子句中填入ID号也可以);ToolButton的Cursor子句定义该按钮处于激活状态时的鼠标形状,Draw-Mode子句指定该按钮在地图窗口中的绘图方式;Calling子句指定与按钮对应的子过程名,即按钮的处理程序;HelpMsg子句指定提示文本的内容,文本内容前加“ ”的功能是,当鼠标在按钮上停留时显示提示文本。

图3 Icon ID对话框Fig.3 Icon ID dialog box

第二种,PushButton触发式按钮。用户鼠标左键点击Push-Button触发式按钮时,与它连接的子过程立即被执行。

第三种,ToggleButton开关式按钮,当用户单击这类按钮时,按钮会在按下/非按下之间来回变换,同时程序会调用相应子过程。

PushButton和ToggleButton都没有Cursor和DrawMode子句。需要指出的是,为了能够使用各种图标,MapBasic程序必须包含如下代码行(一般将其置于程序文件的开始部分):

Include"icons.def"

4.2 实现线剪断功能

本文只给出实现线剪断功能的一般过程:选择线(获取其所在表文件名、行号、属性值)创建以d为半径的圆折线对象通过循环将被选择的线对象的各个片断作为独立线对象如果此对象与圆对象相交则计算它们的相交部分、依前述公式取得交点坐标、同 时记录片断位置创建一个与原对象样式相同的折线对象并添加第一部分节点坐标将选择的线对象的obj列Update 为此新对象再创建一个与原对象样式相同的折线对象并添加第二部分节点坐标将此新对象插入原表将新对象的属性Update为原属性值。

由于MapInfo在许多函数和语句中并不支持以变量表示的表文件名,因此,如s_tab为一表名变量,用“Obj1=s_tab.obj”这样的赋值语句并不能取得一个对象,程序会报错。解决方法是,先声明一个alias类型变量(例如oli),赋值如下:

oli=s_tab+ ”.obj”

Obj1=oli

则Obj1的值就是所要的对象。还应注意,创建新的折线对象时,如果要求该对象与原对象的方向一致,应反向赋值,即依次从末节点向首节点添加坐标。

4.3 存在问题及处理方法

仔细分析图1可知,当单击点刚好位于要剪断的线的某个节点附近时,用上述方法取得的坐标反而发生了偏移。其实,只需添加一个条件语句就能解决这个问题,即当循环枚举原线节点坐标时,如果发现单击点与某节点的距离小于d时,则将该节点作为剪断点。

4.4 编译执行

在MapBasic界面下将代码编译为mbx文件后,双击即可执行。如果要在启动MapInfo时自动运行,则可将mbx文件拷贝至“C:Program FilesMapInfoProfessionalTools”,执行MapInfo环境下的“工具/工具管理器”菜单命令,在图4的界面中选“增加工具”,为工具指定标题和位置。确定后将新工具右侧的自动装入框选中即可。

图4 工具管理器界面Fig.4 The interface of the manager of tools

[1]关健.MapInfo系统功能扩展几例[J].城市勘测,2005(4):35~37.

[2]刘光.地理信息系统二次开发教程——语言篇[M].北京:清华大学出版社,2003.

Primarily Probing into the Snipping Function of Line Object Based on MapInfo

GAO Zi-qiang
(Hebei Institute of Geological Surveying and Mapping,Langfang Hebei 065000,China)

By comparison the line snipping function between MapInfo and MapGIS,this paper points out that the line snipping function of MapInfo is single,for this reason,the paper introduces one kind of method to apply MapBasic compiling and generating way of line object snipping tool,then well solving the problem.

MapGIS;MapInfo;line object;snipping function

P 208

B

1007-9394(2012)02-0038-03

2011-07-11

高自强(1963~),男,满族,河北滦南人,硕士,高级工程师,现主要从事工程测量及GIS方面的工作。

猜你喜欢

子句断线折线
命题逻辑中一类扩展子句消去方法
断线的珍珠
命题逻辑可满足性问题求解器的新型预处理子句消去方法
一起10kV开关控制回路断线故障分析及回路完善
折线的舞台——谈含绝对值的一次函数的图象
西夏语的副词子句
折线
折线图案
断线的风筝
命题逻辑的子句集中文字的分类