張 靜,龔正國,梁 偉,陳慶巖,秦亞東,姚 遠(yuǎn),王 林
(1.國網(wǎng)南陽供電公司,河南 南陽 473000;2.中國電力工程顧問集團(tuán)中南電力設(shè)計院有限公司,湖北 武漢 430071)
ODA 是一個非盈利的組則,在40 多個國家有1 100多個成員。ODA致力于促進(jìn)開放的、工業(yè)標(biāo)準(zhǔn)的CAD數(shù)據(jù)和遺留的CAD數(shù)據(jù)的格式交換。ODA開發(fā)用于技術(shù)圖形應(yīng)用程序的核心平臺TeighaTM,Teigha支持dwg、dgn、stl、pdf之間的數(shù)據(jù)交換。Teigha支持的多個平臺包括Windows、Mac、Unix、Linux 等[1-6]。本文采用Teigha.Net實現(xiàn)dwg文件的寫入功能。
本文基于ArcEngine 和Teigha.Net 的CAD 路徑圖,輸出方法構(gòu)建在統(tǒng)一的地理參考WGS84 坐標(biāo)系統(tǒng)下,通過ArcEngine 獲取路徑信息和底圖信息,利用Teigha.Net 寫入dwg 文件中,以此實現(xiàn)路徑圖的輸出,其原理如圖1所示。
圖1 方法原理圖
實現(xiàn)CAD路徑輸出的關(guān)鍵是不同信息系統(tǒng)之間數(shù)據(jù)轉(zhuǎn)換,需要將ArcGIS系統(tǒng)中的路徑、材料信息和底圖數(shù)據(jù)轉(zhuǎn)化成CAD格式的路徑圖及注記,并添加選擇的圖框樣式。ArcGIS系列軟件作為地理信息專業(yè)處理和管理系統(tǒng),在矢量和柵格數(shù)據(jù)管理方面能力出眾,具有豐富的空間信息,CAD更加偏重于矢量數(shù)據(jù)的管理,針對柵格數(shù)據(jù)處理能力較弱,針對2 個平臺的不同要點(diǎn),可以將對應(yīng)的信息轉(zhuǎn)換分解為3 個方面:柵格、矢量和圖框分別進(jìn)行處理。針對柵格數(shù)據(jù),利用ArcEngine中柵格數(shù)據(jù)處理模塊并結(jié)合.Net平臺自帶的圖像功能,完成柵格數(shù)據(jù)的轉(zhuǎn)換輸出,作為獨(dú)立數(shù)據(jù)文件關(guān)聯(lián)到最終成果中[7]。針對矢量數(shù)據(jù),利用Teigha.Net 進(jìn)行矢量信息寫入CAD,線狀地物直接作為線實體寫入,點(diǎn)狀要素需要讀取對應(yīng)的dwg 格式的圖放入對應(yīng)位置以符號化形式顯示。針對圖框,圖框作為裁剪柵格的范圍比例,在分幅出圖的過程中使用圖框參數(shù),最終圖框需要根據(jù)柵格數(shù)據(jù)的大小進(jìn)行一定比例的縮放,疊加到CAD 圖中[8]。因此,本文設(shè)計的基于ArcEngine和Teigha.Net的CAD路徑圖輸出方法流程如圖2所示。
圖2 方法流程
基于ArcEngine和Teigha.Net的CAD路徑圖輸出方法包括柵格輸出,矢量轉(zhuǎn)換以及圖框的疊加。
柵格數(shù)據(jù)由于來源的不同,例如衛(wèi)星數(shù)據(jù)、航攝數(shù)據(jù)以及其他來源數(shù)據(jù),大小和分辨率不一致,在柵格數(shù)據(jù)的輸出中需要根據(jù)輸出范圍的大小進(jìn)行重采樣,降低柵格數(shù)據(jù)的輸出大小。同時,由于添加了在線地圖天地圖的服務(wù),這種數(shù)據(jù)采用自定義顯示方式,沒有繼承ArcEngine 自帶的IRasterLayer,需要采用特殊的方式進(jìn)行輸出。針對以上情況,本文實現(xiàn)3種柵格數(shù)據(jù)的輸出函數(shù):ArcEngine 自帶函數(shù)封裝、C#自帶Bitmap操作封裝以及針對在線地圖天地圖特殊輸出處理。
針對ArcEngine 自帶柵格數(shù)據(jù)的輸出函數(shù),可以進(jìn)行柵格數(shù)據(jù)的輸出,優(yōu)點(diǎn)是可以進(jìn)行詳細(xì)的設(shè)置,例如柵格數(shù)據(jù)的重采樣,缺點(diǎn)也很明顯,功能復(fù)雜輸出速度慢。封裝的函數(shù)中,設(shè)置輸出的圖層源、輸出范圍、存儲定義以及輸出像素的個數(shù)(int x, int y)。輸出像素的個數(shù)決定了重采樣的比例,例如輸出柵格范圍內(nèi)的像素個數(shù)為10 000×10 000,而輸出像素設(shè)置為1 000×1 000,那么最終的影像個數(shù)為1 000×1 000,這些值會根據(jù)10 000×10 000 個像素進(jìn)行重采樣得來的。本文考慮到像素過多最終CAD顯示的影響以及輸出效率的問題,會將影像進(jìn)行重采樣設(shè)置,控制影像的范圍[1]。判斷的依據(jù)是輸出柵格范圍內(nèi)的影像的寬度或者高度。
針對C#自帶Bitmap的操作函數(shù),也可以用于柵格數(shù)據(jù)的寫入,需要自己獲取每一個點(diǎn)像素值,逐像素寫入。其優(yōu)點(diǎn)是寫入快效率高,缺點(diǎn)是無法處理大范圍影像,影像過大會導(dǎo)致程序內(nèi)存占用過高。首先申請一個對應(yīng)影像大小的Bitmap 以及對應(yīng)的BitmapData,設(shè)置對應(yīng)大小的byte。根據(jù)RasterLayer 的數(shù)據(jù)組織格式,將輸出范圍劃分成128×128大小的塊,分別讀取對應(yīng)像素值寫入對應(yīng)byte中。直到所有的信息都寫入byte 之后,一次性將所有信息拷貝進(jìn)BitmapData對象中,最后寫入影像文件。需要注意的是,bmpData.Stride 應(yīng)該等于bmpWidth,但實際上往往不相等,要差幾個字節(jié),因為bmpData.Stride 必須是4 的倍數(shù),如果不足,則補(bǔ)上幾個字節(jié),讓bmpData.Stride是4的倍數(shù),這些多余的字節(jié)不會存儲任何顏色數(shù)據(jù),如果直接令bmpData.Stride=bmpWidth,會導(dǎo)致影像集體右偏移。針對大柵格數(shù)據(jù)寫入導(dǎo)致的內(nèi)存不足問題,主要是在.NET 中,所有大對象都是分配在另外一個特別的連續(xù)內(nèi)存(LOH)中的,而且,每個大對象在創(chuàng)建時即屬于G2,也就是說只有在進(jìn)行Generation 2的垃圾回收時,才會處理LOH,而且在對LOH 進(jìn)行垃圾回收時不會壓縮內(nèi)存。更進(jìn)一步,LOH 上空間的使用方式也很特殊。當(dāng)分配一個大對象時,運(yùn)行時會優(yōu)先嘗試在LOH 的尾部進(jìn)行分配,如果尾部空間不足,就會嘗試向操作系統(tǒng)請求更多的內(nèi)存空間,只有在這一步也失敗時,才會重新搜索之前無效對象留下的內(nèi)存空隙。如果這一步也失敗,就會出現(xiàn)內(nèi)存不足的錯誤。
在線地圖天地圖是國家基礎(chǔ)地理信息中心建設(shè)的網(wǎng)絡(luò)化地理信息共享與服務(wù)門戶,向各類用戶提供權(quán)威、標(biāo)準(zhǔn)、統(tǒng)一的在線地理信息綜合服務(wù)。本平臺可以調(diào)用天地圖影像服務(wù)和地名服務(wù)作為底圖,進(jìn)行線路規(guī)劃。天地圖作為獨(dú)立在線地圖的提供方,ArcEngine 中并沒有直接的辦法進(jìn)行數(shù)據(jù)的顯示,需要自定義擴(kuò)展天地圖的顯示,擴(kuò)展的核心理念是利用當(dāng)前地圖控件范圍的空間位置,根據(jù)分辨率計算對應(yīng)的天地圖切片數(shù)據(jù)圖塊,通過網(wǎng)絡(luò)請求獲取對應(yīng)的影像,繪制在地圖控件上。由于天地圖數(shù)據(jù)是自定義實現(xiàn)顯示,沒有實現(xiàn)IRasterLayer 對應(yīng)接口,不能采用ArcEngine 自帶函數(shù)或者.Net 自帶函數(shù)進(jìn)行柵格數(shù)據(jù)的輸出,.Net 自帶函數(shù)也利用了IRasterLayer 的像素獲取功能。本文利用地圖控件的打印輸出功能順利解決這個問題。在天地圖柵格數(shù)據(jù)輸出前只顯示天地圖數(shù)據(jù),然后地圖控件將輸出范圍的影像輸出為影像文件,之后將其他圖層再顯示在地圖控件上。
3 種柵格輸出都有優(yōu)缺點(diǎn)以及適用的范圍,根據(jù)柵格數(shù)據(jù)判斷是否是天地圖,確定是,則采用天地圖輸出方法,不是就根據(jù)影像的范圍再次進(jìn)行判斷,范圍過大采用ArcEngine 自帶封裝函數(shù)輸出,否則就采用C#自動函數(shù)輸出。
矢量輸出考慮的關(guān)鍵點(diǎn)是找到ArcGIS平臺和CAD平臺對矢量圖層組織方式的相同點(diǎn)和不同點(diǎn),找到數(shù)據(jù)在兩者之間轉(zhuǎn)換的對應(yīng)關(guān)系。在ArcGIS中,單一圖層里有很多種樣式。在CAD中,只能分散到各層,每個層一個樣式。這樣轉(zhuǎn)出來以后,圖層會比ArcGIS中的要多。根據(jù)分析,進(jìn)行矢量數(shù)據(jù)的輸出可以分解為①在CAD 中建立圖層樣式;②根據(jù)數(shù)據(jù)的樣式不同,將數(shù)據(jù)寫入對應(yīng)的圖層。
在建立圖層樣式之前,需要初始化CAD 對象,這是采用Teigha.Net 封裝的CAD 文件管理類,可以操縱CAD 文件,包括創(chuàng)建圖層和寫入數(shù)據(jù)等。建立圖層樣式就是將單一ArcGIS 圖層多個樣式映射到多個CAD 圖層過程,由于本文渲染是根據(jù)某一個屬性字段來進(jìn)行的,只需要根據(jù)不同的屬性字段值建立對應(yīng)的圖層即可,創(chuàng)建的圖層還需要根據(jù)ArcGIS圖層矢量類型設(shè)置CAD 圖層對應(yīng)的線寬和顏色等屬性。
建立完圖層樣式,就需要將數(shù)據(jù)寫入圖層。遍歷圖層,獲取要素,根據(jù)要素的渲染字段找到對應(yīng)的圖層,寫入矢量數(shù)據(jù)。要素分為點(diǎn)線面,在本文應(yīng)用中暫時只用到了點(diǎn)和線數(shù)據(jù),針對點(diǎn)和線數(shù)據(jù)分別進(jìn)行處理。針對線數(shù)據(jù),將要素轉(zhuǎn)換為點(diǎn)集合,定義CAD 中線對象OdDb2dPolyline,將點(diǎn)集合存入對象中,設(shè)置線型。針對點(diǎn)對象,獲取點(diǎn)的渲染名稱,根據(jù)名稱獲取dwg格式的圖塊,將圖塊寫入對應(yīng)的CAD圖層中。
標(biāo)注的擺放位置,由于路徑圖的走向不固定,無法設(shè)定唯一的標(biāo)注傾斜方向,需要根據(jù)路徑的方向?qū)崟r計算結(jié)果。同時,針對點(diǎn)要素,如果存在鄰接的線,需要根據(jù)鄰接的線方向作為點(diǎn)要素標(biāo)注的放置方向。需要特別注意的是,選擇的Teigha.Net 平臺存在角度達(dá)到臨界值之后,就是靠近PI∕4.0,會導(dǎo)致計算的偏移靠近直線;如果給角度加上PI∕2,會導(dǎo)致靠近角度和坐標(biāo)軸的點(diǎn)靠近直線,只能通過判斷角度來重新生成角度規(guī)避。
圖框的疊加就是將提前選好的dwg 圖框插入對應(yīng)的dwg 中,主要需要考慮比例的縮放,將圖框放到對應(yīng)的位置[9]。
圖框邊框分為外邊框和內(nèi)邊框和數(shù)據(jù)疊加的范圍是內(nèi)邊框范圍,示意圖如圖3 所示。內(nèi)邊框從左下角起始點(diǎn)整個貼合柵格底圖,縮放比例按照內(nèi)邊框的范圍和影像的范圍來計算,具體公式為:
圖3 圖框示意
式中,scaleX為X方向縮放系數(shù)如式(1);scaleY為Y方向縮放系數(shù)如式(2);imageWidth 和imageHeight為影像范圍的地理坐標(biāo)寬度和高度;frameWidth 和frameHeight為圖框在CAD代表的寬度和高度。生成結(jié)果可以在AutoCAD正常打開,編輯等操作也正常。
本文提出基于ArcEngine 和Teigha.Net 的CAD 路徑圖輸出方法,根據(jù)ArcGIS 平臺的數(shù)據(jù)利用Teigha.Net 生成CAD 路徑圖,首先根據(jù)柵格數(shù)據(jù),導(dǎo)出影像地圖,接著轉(zhuǎn)換矢量數(shù)據(jù),最后添加圖框。結(jié)果表明,本文方法能有效解決沒有AutoCAD 環(huán)境下的CAD 路徑圖輸出的問題,減少了配網(wǎng)軟件中對其他組件的依賴。后續(xù)需要進(jìn)一步優(yōu)化輸出細(xì)節(jié)及生成速度。