王育紅,劉康晨
(江蘇師范大學 地理測繪與城鄉規劃學院,江蘇 徐州 221116)
1999年, 美國ESRI公司發布了當時代表最高技術水平的全系列GIS平臺——ArcGIS。Geodatabase則是伴隨ArcGIS而生的、 采用對象關系數據庫技術的新一代空間數據模型。 相對于早期的Shapefile與Coverage空間數據模型, Geodatabase具有一體化、 智能化等優勢, 能夠更清晰、 準確地反映、 描述現實實體的靜態屬性與動態行為特征[1]。 經過多次的技術革新和版本升級, 目前Geodatabase已具備統一集中管理矢量、 柵格、 DEM、 TIN、 網絡、 時態、 常規屬性表格、 音視頻等多種數據的強大能力, 并廣泛應用于眾多領域和部門[2-3]。
為滿足不同的應用需要,Geodatabase針對柵格數據提供了5種不同的存儲與管理機制。其中:柵格數據集用來直接存儲原始格式的柵格數據;柵格目錄和鑲嵌數據集作為特殊形式的關系表,主要來存儲記錄多幅柵格數據及其相關的屬性信息;要素類與表則通過其中自定義的柵格型屬性列(字段)來進一步存儲記錄相關的柵格數據,以豐富擴展空間和非空間對象主體記錄的信息內容、增加直觀認識。對于前3種主體型存儲方式,可通過ArcMAP應用程序提供的“導入柵格數據集”、“加載柵格數據集”等功能將外部原始柵格數據批量加載到所建Geodatabase中。但對于后兩種輔助型存儲方式,目前尚沒有批量加載工具,只能根據表或要素類中已有的數據記錄,人工逐條加載與之相關的柵格數據,人機交互頻繁、效率低、易出錯。針對這一不足,本文在總結分析ArcGIS平臺功能定制擴展方法的基礎上,采用插件技術設計開發了一個面向Geodatabase表與要素類的柵格數據批量加載ArcMAP插件。
為方便在已有功能基礎上量身定制開發出更個性、更簡潔、更智能、更高效的功能或系統,最大限度地滿足不同用戶的應用需要,不同版本的ArcGIS平臺適時提供了多項定制擴展開發技術,如圖1所示。
ArcObjects(AO)是基于Microsoft COM技術所構建的一系列可重用COM組件集, 幾乎提供了ArcGIS全部的底層功能。 基于AO的開發,早期主要有3種方式[4-5]: 利用ArcGIS內嵌的VBA腳本語言直接對ArcGIS桌面應用(如ArcMap)功能進行擴展開發[6-7]; 利用支持COM技術的編程語言(如VB、.Net、C++等), 在AO組件基礎上進一步包裝其自身的dll組件, 經編譯注冊后將其功能添加到ArcGIS系統或其他應用程序中; 采用高級編程語言通過引用AO類庫及其包含的MapControl、 PageLayoutControl等可視化控件開發具有單獨界面、 可獨立運行的GIS應用程序。

圖1 不同版本ArcGIS支持的定制開發技術Fig.1 Customizing and development technology in ArcGIS
ArcEngine(即ArcGIS Engine, AE)是ESRI公司對AO核心組件進行再封裝之后對外發布的一個獨立產品和開發工具包,其組件接口、方法、屬性與AO相同,但功能稍弱于AO。AE主要用來開發獨立GIS應用或嵌入式GIS應用,如將GIS功能嵌入到Mirosoft Word和Excel等已有應用程序中。利用AE開發的應用程序可以脫離ArcGIS產品(如Desktop),只依賴于ArcGIS Engine Runtime獨立運行,而AO程序則必須依賴于ArcGIS產品才能運行[8-9]。
ModelBuilder是一個用來創建、編輯和管理模型的應用程序,也可以將其視為用于構建工作流的可視化編程語言。ModelBuilder主要用于對復雜地理處理流程進行簡化,無需編碼,僅通過拖拽、連線、參數設置等方式就可以將已有地理處理工具串聯起來擴展形成一個新的地理處理工具(模型或工作流),該工具可以進一步嵌入到新模型中,并可以發布為地理處理服務供Web應用調用[10-11]。因此,ModelBuilder所建模型具有可重用、易共享等特點。
Addin(與Add-in、Addon、Add-on、Plugin、Plug-in等詞同義)通常譯作插件,俗稱外掛,是一種遵循一定接口規范編寫出來的程序,主要用來改變宿主軟件的功能和性能[12-13]。這里的宿主軟件是指插件依附于其上,發揮功能的目標程序。ArcGIS目前支持兩種桌面插件擴展開發技術[14]:面向C#、VB、.Net和Java高級編程語言的Addin技術;面向Python腳本語言的Addin技術。前者基于AO組件進行擴展開發,支持的可擴展元素較多;后者基于ArcPY站點包進行擴展開發,不需要了解復雜的AO組件,代碼數量少,不需要編譯,但編碼不易調試、可擴展元素較少。
ArcGIS Runtime是一款基于服務架構的輕量級全新開發產品集合,可用來在不同平臺設備上(如Window、 Linux、 Mac、 iOS、 Android等)通過不同編程語言(C++、 Java、 C#、 Qt等)開發離線或在線的制圖應用及地理分析應用,并且支持按需部署,無需注冊安裝。與AO、AE技術相比,ArcGIS Runtime具有跨平臺、易部署、顯示效率高、與WebGIS無縫集成等特點。
基于對以上各種擴展開發方式的分析,以及已有開發經驗,筆者采用C# 2010編程語言與Addin技術對ArcMAP 10.2柵格數據加載功能進行擴展, 設計實現了一個工具欄插件——iLoader,如圖2所示。

圖2 iLoader插件Fig.2 Addin of iLoader
首先,從“目標表”組合框中選擇ArcMAP文檔中具有柵格型字段(以存儲柵格數據)的表或要素類,并根據需要在“匹配字段”組合框中選擇“目標表”的一個字符型字段用于后期的查詢比較;然后,選擇指定文件夾內的部分或全部柵格圖像文件;最后,依次解析所選柵格圖像文件的文件名,在“目標表”中查詢“匹配字段”取值等于該文件名的記錄,如果返回結果非空,則將該柵格圖像文件賦給返回記錄的柵格字段,直到處理完全部所選柵格文件為止。
(1)創建項目:在Visual Studio 2010中,根據ESRI提供的ArcGIS Desktop Add-ins模板創建一個名稱為“iLoader”的ArcMAP add-in項目,向該項目中添加組成該插件的相應元素并設置名稱、圖片等參數,主要包括2個組合框元素、2個按鈕元素、1個可停靠窗口元素和1個工具欄元素。前5個是基本交互類元素,最后1個是容器類元素, 用來存放前4個元素。可停靠窗口上再添加一個DataGridView控件,用來記錄柵格文件加載結果。
(2)編寫代碼:在上述前5個擴展元素對應的類文件中輸入相應代碼,通過ArcMAP、Addin、thisAddin、IFeatureLayer、ITable、IQueryFilter、IRasterDataset、IRasterValue、IRowBuffer等對象或接口,實現擴展元素之間的交互以及表、要素類的查詢與修改。
(3)編譯調試:第一次編譯調試Addin程序時,應先將其附加到已啟動的ArcMAP主程序上。在關閉主程序之后,重新啟動Addin程序,并將其添加到ArcMAP中,則可以開始反復多次的調試糾正工作。在確保運行正確無誤后,就可對外發布、安裝編譯生成的esriAddIn文件。該文件是一個包含配置文件、程序集和資源文件的zip壓縮包,通過雙擊就可以安裝部署到需要的計算機上,也可通過ArcMap的“加載項管理器”進行查看和卸載所安裝的Addin程序。
(1)獲取ArcMAP文檔中的表或要素類。
//獲取表。
IStandaloneTableCollection iSTC;
iSTC=ArcMap.Document.FocusMap as IStandaloneTableCollection;
IStandaloneTable iSTable;
iSTable=iSTC.getStandaloneTable(i);
ITable iTable=iSTable.Table;
//獲取要素類對應的表。
IFeatureLayer iFlayer;
iFlayer=ArcMap.Document.FocusMap.getLayer(i)as IFeatureLayer;
if (iFlayer !=null)
{
ITable iTable=(ITable) iFlayer.FeatureClass;
//如果iFlayer為Null,則不是要素類。
}
(2)獲取插件包含的擴展元素。
//獲取類名為“C2ComBox”組合框。
C2ComBox cBox2;
cBox2=AddIn.FromID
//獲取類名為“C5DWnd”的可停靠窗口。
UID uID=new UIDClass();
uID=ThisAddIn.IDs.C5DWnd.ToUID();
var dWnd=ArcMap.DockableWindowManager. GetDockableWindow(uID);
//獲取停靠窗口上的DataGridView控件。
DataGridView dGV;
dGV=AddIn.FromID< C5DWnd.AddinImpl> (Th-isAddIn.IDs.C5DWnd).DataGrid;
(3)判斷Geodatabase類型。
Geodatabase有個人、文件和ArcSDE三種類型,不同類型的Geodatabase其查詢語法不同,因此在對表或要素類進行查詢前,應先判斷其所在數據庫的類型,以便輸入符合語法的查詢語句。
//將表接口變量iSTable轉化為數據集接口。
IDataset iDSet=iSTable as IDataset;
//獲取數據集所在工作空間。
IWorkspace iWSpace=iDSet.Workspace;
//判斷工作空間的后綴名,并設置相應的表達式。
string wsName=iWSpace.PathName.Substring (iWSpace.PathName.Length-4)
string SQLExp="";
if (wsName==".mdb")
{
//個人地理數據庫查詢語句一般形式
SQLExp="[字段名]='字段值'";
}
else if (wsName==".gdb")
{
//文件地理數據庫查詢語句一般形式
SQLExp="字段名='字段值'";
}
else
{
//個ArcSDE地理數據庫查詢語句一般形式
SQLExp=@"""字段名""='字段值'";
}
(4)查詢記錄,并修改柵格字段的值。
//將一般形式的查詢語句轉換為具體的查詢語句。
SQLExp=SQLExp.Replace(“字段名”, mFldName);//mFldName為所選匹配字段名稱。
SQLExp=SQLExp.Replace(“字段值”,imageName);//imageName為不包括擴展名的所選圖像文件名稱。
IQueryFilter iQFilter=new QueryFilterClass();
iQFilter.WhereClause=SQLExp;
int rowCount=iTable.RowCount(iQFilter);
if (rowCount> 0)
{
IWorkspaceFactory iWF;
iWF=new RasterWorkspaceFactoryClass();
IRasterWorkspace iRW=iWF.OpenFromFile (imagePath, 0) as IRasterWorkspace;//imagePath為所選柵格圖像文件的路徑目錄。
IRasterDataset iRD=iRW.OpenRasterDataset (imageNameExt);//imageNameExt為包括擴展名的所選圖像文件名稱。
IRasterValue iRV=new RasterValueClass();
iRV.RasterDataset=iRD;
IRowBuffer iRB=iTable.CreateRowBuffer();
//iTable為所選的表或要素類轉化后的表。
iRB.setValue(rFldIndex, iRV);
//rFldIndex為所選表中柵格字段的索引值。
iTable.UpdateSearchedRows(iQFilter, iRB);
Marshal.ReleaseComObject(iQFilter);
}
本插件已在江蘇師范大學Geodatabase建設中得到應用,主要用來加載建筑物、景觀等要素類中所需的平面或全景柵格數據。這兩個要素類(可儲存幾何圖形的特殊表)的數據組織結構形式分別見表1和表2。

表1 建筑物要素類數據組織結構Table 1 Data structure of building features

表2 景觀要素類數據組織結構Table 2 Data structure of landscape features
對于上述要素類,主要采用如下方式采集加載所需數據:首先,利用ArcGIS的“加載數據”功能加載通過實地測量獲得的AutoCAD地圖數據,即要素類所需的幾何圖形與屬性數據;然后,通過實地拍照方式采集各要素相關的柵格圖像數據,并進行拼接、編輯、按要素名稱命名等處理;最后,利用所開發的iLoader插件工具批量加載各要素所需的柵格數據。
為驗證本插件的優越性,筆者以上述兩個要素類為例,對柵格數據人工和批量兩種加載方式進行了對比實驗分析,具體結果見表3。

表3 人工與批量加載對比實驗結果Table 3 Test results of two uploading methods
相對于人工手動逐項加載方式,本文所開發的批量加載方式具有交互少、效率高等明顯優勢,加載效率至少可提高50倍以上。
作為一個全系列、多層次、跨平臺、可伸縮的GIS產品平臺,ArcGIS力爭為各類用戶提供全面的解決方案,雖然新技術、新方法、新工具層出不窮,但遇到特殊情況時這些并非是萬能的,在實際應用中常常需要用戶進行針對性的整合、擴展與改造。本文針對Geodatabase表與要素類加載柵格數據的不足,采用Addin技術設計開發了一個批量加載插件,進一步驗證了Addin技術易創建、易安裝、易共享、更安全的特征,大大提高了加載效率。