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抓取网页中的图片示例
Feb 28 Python
跟老齐学Python之玩转字符串(1)
Sep 14 Python
Python常用的爬虫技巧总结
Mar 28 Python
Python出现segfault错误解决方法
Apr 16 Python
python读写json文件的简单实现
Apr 11 Python
django输出html内容的实例
May 27 Python
Python装饰器简单用法实例小结
Dec 03 Python
使用Python做定时任务及时了解互联网动态
May 15 Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
Feb 11 Python
Python同时处理多个异常的方法
Jul 28 Python
matplotlib 三维图表绘制方法简介
Sep 20 Python
python pip如何手动安装二进制包
Sep 30 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
zend framework配置操作数据库实例分析
2012/12/06 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
PHP redis实现超迷你全文检索
2017/03/04 PHP
ThinkPHP3.2框架操作Redis的方法分析
2019/05/05 PHP
PHP7 其他语言层面的修改
2021/03/09 PHP
在html页面上拖放移动标签
2010/01/08 Javascript
js 处理URL实用技巧
2010/11/23 Javascript
解决Jquery load()加载GB2312页面时出现乱码的两种方案
2013/09/10 Javascript
JavaScript闭包详解
2015/02/02 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
2015/11/04 Javascript
详解angular ui-grid之过滤器设置
2017/06/07 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
2018/02/16 Javascript
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
详解关于vue2.0工程发布上线操作步骤
2018/09/27 Javascript
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
Python实现的检测web服务器健康状况的小程序
2014/09/17 Python
Python返回真假值(True or False)小技巧
2015/04/10 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
Window环境下Scrapy开发环境搭建
2018/11/18 Python
pandas的连接函数concat()函数的具体使用方法
2019/07/09 Python
python标识符命名规范原理解析
2020/01/10 Python
Python 跨.py文件调用自定义函数说明
2020/06/01 Python
Python3如何实现Win10桌面自动切换
2020/08/11 Python
Python3+Appium安装及Appium模拟微信登录方法详解
2021/02/16 Python
你应该知道的30个css选择器
2014/03/19 HTML / CSS
酒吧员工的岗位职责
2013/11/26 职场文书
物理研修随笔感言
2014/02/14 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
协议书的格式
2014/04/23 职场文书
《宿建德江》教学反思
2014/04/23 职场文书
经典演讲稿开场白
2014/08/25 职场文书
行政秘书工作自我鉴定
2014/09/15 职场文书
党员查摆剖析材料
2014/10/10 职场文书
离婚财产分配协议书
2014/10/21 职场文书
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android