劉勝華++徐衛(wèi)兵
摘 要:DXF格式文件是傳統(tǒng)圖形開發(fā)中最常用的繪圖交換文件,具有開放的數(shù)據(jù)結(jié)構(gòu)。針對(duì)內(nèi)業(yè)數(shù)據(jù)處理中常遇到的從圖上快速提取點(diǎn)、線坐標(biāo)、高程等屬性數(shù)據(jù)的問題,通過DXF格式文件的編程操作,是高效解決問題的一種方法。文章簡(jiǎn)要介紹了DXF格式交換文件的結(jié)構(gòu),詳細(xì)分析了實(shí)體段(ENTITIES)組碼與組值的含義,用VB6.0給出了一個(gè)通用的DXF文件讀寫的編程方案。
關(guān)鍵詞:AutoCAD DXF格式 組碼 組值 DXF文件讀寫
中圖分類號(hào):TP31 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2017)04(a)-0015-03
DXF(Drawing Exchange Format繪圖交換文件)是Autodesk公司開發(fā)的用于AutoCAD與其它軟件之間進(jìn)行CAD數(shù)據(jù)交換的文件格式,是AutoCAD圖形文件中所包含的全部信息的標(biāo)記數(shù)據(jù)的一種表示方法。DXF是一種開放的矢量數(shù)據(jù)格式,可以分為兩類:ASCII格式和二進(jìn)制格式;ASCII具有可讀性好,但占有空間較大;二進(jìn)制格式占有空間小、讀取速度快。由于Autocad現(xiàn)在是最流行的cad系統(tǒng),DXF也被廣泛使用,成為事實(shí)上的標(biāo)準(zhǔn)。絕大多數(shù)CAD系統(tǒng)都能讀入或輸出DXF文件。
1 DXF文件結(jié)構(gòu)
通過DxfOut命令輸出DXF文件時(shí),使用“DXF選項(xiàng)”可控制DXF文件的格式是ASCII格式還是BINARY格式,ASCII格式DXF文件是最常用的,具有可讀性好,易于編程開發(fā)的特點(diǎn),文中“DXF文件”表示ASCII DXF文件。
DXF文件的結(jié)構(gòu)雖看來繁雜,本質(zhì)上是有配對(duì)的組碼(group code)和組值(group vaule)依次排列組織成段。在DXF文件中,每個(gè)組碼和值都各占一行。
完整的DXF文件由七個(gè)段(SECTION)組成。每個(gè)段由一行組碼0及一行字符串SECTION開始,緊接著是組碼2及一行表示段名稱的字符串(例如HADER)。段的結(jié)束由一行組碼0及一行表示該段結(jié)束的字符串ENDSEC。這些段中的內(nèi)容由對(duì)象或圖元組成,而這些對(duì)象或圖元由標(biāo)志它們屬性的組碼和組值組成。整個(gè)文件以一行組碼0及一行EOF結(jié)束。DXF文件完整的結(jié)構(gòu)如下:
(1)標(biāo)題段(HEADER):記錄AutoCAD系統(tǒng)的所有標(biāo)題變量的當(dāng)前值或當(dāng)前狀態(tài)。每個(gè)參數(shù)都包含一個(gè)變量名稱及其關(guān)聯(lián)的值。
(2)類段(CLASSES):包括應(yīng)用程序定義的類的信息,這些實(shí)例將顯示在BLOCKS、ENTITIES以及OBJECTS段的數(shù)據(jù)中,類定義在類的層次結(jié)構(gòu)中是固定不變的。
(3)表段(TABLES):包含以下符號(hào)表的定義,每個(gè)表又包含可變數(shù)目的表項(xiàng)。
APPID(應(yīng)用程序標(biāo)識(shí)表)
BLOCK_RECORD(塊參照表)
DIMSTYLE(標(biāo)注樣式表)
LAYER(圖層表)
LTYPE(線型表)
STYLE(文字樣式表)
UCS(用戶坐標(biāo)系表)
VIEW(視圖表)
VPORT(視口配置表)
(4)塊段(BLOCK):記錄了所用塊的塊名,當(dāng)前圖層層名、塊的種類、塊的插入基點(diǎn)及組成該塊的所有成員。塊的種類分為圖形塊、帶有屬性的塊和無名塊3種。
(5)實(shí)體段(ENTITIES):記錄了每個(gè)實(shí)體的名稱、坐標(biāo)、所在圖層及其名字、線型、顏色等。
(6)物體段(OBJECTS):記錄非圖形對(duì)象的數(shù)據(jù),供 AutoLISP 以及ObjectARX應(yīng)用程序所使用。
(7)文件結(jié)束段(EOF of FILE)DXF文件的結(jié)束標(biāo)志。
2 DXF文件組碼與組值
一個(gè)DXF文件由若干個(gè)組構(gòu)成,每個(gè)組占兩行:第一行為組的代碼;第二行為組值。組代碼相當(dāng)于數(shù)據(jù)類型的代碼,它由CAD圖形系統(tǒng)所規(guī)定,而組值為具體的數(shù)值,二者結(jié)合起來表示一個(gè)數(shù)據(jù)的含義和值。例如:代碼10代表一個(gè)點(diǎn)的X坐標(biāo),占一行;而緊隨的第二行3456234.23則表示該點(diǎn)X坐標(biāo)的具體數(shù)值。
(1)組代碼和組值的類型組代碼為一個(gè)非負(fù)的不超過三位的整數(shù),而組值由組代碼的類型決定。例如:
代碼0~9組值類型為字符型。
代碼10~59組值類型為實(shí)型。
代碼60~79組值類型為整型。
(2)組代碼的含義每個(gè)組代碼均有規(guī)定的含義,有些代碼含義是固定的,而有些組代碼則因應(yīng)用場(chǎng)合不同而有多個(gè)含義,應(yīng)具體分析?,F(xiàn)將他們的含義舉例介紹如下。
0:表示一個(gè)事物的開始,如一個(gè)塊、表、圖層、實(shí)體等。
1:字符型數(shù)據(jù)的值,如TEXT的字符串、文件名、屬性值等。
2:一個(gè)事物的名字,如段、表、塊、線型、視圖等的名字。
3~5:字符型數(shù)據(jù)的值,如文件名、線型說明等。
6:線型名(固定類型)。
8:圖層名(固定類型)。
實(shí)體的坐標(biāo)與相應(yīng)的組代碼10~18、20~28、30~38的用法應(yīng)根據(jù)實(shí)體所用到點(diǎn)的數(shù)量,按組代碼個(gè)位的0、1、2、……的順序使用。例如:LINE的起點(diǎn)組代碼為10、20、30,而11、21、31為其終點(diǎn)。其他類似。
3 用VB6.0讀寫DXF
DXF文件的結(jié)構(gòu)相當(dāng)復(fù)雜,完整讀取DXF文件也是一項(xiàng)異常繁瑣的工程。在實(shí)際應(yīng)用中,為了提取圖形的實(shí)體信息(如點(diǎn)的坐標(biāo)、高程),可以省略DXF文件中的許多段,只要獲取ENTITIES段中對(duì)應(yīng)的圖元信息,進(jìn)行點(diǎn)、線、文字等實(shí)體坐標(biāo)的提取。
4 DXF TO DAT程序?qū)嵗?/p>
下面是以VB6.0為開發(fā)平臺(tái),編寫的讀DXF文件輸出DAT文件的程序?qū)嵗?
Dim A As String, B As String, i As Double, kff As Boolean '定義變量
DatName = Text2 'DAT文件
DxfName = Text1 'DXF文件
Szfw = Val(Text4.Text) '取值范圍
If Val(Text5.Text) = 0 Then
Xsw = "0"
Else
For J = 1 To Val(Text5.Text)
Xsw = Xsw & "0"
Next J
End If '小數(shù)位
If InStr(Text3.Text, "默認(rèn)") Then LLay = "" Else LLay = UCase(Trim(Text3.Text))
'圖層控制
If DatName = "" Or DxfName = "" Then
MsgBox "對(duì)不起,你必須要先選擇文件后才能運(yùn)行" & Chr(13) & Chr(10) & "請(qǐng)重新選擇文件"
Else
On Error Resume Next
Open Text1.Text For Input As #1
Open Text2.Text For Output As #2
If Err.Number = 53 Then GoTo R053
If Err.Number = 76 Then GoTo R076
FLG1 = 0: FLG2 = 0: FLG3 = 0
Do While Not (EOF(1))
If FLG1 = 0 And FLG2 = 0 And FLG3 = 0 Then
Line Input #1, A
Line Input #1, B
If Val(A) = 2 And UCase(B) = LBolck Then
FLG1 = 1: FLG2 = 0: FLG3 = 0
Else
FLG1 = 0: FLG2 = 0: FLG3 = 0
End If
End If
'-----------------------------------BLOCK
If FLG1 = 1 And FLG2 = 1 And FLG3 = 0 Then
Line Input #1, A
Line Input #1, B
If LLay = "" Then KKM = InStr(UCase(B), LLay) Else KKM = (UCase(B) = LLay)
If Val(A) = 8 And KKM And InStr(UCase(B), "ENDSEC") = 0 Then
FF = FF + 1: LA(FF) = B: FLG1 = 1: FLG2 = 1: FLG3 = 1
ElseIf Val(A) = 8 And KKM = 0 And InStr(UCase(B), "ENDSEC") = 0 Then
FLG1 = 1: FLG2 = 0: FLG3 = 0
Else
FLG1 = 1: FLG2 = 1: FLG3 = 0
End If
End If
'------------------------------------Layer
If FLG1 = 1 And FLG2 = 1 And FLG3 = 1 Then
Line Input #1, A
Line Input #1, B
If Val(A) = 10 And Val(B) > Szfw Or Val(A) = 11 And Val(B) > Szfw Or Val(A) = 12 And Val(B) > Szfw Or Val(A) = 13 And Val(B) > Szfw Then
i = i + 1: Y(i) = Val(B): PPK(i) = PD(LIN) & LIN & "."
ElseIf Val(A) = 20 And Val(B) > Szfw Or Val(A) = 21 And Val(B) > Szfw Or Val(A) = 22 And Val(B) > Szfw Or Val(A) = 23 And Val(B) > Szfw Then
X(i) = Val(B)
ElseIf A = GcDm Or Val(A) = 30 Or Val(A) = 31 Or Val(A) = 32 Or Val(A) = 33 Then
HH(i) = Val(B)
ElseIf Val(A) = 0 And InStr(UCase(B), LFlg) And InStr(UCase(B), "ENDSEC") = 0 Then
LIN = LIN + 1: PD(LIN) = B: FLG1 = 1: FLG2 = 1: FLG3 = 0
ElseIf Val(A) = 0 And InStr(UCase(B), LFlg) = 0 And InStr(UCase(B), "ENDSEC") = 0 Then
FLG1 = 1: FLG2 = 0: FLG3 = 0
ElseIf Val(A) = 0 And InStr(UCase(B), "ENDSEC") Then
Exit Do
Else
FLG1 = 1: FLG2 = 1: FLG3 = 1
End If
End If
Loop
Close #1
'------------------------------------讀XYH
5 運(yùn)行
輸出dxf文件后,運(yùn)行程序界面如下:
輸入圖層名稱:控制是讀出單一圖層(如HI)的實(shí)體對(duì)象還是全部圖層的實(shí)體對(duì)象(默認(rèn)值A(chǔ)LL)。
讀取實(shí)體類型:控制是讀出單一的點(diǎn)(POINT)對(duì)象、線(LINE)對(duì)象……還是全部(ALL)對(duì)象的坐標(biāo)。
6 結(jié)語
在現(xiàn)實(shí)測(cè)量中,從圖上取點(diǎn)、線的坐標(biāo)是內(nèi)業(yè)成圖中經(jīng)常遇到的事情。目前的成圖軟件大多是基于AutoCAD為平臺(tái)開發(fā)的,而AutoDXF文件作為通用的數(shù)據(jù)交換格式,編程可以大大提高數(shù)據(jù)轉(zhuǎn)換的效率,希望該例對(duì)工作中遇到的類似事情有所借鑒作用。
參考文獻(xiàn)
[1] 羅卓書.AutoCAD2000中文版基礎(chǔ)培訓(xùn)教程[M].北京:電子工業(yè)出版社,2000.
[2] 唐學(xué)忠.Visual Basic程序設(shè)計(jì)教程[M].中國電力出版社,2002.
[3] 王玉琨.CAD二次開發(fā)技術(shù)及其工程應(yīng)用[M].清華大學(xué)出版社,2008.