張 靜,龔正國,梁 偉,陳慶巖,秦亞東,姚 遠,王 林
(1.國網南陽供電公司,河南 南陽 473000;2.中國電力工程顧問集團中南電力設計院有限公司,湖北 武漢 430071)
ODA 是一個非盈利的組則,在40 多個國家有1 100多個成員。ODA致力于促進開放的、工業標準的CAD數據和遺留的CAD數據的格式交換。ODA開發用于技術圖形應用程序的核心平臺TeighaTM,Teigha支持dwg、dgn、stl、pdf之間的數據交換。Teigha支持的多個平臺包括Windows、Mac、Unix、Linux 等[1-6]。本文采用Teigha.Net實現dwg文件的寫入功能。
本文基于ArcEngine 和Teigha.Net 的CAD 路徑圖,輸出方法構建在統一的地理參考WGS84 坐標系統下,通過ArcEngine 獲取路徑信息和底圖信息,利用Teigha.Net 寫入dwg 文件中,以此實現路徑圖的輸出,其原理如圖1所示。

圖1 方法原理圖
實現CAD路徑輸出的關鍵是不同信息系統之間數據轉換,需要將ArcGIS系統中的路徑、材料信息和底圖數據轉化成CAD格式的路徑圖及注記,并添加選擇的圖框樣式。ArcGIS系列軟件作為地理信息專業處理和管理系統,在矢量和柵格數據管理方面能力出眾,具有豐富的空間信息,CAD更加偏重于矢量數據的管理,針對柵格數據處理能力較弱,針對2 個平臺的不同要點,可以將對應的信息轉換分解為3 個方面:柵格、矢量和圖框分別進行處理。針對柵格數據,利用ArcEngine中柵格數據處理模塊并結合.Net平臺自帶的圖像功能,完成柵格數據的轉換輸出,作為獨立數據文件關聯到最終成果中[7]。針對矢量數據,利用Teigha.Net 進行矢量信息寫入CAD,線狀地物直接作為線實體寫入,點狀要素需要讀取對應的dwg 格式的圖放入對應位置以符號化形式顯示。針對圖框,圖框作為裁剪柵格的范圍比例,在分幅出圖的過程中使用圖框參數,最終圖框需要根據柵格數據的大小進行一定比例的縮放,疊加到CAD 圖中[8]。因此,本文設計的基于ArcEngine和Teigha.Net的CAD路徑圖輸出方法流程如圖2所示。

圖2 方法流程
基于ArcEngine和Teigha.Net的CAD路徑圖輸出方法包括柵格輸出,矢量轉換以及圖框的疊加。
柵格數據由于來源的不同,例如衛星數據、航攝數據以及其他來源數據,大小和分辨率不一致,在柵格數據的輸出中需要根據輸出范圍的大小進行重采樣,降低柵格數據的輸出大小。同時,由于添加了在線地圖天地圖的服務,這種數據采用自定義顯示方式,沒有繼承ArcEngine 自帶的IRasterLayer,需要采用特殊的方式進行輸出。針對以上情況,本文實現3種柵格數據的輸出函數:ArcEngine 自帶函數封裝、C#自帶Bitmap操作封裝以及針對在線地圖天地圖特殊輸出處理。
針對ArcEngine 自帶柵格數據的輸出函數,可以進行柵格數據的輸出,優點是可以進行詳細的設置,例如柵格數據的重采樣,缺點也很明顯,功能復雜輸出速度慢。封裝的函數中,設置輸出的圖層源、輸出范圍、存儲定義以及輸出像素的個數(int x, int y)。輸出像素的個數決定了重采樣的比例,例如輸出柵格范圍內的像素個數為10 000×10 000,而輸出像素設置為1 000×1 000,那么最終的影像個數為1 000×1 000,這些值會根據10 000×10 000 個像素進行重采樣得來的。本文考慮到像素過多最終CAD顯示的影響以及輸出效率的問題,會將影像進行重采樣設置,控制影像的范圍[1]。判斷的依據是輸出柵格范圍內的影像的寬度或者高度。
針對C#自帶Bitmap的操作函數,也可以用于柵格數據的寫入,需要自己獲取每一個點像素值,逐像素寫入。其優點是寫入快效率高,缺點是無法處理大范圍影像,影像過大會導致程序內存占用過高。首先申請一個對應影像大小的Bitmap 以及對應的BitmapData,設置對應大小的byte。根據RasterLayer 的數據組織格式,將輸出范圍劃分成128×128大小的塊,分別讀取對應像素值寫入對應byte中。直到所有的信息都寫入byte 之后,一次性將所有信息拷貝進BitmapData對象中,最后寫入影像文件。需要注意的是,bmpData.Stride 應該等于bmpWidth,但實際上往往不相等,要差幾個字節,因為bmpData.Stride 必須是4 的倍數,如果不足,則補上幾個字節,讓bmpData.Stride是4的倍數,這些多余的字節不會存儲任何顏色數據,如果直接令bmpData.Stride=bmpWidth,會導致影像集體右偏移。針對大柵格數據寫入導致的內存不足問題,主要是在.NET 中,所有大對象都是分配在另外一個特別的連續內存(LOH)中的,而且,每個大對象在創建時即屬于G2,也就是說只有在進行Generation 2的垃圾回收時,才會處理LOH,而且在對LOH 進行垃圾回收時不會壓縮內存。更進一步,LOH 上空間的使用方式也很特殊。當分配一個大對象時,運行時會優先嘗試在LOH 的尾部進行分配,如果尾部空間不足,就會嘗試向操作系統請求更多的內存空間,只有在這一步也失敗時,才會重新搜索之前無效對象留下的內存空隙。如果這一步也失敗,就會出現內存不足的錯誤。
在線地圖天地圖是國家基礎地理信息中心建設的網絡化地理信息共享與服務門戶,向各類用戶提供權威、標準、統一的在線地理信息綜合服務。本平臺可以調用天地圖影像服務和地名服務作為底圖,進行線路規劃。天地圖作為獨立在線地圖的提供方,ArcEngine 中并沒有直接的辦法進行數據的顯示,需要自定義擴展天地圖的顯示,擴展的核心理念是利用當前地圖控件范圍的空間位置,根據分辨率計算對應的天地圖切片數據圖塊,通過網絡請求獲取對應的影像,繪制在地圖控件上。由于天地圖數據是自定義實現顯示,沒有實現IRasterLayer 對應接口,不能采用ArcEngine 自帶函數或者.Net 自帶函數進行柵格數據的輸出,.Net 自帶函數也利用了IRasterLayer 的像素獲取功能。本文利用地圖控件的打印輸出功能順利解決這個問題。在天地圖柵格數據輸出前只顯示天地圖數據,然后地圖控件將輸出范圍的影像輸出為影像文件,之后將其他圖層再顯示在地圖控件上。
3 種柵格輸出都有優缺點以及適用的范圍,根據柵格數據判斷是否是天地圖,確定是,則采用天地圖輸出方法,不是就根據影像的范圍再次進行判斷,范圍過大采用ArcEngine 自帶封裝函數輸出,否則就采用C#自動函數輸出。
矢量輸出考慮的關鍵點是找到ArcGIS平臺和CAD平臺對矢量圖層組織方式的相同點和不同點,找到數據在兩者之間轉換的對應關系。在ArcGIS中,單一圖層里有很多種樣式。在CAD中,只能分散到各層,每個層一個樣式。這樣轉出來以后,圖層會比ArcGIS中的要多。根據分析,進行矢量數據的輸出可以分解為①在CAD 中建立圖層樣式;②根據數據的樣式不同,將數據寫入對應的圖層。
在建立圖層樣式之前,需要初始化CAD 對象,這是采用Teigha.Net 封裝的CAD 文件管理類,可以操縱CAD 文件,包括創建圖層和寫入數據等。建立圖層樣式就是將單一ArcGIS 圖層多個樣式映射到多個CAD 圖層過程,由于本文渲染是根據某一個屬性字段來進行的,只需要根據不同的屬性字段值建立對應的圖層即可,創建的圖層還需要根據ArcGIS圖層矢量類型設置CAD 圖層對應的線寬和顏色等屬性。
建立完圖層樣式,就需要將數據寫入圖層。遍歷圖層,獲取要素,根據要素的渲染字段找到對應的圖層,寫入矢量數據。要素分為點線面,在本文應用中暫時只用到了點和線數據,針對點和線數據分別進行處理。針對線數據,將要素轉換為點集合,定義CAD 中線對象OdDb2dPolyline,將點集合存入對象中,設置線型。針對點對象,獲取點的渲染名稱,根據名稱獲取dwg格式的圖塊,將圖塊寫入對應的CAD圖層中。
標注的擺放位置,由于路徑圖的走向不固定,無法設定唯一的標注傾斜方向,需要根據路徑的方向實時計算結果。同時,針對點要素,如果存在鄰接的線,需要根據鄰接的線方向作為點要素標注的放置方向。需要特別注意的是,選擇的Teigha.Net 平臺存在角度達到臨界值之后,就是靠近PI∕4.0,會導致計算的偏移靠近直線;如果給角度加上PI∕2,會導致靠近角度和坐標軸的點靠近直線,只能通過判斷角度來重新生成角度規避。
圖框的疊加就是將提前選好的dwg 圖框插入對應的dwg 中,主要需要考慮比例的縮放,將圖框放到對應的位置[9]。
圖框邊框分為外邊框和內邊框和數據疊加的范圍是內邊框范圍,示意圖如圖3 所示。內邊框從左下角起始點整個貼合柵格底圖,縮放比例按照內邊框的范圍和影像的范圍來計算,具體公式為:

圖3 圖框示意
式中,scaleX為X方向縮放系數如式(1);scaleY為Y方向縮放系數如式(2);imageWidth 和imageHeight為影像范圍的地理坐標寬度和高度;frameWidth 和frameHeight為圖框在CAD代表的寬度和高度。生成結果可以在AutoCAD正常打開,編輯等操作也正常。
本文提出基于ArcEngine 和Teigha.Net 的CAD 路徑圖輸出方法,根據ArcGIS 平臺的數據利用Teigha.Net 生成CAD 路徑圖,首先根據柵格數據,導出影像地圖,接著轉換矢量數據,最后添加圖框。結果表明,本文方法能有效解決沒有AutoCAD 環境下的CAD 路徑圖輸出的問題,減少了配網軟件中對其他組件的依賴。后續需要進一步優化輸出細節及生成速度。