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

废话不多说,看代码吧!

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

此代码运行时,要读取的 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实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 利用python控制Autocad:pyautocad方式

    发现pyautocad模块:可以用python控制autocad的包.今天把文档中的重点内容摘录出来,以后绘图.计算大工程量.或者识别施工图的时候时候也许可以用到. 一.连接cad pyautocad包可以用任何版本的cad进行操作,实际上接口都是一样的.文档中首先给出连接cad的代码: from pyautocad import Autocad, APoint acad = Autocad(create_if_not_exists=True) acad.prompt("Hello, Autoc

  • 利用Python自动化操作AutoCAD的实现

    1 Python自动绘图 在这里我主要运用了pyautocad库进行AutoCAD的自动化操作,pyautocad是一款功能非常强大的AutoCAD操作处理库,可以实现Python自动绘图.CAD图像对象读取.对象属性修改等操作. from pyautocad import Autocad,APoint # 连接及库导入 acad = Autocad(create_if_not_exists = True) acad.prompt("Hello! Autocad from Python.&quo

  • Python实现读取txt文件中的数据并绘制出图形操作示例

    本文实例讲述了Python实现读取txt文件中的数据并绘制出图形操作.分享给大家供大家参考,具体如下: 下面的是某一文本文件中的数据. 6.1101,17.592 5.5277,9.1302 8.5186,13.662 7.0032,11.854 5.8598,6.8233 8.3829,11.886 7.4764,4.3483 8.5781,12 6.4862,6.5987 5.0546,3.8166 5.7107,3.2522 14.164,15.505 5.734,3.1551 8.408

  • Python3读取文件常用方法实例分析

    本文实例讲述了Python3读取文件常用方法.分享给大家供大家参考.具体如下: ''''' Created on Dec 17, 2012 读取文件 @author: liury_lab ''' # 最方便的方法是一次性读取文件中的所有内容放到一个大字符串中: all_the_text = open('d:/text.txt').read() print(all_the_text) all_the_data = open('d:/data.txt', 'rb').read() print(all

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

    废话不多说,看代码吧! ''' 待完善. 此代码实现了,根据标注文本的 属性,数值,位置,及 容差, 去判断 设计 和 实测两图中的同一位置的尺寸. 如果是同一位置的尺寸,则进行比较, 并把结果存成表格,到运行此代码的当前目录. 此代码运行时,要读取的 dwg文件 必须处于打开状态. 且 不能在 移动(pan) 模式. 启动代码: python dwg_measurements_comparison4.py [8] 其中,8代表,判定两图尺寸为同一尺寸的最大距离, 单位:米(图上单位).自己决定

  • python3读取csv和xlsx文件的实例

    基于win10系统,python3.6 读取csv 使用csv函数包,安装 pip install csv 使用方法: import csv def fileload(filename = '待读取.csv'): csvfile = open(filename, encoding = 'utf-8') data = csv.reader(csvfile) dataset = [] for line in data: dataset.append(line) csvfile.close() ret

  • python3读取csv文件任意行列代码实例

    这篇文章主要介绍了python3读取csv文件任意行列代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 读取每一行 reader = csv.reader(f) 此时reader返回的值是csv文件中每行的列表,将每行读取的值作为列表返回 #读取每一行 filename='D:\\file_information1.csv' import csv with open(filename,newline = '',encoding = 'ut

  • Python3读取zip文件信息的方法

    本文实例讲述了Python3读取zip文件信息的方法.分享给大家供大家参考.具体实现方法如下: 该程序接受一个字符串,其内容是一个zip文件,需要读取这个zip文件中的信息 import zipfile class zip_string(zipfile.ZipFile): def __init__(self, data_string): zipfile.ZipFile.__init__(self, data_string) zstr = zip_string('d:/中华十大名帖.zip') f

  • Python3读取UTF-8文件及统计文件行数的方法

    本文实例讲述了Python3读取UTF-8文件及统计文件行数的方法.分享给大家供大家参考.具体实现方法如下: ''''' Created on Dec 21, 2012 Python 读取UTF-8文件 统计文件的行数目 @author: liury_lab ''' # -*- coding: utf-8 -*- import codecs # 对较小的文件,最简单的方法是将文件读入一个行列表中, # 然后计算列表的长度即可 count = len(codecs.open('d:/FreakOu

  • 使用python3+xlrd解析Excel的实例

    实例如下所示: # -*- coding: utf-8 -*- import xlrd def open_excel(file = 'file.xls'):#打开要解析的Excel文件 try: data = xlrd.open_workbook(file) return data except Exception as e: print(e) def excel_by_index(file = 'file.xls', colindex = 0, by_index = 0):#按表的索引读取 d

  • python3.7简单的爬虫实例详解

    python3.7简单的爬虫,具体代码如下所示: #https://www.runoob.com/w3cnote/python-spider-intro.html #Python 爬虫介绍 import urllib.parse import urllib.request from http import cookiejar url = "http://www.baidu.com" response1 = urllib.request.urlopen(url) print("

  • python3 enum模块的应用实例详解

    一.枚举与字典类型 字典类型的缺点: 1.值可变 2.没有防止相同标签的功能 枚举的特点: 1.枚举类的值不可以被外界更改 2.不能存在相同的标签,但允许不同标签存在相同的枚举值,即后者相当于前者的别名 3.枚举值可以是任意类型 4.枚举标签尽量用大写 from enum import Enum #普通类 class dict(): green = 1 green = 2 red = 3 dict.red = 4 print(dict.red) >>> 4 class VIP(Enum)

  • 通过python3实现投票功能代码实例

    这篇文章主要介绍了通过python3实现投票功能代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 import urllib.request # cd C:\Python36-32\Scripts # pip install BeautifulSoup from bs4 import BeautifulSoup def vote(get_url, post_url, option): # 访问投票页面,拿到cookie resp = ur

随机推荐