AUTOLISP实现SCS编码与南方CASS编码的转换
2016-08-22陈培龙
■陈培龙
(漳州市测绘设计研究院福建漳州363000)
AUTOLISP实现SCS编码与南方CASS编码的转换
■陈培龙
(漳州市测绘设计研究院福建漳州363000)
地形图的编码在各种软件中存在的方式各不一样,由于地形图成图软件的更换,地形图编码也需要进行转换。本文主要论述利用Autolisp语言进行二次开发,实现SCS地形图编码转换到南方CASS地形图编码的一种方法。
SCS编码 CASS编码 编码转换
1 引言
近年来随着计算机技术的进步,测绘行业的计算机参与也在发生着日新月异的变化,特别是随着Autocad软件的更新,各种成图软件的发展变得更加快速。笔者所在单位一直在使用广州SCS成图软件,但随着SCS软件停止更新以及南方CASS的普及和发展,在去年笔者的单位也对成图软件进行了全面的更新。由于两种软件的编码方式存在较大的差异,地形图地物编码在软件中存在的方式和编码采用的规范,都存在较大的区别,造成大量已有图形需要由SCS编码格式转换为南方CASS格式。限于文章篇幅,本文主要讲述如何使用Autolisp程序语言,实现SCS图形中的建筑物批量转换成南方CASS编码。
2 SCS编码与CASS编码的区别
SCS中建筑物的编码存储于建筑轮廓线的厚度值属性中,建筑物的层数仅依靠对应的文字来体现,在编码中无法直接识别。通过查询建筑物轮廓线的图元组码可以发现其厚度值存储于39组码中,譬如砖的编码为2110300,则其对应的建筑物轮廓线的组码可以查询到(39.2110300)的属性(如图1)。南方CASS的编码方式与SCS有较大的区别,在南方CASS中建筑物的编码也是存储建筑物轮廓线中,但区别于SCS的是南方CASS编码不是存储于厚度值中,而是存储于一个名为SOUTH的扩展属性组中。该属性组不仅保存了建筑物的编码,而且存储了该建筑物的层数(地上建筑层数为正值,地下为负值)。譬如砼的编码为141111,层数为1,则其对应的建筑物轮廓线的Cad组码可以查询到(~3(SOUTH(1000.141111) (1040.1.0))))(如图2)。两种编码方式存在较大的不同,SCS直接存储于厚度值中,能够非常方便的进行修改,但是也比较容易出错;比如在缩放图形的过程中,编码值也会随之变换;CASS的编码方式只能通过特定的程序进行读取和修改,易用性较差,但是不会引起误操作,安全性高很多,而且在编码中直接存了建筑物层数,在后期如果需要对地形图的建筑物面积进行计算时,能够非常方便的使用。
由于成图平台的更换,大量的地形图需要由SCS编码转换为南方CASS编码,对于明确对应的编码只需根据编码值批量转换即可,但是建筑物中,由于SCS的编码中没有表示建筑物的层数,所以无法直接转换为对应的南方CASS编码,人工操作只能一个一个进行,过程繁琐而且耗费大量的人力,出错率很高。故笔者使用LISP语言编写了一个程序,能够直接根据建筑物轮廓线识别其对应的文字注记从而分辨出该建筑物层数,并直接根据南方CASS编码的结构模式,写入对应的南方CASS编码,从而实现两种编码的转换。
图1 SCS编码的CAD组码
图2 CASS编码的CAD组码
3 基本流程
在图形转换前,先将需要转换的建筑物注记文字图层修改为建筑物标注图层,选取JMD图层中所有闭合的建筑物轮廓线,然后一一读取多段线的端点坐标,组成一个列表,再根据这个表使用SSGET函数分别选取多段线内的注记文字,然后根据文字中的内容识别出该建筑物的层数。然后构建类似于(~3(SOUTH(1000.141121) (1040.2.0))))格式的编码值,将其存入该建筑物轮廓线中,实现编码的转换。
4 开发思路及程序实现
4.1批量归层建筑文字
由于时间跨度较多,地形图上的很多数据并不是非常的规范,建筑物文字注记的图层也比较多而且比较乱。由于识别建筑物层数主要的依据就是建筑的文字注记,因此为确保建筑物轮廓线与其文字注记的一一对应关系,首先需要把建筑物注记文字都归类到相同的图层中,命名该图层为建筑物标注图层。在编码转换的过程中,只需搜索图面上文字基点在建筑物轮廓线内并且在建筑物标注图层内的文字进行分析即可,大大提高程序的准确性和执行速度。为了快速的实现文字的图层归类,笔者提供了jjgc命令,程序首先读取一个预先编辑好的对照文件,程序自动搜索文本中定义的文字,并将其归类入文本的设定好的图层中。
4.2自动生成南方CASS编码
程序运行前,先根据南方CASS编码规则,创建一个列表如下:
(("砼"141111)("砖"141121)("铁"141131)("钢"141141)(" 木"141151)("混"141161)("简 "141200)("建"141300)("破" 141400)))
表中存储了各种建筑物材质及对应的南方CASS编码。执行时,根据建筑物轮廓线一一搜索在线内且图层为建筑物标注图层的文字,将这些文字图元放入一个选择集中。当选择集的数目为0或者大于1时,将该轮廓线放入无法识别的建筑物轮廓线图层中;如果选择集的数目为1,程序就将其作为该轮廓线的文字标注进行编码匹配。匹配时首先使用Substr函数,截取注记的第一个文字,并在列表中搜索相应的编码,根据返回的值,构建一个类似于(~3 (SOUTH(1000.141121)(1040.2.0))))格式的列表,使用Append函数将该属性加入到建筑物轮廓线中,最后将该文字放入JMD图层并将其与建筑物轮廓线使用Group命令编组,即可实现编码的自动转换。
主要代码如下:
(defun c:crsx(/wlist listcz ss i en)
(if(not(tblsearch"layer""识别后的房屋注记"))(command"lay~er""n""识别后的房屋注记"""));如果不存在图层则新建识别后的房屋注记图层
(if(not(tblsearch"layer""无法识别"))(command"layer""n""无法识别"""));如果不存在图层则新建无法识别图层
(setq oldpk(getvar"PICKSTYLE")(setvar"PICKSTYLE"0) (vl~load~com)
(regapp"SOUTH")(setq wlist'())
(setq listcz'(("砼"141111)("砖"141121)("铁"141131)("钢" 141141)("木"141151)("混"141161)("简"141200)("建"141300)(" 破"141400)));创建建筑物注记文字及南方CASS编码对照列表
(setq ss(ssget"x"'((~4."
(if ss(prong(setq i 0)
(repeat(sslength ss);对每个建筑物轮廓线一一处理
(setq en(Vlax~Ename~>Vla~Object(ssname ss i)))
(setq listzb(Vlax~Get en'Coordinates))(setq j 0)(setq listzbx'())
(while( (setq listzbx(append listzbx(list(list(nth j listzb)(nth(+j 1)listzb))) )) (if(="AcDb2dPolyline"(Vlax~Get en'ObjectName))(setq j(1+j)));构建坐标表 (setq j(+j 2))) (setq ss1(ssget"cp"listzbx'((0."TEXT")(8."建筑物标注图层") )));选择轮廓线内的文字 (setq ss2(ssadd)) (if ss1(fenxiwenzi)(command"change"ss"p""la""无法识别" ""));如果建筑物轮廓线内有建筑物标注文字则进行识别,否则将建筑物轮廓线放入无法识别图层 (setq i(1+i)))))(setvar"PICKSTYLE"oldpk) (defun fenxiwenzi();开始建筑物材质、层数识别 (setq cengshu"1") (setq nr(cdr(assoc 1(entget(ssname ss1 0))))) (if(=(strlen nr)2)(setq caizhi(substr nr 1 2)));识别材质 (if(=(strlen nr)3)(progn(setq caizhi(substr nr 1 2))(setq cengshu (substr nr 3 1))));识别层数 (if(>(strlen nr)3)(progn(setq caizhi(substr nr 1 2)) (if(and(>(ascii(substr nr 4 1))47)(<(ascii(substr nr 4 1))59)) (setq cengshu(substr nr 3 2)) (setq cengshu(substr nr 3 1))))) (if(assoc caizhi listcz)(progn (setq listkzsx(list~3(list"SOUTH"(cons 1000(itoa(nth 0(cdr (assoc caizhi listcz)))))(cons 1040(atof cengshu)))));根据材质从列表中找到对应的南方CASS编码 (setq endata(entget(ssname ss i))) (setq ss2(ssadd(ssname ss i)ss2)) (setq endata(append endata(list listkzsx))) (entmod endata);将建筑轮廓线加入南方CASS编码 (if(/=cengshu"1")(progn (command"layer""s""识别后的房屋注记""");将识别的文字注记修改图层 (setq enwz(ssname ss1 0)) (setq endatawz(entget enwz)) (setq ptwz(polar(polar(cdr(assoc 10 endatawz))0 0.7232)(/pi 2) 0.25)) (setq oldys(getvar"textstyle")) (setvar"textstyle""细等线体") (command"text""j""mr"ptwz"0.5"""caizhi);生成南方格式的文字注记 (wenzisx(entlast))(setq ss2(ssadd(entlast)ss2))(setvar"textstyle" oldys) (setq oldys(getvar"textstyle"))(setvar"textstyle""正等线体") (command"text""j""ml"(polar ptwz 0 0.25)"0.4"""cengshu) (wenzisx(entlast)) (setq ss2(ssadd(entlast)ss2))(setvar"textstyle"oldys)) (prong(command"layer""s""识别后的房屋注记""") (setq enwz(ssname ss1 0))(setq endatawz(entget enwz)) (setq ptwz(polar(polar(cdr(assoc 10 endatawz))0 0.7232)(/pi 2) 0.25)) (setq oldys(getvar"textstyle"))(setvar"textstyle""细等线体") (command"text""j""mr"ptwz"0.5"""caizhi)(wenzisx(entlast)) (setq ss2(ssadd(entlast)ss2))(setvar"textstyle"oldys))) (command"group""c""*"""ss2"");将文字注记及轮廓线编组 (command"erase"(ssname ss1 0)"")))) (defun wenzisx(enwzsx)(setq endatawzsx(entget enwzsx)) (setq listwzsx(list~3(list"SOUTH"(cons 1000"141111~1"))));将建筑文字注记加入南方CASS编码 (setq endatawzsx(append endatawzsx(list listwzsx)))(entmod endatawzsx)) 通过笔者的方法,能够实现地形图SCS编码与南方CASS编码的快速转换。由于两种编码方式的不同,在地形图转换时会产生大量的需要人工干预的工作。通过本文描述的办法,能够快速、准确的将地形图的建筑编码转换为南方CASS编码,转换的速度快、准确率高,大大提高了工作效率,节省了人力物力。 [1]AutoCAD 2004帮助:开发者文档 [R]. [2]任航科.LISP语言在测绘作业中的应用 [J].城市勘测,2011(1):110~112. [3]朱虹.浅谈Autocad与一些常用软件的结合运用 [J].科技转让集锦,2010(2). P694[文献码]B 1000~405X(2016)~4~476~25 结语