利用AutoLisp、Microsoft VBA批量生成断面图及断面电子表格数据 联系客服

发布时间 : 星期五 文章利用AutoLisp、Microsoft VBA批量生成断面图及断面电子表格数据更新完毕开始阅读98eab20c4a7302768e99391b

利用AutoLisp、Microsoft VBA批量生成断面图及断面电子表格数据 2008-12-19 16:12:45 新闻类别:学术研究论文

【摘 要】 本文主要讨论如何利用AutoCAD的二次开发语言AutoLisp 和Excel

中的Microsoft VBA语言技术,利用地形图上的高程点数据批量生成断面图和断面数据表格。

【关键字】 断面图 AutoLisp Microsoft VBA 1 引言

Visual Basic作为一个集成的开发环境,能够使AutoCAD数据与其它的Visual

Basic应用程序,如Microsoft Excel软件,直接共享,实现无缝连接,交换数据。

在没有专业软件辅助的情况下,绘制纵横断面图是很繁琐的事,需要进行大量的、重复的操作,既劳神,又容易出错。我们在完成老挝南塔河1#水电站进站道路测绘项目中,利用地形图上的高程点数据,通过Auto Lisp、Visual Basic编程建立AutoCAD与Excel的通信,实现数据交换,快速绘制公路纵横断面及相关成果表,大大的提高了工作效率。

2 应用程序的开发

在实现对地形图上的高程点数据批量生成断面图和断面数据表格处理的程序

代码编写过程中,主要分以下步骤:

(1)注记纵、横断面交点的里程和高程并生成纵断面曲线,输出断面数据。 首先我们取得纵断面线折点的坐标集合(XY-List)。如果纵断面线图元为LWPOLYLINE,则只要依次取出纵断面线图元数据中群码为10的数据即可;如果纵断面线图元为POLYLINE,则只要依次取出纵断面图元之后SEQEND之前的所有VERTEX图元数据中群码为10的数据即可。

取得纵断面线上所有高程点和横断面图元。代码如下: (SETQ ALL-DATA(SSGET \((-4 . \ (-4 . \ (-4 . \ (-4 . \))))

取得高程点和横断面图元数据之后,对数据进行区分。如果是INSERT图元,则取得其插入点XYZ坐标,存入纵断面坐标数据表(ZDM-XYZ-List)中;如果是线型图元,则存入横断面图元数据表(HDM-Entity-List)中。

求得纵、横断面的交点,并生成一个表。Autolisp给我们提供了一个求线段交点的函数(INTERS <线段1起点> <线段1终点> <线段2起点> <线段2终点> [实体相交标记]),我们就利用这个函数求得纵断面与所有横断面交点的坐标表(JD-XY-LIST)。代码如下: (setq jd-xy-list (list));_初始化交点坐标表 (setq BEI-xy-list XY-List);_生成一个备用的中线二维坐标表 (setq i 0)

(repeat (length HDM-Entity-List)

(setq dm-entity (nth i HDM-Entity-List));_取出第i+1个横断面 (setq HDM-xy-list (Q-XY-LIST dm-entity)) ;;;;Q-XY-LIST是求线状二维坐标的函数。

(setq dm-start-xy (list (car (nth 0 HDM-xy-list))(cadr (nth 0 HDM-xy-list)))) (setq dm-end-xy (list (car (nth 1 HDM-xy-list))(cadr (nth 1 HDM-xy-list)))) (setq int-bj nil);_清空交点标记

(while (and (= int-bj nil) (/= (length BEI-xy-list) 1)) (setq m-xy (nth 0 BEI-xy-list));_线段的第一个坐标

(setq n-xy (nth 1 BEI-xy-list));_线段的第二个坐标

(if(setq int-xy (inters dm-start-xy dm-end-xy m-xy n-xy t)) (setq int-bj 1)) ;_ 如果有交点,则设交点标记(int-bj)为1,用于退出循环 (setq b-xy-list (cdr b-xy-list))) ;_ 结束while (setq xy (list (car int-xy) (cadr int-xy)));_取得交点二维坐标XY (setq jd-xy-list (append jd-xy-list (list xy)));_加交点坐标到交点坐标表中 (setq i (1+ i)) );_结束 Repeat

求两个数据表,一个为输出断面电子表格所需要的数据——累距、高程、坐标表(LeiJu-GaoCheng-list);另一个为绘制断面曲线所需要的数据——累距、高差表(LJ-GC-LIST)。因为断面整体高程有高有低,所以高程轴起点一般为最小高程往下一个单位(一般为图上1cm)。生成累距、高程、坐标表的同时,如果检测到其坐标的XY包含在交点坐标表(JD-XY-LIST)中,则在图上作里程、高程的分式注记,其代码如下: (setq LeiJu-GaoCheng-list (list)) (setq LJ-GC-LIST (list))

(setq len (length ZDM-XYZ-List))

(setq org-xy (list (car (nth 0 ZDM-XYZ-List))(cadr (nth 0 ZDM-XYZ-List)))) (setq m 0) (setq LeiJu 0);_初始化累距 (repeat len

(setq xyz (nth m ZDM-XYZ-List)) (setq xy (list (car xyz)(cadr xyz)));_我们需要的是平面距离,所以需要二维坐标 (setq z (nth 2 xyz))

(setq LeiJu (+ LeiJu (distance org-xy xy))) (setq LeiJu-GaoCheng-list (append LeiJu-GaoCheng-list (list (list LeiJuz(cadr xy)(car xy)))));_endsetq

(setq LJ-GC-LIST (append LJ-GC-LIST (list (list LeiJu (- z min-gc))))) ;_min-gc为本断面中的最小高程减去一个单位的值 (if (member xy JD-XY-LIST)(ZJ-FenShi xy LeiJu z))

;_ZJ-FenShi为在图上注记交点里程、高程的函数,需要的参数为注记位置、累距、高程。

(setq org-xy xy) (setq m (1+ m)) );_endrepeat

通过以上步骤我们已经注记了纵、横断面交点,并取得了绘制纵断面曲线所需要的数据。尽管现在的AutoCAD二次开发工具中都提供了Active X,来对Excel等支持Active X的应用程序进行操作。但我们还是选择了生成中间文件的方法,这样可以减少操作系统的进程数,提高运行速度。写断面数据到文件时,第一行为断面的名称,第二行开始为累距、高程等数据,其格式为:

编号 累距 高程 X坐标 Y坐标 备注

断面数据的文件名必需有一定的规律,这样可以便于我们在Excel中按顺序的读入全部断面数据并生成表格。例如:纵断面的文件名为DM1.dm,横断面的以DM2.dm开始往下编号。

(2)绘制横断面图

绘制横断面的方法与纵断的绘制方法基本相同。我们以横断面图元表(HDM-Entity-List)的长度作为REPEAT语句的循环次数,先取出横断面线的头、尾坐标,然后通过SSGET取得横断面线上的高程数据集合,接着重复步骤(4)生成两个表,最后绘制断面曲线并写数据到中间文件。有多个横断面时,我们可以通过对上一断面的累距或高差的最大值进行按比例转换,来确定本横断面图绘制的原点,使得横断面能横向或纵向依序排列。 3、在Excel中生成断面数据表格。

strDir为存储断面数据文件的文件夹名,其代码如下: Dim dmno As Integer '定义全局变量断面号 Dim sti As Integer'定义全局变量表单号 Private Sub C1_Click() Dim strDir as String

strDir = GetSetting(\,\,\)'取得存在注册表中的断面数据文件名 dmno = 1

Let Filename$ = strDir + \(Str$(dmno)) + \Dim fileid As Integer'定义文件号

Dim linehead As String'.dm文件中的断面名称文本 Dim linedata As String'.dm文件中的断面表数据 Let sheetname = \模版\While 1

fileid = FreeFile()

Open Filename$ For Input As fileid On Error GoTo 100

Line Input #fileid,linehead

Sheets(\模版\).Copy after:=Sheets(ActiveSheet.name) ActiveSheet.name = linehead

Range(\).Value = linehead + \断面测量成果表\Let rno = 5 '起始写入数据的行号 Do Until EOF(fileid)

Line Input #fileid,linedata

'为了方便读入,我们的各项数据者是定长的

Cells(rno,1).Value = RTrim(Mid$(linedata,1,20)) Cells(rno,2).Value = RTrim(Mid$(linedata,21,20)) Cells(rno,3).Value = RTrim(Mid$(linedata,41,20)) Cells(rno,4).Value = RTrim(Mid$(linedata,61,20)) Cells(rno,5).Value = RTrim(Mid$(linedata,81,20)) Cells(rno,6).Value = RTrim(Mid$(linedata,101,20)) rno = rno + 1 Loop

ActiveSheet.PageSetup.PrintArea = Range(Cells(1,1),Cells(rno,6)) Close fileid

Kill (Filename$) dmno = dmno + 1

Filename$ = strDir+ \(Str$(dmno)) + \

Wend

100: Exit Sub End Sub

我们开发工作是基于Autocad平台,在运行Autocad后,通过菜单或命令即可打开该程序。

3 程序操作流程图

4 结束语

利用Autocad平台,采用AutoLisp和Excel中的Microsoft VBA语言技术进行简

单的二次开发,即从数据处理,直接到成果输出,实现了内业处理一体化。

AutoLisp和Microsoft VBA分别作为AutoCAD和Microsoft office二次开发的工具,具有语法简单、功能强大、易于掌握的特点,在测量内业数据处理中实现自动化,特别是处理批量数据,使工作变得简单,效率高。

【参考文献】

[1] 刘炳文,许蔓舒.Visual Basic程序设计教程.清华大学出版社

[2] 梁雪春,崔洪斌,吴义忠,曹康.Visual Lisp实用教程.人民邮电出版社