基于AutoLISP 的工程测量制图辅助软件
2015-11-26安徽省水利水电勘测设计院安徽蚌埠233000
赵 健 (安徽省水利水电勘测设计院,安徽 蚌埠 233000)
1 开发工具及软件部署
1.1 AutoLISP 简介
AutoLISP语言是嵌入在AutoCAD内部的LISP编程语言,是LISP语言与AutoCAD有机结合的产物。它可以方便调用AutoCAD的绘图命令,使设计和绘图完全溶为一体;还可以实现对AutoCAD当前数据库的直接访问、修改,为实现对屏幕图形的实时修改、交互设计、参数化设计以及在绘图领域中应用人工智能提供了方便。
AutoLISP语言继承了LISP语言擅长处理各种结构的数据表的特点,用户可以按需求来设计和使用自定义的结构类型数据。而且,AutoLISP擅长描述人机交互操作的过程,对于各种用户输入的接受、错误识别与恢复等方面的优秀功能(尤其是DCL语言加入以后),其他语言很难在此方面比及。
1.2 软件的自动加载及打包
AutoCAD在启动时会有一个自动加载的LISP程序,该程序位于CAD安装目录下的Support文件夹里,以acadxxxx.lisp的方式命名(xxxx为版本号)。用记事本打开这个文件并加入下面这条语句(vl-load-all"XZS.fas"),CAD则会在“支持文件搜索路径”所包含的文件夹里寻找“XZS.fas”并加载它(XZS.fas是笔者所编写的LISP程序)。除此之外,还需要在XZS.fas的源代码中加入下列语句,以实现自定义的菜单文件XZS.mnu和对话框控制语言文件XZS.DCL的自动加载:
(command"menuload""XZS.mnu");加载菜单
(menucmd(strcat"P"(itoa i)"=+XZS.POP1"));将菜单显示在菜单栏最后一列
(setq DCL_ID(LOAD_DIALOG"XZS.DCL"))
(NEW_DIALOG"RECT"DCL_ID)
(START_DIALOG)(UNLOAD_DIALOGDCL_ID);加载DCL
接下来,是软件安装包的制作。在本文中,安装包需完成以下任务:①在注册表中搜索AutoCAD的安装目录和版本信息;②提示用户选择需要安装的CAD平台版本;③将XZS.fas、XZS.mnu和XZS.DCL文件复制到用户所选择的CAD的Support文件夹中;④在Support目录下的acadxxxx.lsp文件中追加(vl-load-all"XZS.fas")语句。
作为一款功能强大的安装程序制作工具,Setup Factory可以实现笔者所需要的上述要求。以下是安装包制作过程中的主要操作代码:
Reg2004=Registry.GetValue(HKEY_LOCAL_MACHINE,"Software\Autodesk\AutoCAD\R16.0\ACAD-201:804","AcadLocation",false);
Path2004=String.Concat(Reg2004,"\support");
File.Copy(SessionVar.Expand("%TempLaunchFolder%\XZS.fas"),Path2004,true,true,false,true,nil);
TextFile.WriteFromString(String.Concat(Path2004,"\acad2004.lsp"),strLisp,true);
2 软件功能介绍
2.1 插入节点
在绘制线状地物,如水涯线、陡坎时,野外采集的碎部点连线后,显示的是折点棱角分明的多线段,这和实际地貌是不符的。为了尽可能还原实际地貌,我们需要对多线段进行拟合。AutoCAD提供了多种拟合方式,如果直接进行拟合操作的话,会导致线条偏离节点位置较远。我们通常的做法是在折点附近手工插入点,以减轻“脱点”现象。
以1:500地形图为例,当一条多线段折角为90°时,在距折点1m处,和多线段成20°夹角的前后位置各插入一点,再用“样条曲线”方式进行拟合,可大幅减轻“脱点”现象。随着折角逐渐增大,插入点至折点距离可适当增加,两者连线与多线段夹角则逐渐减小。
手工插点是一项繁复的工作,通过本软件的“插入节点”功能,可以让制图人员轻松完成这一步。该功能的整体思路为:先将多线段坐标写入到表lst中,然后依次计算每个折点的角度angPnt,根据地形图比例尺和angPnt再推算出插入点至节点的距离disIns1和夹角angIns1,用POLAR函数计算出插入点坐标并存储在表lstNew中,最后调用AutoCAD的command命令生成新的多线段。主要实现代码如下:
;----------计算出插入节点处角度及距离---------
(if(>angPnt pi)(setq angIns(-(*pi 2)angPnt))(setq angIns angPnt));angIns为改正为<180度角的angPnt
(if(<=angIns(/pi2))
(progn
(setq angIns1(+(/pi12)(*(/1.0 18)angIns)))
(setq disIns1(+0.4(*(/1.2 pi)angIns)))
)
(progn
(setq angIns1(-(/pi9)(*(/19.0 90)(-angIns(/pi2)))))
(setq disIns1(+1(*(/8 pi)(-angIns(/pi2)))))
)
);end if
(setq sca(getvar"ltscale"))
(if(>sca 0.5)
(setq disIns1(*(sqrt(/sca 0.5))disIns1))
)
;-----------插入新节点----------
(if( (progn (if(<(distance(nth 0 lst)(nth 1 lst))(*disIns1 2))(setq disIns1(/(distance(nth 0 lst)(nth 1 lst))3))) (setq lstNew(cons(polar(nth 0 lst)(+ang1 ang2c angIns1)disIns1)lstNew)) ) );end if (if(>angPnt pi) (progn (if(<(distance(nth 0 lst)(nth 1 lst))(*disIns1 2))(setq disIns1(/(distance(nth 0 lst)(nth 1 lst))3))) (setq lstNew(cons(polar(nth 0 lst)(+ang1(-ang2c angIns1))disIns1)lstNew)) ) );end if ;------生成新LWPOLYLINE------ (setvar"osmode"0) (setvar"cmdecho"0) (apply 'command (cons"pline"lstNew) ) (if(=isClose1) (command"c") (command"") ) 该功能可以根据特定的命名规则将地物自动连线,熟练掌握后可节省大量外业画草图及内业连线的时间。具体规则如下: ①软件对点名中地物代码相同的点进行自动连线(如果是高程点或散点应以数字开头); ②字母c表示地物闭合,z表示到该点结束,如:k1c,k2z; ③如果一个点代表两个以上地物,则其之间的分隔符以“/”表示,如:k1/g3; ④往前插入一个点以“-”表示。也可在“-”后加1~9之间的数字表示回插个数,如:k1-/g3-2。 虽然有的软件有着类似的功能,如南方CASS中的“简码识别”,不过其连线方式不够灵活。比如在测图过程中经常需要交替跑点,而“简码识别”中“N+/N-”连线方法需要在一个地物未测完之前时刻记着采集过的点数及每个点在哪个位置,这一点在实际工作中很难做到。相比之下,“编码成图”在设计时充分考虑了测图人员在跑杆时的测点顺序和点号命名习惯,使用起来更加贴合实际、灵活方便。 假设某点点名是k1-2z/g3,则在软件中的操作流程见图3。 ①将点名分隔成k1-2z和g3,存放于表lstName中,并最终获得地物代码k1,赋于变量nameCod。 ②遍历表lstLib,当其包含k1且不含有结束符(“c”或者“z”)时,返回k1后的数字“1”。“1”表示k1在表lstCor中的位置,随后将该点的坐标追加到lstCor中的1号表中。 ③若在表lstLib中未找到k1或者k1后已有结束符,则在lstLib中新增表(k1,3),在lstCor中新增3号表(k1,),然后将该点的坐标追加到lstCor中的3号表中。 ④最后当nameAll中包含“-”和结束符时,对lstCor相应表中的数据进行重新排序,将结束符写人到lstLib对应的记录中。 以下是部分实现代码: ;---------将坐标写入表lstcor中----------- (setq lstTmp(list(atof(nth 2 lstcode))(atof(nth 3 lstcode)))) (setq lstcor-new'()) (setq i01 0) (repeat(length lstcor) (if(=i01(-isFound 1)) (progn (setq lstTmp(cons lstTmp(nth(-isFound 1)lstcor))) (setq lstcor-new(cons lstTmp lstcor-new)) ) (setq lstcor-new(cons(nth i01 lstcor)lstcor-new)) ) (setq i01(+1 i01)) ) (setq lstcor(reverse lstcor-new)) ;---------当nameAll中包含“-“时部分代码----------- (if(=(length(nth(-isFound 1)lstLib))2) (progn;当nameall中不包含结束符时 (repeat(-(-(length lstcorRe)x)1) (setq lstcor-tmp(cons(nth x lstcorRe)lstcor-tmp)) (setq x(+x 1)) ) ) (progn;当nameall中包含结束符时 (setq lstLib(cons(list namecod(+(length lstLib)1))lstLib)) (setq lstadd(list namecod)) (setq isContainEnd 1) (repeat(-(-(length lstcorRe)x)1) (setq lstadd(cons(nth x lstcorRe)lstadd)) (setq x(+x 1)) ) ) ) 经笔者实践,合理利用本软件中提供的功能可以方便快速的绘制地形图,提高处理内业资料时的工作效率。相比之下,“草图法”在测点顺序过于杂乱无章和描述地物相对位置关系时有着不可替代的优越性,而该软件则在绘制较整状的带状地形图时更加高效便捷。在刚接触“编码成图”功能时建议草图和软件相结合使用,当熟练掌握其点号命名的各种技巧后,则可以有针对性的用编码替代部分草图,最终达到降低内业时间,提高工作效率的目的。2.2 编码成图
3 结 论