python3讀取autocad圖形文件.py實例
廢話不多說,看代碼吧!
'''
待完善。
此代碼實現(xiàn)了,根據(jù)標注文本的
屬性,數(shù)值,位置,及 容差,
去判斷 設計 和 實測兩圖中的同一位置的尺寸。
如果是同一位置的尺寸,則進行比較,
并把結果存成表格,到運行此代碼的當前目錄。
此代碼運行時,要讀取的 dwg文件 必須處于打開狀態(tài)。
且 不能在 移動(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():
'''
此函數(shù)用于讀取 實測圖 的尺寸標注的 屬性,尺寸,尺寸位置。
并返回結果。
目前實測圖帶屬性,對比圖不帶。
'''
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():
'''
此函數(shù)用于讀取 對比圖 的尺寸,尺寸位置。
并返回結果。
'''
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))
此函數(shù)通過 兩個標注的距離來判斷,
兩個尺寸,是否是同一位置處的尺寸。
是,return True
否,return False
tolerance,設計/實測圖的同一位置兩個尺寸標注允許的距離差。
即,在這個距離差之內(nèi),認為是同一個對象的尺寸,可以進行比對。
'''
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):
'''
此函數(shù)用于處理讀取到的原始數(shù)據(jù),
把原始數(shù)據(jù)分成三類:
長,寬,間距 三個列表如下:
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):
'''
此函數(shù)用于處理長度列表和寬度列表,
組合成一個列表,即報告中需要的數(shù)據(jù)結構。
其中,連廊只有寬度,需單獨處理。
'''
tableContents = []
tableName = '竣工建(構)筑物滿外尺寸對比表'
tableHead = ['\\', '發(fā)證長度', '實測長度', '長度差值(允許誤差值)',
'發(fā)證寬度', '實測寬度', '寬度差值(允許誤差值)'
]
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):
'''
此函數(shù)用于處理建筑物 間距尺寸。
'''
tableContents = []
tableName = '竣工建(構)筑物間距對比表'
tableHead = [
'\\', '發(fā)證間距', '實測間距',
'差值', '允許誤差值'
]
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():
'''
此函數(shù)用于處理地界特征點。
'''
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('此圖有效尺寸數(shù):', len(dmt1), ' 個')
# print(dmt1)
print()
i = input('請在CAD軟件中切換到 實測圖。切換了嗎?[Y]')
if i == '' or i.upper() == 'Y':
# dmt2, 第二次讀取的尺寸,實測尺寸。
dmt2 = getDescription_Measurement_TextPositions()
print('此圖有效尺寸數(shù):', 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('比對兩圖尺寸數(shù):', 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米內(nèi)算同一個尺寸。
main(2)
補充知識:使用python來操作autocad,并且將坐標點轉換成cad可見對象
由于工作需要,在項目中遇到一個棘手的問題,如何將(mssql)數(shù)據(jù)庫中的BLOB文件轉成cad可見圖形
(可能每個項目需求不一樣,解決方式不同)
第一步 . 需要轉換的圖形類型

第二步 . 那我們先查詢這個字段

第三步 試試將這個寫入一個文本中 看看是那種圖形 (data:image/*;base64) *號 為圖片格式后綴
1.試試用新學的python 來操作,當然java也可以
(這個鏈接數(shù)據(jù)庫,寫入某個字段的內(nèi)容就貼出來了,畢竟是做python與cad的)
2.生成后的文件內(nèi)容

3.不是我們期待的普通圖形,是cad的一些坐標點什么的,那我們就可以找到坐標點來操作
查看文本內(nèi)容后,我們看到的是開頭標識符T , TEXT , LINE , JZMJ (還有其他的圖形包含 ARC , ARRORW , PL , DIMQJ)還有一部分 就不一一寫了(主要是目前就只用到幾個常用的開頭標識符)
轉換一下(在cad命令行中輸入) 可以知道 PL LINE RULEDIM 為直線,有兩個坐標點
如: p1 = (0,0) p2 = (0,10) 就可以生成一條直線
4 . 那么從上面的內(nèi)容中可以看到,我們找到坐標點,
如: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 . 找到坐標之后發(fā)現(xiàn)一個規(guī)律 可以將這一行 截?。ā癬”),生成數(shù)組下標為 [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, '發(fā)生意外。', ('無法獲取 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)
添加文本
文本內(nèi)容,點一,字體高度
AddArc(center,radius,sDrgress,eDrgress)
添加圓弧
圓心 , 半徑 ,開始弧 , 結束弧
SaveAs(filepath ,1)
保存當前畫好的圖形
文件絕對路徑 , 后面默認寫1 不知道原因 (這方面文檔很少,所以不知道怎么查)
最后,如果有不懂得地方,或者我哪些沒有做好,都可以聯(lián)系我,感謝!
以上這篇python3讀取autocad圖形文件.py實例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Python使用Pickle庫實現(xiàn)讀寫序列操作示例
這篇文章主要介紹了Python使用Pickle庫實現(xiàn)讀寫序列操作,結合實例形式分析了pickle模塊的功能、常用函數(shù)以及序列化與反序列化相關操作技巧,需要的朋友可以參考下2018-06-06
Appium+Python自動化環(huán)境搭建實例教程
這篇文章主要介紹了Appium+Python自動化環(huán)境搭建實例教程,本文通過實例代碼圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08
Python 網(wǎng)絡編程起步(Socket發(fā)送消息)
現(xiàn)在開始學習網(wǎng)絡編程,先從簡單的UDP協(xié)議發(fā)送消息開始。我們需要有接受消息的服務端程序(Server.py)和發(fā)送消息的客戶端程序(Client)。2008-09-09
Python控制臺輸出時刷新當前行內(nèi)容而不是輸出新行的實現(xiàn)
今天小編就為大家分享一篇Python控制臺輸出時刷新當前行內(nèi)容而不是輸出新行的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02

