作為苦逼的測繪工作者,免不了和AutoCAD及其衆多二次開發版打交道,在這類軟體中,有時需要進行一些工作量巨大的操作,手工做是不可能手工做的,Lisp又不會寫,怎麼辦呢?(衆所周知,AutoCAD提供有AutoLisp來實作程式設計,但是并不簡單易學,反正本人是不會2333),現在我們使用Python中提供的pyautocad包就能夠簡單地操作CAD啦。
背景:
前段時間部落客遇到一個很蛋疼的問題,拿到一幅地形圖,裡面的等高線密密麻麻(由于地形圖涉密,就不給大家看了),然而并不需要這麼多條等高線,因為非常不利于後續導入其他軟體裡面處理,會造成很大性能開銷,甚至導緻軟體崩潰,到這裡有同學可能會問:這個用南方CASS處理一下不就好了嗎?是的,CASS的确提供處理等高線功能,但是這幅圖并不是CASS畫出來的,也就是說要在CASS中當做等高線處理,必須先刷屬性,可是經部落客嘗試,可能因為資料量太大,一刷屬性整個軟體就崩潰掉了,是以這個辦法顯然行不通(在這裡不得不吐槽南方CASS性能有點堪憂),而原生CAD裡又沒有專門提供等高線的處理功能,是以我們還是得自己動手,豐衣足食。
環境:
Python 3.6.1
AutoCAD 2010
走你!
第一步當然是安裝pyautocad這個庫,推薦用pip方式安裝,如下:
pip install pyautocad
回車,稍等片刻後搞定
然後根據pyautocad的官方文檔,需要用如下代碼來初始化:
from pyautocad import Autocad
acad = Autocad(create_if_not_exists=True)
acad.prompt("Hello, Autocad from Python\n")#這句話作用是在CAD控制台裡輸出Hello, Autocad from Python,用于測試對CAD的控制是否成功
然後我們可以列印目前文檔名稱:
print (acad.doc.Name)
我們的目的是對等高線進行過濾,保留指定等高距的等高線,是以必須知道圖面上等高線最大高程和最小高程
temp_height = list()
for dgx in acad.iter_objects('Spline'):#Spline表示樣條曲線
temp_height.append(dgx.ControlPoints[2])#ControlPoints是曲線上的錨點,這句話作用是把曲線上所有錨點的Z坐标提取出來
maximum = max(temp_height)
minimum = min(temp_height)
接下來可以根據想要的等高距,确定處于哪些高程的等高線需要保留
height_arr = list()
for height in range(int(minimum),int(maximum)+1,250):#這裡的等高距設定的250米,可以根據自己需要修改
height_arr.append(height)
然後周遊所有等高線,檢查每一條等高線是否需要保留,将不需要保留的删除(在這個過程中,可能會由于謎之原因抛出異常,初步猜測是資料量過大,是以搞個異常處理,然後遞歸即可)
def delete():
try:
for dgx in acad.iter_objects('Spline'):
if(int(dgx.ControlPoints[2]) not in height_arr):
dgx.Delete()
except:
delete()
細心的同學會發現,我直接調用了dgx的Delete方法,沒錯,pyautocad已經提供了很多方法和屬性,我們可以通過
print(dir(dgx))
來把這些屬性或者方法列印出來檢視,例如對于樣條曲線,有如下方法\屬性:
AddFitPoint
AddRef
Application
Area
ArrayPolar
ArrayRectangular
Closed
ControlPoints
Copy
Database
Degree
Delete
DeleteFitPoint
Document
ElevateOrder
EndTangent
EntityName
EntityType
Erase
FitPoints
FitTolerance
GetBoundingBox
GetControlPoint
GetExtensionDictionary
GetFitPoint
GetIDsOfNames
GetTypeInfo
GetTypeInfoCount
GetWeight
GetXData
Handle
HasExtensionDictionary
Highlight
Hyperlinks
IntersectWith
Invoke
IsPeriodic
IsPlanar
IsRational
Knots
Layer
Linetype
LinetypeScale
Lineweight
Material
Mirror
Mirror3D
Move
NumberOfControlPoints
NumberOfFitPoints
ObjectID
ObjectID32
ObjectName
Offset
OwnerID
OwnerID32
PlotStyleName
PurgeFitData
QueryInterface
Release
Reverse
Rotate
Rotate3D
ScaleEntity
SetControlPoint
SetFitPoint
SetWeight
SetXData
StartTangent
TransformBy
TrueColor
Update
Visible
Weights
_AddRef
_GetIDsOfNames
_GetTypeInfo
_IAcadEntity__com_ArrayPolar
_IAcadEntity__com_ArrayRectangular
_IAcadEntity__com_Copy
_IAcadEntity__com_GetBoundingBox
_IAcadEntity__com_Highlight
_IAcadEntity__com_IntersectWith
_IAcadEntity__com_Mirror
_IAcadEntity__com_Mirror3D
_IAcadEntity__com_Move
_IAcadEntity__com_Rotate
_IAcadEntity__com_Rotate3D
_IAcadEntity__com_ScaleEntity
_IAcadEntity__com_TransformBy
_IAcadEntity__com_Update
_IAcadEntity__com__get_EntityName
_IAcadEntity__com__get_EntityType
_IAcadEntity__com__get_Hyperlinks
_IAcadEntity__com__get_Layer
_IAcadEntity__com__get_Linetype
_IAcadEntity__com__get_LinetypeScale
_IAcadEntity__com__get_Lineweight
_IAcadEntity__com__get_Material
_IAcadEntity__com__get_PlotStyleName
_IAcadEntity__com__get_TrueColor
_IAcadEntity__com__get_Visible
_IAcadEntity__com__get_color
_IAcadEntity__com__set_Layer
_IAcadEntity__com__set_Linetype
_IAcadEntity__com__set_LinetypeScale
_IAcadEntity__com__set_Lineweight
_IAcadEntity__com__set_Material
_IAcadEntity__com__set_PlotStyleName
_IAcadEntity__com__set_TrueColor
_IAcadEntity__com__set_Visible
_IAcadEntity__com__set_color
_IAcadObject__com_Delete
_IAcadObject__com_Erase
_IAcadObject__com_GetExtensionDictionary
_IAcadObject__com_GetXData
_IAcadObject__com_SetXData
_IAcadObject__com__get_Application
_IAcadObject__com__get_Database
_IAcadObject__com__get_Document
_IAcadObject__com__get_Handle
_IAcadObject__com__get_HasExtensionDictionary
_IAcadObject__com__get_ObjectID
_IAcadObject__com__get_ObjectID32
_IAcadObject__com__get_ObjectName
_IAcadObject__com__get_OwnerID
_IAcadObject__com__get_OwnerID32
_IAcadSpline__com_AddFitPoint
_IAcadSpline__com_DeleteFitPoint
_IAcadSpline__com_ElevateOrder
_IAcadSpline__com_GetControlPoint
_IAcadSpline__com_GetFitPoint
_IAcadSpline__com_GetWeight
_IAcadSpline__com_Offset
_IAcadSpline__com_PurgeFitData
_IAcadSpline__com_Reverse
_IAcadSpline__com_SetControlPoint
_IAcadSpline__com_SetFitPoint
_IAcadSpline__com_SetWeight
_IAcadSpline__com__get_Area
_IAcadSpline__com__get_Closed
_IAcadSpline__com__get_ControlPoints
_IAcadSpline__com__get_Degree
_IAcadSpline__com__get_EndTangent
_IAcadSpline__com__get_FitPoints
_IAcadSpline__com__get_FitTolerance
_IAcadSpline__com__get_IsPeriodic
_IAcadSpline__com__get_IsPlanar
_IAcadSpline__com__get_IsRational
_IAcadSpline__com__get_Knots
_IAcadSpline__com__get_NumberOfControlPoints
_IAcadSpline__com__get_NumberOfFitPoints
_IAcadSpline__com__get_StartTangent
_IAcadSpline__com__get_Weights
_IAcadSpline__com__set_ControlPoints
_IAcadSpline__com__set_EndTangent
_IAcadSpline__com__set_FitPoints
_IAcadSpline__com__set_FitTolerance
_IAcadSpline__com__set_Knots
_IAcadSpline__com__set_StartTangent
_IAcadSpline__com__set_Weights
_IDispatch__com_GetIDsOfNames
_IDispatch__com_GetTypeInfo
_IDispatch__com_GetTypeInfoCount
_IDispatch__com_Invoke
_IUnknown__com_AddRef
_IUnknown__com_QueryInterface
_IUnknown__com_Release
_Invoke
_QueryInterface
_Release
__bool__
__class__
__cmp__
__com_interface__
__ctypes_from_outparam__
__del__
__delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattr__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__map_case__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__setstate__
__sizeof__
__str__
__subclasshook__
__weakref__
_b_base_
_b_needsfree_
_case_insensitive_
_compointer_base__get_value
_idlflags_
_iid_
_invoke
_methods_
_needs_com_addref_
_objects
_type_
color
from_param
value
至于以上屬性\方法的各自作用,就留給大家自己去研究、測試啦。關于pyautocad的其他用法,可以通路pyautocad的官網http://pyautocad.readthedocs.io/en/latest/翻閱文檔(雖然官網的文檔也很少2333,但也聊勝于無吧),最後附上源代碼:
from pyautocad import Autocad
acad = Autocad(create_if_not_exists=True)
acad.prompt("Hello, Autocad from Python\n")
print (acad.doc.Name)
temp_height = list()
for dgx in acad.iter_objects('Spline'):
temp_height.append(dgx.ControlPoints[2])
maximum = max(temp_height)
minimum = min(temp_height)
height_arr = list()
for height in range(int(minimum),int(maximum)+1,250):
height_arr.append(height)
print('開始删除')
def delete():
try:
for dgx in acad.iter_objects('Spline'):
if(int(dgx.ControlPoints[2]) not in height_arr):
dgx.Delete()
except:
delete()
delete()
print('OK')