周 飛
(江蘇省測繪工程院,江蘇南京 210013)
地理信息數據的格式轉換是相當普遍的。各主流數據處理軟件能夠實現一些簡易的格式轉換功能,但存在要素或屬性丟失、圖形變形的情況,無法滿足無損轉換的需要。
FME Objects 提供了一套軟件組件用于處理空間數據。程序的二次開發引用軟件安裝生成的FME Objects Dot Net 4 庫,該庫包含了一整套處理空間數據的類、對象、常用變量、函數方法。本文利用FME Objects 讀寫數據、編輯數據、屬性傳遞的特性及對多種數據格式支持、靈活嵌入其他系統的優勢,開發集成了多源數據的格式轉換工具,高效滿足了各類數據源的統一使用。
FME 主要功能由FME Data Inspector 與FME Workbench 實現。FME Data Inspector 主要用于查看數據的要素數量、組織結構、要素屬性、圖層分類。FME Workbench 是支持數據格式轉換與處理的軟件平臺,可手動設置讀模塊、轉換器、寫模塊3部分,用于數據的格式轉換。FME 采用的是語義轉換方法,支持多源數據的讀取與相互轉換,針對需求,調用豐富的函數轉換器,處理坐標、圖形、屬性,在轉換過程中實現數據重構的功能?!罢Z義轉換”運用映射文件的對應模型,提供了不同類型數據的流通通道,破除了數據之間的壁壘,有效避免了數據丟失或圖形變形的發生,實現全過程自動化。FME憑借其強大的功能,封裝了500 多種轉換器(函數),實現了數據的多需求、多方向的格式轉換。對于大批量數據格式的轉換處理,借助開發鏈接庫,運用程序定制處理同類型的數據轉換是高效的。
依托FME Objects 動態鏈接庫,運用C#語言,在.NET 平臺面向對象開發的程序界面如圖1 所示。界面提供了選擇源數據按鈕、目標數據存儲路徑選擇按鈕、對應格式轉換按鈕,以及更新狀態欄。軟件主要包括dgn->shp、dgn->dwg、dgn->gdb、dgn->mdb、dwg->dgn、mdb->dgn、dwg->shp、gdb->dgn 八種格式轉換功能。程序運行流程如圖2 所示。
圖1 程序界面圖
圖2 轉換流程圖
c#界面窗體的運行是以static void Main()為起點,主要調用EnableVisualStyles()、SetCompatibleTextRenderingDefault(false)、Run(new Form1())這三個函數方法實現窗體的初步運行。
EnableVisualStyles()函數實現窗體及設置控件的可視化;SetCompatibleTextRenderingDefault(false)函數的參數一般設置為false,此函數使用GDI 方式設置控件的顯示文本;Run(new Form1())則用于窗體標準消息的運行與循環。
窗體的設置主要包括button(按鈕)、ListBox(列表盒)、StatusStrip(狀態欄)、OpenFileDialog(打開對話框)。地理信息數據格式中的Geodatabase(簡稱gdb)是以文件夾形式表示的,應選用FloderBrowser Dialog 打開數據對話框。窗體設置的控件、對話框、狀態欄主要用于觸發函數的運行、顯示數據的選擇及狀態等。
FME Objects 運用接口定義了對象必須實現的成員變量。IFM EOSession 定義成員m_fmeSession并使其初始化,這是所有后續成員變量定義的起點。由于接口不能直接創建對象,所以對象m_fmeSession 由FME Objects 根類通過CreateSession()方法創建,其他對象均由對象m_fmeSession 通過函數方法創建。次級生成的6 種對象主要包括圖形操作工具、轉換日志、對話框、要素、磁盤向量以及讀寫器,對象的關系及創建方法如圖3 所示。
圖3 對象關系及創建方法圖
3.3.1 釋放內存函數
Dispose()函數廣泛用于釋放界面對象的資源空間,如m_fmeSession 等對象在調用后釋放資源避免報警,代碼編寫位于設計頁面的void Dispose(bool disposing)函數中,偽代碼如下:
if(m_fmeSession!=null)
{ m_fmeSession.Dispose();
m_fmeSession=null;}
其他各類對象的釋放資源可參考m_fmeSession對象的操作,所有對象釋放完成后調用系統基類的釋放函數base.Dispose()。
3.3.2 屬性復制傳遞
地理信息數據的非圖形屬性是不可或缺的,FME 默認的轉換通道不能直接實現此類屬性的復制傳遞。我們以dgn 數據轉換為shapefile 數據為例,實現在讀取過程中加入屬性參數。
如圖3 所示,已闡述對象fmeReader 通過CreateReader(參數)創建,CreateReader()方法主要包含m_dataInfo、m_createDirectives 兩個變量和一個布爾值。m_dataInfo 用于設定數據導入的路徑與數據格式,m_createDirectives 用于設置屬性參數。由于兩個參數是基于FME 的m_fmeDialog 對象設置的,而m_fmeDialog 是啟用對話框形式實現參數與路徑的傳輸,每次只能導入一個文件,限制了批量轉換的可能性,故程序將對象m_fmeDialog 解構,分別設置兩個變量的傳入參數。
m_createDirectives 通過Add()的方法加入屬性參數,偽代碼如下:
m_createDirectives.Add(“......DGNV8_EXPOSE_FORMAT_ATTRS,“entity_num_0,integer entity_num_1,integer link_type_0,char(40)link_type_1,char(40)”......”);
加入屬性參數設定后,程序根據屬性名稱依次復制屬性值到目標數據,可靈活增添刪除非圖形類屬性。Shapefile 文件由于對屬性字段長度的限制,超過10 個字符的屬性字段會被強制截取表示,故可導入mdb/gdb 數據庫后另行操作。
3.3.3 讀取數據與模式要素函數
FME 設計中同時讀取數據要素與模式要素才能夠完整地讀取文件數據。數據轉換系統將讀取數據要素函數命名為readDataFeatures,讀取模式要素函數命名為readSchemaFeatures。
readDataFeatures 函數運用while(fmeReader.Read(fmeFeature))的循環遍歷數據特征并記錄存儲到數據字典中,讀完每條信息后重建對象,同時在轉換日志中記錄每條信息。偽代碼如下:
while(fmeReader.Read(fmeFeature))
{m_fmeLogFile.LogFeature(fmeFeature,FMEOMessageLevel.Inform,-1);
insertIntoFeatureTypeDictionary(fmeFeature);
fmeFeature=m_fmeSession.CreateFeature(); }
readSchemaFeatures 函數運用方法與readData-Features 類似。
為將完整的數據信息整合存入到字典中,需設置insertIntoFeatureTypeDictionary 函數。此函數通過FME OFeature 定義的成員對象pFeature 所收集字符串形式的信息與原庫自定義的FeatureType 格式,實現數據字典格式的存儲。偽代碼如下:
string currFeatureType=pFeature.FeatureType;
IFMEOFeatureVectorOnDisk
currVectorOnDisk=m_featureTypeDictionary-
[currFeatureType];
currVectorOnDisk.Append(pFeature);
由已創建的對象fmeReader 實現數據的磁盤存儲,偽代碼如下:
StringCollection openParams=new
StringCollection();
fmeReader.Open(m_dataInfo.Dataset,
openParams);
readSchemaFeatures(fmeReader,ref
schemaFeatureCount);
readDataFeatures(fmeReader,ref featureCount);
3.3.4 轉換輸出
數據的轉換輸出類似于數據的讀取,創建打開FMEOWriter 對象,設定輸出格式與路徑,輸出目標的數據和模式要素。偽代碼如下:
StringCollection openParams=new
StringCollection();
fmeWriter.Open(m_dataInfo.Dataset,
openParams);
writeSchemaFeatures(fmeWriter,ref
schemaFeatureCount);
writeDataFeatures(fmeWriter,ref featureCount);
狀態欄位于程序的左下角,用于更新數據轉換的進度及數量,更新狀態欄的代碼如下:
private void updateStatusBar(string pText)
{ toolStripStatusLabel1.Text=pText;
statusStrip1.Refresh();}
為方便用戶了解讀取與轉換的進程,每循環一次要素的讀取,便通過numFeatures 計數。狀態欄展示內容的更新代碼如下:
while(fmeReader.Read(fmeFeature))
{ numFeatures++;
updateStatusBar(" 已讀取" + numFeatures.ToString()+"要素......"); }
m_fmeLogFile 對象通過LogFeature()函數輸出轉換日志,日志內容包含了源數據與目標數據的格式和路徑、調用的動態庫函數、讀取要素的模式、讀取要素量、轉換線型的粗細顏色值、屬性名字段、輸出要素量等。但是要素是否丟失是最為關鍵的,故系統設置了用于對比要素讀取量與轉換量的檢查文件,結合numFeatures 的計數功能,在讀取函數和轉換函數中嵌入文件流代碼。偽代碼如下:
string datacheck=@"D:datacheck.txt";
streamWriter=new StreamWriter(fileStream);
streamWriter.WriteLine("第" +(i + 1).ToString()+ "個文件所有要素量為:" + numFeatures.ToString());//嵌入讀取函數
streamWriter.WriteLine("第" +(i + 1).ToString()+"個文件要素轉換量為:"+featureCount.ToString());//嵌入轉換函數
檢查文本示意圖如圖4 所示:
圖4 要素數量檢查文本
本文基于FME Objects 動態鏈接庫開發的格式轉換軟件,解析了FME Objects 應用的類對象、函數方法、成員變量。通過對帶屬性數據的格式歸類與批量輸入,軟件實現了各類數據圖形與屬性的無損轉換,促進了多源地理信息類文件的高效使用。隨著自然資源機構改革的深入,原屬國土、測繪、海洋、規劃等行業數據的格式轉換并疊加分析使用是必然的趨勢。對于FME Objects 中涉及要素操作、坐標轉換的程序處理則是下一步的研究點。