基于VBA 的线路纵断面图的自动绘制
2010-01-01邱荣茂王大鸣张德莹
邱荣茂, 王大鸣, 张 涛, 张德莹
(1. 石家庄铁道学院土木工程分院,河北 石家庄 050043; 2. 石家庄铁道学院机械工程分院,河北 石家庄 050043; 3. 同济大学土木工程学院建筑工程系虚拟建筑教研室,上海 200092)
1 概 述
线路纵断面图包括图样和资料表两部分,图样包括地面纵断面线、设计路肩线以及桥涵、隧道、车站、水准点等构造物的标识等内容;资料表包括线路平面、里程桩号、地面高程、设计坡度、路肩高程、工程地质特征等[1-2]。图1 是某铁路线路的一段纵断面图。
由于线路纵断面图包含的内容较多,手工绘图或者直接用AutoCAD 命令逐步绘制的效率很低,工作量极大,需要进行大量繁复的操作,非常容易出错,而且绘图精度不高。本文介绍利用VBA 对AutoCAD 进行自主定制,从而实现自动绘制线路纵断面图的方法。
图1 线路纵断面图实例
2 线路纵断面图的数据组织
线路纵断面图是线路设计的最终成果,在纵断面设计过程中已经得到了有关的设计数据,例如,不同里程的地面高程、路肩高程、设计坡度以及桥、涵等构筑物的结构类型等,所有这些设计数据都与里程有关。从便于对数据进行处理的角度出发,可将纵断面图的设计数据组织成以里程为主数据的Excel 数据表。以图1 为例,可以组织成下面的4 个表(表1~表4)。
在表3 中,第六列是根据桥涵的不同类型创建的带有属性的图块的块名,第四列表示桥涵的结构类型。对于大中桥有可能采用两种不同类型的梁,此时第四列为梁一的类型特征,第五列为梁二的类型特征;若只有一种梁,则第五列为空。
表1 里程-地面高程、路肩高程
表2 里程-设计坡度
表3 里程-桥涵
表4 里程-平面曲线
3 AutoCAD VBA 和Excel 之间的交互
3.1 AutoCAD VBA 对Excel 的引用[3]
进入VBA 集成开发环境,选择“工具”→“引用”菜单项,打开如图2 所示的对话框,钩选Microsoft Excel 11.0 Object Library(Excel 类型库,其版本与计算机上安装的Office 版本有关,11.0 是Office 2003 对应的版本)、Microsoft Visual Basic for Applications Extensibility 5.3(VBA 类型库)两项。
3.2 从Excel 表中读取数据
在引用了Excel 和VBA 类型库后,就可以编写VBA 代码对Excel 数据表进行访问。
首先声明一个指定类ID 的对象变量,并用CreateObject 函数创建下面Microsoft Excel 引用:
在 CreateObject 函数创建并返回一个对Microsoft Excel 对象的引用后,可以用集合Workbooks 的Open 方法打开一个Excel 文档,其位置就是Excel 数据表所在位置。例如,在上面创建Microsoft Excel 引用后欲打开绝对路径为“F:数据汇总.xls”的工作簿文件(假设该文件中包含上述4 个Excel 数据表),可以运用下面的语句:
ExcelApp.Workbooks.Open “F: 数 据 汇总.xls”
图2 引用Excel 类型库和VBA IDE 类型库
要访问已经打开的工作簿中的工作表可以使用工作簿的Sheets 属性,例如下面代码将打开当前活动工作簿“F:数据汇总.xls”中名为“里程-地面高程、路肩高程”的工作表,并赋予对象变量ExcelSheet:
Dim ExcelSheet As Excel.Worksheet
Set ExcelSheet = ExcelApp.ActiveWorkbook. Sheets("里程-地面高程、路肩高程")
最后用ExcelSheet 的Cells 属性从打开的工作表中读取指定的单元格的数据。例如:
ExcelSheet.Cells(i, j).value 可获得Excel 的“里程-地面高程、路肩高程”表第i 行第j 列的单元格的值。利用读出的数据,AutoCAD 就可以在绘图窗口中绘图。
4 线路纵断面图构成要素的数字分析及VBA 实现
4.1 线路纵断面示意图
线路纵断面图的上半部为线路纵断面示意图,表示线路纵断面概貌和沿线建筑物特征。细线表示地面线,粗线表示路肩线。线路上相应的里程位置应该标出大小桥涵、中间站和立体交叉等图形符号。
4.1.1 地面线及路肩线
地面线和路肩线只是高程不同,绘制的方法相同,用AutoCAD 中的多段线来绘制,可以实现地面线和路肩线的连贯和一致,便于管理和修改。
在当前AutoCAD 文档的模型空间中创建二维多段线的方法为:
Set plineObj=ThisDrawing.ModelSpace. AddLightWeightPolyline(points)
其中plineObj 为所创建的二维多段线的对象变量,points 为存储二维多段线顶点二维坐标的数组名,它所含有的坐标值个数必须为偶数且至少为4 个(即两个顶点)。
在这里不是把构成二维多段线的所有顶点坐标一次性放入points 数组,而是采用了向多段线添加顶点的方法AddVertex[4]:
plineObj.AddVertex VertexNumber, newVertex
newVertex 为存储了新加入顶点二维坐标值的数组,VertexNumber 是新加入顶点在整个多段线顶点顺序数列中的号码,以初始点为0、累计递增所得。
4.1.2 桥涵的标识与大、中桥示意图
(1) 桥、涵的标识
桥、涵的标识采用AutoCAD 属性块的方式插入。
首先定义如图3 所示的几种类型的图块,分别代表立体交叉(如框架涵)、涵洞(包括圆涵和盖板涵)、大中桥,每种图块都包含中间的图素和两侧的属性,左侧的属性代表桥梁或涵洞的类型特征,右侧的属性代表该涵洞的里程标记(离开百米桩的距离)或桥梁的名称和里程;由于有些大、中桥采用两种不同类型的梁,所以统一在图素的左侧定义两个属性,第一个代表梁1 的类型特征,第二个代表梁2 的类型特征。如果只有一种类型的梁,则左侧第二个属性(梁2 的类型特征)为空。
图3 带属性的图块
上述图块在插入时,它们的插入点的横、纵坐标可分别从它们的里程、路肩高程得到。
1) VBA 在AutoCAD 中插入图块的方法
Set objBlkRef = ThisDrawing.ModelSpace. InsertBlock(BlkInsertPnt, BlkName, 1, 1, 1, 0)
其中BlkInsertPnt 为保存插入点三维坐标的数组名,BlkName 为所要插入的块名(表3 中第六列的数据),后面4 个常数分别为X、Y、Z 向的比例因子和图块插入时的旋转角度。
2) 取得图块属性,然后更改图块属性值
varAttributes = objBlkRef.GetAttributes
用图块对象的GetAttributes 方法获得插入图块的属性,varAttributes 是用于存储图块objBlkRef 属性的变体数组。
接着就可以逐个更改属性值:
varAttributes(0).textstring = “+” & excelsheet. Cells(i , 3)
varAttributes(1).textstring = excelsheet.Cells (i , 4)
若插入的图块名为“DZHQ”,则
varAttributes(0).textstring = excelsheet.Cells (i , 7)
varAttributes(2).textstring = excelsheet.Cells (i , 5)
(2) 大中桥示意图
大中桥示意图的绘制比标识要复杂些。Excel数据表“里程-桥涵表”只是给出了大中桥的中心里程和桥长,当需要绘制大中桥的前后桥台时需要计算出它们各自的里程,而“里程-桥涵表”数据表里并不能正好设有此里程,从而也并不能得出桥台插入点的高程,并且桥梁的上下承结构需要在前后桥台之间绘制距桥面一定距离的桥面平行线,此平行线两个端点高程的获得存在同样的问题。
绘制桥台的方法如下:
1) 中心里程增减一半的桥长即可得出前后桥台的里程。
2) 在绘制路肩线的数据表里搜索比前桥台插入里程稍大的百米桩号i1和比后桥台插入里程稍小的百米桩号i2。
3) 从这两个百米桩号即可得到前后桥台的近似高程,其精度已足够满足绘图要求。
4) 利用得到的前后桥台里程和高程,绘制前后桥台。
桥面平行线两个端点的里程和前后桥台的里程一致,而两个端点的高程需要将桥台上端点的高程同时向下(或上)移动少量距离(约1~1.5m);桥面平行线的绘制可根据i1和i2的关系分为3 种情况:① i1<i2:此情况如图4(a)所示。首先需要连接前端点和i1处、后端点和i2处的桥面平行线,最后用和绘制路肩线同样的方法补充出从i1到i2的桥面平行线;② i1=i2和i1>i2:此两种情况分别如图4(b)、图4(c)所示。只需要连接前端点和后端点(只是统一地前端点取i2处的高程、后端点取i1处的高程)即可。
图4 桥台与百米桩的3 种相对位置
(3) 桥涵标识符号的挪动
当前后两个标识符号的插入点距离较近时,前后标识符号的显示会相互影响,因此需要将标识符号挪动一定距离,如图5 所示。方法是:
先从理论插入点引出一条折线,向后面牵引一个适当距离,然后以此处作为图块的真正插入点,和其它地方一样正常插入,即可实现标识符号的挪动。
为了图形绘制的紧凑,挪动的距离可按下列的方法计算:
L=n×字高×1.2-d
其中 n 为前后两个图形符号之间描述文字行数(有些大中桥采用两种类型的梁架设,这时描述文字为3 行),其值等于属性个数;d 为前后两个标识符号的理论插入点间的距离。
4.2 线路资料和数据
线路纵断面图的下半部为线路资料和数据,自下而上顺序有:线路平面、里程桩号、地面高程、设计坡度、路肩高程、工程地质特征等栏目。其中,地面高程和路肩高程实现绘制的方法雷同,而工程地质和它们的标记方法也基本一致,均是书写文本,而文本的内容就是Excel 数据表中的数据(因为篇幅限制,本文未给出地质特征的Excel 数据表)。例如,书写地面高程、路肩高程所需要的数据就是表1 中的第二、三列数据;表中的第一列(里程)数据既是横坐标,要书写的里程桩号文本也可从中稍加处理而得到。下面主要分析线路平面示意图和设计坡度的实现方法。
图5 桥涵标识符号的挪动
4.2.1 线路平面示意图
如图6,线路平面示意图主要由左曲线、右曲线、夹直线、里程标记、曲线要素等组成,它们的绘图数据来自“里程-平面曲线”表。
图6 线路平面示意图
(1) 缓圆点和圆缓点里程的确定
缓圆点的里程=曲线起点里程+缓和曲线长度l。
圆缓点的里程=曲线终点里程–缓和曲线长度l。
(2) 里程标记
因为夹直线均在左曲线或右曲线之间,所以左曲线或右曲线的终点便是夹直线的起点,夹直线的终点便是左曲线或右曲线的起点,不论左曲线、右曲线还是夹直线,它们交界处(缓直点或直缓点)均需要绘制比里程标记稍长的竖向短线,它们的长度均一致,在竖线的左侧要标注该点的里程标记(该点到百米标的距离且字头向左)。因此,要截取Excel 数据表里完整里程数的后4位,并换算单位成m。其实现的VBA 代码如下:
textstring =Format_
(Val(Right(Format(excelsheet.Cells(i , 1).Value, "0.00000"), 4)) * 0.01, "00.00")
1) 用Format(excelsheet.Cells(i , 1).Value, "0.00000")将取出的单元格数值统一成5 位小数的千米数。
2) 在其中取右边后4 位用Right(…, 4),显然此时这4 个数字的单位已经变成了cm 。
3) 变换单位成m,需要将上边的数缩小0.01倍。
4) 显示成小数点前后均为2 位的形式用Format 函数实现:Format(…, "00.00")。
然后,即可在缓直点(或圆直点)及直缓点(或直圆点)处标记里程,应用添加文字的方法
Txtpt 为文字插入点坐标数组,25000 规定了字高。
接着用Rotation 方法将它们逆时针旋转π/2: textObj.Rotation = Atn(1) * 2
Atn(1)是1 的反正切值,即π/4,所以上式将得到π/2 的精确值。
(3) 曲线要素
曲线要素包括转向角(α)、曲率半径(R)、缓和曲线长(l)、切线长(T)和曲线长(L)等。它们均是直接从Excel 数据表读出,可以逐个用添加文字的方法将其绘出。但为了省略每次均为它们独立设置文字位置的麻烦,本程序的实现依然采用插入图块的方法,只不过这个图块不含有任何图形元素,只含有由文本组成的块属性。各文本属性在图块中的显示位置设置好以后,只需定位好该图块的插入点,然后更改属性即可。
4.2.2 设计坡度
只需将前后两个变坡点连线即可得坡度线。变坡点的x 坐标可由里程得到,y 坐标则固定在上下两条水平线上。在变坡点处需要设置和平面曲线一样的短竖线,并标记变坡点里程,所以实现的方法也一样,但需要注意的是紧跟在平坡后面的变坡点的标记不能和其它变坡点一样标记在竖线的左侧,应该调整到右侧,否则其显示会与坡度线重叠。
坡度线的上方应显示坡度值(以‰为单位);坡度线的下方应显示其坡长。为了使整个标记显示完整而匀称,平坡的坡度和坡长可显示在该段坡度线的中部上侧和下侧;上坡的坡度显示在该段坡度线的上方中部偏左位置,坡长显示在该段坡度线的下方中部偏右位置;下坡的坡度显示在该段坡度线的上方中部偏右位置,坡长标记显示在该段坡度线的下方中部偏左位置。
5 结 束 语
(1) 根据上述方法研制开发的线路纵断面图自动绘图软件,已经用于朔黄铁路竣工图详细纵断面图的绘制,用户反映良好;本文图1 就是用所开发的程序自动绘制的。
(2) 由于篇幅所限,本文只对线路纵断面图中的主要要素进行较详细的分析并给出VBA实现方法,还有一些要素(如水准点、断链、车站等的标识,这些要素在纵断面图中所占的比重较小)本文未作介绍,但绘制的方法与桥涵标识的绘制类似。
[1] 杨春风. 道路工程[M]. 北京: 中国建材工业出版社, 2000. 34-50.
[2] 张新来. 工程制图(第2 版)[M]. 北京: 中国铁道出版社, 2001. 224-226.
[3] 张 帆, 郑立楷, 卢择临, 等. AutoCAD VBA 二次开发教程[M]. 北京: 清华大学出版社, 2006. 313-316.
[4] 王 钰. 用VBA 开发AutoCAD 2000 应用程序[M]. 北京: 人民邮电出版社, 1999. 153-155.
[5] 潘学英. 北京铁路局京九线纵断面绘图软件的研制与应用[J]. 铁路航测, 2001, 4l(2): 32-33.
[6] 王永辉, 胡青泥, 李红彩. AutoCAD 二次开发方法的研究[J]. 计算机系统应用, 2007, (3): 94-96, 100.
[7] 张 锋, 陈爱萍. AutoCAD 二次开发环境的探讨[J]. 机械设计与制造, 2005, (9): 125-127.