python3读取autocad图形文件.py实例


Posted in Python onJune 05, 2020

废话不多说,看代码吧!

'''
待完善。
此代码实现了,根据标注文本的
属性,数值,位置,及 容差,
去判断 设计 和 实测两图中的同一位置的尺寸。
如果是同一位置的尺寸,则进行比较,
并把结果存成表格,到运行此代码的当前目录。

此代码运行时,要读取的 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可见图形

(可能每个项目需求不一样,解决方式不同)

第一步 . 需要转换的图形类型

python3读取autocad图形文件.py实例

第二步 . 那我们先查询这个字段

python3读取autocad图形文件.py实例

第三步 试试将这个写入一个文本中 看看是那种图形 (data:image/*;base64) *号 为图片格式后缀

1.试试用新学的python 来操作,当然java也可以

(这个链接数据库,写入某个字段的内容就贴出来了,毕竟是做python与cad的)

2.生成后的文件内容

python3读取autocad图形文件.py实例

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都可以)

python3读取autocad图形文件.py实例

(个人使用的是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没有新建一个窗口

python3读取autocad图形文件.py实例

5.新建一个画图窗口就可以运行上面测试代码了

6.介绍几个常用命令:

AddLine(p1,p2)

添加直线

点一,点二

AddText(text,p1,fontSize)

添加文本

文本内容,点一,字体高度

AddArc(center,radius,sDrgress,eDrgress)

添加圆弧

圆心 , 半径 ,开始弧 , 结束弧

SaveAs(filepath ,1)

保存当前画好的图形

文件绝对路径 , 后面默认写1 不知道原因 (这方面文档很少,所以不知道怎么查)

最后,如果有不懂得地方,或者我哪些没有做好,都可以联系我,感谢!

以上这篇python3读取autocad图形文件.py实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python检测某个变量是否有定义的方法
May 20 Python
Python编码爬坑指南(必看)
Jun 10 Python
Python实现繁?转为简体的方法示例
Dec 18 Python
python科学计算之narray对象用法
Nov 25 Python
Python imageio读取视频并进行编解码详解
Dec 10 Python
Python request使用方法及问题总结
Apr 26 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
python基本算法之实现归并排序(Merge sort)
Sep 01 Python
安装不同版本的tensorflow与models方法实现
Feb 20 Python
Python import模块的缓存问题解决方案
Jun 02 Python
python cv2图像质量压缩的算法示例
Jun 04 Python
Python实现单例模式的5种方法
Jun 15 Python
Python实现加密接口测试方法步骤详解
Jun 05 #Python
基于python 将列表作为参数传入函数时的测试与理解
Jun 05 #Python
python 引用传递和值传递详解(实参,形参)
Jun 05 #Python
Python检测端口IP字符串是否合法
Jun 05 #Python
Python如何基于Tesseract实现识别文字功能
Jun 05 #Python
如何导出python安装的所有模块名称和版本号到文件中
Jun 05 #Python
在python中list作函数形参,防止被实参修改的实现方法
Jun 05 #Python
You might like
isset和empty的区别
2007/01/15 PHP
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
php中输出json对象的值(实现方法)
2018/03/07 PHP
php中上传文件的的解决方案
2018/09/25 PHP
JavaScript 学习笔记(五)
2009/12/31 Javascript
JS面向对象编程之对象使用分析
2010/08/19 Javascript
Jquery 一次处理多个ajax请求的代码
2011/09/02 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
js模仿php中strtotime()与date()函数实现方法
2015/08/11 Javascript
Java Mybatis框架入门基础教程
2015/09/21 Javascript
Bootstrap每天必学之标签与徽章
2015/11/27 Javascript
Angularjs中的事件广播 —全面解析$broadcast,$emit,$on
2016/05/17 Javascript
vue.js开发环境搭建教程
2017/05/04 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
vue-cli + sass 的正确打开方式图文详解
2017/10/27 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
2018/06/24 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
微信小程序实现传递多个参数与事件处理
2019/08/12 Javascript
使用Vue实现一个树组件的示例
2020/11/06 Javascript
python基础教程之实现石头剪刀布游戏示例
2014/02/11 Python
Python操作MySQL简单实现方法
2015/01/26 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
python 实现简易的记事本
2020/11/30 Python
澳大利亚最便宜的网上药房:Chemist Warehouse
2020/01/30 全球购物
什么是反射
2012/03/17 面试题
小学生自我评价范文
2014/01/25 职场文书
教师个人读书活动总结
2014/07/08 职场文书
公司离职证明标准范本
2014/10/05 职场文书
平安建设汇报材料
2014/12/29 职场文书
2016年班主任培训心得体会
2016/01/07 职场文书
2016党员读书思廉心得体会
2016/01/23 职场文书
2016年“我们的节日·中秋节”活动总结
2016/04/05 职场文书
防止web项目中的SQL注入
2021/12/06 MySQL
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
Android自定义双向滑动控件
2022/04/19 Java/Android