劉學杰,張福利
(河南省中緯測繪規劃信息工程有限公司,河南 焦作 454000)
基于VB.NET的房屋擴展數據自動掛接方法
劉學杰,張福利
(河南省中緯測繪規劃信息工程有限公司,河南 焦作 454000)
在AutoCAD平臺下大比例尺地圖制圖中,房屋作為重要的地物要素,不僅需要圖面注記樓層、建筑結構等文字信息,而且要在內部附加符合地理信息系統要求的擴展信息。本文系統闡述了使用編程的方法,通過對AutoCAD二次開發將房屋文字注記轉換為圖形內部擴展信息的實現原理及程序開發設計過程,為廣大測繪工作者提高生產效率開辟新的工作思路。
VB.NET;AutoCAD;房屋屬性;擴展數據;自動掛接;選擇集
目前隨著制圖軟件技術的發展,以及全國性的城鎮地籍調查、集體土地使用權確權工作的開展,各地區對房屋測繪要求也呈現多樣化趨勢,針對房屋測繪主要體現在成圖軟件多樣化、房屋注記形式多樣化、入庫數據格式多樣化,一套軟件將很難完成所有工作。在基于AutoCAD的大比例尺地圖制圖中,房屋是由不規則的多邊形和房屋屬性注記組成,其中多邊形是房屋空間位置、形狀、大小的抽象描述,注記則是房屋結構、樓層屬性的圖面表述。當房屋僅用作DLG線劃圖制作時,房屋屬性采用圖面注記表達即可滿足要求;而當房屋進行GIS入庫工作時,就需要將房屋內部注記的結構、樓層轉換為符合地理信息系統要求的擴展信息。
AutoCAD具有開放的體系結構,AutoCAD ActiveX提供了從AutoCAD內部或外部以程序設計的方法來操作ActiveX自動化對象模型,允許用戶和開發者采用高級編程語言對其進行擴充和修改。本文通過對房屋多邊形與圖面注記關系,以及AutoCAD對象模型的定義等進行分析,采用基于VB.NET的二次開發不僅可以實現AutoCAD智能識別并自動批量掛接房屋屬性信息,而且可最大限度地滿足用戶的特殊要求,顯著地減少了人工逐個轉換的工作量。
在基于VB.NET的面向對象程序編寫中,需要了解對象的屬性、方法和事件。AutoCAD對象模型中的對象具有一個或多個屬性,以多段線為例,可以用長度、拐點、線寬等來描述,其所具有的特征稱為“屬性”,如Application、Length、Coordinates、Lineweight、Area、Color、Layer等。在ActiveX函數中要獲得AutoCAD圖形對象的有關特征就要用到對應的屬性名稱;對象的方法用來指定對象的執行方式,即要對ActiveX的對象進行怎樣的操作,如多段線的方法包括Copy、Delete、GetXData、SetXData等。
1. Coordinates屬性
多段線在AutoCAD中對應的是LightweightPolyline對象,Coordinates是其屬性之一,它是個維數可變的一維雙精度數組,存儲了多段線在OCS坐標系統下的二維拐點數組。獲取多段線所有拐點的方法為Object.Coordinates,返回一個Object類型的數組,包含了對象從起點開始按X、Y序列排列的每個拐點坐標數據。
2. SetXData方法
向對象添加或修改擴展數據可以使用SetXData方法,其定義為:Object.SetXData(XDataType,XData)。其中,XDataType是一個short類型變量數組,數組中的每個元素用于說明擴展數據的類型;XData是一個Object類型的數組,數組中每個元素包含擴展數據的內容,XDataType中的元素一一對應地說明Xdata中元素的類型。
3. GetXData方法
獲取對象的擴展數據可以使用GetXData方法,其定義為:Object.GetXData(AppName,XDataType,XDataValue)。其中,AppName指定添加擴展數據的應用程序名稱,如果輸入一個空字符串表示要獲得所有應用程序添加的擴展數據;XDataType返回一個short類型的數組,包含對象擴展數據的類型信息;XDataValue返回一個Object類型的數組,包含對象的擴展數據。
選擇集對象SelectionSet是AutoCAD與用戶操作的重要手段,它是一個或多個AutoCAD對象組成的集合,可以指定為一個單一的單元用于處理。選擇集允許用戶同時選擇多個圖形對象,并提供豐富的手段來選擇符合特定條件的實體。
1. 對象選擇的方法
要創建一個選擇集,可使用SelectionSets集合的Add方法。在創建選擇集時,如果存在同名的選擇集,AutoCAD將返回一條錯誤的信息,因此,要及時刪除不再需要的選擇集,刪除一個選擇集,可以使用SelectionSet對象的Delete方法。對象選擇的方法很多,Select方法允許用戶選擇所有對象、窗口內的對象、位于矩形區域內或與其相交的對象、位于多邊形區域內或與其相交的對象等;SelectBypolygon方法選擇多邊形區域內的對象,并將其添加到活動的選擇集中。選擇集對象為程序編寫提供了5種選擇模式,分別為:AcselectionSetwindows、AcselectionSetcrossing、AcselectionSetprevious、AcselectionSetlast、AcselectionSetall。
本文中用到的主要是AcselectionSetwindows窗口選擇模式,即以多邊形拐點作為窗口角點,選中窗口內全部實體,即SSet.SelectByPolygon(AcselectionSetwindows, pointArrs)。
2. 對象選擇的過濾
對象選擇的過濾就是對象選擇時的過濾規則,可以同時指定多個過濾條件,支持帶有通配符的過濾條件,并且可使用邏輯運算符將多個條件進行組合。如使用AcselectionSetwindows模式選擇多邊形框內的對象,并且對象只選擇圓弧、圓、橢圓的代碼如下:
Dim FilterType(4) As Short, FilterData(4) As Object
FilterType(0)=-4: FilterData(0)=" ′邏輯運算符的開始,表示一個或多個運算對象 FilterType(1)=0: FilterData(0)="Arc" FilterType(2)=0: FilterData(0)="Circle" FilterType(3)=0: FilterData(0)="Ellipse" FilterType(4)=-4: FilterData(0)="or>" SSet.SelectByPolygon(AcSelect.AcselectionSetwindows,pointArrs,FilterType,FilterData) 1. 房屋多邊形建立選擇窗口 前文中知道房屋多邊形對象有個重要屬性Coordinates,存儲了構成多段線所有拐點的二維坐標,如圖1所示,多段線坐標存儲結構為從起點開始按拐點次序依次排列的X1、Y1、X2、Y2、X3、Y3、…、Xn、Yn坐標數據。建立多邊形選擇窗口時,多邊形窗口在圖形中是虛擬化的,僅需知道組成窗口的多邊形拐點坐標數據即可,而不必繪制出多邊形,與房屋多邊形比較其拐點坐標為三維坐標(用0值代替Z值),對于封閉窗口還需增加一個末點,末點坐標應該與起點坐標相一致。多邊形選擇窗口的坐標需存儲在雙精度類型的一維數組中,如圖2所示,其存儲格式為X1、Y1、0、X2、Y2、0、X3、Y3、0、…、X1、Y1、0。 圖1 多段線拐點坐標存儲結構 圖2 選擇窗口坐標存儲結構 2. 房屋注記提取結構和樓層 大比例尺地圖制圖時房屋注記的形式是多樣化的,依據現行的規范、規程和地方規定,房屋注記的樣式總結有3種形式:①結構和樓層分離表示,如圖3所示,“混”表示房屋的結構,“2”表示房屋樓層,結構與樓層為單獨的字符;②結構和樓層合并表示,如圖4所示,“混2”用字符串表示結構和樓層;③采用分數形式的字符串表示,如圖5所示,分母“4”表示結構,分子“2”表示樓層。程序設計時,以組成房屋的多邊形為選擇窗口,過濾選擇房屋注記所在圖層上的全部字符,然后遍歷所選字符對象,針對圖3首先判斷文字是否為關鍵字“混”,若是就提取出房屋結構,否則進一步判斷該字符是否為數字,若是就提取出房屋樓層;針對圖4,相對圖3僅需要用代碼將字符串分解為2個部分,然后依次判斷即可;對于圖5,可以通過判斷字符串內是否包含關鍵字“/”,以“/”為分割符,分別截取分子(樓層)和分母(結構)。 圖3 結構與樓層分離注記 圖4 結構與樓層合并 圖5 分數形式注記 3. 擴展數據中表示房屋屬性 AutoCAD中擴展數據的引入為圖形提供了GIS的屬性管理能力,對象的SetXData方法可以為房屋添加1個或N個自定義的擴展數據,如結構、樓層、年代、編號等,擴展數據由開發者自行定義和解釋,AutoCAD只維護這些數據而不管其具體含義,擴展數據可以是字符串、實數、整數等。這樣不僅節省了圖面注記占用的空間,而且為二次開發批量處理數據提供了技術保障。 SetXData方法中,參數XDataType用于說明擴展數據的類型,所支持的DXF組碼只能采用1000~1071之間的組碼值,不同的組碼對應不同的類型信息。以下為某制圖軟件中一房屋的擴展數據記錄: * Registered Application Name:SOUTH-(1) * Code 1000, ASCII string: 141161---(2) * Code 1040, Real number: 2.0000----(3) 第一行表示下列擴展數據的注冊程序名稱為“SOUTH”;第二行規定了數據為字符類型,值為“141161”,實際表示房屋的編碼為141161;第三行中規定了數據為浮點類型,值為“2.0000”,實際表示房屋的樓層為2層。 4. 程序開發設計代碼組織編寫 程序中重復執行的代碼可定義為過程或函數,能顯著提高程序的運行效率,當以房屋為遍歷對象并建立選擇集窗口時,設計一個創建選擇集的過程和一個轉換多段線為選擇窗口坐標的函數。代碼如下: Private Sub CreateSset(ByVal Sname As String, ByRef Sset As AcadSelectionSet) Try ′創建新的選擇集或引用一個同名選擇集并清空選擇集對象 Sset=myacadapp.ActiveDocument.SelectionSets.Add(Sname) Catch ex As System.Exception Sset=myacadapp.ActiveDocument.SelectionSets.Item(Sname) Sset.Clear(): Err.Clear() End Try End Sub Private Function GetPcood_ary(ByVal objline As AcadEntity) As Double()′將房屋多段線轉為選擇窗口坐標數組 Dim pointArrs() As Double=Nothing, k As Integer=-1′定義存儲選擇窗口坐標的數組 Dim getpt As Object=objline.Coordinates ′讀取多段線拐點坐標值到數組中 For i As Integer=0 To UBound(getpt) Step 2′變換數組 k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=getpt(i) k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=getpt(i + 1) k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=0.0# Next i If objline.Closed=True Then k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=getpt(0) k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=getpt(1) k+=1: ReDim Preserve pointArrs(k): pointArrs(k)=0.0# End If Return pointArrs End Function 在主程序中,首先設定過濾條件,將符合要求的房屋多段線添加到一個選擇集變量中;然后遍歷選擇集中的所有房屋多段線并建立新的選擇窗口,將該窗口內的所有符合條件的文字添加到新的選擇集中;再遍歷新選擇集中的文字,依據文字注記的特征及級別分離出房屋結構和房屋樓層,如分數形式的注記級別最高,一旦遍歷到分數文字,立即解析結構和樓層并退出循環體。 主程序中Srtxt.LastIndexOf("/")函數可以查找字符串中是否包含指定字符,能協助判斷出文字是否為分數注記;Srtxt.Length函數能計算字符串內字符的數量,以此忽略3個以上字符的字符串;IsNumeric(Srtxt)函數可判斷指定的字符是否為數字。以下為主程序的完整代碼: Private Sub ButtonSetdata_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSetdata.Click Dim sset As AcadSelectionSet=Nothing′定義一個選擇集變量,用于選擇所有房屋 Dim FilterType(1) As Short, FilterData(1) As Object′定義選擇集過濾器變量 FilterType(0)=0: FilterData(0)="LWPOLYLINE" ′添加過濾條件:多段線 FilterType(1)=8: FilterData(1)="FW" ′添加過濾條件:FW層 CallCreateSset("sset",sset) ′調用自定義過程,建立或引用選擇集 set.Select(AcSelect.acSelectionSetAll, , , FilterType, FilterData)′選擇圖形中符合過濾條件的實體 For Each objline As AcadLWPolyline In sset′遍歷所有選擇集中的多段線(房屋) Dim pointArrs() As Double=GetPcood_ary(objline)′調用自定義函數轉換多段線為選擇窗口坐標 Dim House_jg As String=Nothing, House_lc As Double=1′定義房屋結構、房屋樓層變量并初始化 Dim Keywd_bm() As String={"141141", "141111", "141161", "141121", "141151"}′定義存儲房屋編碼的數組 Dim Keywd_jg() As String={"鋼", "砼", "混", "磚", "木"}′定義存儲房屋結構(文字)的關鍵字數組 Dim Keynm_jg() As String={"1", "3", "4", "5", "6"}′定義存儲房屋結構(分母)的關鍵字數組 FilterType(0)=0: FilterData(0)="TEXT"′修改過濾條件:文字 FilterType(1)=8: FilterData(1)="TZFG"′修改過濾條件:TFZG層 Dim stxt As AcadSelectionSet=Nothing:Call CreateSset("stxt", stxt) stxt.SelectByPolygon(AcSelect.acSelectionSetWindowPolygon, pointArrs, FilterType, FilterData) For Each Lstxt As AcadText In stxt′遍歷多段線內部的所有文字注記 Dim Srtxt As String=Lstxt.TextString′讀取文字對象的注記內容 If Srtxt.LastIndexOf("/") <> -1 Then′查找文字注記是否含字符′/′ House_jg=Mid(Srtxt, InStr(1, Srtxt, "/") + 1)′獲取房屋建筑結構 House_jg Keywd_jg(Array.IndexOf(Keynm_jg, Hours_jg))′轉換結構為漢字形式 House_lc=CDbl(Mid(Srtxt, 1, InStr(1, Srtxt, "/") - 1))′獲取房屋樓層數 Exit For′符合條件后,退出循環,提高運行效率 Else If IsNumeric(Srtxt)=True Then′判斷文字為數字 House_lc=CDbl(Srtxt)′如是就提取寫入樓層變量 Else House_jg=Mid(Srtxt, 1, 1)′讀取字符串中的第一個字符 If System.Array.IndexOf(Keywd_jg, House_jg) <> -1 Then′判斷是否符合關鍵字 If Srtxt.Length=2 Then′判斷文字長度是否等于2 House_jg=Mid(Srtxt, 1, 1)′獲取房屋建筑結構 House_lc=CDbl(Mid(Srtxt, 2, 1))′獲取房屋樓層數 Exit For′符合條件后,退出循環 ElseIf Srtxt.Length=1 Then House_jg=Srtxt End If:End If:End If:End If Next If House_jg IsNot Nothing Then′向實體添加擴展數據 Dim dataTy(3) As Short, datatx(3) As Object dataTy(0)=1001: datatx(0)="TDGIS" dataTy(1)=1000: datatx(1)=Keywd_bm(Array.IndexOf(Keywd_jg, House_jg)) dataTy(2)=1000: datatx(2)=House_jg dataTy(3)=1040: datatx(3)=House_lc objline.SetXData(dataTy, datatx) End If objline.Update()′保存多段線的修改 Next End Sub 分別按照圖3、圖4、圖5在AutoCAD中繪制房屋并注記文字,程序運行后,使用CAD擴展命令XDLIST查看各房屋的擴展數據內容如下,結果如圖6所示。 圖6 * Registered Application Name: TDGIS * Code 1000, ASCII string: 141161 * Code 1000, ASCII string: 混 * Code 1040, Real number: 2.0000 上述程序設計合理、邏輯緊湊,限于篇幅程序中略去了啟動CAD的代碼。用較簡短的代碼將多種不同的注記樣式統一處理,具有較強的通用性和實用性。在當前的農村集體土地使用權確權項目中,僅需要在房屋內部注記表示結構和樓層的文字,就可以通過程序自動掛接屬性,不僅解決了無屬性房屋難處理, 房屋注記與房屋擴展數據不一致等一系 列難題,而且避免了手工掛接房屋擴展數據的重復浪費,在實際作業中針對不同的GIS入庫要求,通過二次開發很容易實現用戶的特殊要求,顯著提高了生產效率。 [1] 曹祖圣,蔡文龍,林義證.Visual Basic 2005[M].北京:科學出版社,2007. [2] 張帆,鄭立楷,盧擇臨,等.AutoCAD VBA二次開發教程[M].北京:清華大學出版社,2006. [3] 張曜,張青,李丁.Visual Basic函數實用手冊[M].北京:冶金工業出版社,2002. [4] 曾洪飛.AutoCADVBA&VB.NET開發基礎與實例教程[M].北京:中國電力出版社,2013. [5] 中華人民共和國國家質量監督檢驗檢疫總局. 1∶500 1∶1000 1∶2000地形圖圖式:GB/T 20257.1—2007[S].北京:中國標準出版社,2008. [6] 中華人民共和國住房和城鄉建設部. 城市測量規范:GJJ/T 8—2011[S].北京:中國建筑工業出版社,2012. [7] 洪濤,譚仁春,李寧.AutoCAD數據自動創建ArcGIS“地圖瓦片”服務的方法研究[J].測繪通報,2015(12): 85-87. [8] 劉仁峰,吳志春.AutoCAD平臺下DLG建庫的關鍵技術研究[J].測繪通報,2015(9):113-116. [9] 河南省國土資源廳.河南省農村集體土地使用權確權登記發證實施細則(試行)[EB/OL].[2016-04-10].wenku.baidu.com. Research of Method Based on VB.NET House Extension Data Automatic Articulated LIU Xuejie,ZHANG Fuli 2016-06-21 劉學杰(1968—),男,高級工程師,主要從事工程測量方面的工作。E-mail:zwchlxj@126.com 劉學杰,張福利.基于VB.NET的房屋擴展數據自動掛接方法[J].測繪通報,2016(12):111-115. 10.13474/j.cnki.11-2246.2016.0414. P208 B 0494-0911(2016)12-0111-05三、程序實現的過程分析





四、程序運行及實踐應用
