王育紅,劉康晨
(江蘇師范大學(xué) 地理測繪與城鄉(xiāng)規(guī)劃學(xué)院,江蘇 徐州 221116)
1999年, 美國ESRI公司發(fā)布了當(dāng)時代表最高技術(shù)水平的全系列GIS平臺——ArcGIS。Geodatabase則是伴隨ArcGIS而生的、 采用對象關(guān)系數(shù)據(jù)庫技術(shù)的新一代空間數(shù)據(jù)模型。 相對于早期的Shapefile與Coverage空間數(shù)據(jù)模型, Geodatabase具有一體化、 智能化等優(yōu)勢, 能夠更清晰、 準(zhǔn)確地反映、 描述現(xiàn)實實體的靜態(tài)屬性與動態(tài)行為特征[1]。 經(jīng)過多次的技術(shù)革新和版本升級, 目前Geodatabase已具備統(tǒng)一集中管理矢量、 柵格、 DEM、 TIN、 網(wǎng)絡(luò)、 時態(tài)、 常規(guī)屬性表格、 音視頻等多種數(shù)據(jù)的強大能力, 并廣泛應(yīng)用于眾多領(lǐng)域和部門[2-3]。
為滿足不同的應(yīng)用需要,Geodatabase針對柵格數(shù)據(jù)提供了5種不同的存儲與管理機制。其中:柵格數(shù)據(jù)集用來直接存儲原始格式的柵格數(shù)據(jù);柵格目錄和鑲嵌數(shù)據(jù)集作為特殊形式的關(guān)系表,主要來存儲記錄多幅柵格數(shù)據(jù)及其相關(guān)的屬性信息;要素類與表則通過其中自定義的柵格型屬性列(字段)來進一步存儲記錄相關(guān)的柵格數(shù)據(jù),以豐富擴展空間和非空間對象主體記錄的信息內(nèi)容、增加直觀認(rèn)識。對于前3種主體型存儲方式,可通過ArcMAP應(yīng)用程序提供的“導(dǎo)入柵格數(shù)據(jù)集”、“加載柵格數(shù)據(jù)集”等功能將外部原始柵格數(shù)據(jù)批量加載到所建Geodatabase中。但對于后兩種輔助型存儲方式,目前尚沒有批量加載工具,只能根據(jù)表或要素類中已有的數(shù)據(jù)記錄,人工逐條加載與之相關(guān)的柵格數(shù)據(jù),人機交互頻繁、效率低、易出錯。針對這一不足,本文在總結(jié)分析ArcGIS平臺功能定制擴展方法的基礎(chǔ)上,采用插件技術(shù)設(shè)計開發(fā)了一個面向Geodatabase表與要素類的柵格數(shù)據(jù)批量加載ArcMAP插件。
為方便在已有功能基礎(chǔ)上量身定制開發(fā)出更個性、更簡潔、更智能、更高效的功能或系統(tǒng),最大限度地滿足不同用戶的應(yīng)用需要,不同版本的ArcGIS平臺適時提供了多項定制擴展開發(fā)技術(shù),如圖1所示。
ArcObjects(AO)是基于Microsoft COM技術(shù)所構(gòu)建的一系列可重用COM組件集, 幾乎提供了ArcGIS全部的底層功能。 基于AO的開發(fā),早期主要有3種方式[4-5]: 利用ArcGIS內(nèi)嵌的VBA腳本語言直接對ArcGIS桌面應(yīng)用(如ArcMap)功能進行擴展開發(fā)[6-7]; 利用支持COM技術(shù)的編程語言(如VB、.Net、C++等), 在AO組件基礎(chǔ)上進一步包裝其自身的dll組件, 經(jīng)編譯注冊后將其功能添加到ArcGIS系統(tǒng)或其他應(yīng)用程序中; 采用高級編程語言通過引用AO類庫及其包含的MapControl、 PageLayoutControl等可視化控件開發(fā)具有單獨界面、 可獨立運行的GIS應(yīng)用程序。
圖1 不同版本ArcGIS支持的定制開發(fā)技術(shù)Fig.1 Customizing and development technology in ArcGIS
ArcEngine(即ArcGIS Engine, AE)是ESRI公司對AO核心組件進行再封裝之后對外發(fā)布的一個獨立產(chǎn)品和開發(fā)工具包,其組件接口、方法、屬性與AO相同,但功能稍弱于AO。AE主要用來開發(fā)獨立GIS應(yīng)用或嵌入式GIS應(yīng)用,如將GIS功能嵌入到Mirosoft Word和Excel等已有應(yīng)用程序中。利用AE開發(fā)的應(yīng)用程序可以脫離ArcGIS產(chǎn)品(如Desktop),只依賴于ArcGIS Engine Runtime獨立運行,而AO程序則必須依賴于ArcGIS產(chǎn)品才能運行[8-9]。
ModelBuilder是一個用來創(chuàng)建、編輯和管理模型的應(yīng)用程序,也可以將其視為用于構(gòu)建工作流的可視化編程語言。ModelBuilder主要用于對復(fù)雜地理處理流程進行簡化,無需編碼,僅通過拖拽、連線、參數(shù)設(shè)置等方式就可以將已有地理處理工具串聯(lián)起來擴展形成一個新的地理處理工具(模型或工作流),該工具可以進一步嵌入到新模型中,并可以發(fā)布為地理處理服務(wù)供Web應(yīng)用調(diào)用[10-11]。因此,ModelBuilder所建模型具有可重用、易共享等特點。
Addin(與Add-in、Addon、Add-on、Plugin、Plug-in等詞同義)通常譯作插件,俗稱外掛,是一種遵循一定接口規(guī)范編寫出來的程序,主要用來改變宿主軟件的功能和性能[12-13]。這里的宿主軟件是指插件依附于其上,發(fā)揮功能的目標(biāo)程序。ArcGIS目前支持兩種桌面插件擴展開發(fā)技術(shù)[14]:面向C#、VB、.Net和Java高級編程語言的Addin技術(shù);面向Python腳本語言的Addin技術(shù)。前者基于AO組件進行擴展開發(fā),支持的可擴展元素較多;后者基于ArcPY站點包進行擴展開發(fā),不需要了解復(fù)雜的AO組件,代碼數(shù)量少,不需要編譯,但編碼不易調(diào)試、可擴展元素較少。
ArcGIS Runtime是一款基于服務(wù)架構(gòu)的輕量級全新開發(fā)產(chǎn)品集合,可用來在不同平臺設(shè)備上(如Window、 Linux、 Mac、 iOS、 Android等)通過不同編程語言(C++、 Java、 C#、 Qt等)開發(fā)離線或在線的制圖應(yīng)用及地理分析應(yīng)用,并且支持按需部署,無需注冊安裝。與AO、AE技術(shù)相比,ArcGIS Runtime具有跨平臺、易部署、顯示效率高、與WebGIS無縫集成等特點。
基于對以上各種擴展開發(fā)方式的分析,以及已有開發(fā)經(jīng)驗,筆者采用C# 2010編程語言與Addin技術(shù)對ArcMAP 10.2柵格數(shù)據(jù)加載功能進行擴展, 設(shè)計實現(xiàn)了一個工具欄插件——iLoader,如圖2所示。
圖2 iLoader插件Fig.2 Addin of iLoader
首先,從“目標(biāo)表”組合框中選擇ArcMAP文檔中具有柵格型字段(以存儲柵格數(shù)據(jù))的表或要素類,并根據(jù)需要在“匹配字段”組合框中選擇“目標(biāo)表”的一個字符型字段用于后期的查詢比較;然后,選擇指定文件夾內(nèi)的部分或全部柵格圖像文件;最后,依次解析所選柵格圖像文件的文件名,在“目標(biāo)表”中查詢“匹配字段”取值等于該文件名的記錄,如果返回結(jié)果非空,則將該柵格圖像文件賦給返回記錄的柵格字段,直到處理完全部所選柵格文件為止。
(1)創(chuàng)建項目:在Visual Studio 2010中,根據(jù)ESRI提供的ArcGIS Desktop Add-ins模板創(chuàng)建一個名稱為“iLoader”的ArcMAP add-in項目,向該項目中添加組成該插件的相應(yīng)元素并設(shè)置名稱、圖片等參數(shù),主要包括2個組合框元素、2個按鈕元素、1個可??看翱谠睾?個工具欄元素。前5個是基本交互類元素,最后1個是容器類元素, 用來存放前4個元素。可??看翱谏显偬砑右粋€DataGridView控件,用來記錄柵格文件加載結(jié)果。
(2)編寫代碼:在上述前5個擴展元素對應(yīng)的類文件中輸入相應(yīng)代碼,通過ArcMAP、Addin、thisAddin、IFeatureLayer、ITable、IQueryFilter、IRasterDataset、IRasterValue、IRowBuffer等對象或接口,實現(xiàn)擴展元素之間的交互以及表、要素類的查詢與修改。
(3)編譯調(diào)試:第一次編譯調(diào)試Addin程序時,應(yīng)先將其附加到已啟動的ArcMAP主程序上。在關(guān)閉主程序之后,重新啟動Addin程序,并將其添加到ArcMAP中,則可以開始反復(fù)多次的調(diào)試糾正工作。在確保運行正確無誤后,就可對外發(fā)布、安裝編譯生成的esriAddIn文件。該文件是一個包含配置文件、程序集和資源文件的zip壓縮包,通過雙擊就可以安裝部署到需要的計算機上,也可通過ArcMap的“加載項管理器”進行查看和卸載所安裝的Addin程序。
(1)獲取ArcMAP文檔中的表或要素類。
//獲取表。
IStandaloneTableCollection iSTC;
iSTC=ArcMap.Document.FocusMap as IStandaloneTableCollection;
IStandaloneTable iSTable;
iSTable=iSTC.getStandaloneTable(i);
ITable iTable=iSTable.Table;
//獲取要素類對應(yīng)的表。
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”的可??看翱凇?/p>
UID uID=new UIDClass();
uID=ThisAddIn.IDs.C5DWnd.ToUID();
var dWnd=ArcMap.DockableWindowManager. GetDockableWindow(uID);
//獲取??看翱谏系腄ataGridView控件。
DataGridView dGV;
dGV=AddIn.FromID< C5DWnd.AddinImpl> (Th-isAddIn.IDs.C5DWnd).DataGrid;
(3)判斷Geodatabase類型。
Geodatabase有個人、文件和ArcSDE三種類型,不同類型的Geodatabase其查詢語法不同,因此在對表或要素類進行查詢前,應(yīng)先判斷其所在數(shù)據(jù)庫的類型,以便輸入符合語法的查詢語句。
//將表接口變量iSTable轉(zhuǎn)化為數(shù)據(jù)集接口。
IDataset iDSet=iSTable as IDataset;
//獲取數(shù)據(jù)集所在工作空間。
IWorkspace iWSpace=iDSet.Workspace;
//判斷工作空間的后綴名,并設(shè)置相應(yīng)的表達式。
string wsName=iWSpace.PathName.Substring (iWSpace.PathName.Length-4)
string SQLExp="";
if (wsName==".mdb")
{
//個人地理數(shù)據(jù)庫查詢語句一般形式
SQLExp="[字段名]='字段值'";
}
else if (wsName==".gdb")
{
//文件地理數(shù)據(jù)庫查詢語句一般形式
SQLExp="字段名='字段值'";
}
else
{
//個ArcSDE地理數(shù)據(jù)庫查詢語句一般形式
SQLExp=@"""字段名""='字段值'";
}
(4)查詢記錄,并修改柵格字段的值。
//將一般形式的查詢語句轉(zhuǎn)換為具體的查詢語句。
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為所選的表或要素類轉(zhuǎn)化后的表。
iRB.setValue(rFldIndex, iRV);
//rFldIndex為所選表中柵格字段的索引值。
iTable.UpdateSearchedRows(iQFilter, iRB);
Marshal.ReleaseComObject(iQFilter);
}
本插件已在江蘇師范大學(xué)Geodatabase建設(shè)中得到應(yīng)用,主要用來加載建筑物、景觀等要素類中所需的平面或全景柵格數(shù)據(jù)。這兩個要素類(可儲存幾何圖形的特殊表)的數(shù)據(jù)組織結(jié)構(gòu)形式分別見表1和表2。
表1 建筑物要素類數(shù)據(jù)組織結(jié)構(gòu)Table 1 Data structure of building features
表2 景觀要素類數(shù)據(jù)組織結(jié)構(gòu)Table 2 Data structure of landscape features
對于上述要素類,主要采用如下方式采集加載所需數(shù)據(jù):首先,利用ArcGIS的“加載數(shù)據(jù)”功能加載通過實地測量獲得的AutoCAD地圖數(shù)據(jù),即要素類所需的幾何圖形與屬性數(shù)據(jù);然后,通過實地拍照方式采集各要素相關(guān)的柵格圖像數(shù)據(jù),并進行拼接、編輯、按要素名稱命名等處理;最后,利用所開發(fā)的iLoader插件工具批量加載各要素所需的柵格數(shù)據(jù)。
為驗證本插件的優(yōu)越性,筆者以上述兩個要素類為例,對柵格數(shù)據(jù)人工和批量兩種加載方式進行了對比實驗分析,具體結(jié)果見表3。
表3 人工與批量加載對比實驗結(jié)果Table 3 Test results of two uploading methods
相對于人工手動逐項加載方式,本文所開發(fā)的批量加載方式具有交互少、效率高等明顯優(yōu)勢,加載效率至少可提高50倍以上。
作為一個全系列、多層次、跨平臺、可伸縮的GIS產(chǎn)品平臺,ArcGIS力爭為各類用戶提供全面的解決方案,雖然新技術(shù)、新方法、新工具層出不窮,但遇到特殊情況時這些并非是萬能的,在實際應(yīng)用中常常需要用戶進行針對性的整合、擴展與改造。本文針對Geodatabase表與要素類加載柵格數(shù)據(jù)的不足,采用Addin技術(shù)設(shè)計開發(fā)了一個批量加載插件,進一步驗證了Addin技術(shù)易創(chuàng)建、易安裝、易共享、更安全的特征,大大提高了加載效率。