废话不多说,看代码吧!
''' 待完善。 此代码实现了,根据标注文本的 属性,数值,位置,及 容差, 去判断 设计 和 实测两图中的同一位置的尺寸。 如果是同一位置的尺寸,则进行比较, 并把结果存成表格,到运行此代码的当前目录。 此代码运行时,要读取的 dwg文件 必须处于打开状态。 且 不能在 移动(pan) 模式。 启动代码: python dwg_measurements_comparison4.py [8] 其中,8代表,判定两图尺寸为同一尺寸的最大距离, 单位:米(图上单位)。自己决定具体是多少。 注意: 启动此代码后,首先要在cad软件中打开 对比图, 当该图读完后,提示切换到实测图时,请在cad软件中切换。 切换完成后,回车,即可。 包的安装: pip install pyautocad 注: 1.该操作会自动安装 comtypes模块。 2.如要使用tables 命令,要另外安装xlrd 和 tablib ''' from pyautocad import Autocad import sys from pyautocad.contrib.tables import Table import re acad = Autocad(create_if_not_exists=True) def getDescription_Measurement_TextPositions(): ''' 此函数用于读取 实测图 的尺寸标注的 属性,尺寸,尺寸位置。 并返回结果。 目前实测图带属性,对比图不带。 ''' print('正在读取 ', acad.doc.Name, ' ...') description_measurement_textPositions = [] for obj in acad.iter_objects('Dimension'): description_measurement_textPositions.append( (obj.GetXData("MyDimDist")[1][1], round(obj.Measurement,2), obj.TextPosition) ) return description_measurement_textPositions def getMeasurement_TextPositions(): ''' 此函数用于读取 对比图 的尺寸,尺寸位置。 并返回结果。 ''' print('正在读取 ', acad.doc.Name, ' ...') measurements_textPositions = [] for a in acad.iter_objects('Dimension'): measurements_textPositions.append((round(a.Measurement,2), a.TextPosition)) return measurements_textPositions def isTheSameMeasurement(point1,point2,tolerance): ''' point1, 类似这样(82.37, (81953.97462829649, 276686.2885731713, 0.0)), 82.37,代表标注的尺寸,后边代表,该尺寸在图上显示的位置坐标。 point2, 类似这样('车间二;长', 82.44, (81951.56923143109, 276679.7827104012, 0.0)) 此函数通过 两个标注的距离来判断, 两个尺寸,是否是同一位置处的尺寸。 是,return True 否,return False tolerance,设计/实测图的同一位置两个尺寸标注允许的距离差。 即,在这个距离差之内,认为是同一个对象的尺寸,可以进行比对。 ''' p1x = point1[1][0] p1y = point1[1][1] p2x = point2[2][0] p2y = point2[2][1] d = ((p1x - p2x) ** 2 + (p1y - p2y) ** 2) ** 0.5 if d < tolerance: return True else: return False def handleData(lst): ''' 此函数用于处理读取到的原始数据, 把原始数据分成三类: 长,宽,间距 三个列表如下: lengthLst,widthLst,distanceLst, 并返回。 ''' lengthLst = [] widthLst = [] distanceLst = [] for i in lst: key = i[0].split(';')[1] if key == '间距': distanceLst.append(i) elif key == '长': lengthLst.append(i) elif key == '宽': widthLst.append(i) return lengthLst,widthLst,distanceLst def handleLengthWidth(lengthLst,widthLst): ''' 此函数用于处理长度列表和宽度列表, 组合成一个列表,即报告中需要的数据结构。 其中,连廊只有宽度,需单独处理。 ''' tableContents = [] tableName = '竣工建(构)筑物满外尺寸对比表' tableHead = ['\\', '发证长度', '实测长度', '长度差值(允许误差值)', '发证宽度', '实测宽度', '宽度差值(允许误差值)' ] tableContents.append(tableHead) # 处理连廊尺寸。 for w in widthLst: keyW = w[0].split(';')[0] if re.match('连廊', keyW): w2 = [keyW] w2.extend(['---','---','---']) w2.extend(w[1:]) tableContents.append(w2) # 处理同时有长宽的尺寸。 for l in lengthLst: keyL = l[0].split(';')[0] for w in widthLst: keyW = w[0].split(';')[0] if keyL == keyW: w2 = w[1:] l[0] = l[0].split(';')[0] l.extend(w2) tableContents.append(l) break tableContents.sort() return tableName,tableContents def handleDistance(distanceLst): ''' 此函数用于处理建筑物 间距尺寸。 ''' tableContents = [] tableName = '竣工建(构)筑物间距对比表' tableHead = [ '\\', '发证间距', '实测间距', '差值', '允许误差值' ] tableContents.append(tableHead) for dl in distanceLst: dl[0] = dl[0][:-3] new = dl[-1][6:-1] dl[-1] = dl[-1][:5] dl.append(new) tableContents.append(dl) tableContents.sort() return tableName,tableContents def handleDJ(): ''' 此函数用于处理地界特征点。 ''' tableContents = [] tableName = '用地界址坐标表' tableHead = [ '点号', 'X坐标(米)', 'Y坐标(米)' ] tableContents.append(tableHead) area = 0 for obj in acad.iter_objects("PolyLine"): if obj.Layer == 'DJHX': area = '%.1f' % obj.Area t = obj.Coordinates if 0 in t: DJHX = [('%.3f' % t[i], '%.3f' % t[i+1], t[i+2]) for i in range(0,len(t),3)] else: DJHX = [('%.3f' % t[i], '%.3f' % t[i+1], 0) for i in range(0,len(t),2)] break for i in range(len(DJHX)): tableContents.append(['J' + str(i + 1), DJHX[i][1], DJHX[i][0]]) tableContents.append(['用地面积', area, '平方米']) return tableName,tableContents def write_to_table(tableName,tableContents): table = Table() for row in tableContents: table.writerow(row) table.save(tableName + '.xls', 'xls') def main(tolerance): i = input('请在CAD软件中打开 对比图。打开了吗?[Y]') if i == '' or i.upper() == 'Y': # dmt1, 第一次读取的尺寸, 设计尺寸。 dmt1 = getMeasurement_TextPositions() print('此图有效尺寸数:', len(dmt1), ' 个') # print(dmt1) print() i = input('请在CAD软件中切换到 实测图。切换了吗?[Y]') if i == '' or i.upper() == 'Y': # dmt2, 第二次读取的尺寸,实测尺寸。 dmt2 = getDescription_Measurement_TextPositions() print('此图有效尺寸数:', len(dmt2), ' 个') # print(dmt2) print() # print(dmt1,dmt2,sep='\n\n') # d_value, 存储两个同位置尺寸的 属性,设计尺寸,实测尺寸,及差值。 d_value = [] for m1 in dmt1: for m2 in dmt2: if isTheSameMeasurement(m1,m2,tolerance): d_value.append([ m2[0],'%.2f' % m1[0],'%.2f' % m2[1], '%.2f' % (m2[1] - m1[0]) + '(±' + '%.2f' % (m1[0] * 0.005) + ')' ]) break print('比对两图尺寸数:', len(d_value), ' 个') print('两图中判定为同一尺寸的容差:', tolerance, ' 米(图上单位)。') lengthLst,widthLst,distanceLst = handleData(d_value) # print(lengthLst,widthLst,distanceLst,sep='\n') tableName,tableContents = handleLengthWidth(lengthLst,widthLst) print() print(tableName) write_to_table(tableName,tableContents) tableName,tableContents = handleDistance(distanceLst) print(tableName) write_to_table(tableName,tableContents) tableName,tableContents = handleDJ() print(tableName) write_to_table(tableName,tableContents) if __name__ == '__main__': try: tolerance = sys.argv[1] main(int(tolerance)) except IndexError: # 默认两图尺寸相差2米内算同一个尺寸。 main(2)
补充知识:使用python来操作autocad,并且将坐标点转换成cad可见对象
由于工作需要,在项目中遇到一个棘手的问题,如何将(mssql)数据库中的BLOB文件转成cad可见图形
(可能每个项目需求不一样,解决方式不同)
第一步 . 需要转换的图形类型
第二步 . 那我们先查询这个字段
第三步 试试将这个写入一个文本中 看看是那种图形 (data:image/*;base64) *号 为图片格式后缀
1.试试用新学的python 来操作,当然java也可以
(这个链接数据库,写入某个字段的内容就贴出来了,毕竟是做python与cad的)
2.生成后的文件内容
3.不是我们期待的普通图形,是cad的一些坐标点什么的,那我们就可以找到坐标点来操作
查看文本内容后,我们看到的是开头标识符T , TEXT , LINE , JZMJ (还有其他的图形包含 ARC , ARRORW , PL , DIMQJ)还有一部分 就不一一写了(主要是目前就只用到几个常用的开头标识符)
转换一下(在cad命令行中输入) 可以知道 PL LINE RULEDIM 为直线,有两个坐标点
如: p1 = (0,0) p2 = (0,10) 就可以生成一条直线
4 . 那么从上面的内容中可以看到,我们找到坐标点,
如:LINE_宋体_1_120_-1__18_1_0__clBlack_0_0_3_13580_-7520_7280_-7520_0_0_13580_-7520_
p1 = (13580,-7520)
p2 = (7280,-7520)
5 . 找到坐标之后发现一个规律 可以将这一行 截取(“_”),生成数组下标为 [14] ,[15], [16], [17]
第四步 打开CAD (任意版本的cad都可以)
(个人使用的是2017版)
第五步 使用python操作CAD
1.首先导入pyautocad库,并且看看自己python的comtypes是否安装
2.先插入一条测试线 看看能否成功
from pyautocad import Autocad,APoint p1 = APoint(10,20) p2 = APoint(10,80) acad = Autocad(create_if_not_exists = True) acad.model.AddLine(p1,p2)
3.提示错误:
_ctypes.COMError: (-2147352567, '发生意外。', ('无法获取 Document 对象', 'AutoCAD', 'C:\\Program Files\\Autodesk\\AutoCAD 2017\\HELP\\OLE_ERR.CHM', -2145320900, None))
4.这个错误一般是cad没有新建一个窗口
5.新建一个画图窗口就可以运行上面测试代码了
6.介绍几个常用命令:
AddLine(p1,p2)
添加直线
点一,点二
AddText(text,p1,fontSize)
添加文本
文本内容,点一,字体高度
AddArc(center,radius,sDrgress,eDrgress)
添加圆弧
圆心 , 半径 ,开始弧 , 结束弧
SaveAs(filepath ,1)
保存当前画好的图形
文件绝对路径 , 后面默认写1 不知道原因 (这方面文档很少,所以不知道怎么查)
最后,如果有不懂得地方,或者我哪些没有做好,都可以联系我,感谢!
以上这篇python3读取autocad图形文件.py实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。