python3讀取autocad圖形文件.py實(shí)例
廢話不多說,看代碼吧!
''' 待完善。 此代碼實(shí)現(xiàn)了,根據(jù)標(biāo)注文本的 屬性,數(shù)值,位置,及 容差, 去判斷 設(shè)計(jì) 和 實(shí)測兩圖中的同一位置的尺寸。 如果是同一位置的尺寸,則進(jìn)行比較, 并把結(jié)果存成表格,到運(yùn)行此代碼的當(dāng)前目錄。 此代碼運(yùn)行時(shí),要讀取的 dwg文件 必須處于打開狀態(tài)。 且 不能在 移動(dòng)(pan) 模式。 啟動(dòng)代碼: python dwg_measurements_comparison4.py [8] 其中,8代表,判定兩圖尺寸為同一尺寸的最大距離, 單位:米(圖上單位)。自己決定具體是多少。 注意: 啟動(dòng)此代碼后,首先要在cad軟件中打開 對(duì)比圖, 當(dāng)該圖讀完后,提示切換到實(shí)測圖時(shí),請(qǐng)?jiān)赾ad軟件中切換。 切換完成后,回車,即可。 包的安裝: pip install pyautocad 注: 1.該操作會(huì)自動(dòng)安裝 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ù)用于讀取 實(shí)測圖 的尺寸標(biāo)注的 屬性,尺寸,尺寸位置。 并返回結(jié)果。 目前實(shí)測圖帶屬性,對(duì)比圖不帶。 ''' 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ù)用于讀取 對(duì)比圖 的尺寸,尺寸位置。 并返回結(jié)果。 ''' 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,代表標(biāo)注的尺寸,后邊代表,該尺寸在圖上顯示的位置坐標(biāo)。 point2, 類似這樣('車間二;長', 82.44, (81951.56923143109, 276679.7827104012, 0.0)) 此函數(shù)通過 兩個(gè)標(biāo)注的距離來判斷, 兩個(gè)尺寸,是否是同一位置處的尺寸。 是,return True 否,return False tolerance,設(shè)計(jì)/實(shí)測圖的同一位置兩個(gè)尺寸標(biāo)注允許的距離差。 即,在這個(gè)距離差之內(nèi),認(rèn)為是同一個(gè)對(duì)象的尺寸,可以進(jìn)行比對(duì)。 ''' 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ù)分成三類: 長,寬,間距 三個(gè)列表如下: 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ù)用于處理長度列表和寬度列表, 組合成一個(gè)列表,即報(bào)告中需要的數(shù)據(jù)結(jié)構(gòu)。 其中,連廊只有寬度,需單獨(dú)處理。 ''' tableContents = [] tableName = '竣工建(構(gòu))筑物滿外尺寸對(duì)比表' tableHead = ['\\', '發(fā)證長度', '實(shí)測長度', '長度差值(允許誤差值)', '發(fā)證寬度', '實(shí)測寬度', '寬度差值(允許誤差值)' ] 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) # 處理同時(shí)有長寬的尺寸。 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 = '竣工建(構(gòu))筑物間距對(duì)比表' tableHead = [ '\\', '發(fā)證間距', '實(shí)測間距', '差值', '允許誤差值' ] 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ù)用于處理地界特征點(diǎn)。 ''' tableContents = [] tableName = '用地界址坐標(biāo)表' tableHead = [ '點(diǎn)號(hào)', 'X坐標(biāo)(米)', 'Y坐標(biāo)(米)' ] 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('請(qǐng)?jiān)贑AD軟件中打開 對(duì)比圖。打開了嗎?[Y]') if i == '' or i.upper() == 'Y': # dmt1, 第一次讀取的尺寸, 設(shè)計(jì)尺寸。 dmt1 = getMeasurement_TextPositions() print('此圖有效尺寸數(shù):', len(dmt1), ' 個(gè)') # print(dmt1) print() i = input('請(qǐng)?jiān)贑AD軟件中切換到 實(shí)測圖。切換了嗎?[Y]') if i == '' or i.upper() == 'Y': # dmt2, 第二次讀取的尺寸,實(shí)測尺寸。 dmt2 = getDescription_Measurement_TextPositions() print('此圖有效尺寸數(shù):', len(dmt2), ' 個(gè)') # print(dmt2) print() # print(dmt1,dmt2,sep='\n\n') # d_value, 存儲(chǔ)兩個(gè)同位置尺寸的 屬性,設(shè)計(jì)尺寸,實(shí)測尺寸,及差值。 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('比對(duì)兩圖尺寸數(shù):', len(d_value), ' 個(gè)') 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: # 默認(rèn)兩圖尺寸相差2米內(nèi)算同一個(gè)尺寸。 main(2)
補(bǔ)充知識(shí):使用python來操作autocad,并且將坐標(biāo)點(diǎn)轉(zhuǎn)換成cad可見對(duì)象
由于工作需要,在項(xiàng)目中遇到一個(gè)棘手的問題,如何將(mssql)數(shù)據(jù)庫中的BLOB文件轉(zhuǎn)成cad可見圖形
(可能每個(gè)項(xiàng)目需求不一樣,解決方式不同)
第一步 . 需要轉(zhuǎn)換的圖形類型
第二步 . 那我們先查詢這個(gè)字段
第三步 試試將這個(gè)寫入一個(gè)文本中 看看是那種圖形 (data:image/*;base64) *號(hào) 為圖片格式后綴
1.試試用新學(xué)的python 來操作,當(dāng)然java也可以
(這個(gè)鏈接數(shù)據(jù)庫,寫入某個(gè)字段的內(nèi)容就貼出來了,畢竟是做python與cad的)
2.生成后的文件內(nèi)容
3.不是我們期待的普通圖形,是cad的一些坐標(biāo)點(diǎn)什么的,那我們就可以找到坐標(biāo)點(diǎn)來操作
查看文本內(nèi)容后,我們看到的是開頭標(biāo)識(shí)符T , TEXT , LINE , JZMJ (還有其他的圖形包含 ARC , ARRORW , PL , DIMQJ)還有一部分 就不一一寫了(主要是目前就只用到幾個(gè)常用的開頭標(biāo)識(shí)符)
轉(zhuǎn)換一下(在cad命令行中輸入) 可以知道 PL LINE RULEDIM 為直線,有兩個(gè)坐標(biāo)點(diǎn)
如: p1 = (0,0) p2 = (0,10) 就可以生成一條直線
4 . 那么從上面的內(nèi)容中可以看到,我們找到坐標(biāo)點(diǎn),
如: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 . 找到坐標(biāo)之后發(fā)現(xiàn)一個(gè)規(guī)律 可以將這一行 截?。ā癬”),生成數(shù)組下標(biāo)為 [14] ,[15], [16], [17]
第四步 打開CAD (任意版本的cad都可以)
(個(gè)人使用的是2017版)
第五步 使用python操作CAD
1.首先導(dǎo)入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.提示錯(cuò)誤:
_ctypes.COMError: (-2147352567, '發(fā)生意外。', ('無法獲取 Document 對(duì)象', 'AutoCAD', 'C:\\Program Files\\Autodesk\\AutoCAD 2017\\HELP\\OLE_ERR.CHM', -2145320900, None))
4.這個(gè)錯(cuò)誤一般是cad沒有新建一個(gè)窗口
5.新建一個(gè)畫圖窗口就可以運(yùn)行上面測試代碼了
6.介紹幾個(gè)常用命令:
AddLine(p1,p2)
添加直線
點(diǎn)一,點(diǎn)二
AddText(text,p1,fontSize)
添加文本
文本內(nèi)容,點(diǎn)一,字體高度
AddArc(center,radius,sDrgress,eDrgress)
添加圓弧
圓心 , 半徑 ,開始弧 , 結(jié)束弧
SaveAs(filepath ,1)
保存當(dāng)前畫好的圖形
文件絕對(duì)路徑 , 后面默認(rèn)寫1 不知道原因 (這方面文檔很少,所以不知道怎么查)
最后,如果有不懂得地方,或者我哪些沒有做好,都可以聯(lián)系我,感謝!
以上這篇python3讀取autocad圖形文件.py實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
表格梳理解析python內(nèi)置時(shí)間模塊看完就懂
這篇文章主要介紹了python內(nèi)置的時(shí)間模塊,本文用表格方式清晰的對(duì)Python內(nèi)置時(shí)間模塊進(jìn)行語法及用法的梳理解析,有需要的朋友建議收藏參考2021-10-10Python使用Pickle庫實(shí)現(xiàn)讀寫序列操作示例
這篇文章主要介紹了Python使用Pickle庫實(shí)現(xiàn)讀寫序列操作,結(jié)合實(shí)例形式分析了pickle模塊的功能、常用函數(shù)以及序列化與反序列化相關(guān)操作技巧,需要的朋友可以參考下2018-06-06Python實(shí)現(xiàn)自動(dòng)化發(fā)送郵件
大家好,本篇文章主要講的是Python實(shí)現(xiàn)自動(dòng)化發(fā)送郵件,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01Appium+Python自動(dòng)化環(huán)境搭建實(shí)例教程
這篇文章主要介紹了Appium+Python自動(dòng)化環(huán)境搭建實(shí)例教程,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08用Pycharm實(shí)現(xiàn)鼠標(biāo)滾輪控制字體大小的方法
今天小編就為大家分享一篇用Pycharm實(shí)現(xiàn)鼠標(biāo)滾輪控制字體大小的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python 網(wǎng)絡(luò)編程起步(Socket發(fā)送消息)
現(xiàn)在開始學(xué)習(xí)網(wǎng)絡(luò)編程,先從簡單的UDP協(xié)議發(fā)送消息開始。我們需要有接受消息的服務(wù)端程序(Server.py)和發(fā)送消息的客戶端程序(Client)。2008-09-09Python控制臺(tái)輸出時(shí)刷新當(dāng)前行內(nèi)容而不是輸出新行的實(shí)現(xiàn)
今天小編就為大家分享一篇Python控制臺(tái)輸出時(shí)刷新當(dāng)前行內(nèi)容而不是輸出新行的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02