何偉平 代勁松 宋盛
?
基于ArcGIS Add-in開發(fā)模式的森調(diào)數(shù)據(jù)格式一致性檢查
何偉平 代勁松 宋盛
(浙江省森林資源監(jiān)測中心 浙江杭州 310020)
為完成全省各縣(市、區(qū))森林資源規(guī)劃設(shè)計調(diào)查成果屬性數(shù)據(jù)格式的一致性檢查,在Visual Studio 2015開發(fā)環(huán)境下基于ArcObjects的開發(fā)接口,采用C#語言編寫開發(fā)與浙江省森林資源規(guī)劃調(diào)查技術(shù)規(guī)程要求的標準格式對比的ArcGIS插件,實現(xiàn)森林資源規(guī)劃設(shè)計調(diào)查成果屬性數(shù)據(jù)格式一致性檢查自動化,具有準確、快捷、高效的特點。
ArcGIS;Add-in開發(fā);格式檢查
浙江省新一輪森林資源規(guī)劃設(shè)計調(diào)查(以下簡稱二類調(diào)查)的外業(yè)調(diào)查工作已基本完成,內(nèi)業(yè)處理也接近尾聲,各縣(市、區(qū))的調(diào)查成果已陸續(xù)上報到浙江省林業(yè)廳,進入后期的成果檢查驗收報批工作階段。二類調(diào)查數(shù)據(jù)內(nèi)容豐富、各區(qū)縣格式不一,同時質(zhì)量要求高,格式審查是規(guī)范數(shù)據(jù)的重要環(huán)節(jié),具有工作量大、任務(wù)重、時間緊等特點。
ArcGIS的二次開發(fā)接口ArcObjects功能強大,Add-in技術(shù)是ArcObjectS開發(fā)的一種模式,采用ArcObjectS組件技術(shù)開發(fā)實現(xiàn)對ArcGIS桌面系統(tǒng)進行定制與擴展[1]。通過研發(fā)符合浙江省二類調(diào)查技術(shù)規(guī)程要求的格式審查插件,來實現(xiàn)對屬性數(shù)據(jù)格式校驗審核功能,克服傳統(tǒng)人工檢驗方法的弊端,能有效提高二類調(diào)查成果檢驗的準確性和工作效率,對提高二類調(diào)查成果的質(zhì)量有重要意義。
插件技術(shù)是在軟件的設(shè)計和開發(fā)過程中,將整個應(yīng)用程序劃分為宿主程序和插件對象二部分,宿主程序能夠調(diào)用插件對象,插件對象能夠在宿主程序上實現(xiàn)自己的邏輯,而二者交互基于一種公共的通信契約。宿主程序可以獨立于插件對象存在,即使沒有任何插件對象,宿主程序的運行也不受影響,因此,我們可以在避免改變宿主程序的情況下通過增加或調(diào)整功能[2]。
ArcObjects是ESRI公司ArcGIS可采用的通用二次開發(fā)組件集,它提供基礎(chǔ)的COM對象集合,包括1200多個可訂制、可擴展、可開發(fā)的GIS應(yīng)用程序的對象,利用這些組件可以進行全面的面向特殊功能的組件開發(fā)[3]。
ArcGIS Add-in 支持的功能類型廣泛、文件結(jié)構(gòu)簡單、安裝部署方便,在實際生產(chǎn)過程中可以快速開發(fā)投入應(yīng)用。主要組件有以下幾種:
Buttons and tools(按鈕和工具);Combo boxes(組合框);Menus and context menus(菜單和快捷菜單);Multi items(多項目);Toolbars (工具欄);Tool palettes(工具欄選項);Dockable windows(可??看绑w);Application extensions(應(yīng)用程序擴展);Editor extensions(編輯器擴展)。
ArcGIS Add-in 是以 Esri Add-in 為后綴的壓縮文件,由配置文件、程序集和資源組成。其中,配置文件XML文件包含了描述Add-in 的信息,包括ID、目標、作者、版本等;程序集包含功能代碼和相關(guān)類庫等;資源包括界面圖標等文件。
Microsoft Visual Studio(VS)作為目前最流行的集成開發(fā)環(huán)境之一,被大量開發(fā)團隊用于實現(xiàn)諸多類型和不同規(guī)模的軟件項目,能夠支持C#、C+、javaScript、F#、Visual Basic、Python等多種編程語言,有較強的實用性。之所以選擇編程語言為C#的項目,是考慮到VS的核心是基于.NET框架開發(fā)的,而C#是由微軟所開發(fā)的編寫.NET框架的程序設(shè)計語言。對于C#項目,VS所能提供的功能將會更加全面[4]。
根據(jù)浙江省二類調(diào)查技術(shù)規(guī)程的要求形成標準的小班(林帶)屬性數(shù)據(jù)結(jié)構(gòu)表和樹帶屬性數(shù)據(jù)結(jié)構(gòu)表,將小班(林帶)和樹帶等圖層數(shù)據(jù)加載到ArcGIS Desktop,再通過利用Visual studio2015開發(fā)的ArcGIS Desktop Add-in自動檢驗相關(guān)屬性數(shù)據(jù)格式與標準數(shù)據(jù)結(jié)構(gòu)表的一致性。
本次ArcGIS Add-in的開發(fā)環(huán)境VS2015+ ArcGIS Desktop 10.5+ Win7 64bit。
啟動VS2015,打開“新建項目”界面,確定好項目的名稱和保存的位置,點擊確定,完成新建一個項目(ArcMap Add-in)。
在Welcome頁面中填寫好相應(yīng)的Add-inName(插件的名稱),Company/Publisher(插件的制作公司或發(fā)布者),Author(插件的制作者),Description(插件的描述),最后選擇Image(插件的圖標)。
Add-inTypes頁面用于設(shè)置創(chuàng)建的插件類型。
選擇Add-inTypes,此處選擇按鈕。填寫ClassName:類的名稱;Caption:按鈕上顯示的文本;Image:按鈕上的圖標;Category:所屬Command的分類;Tooltip:鼠標在上面時狀態(tài)欄顯示的文字;Description:工具的描述。點擊Finish完成設(shè)置。
在已安裝模板中,選擇Visual C#,右邊會顯示出各種項目類型。這里第一項就是Windows窗體應(yīng)用程序。
默認狀態(tài)下,會自動生成一個窗體文件。這個窗體是主啟動窗體,當(dāng)程序運行的時候會先運行這個窗體。如果需要修改,可以在創(chuàng)建項目時默認生成的Program.cs文件中進行更改。
一個桌面應(yīng)用程序中往往會有多個窗體。我們可以右鍵點擊項目名稱,在“添加”選項中,選擇“新建項”來添加窗體。注意不要選錯,否則會進行其它操作。本次程序就只要一個窗體,無需添加多個窗體。
有了窗體,我們就可以在窗體上放置各種各樣的控件。左邊的工具箱中有各式各樣的控件,按鈕、文本框、復(fù)選框等。用鼠標按住工具箱中的某個控件,把它拖放到窗體上,便可以往窗體內(nèi)添加控件。也可以直接雙擊工具箱內(nèi)的某個控件,將控件添加到窗體上。
可以用鼠標對窗體上的控件進行拖動操作,來改變控件在窗體上的位置。當(dāng)鼠標移動到窗體中的控件上時,鼠標的指針會變成十字形狀,左鍵點住,就可以進行拖動。
右鍵點擊窗體中的控件,在上下文菜單中選擇“屬性”,右側(cè)就會出現(xiàn)這個控件的屬性設(shè)置欄。在屬性設(shè)置欄中,可以設(shè)置控件的各種屬性。有顯示文本、顏色等。
本次程序的窗體設(shè)計的最終結(jié)果如下圖:
雙擊某個控件,就會跳到對應(yīng)的代碼編輯頁面,進行相對應(yīng)的操作響應(yīng)事件代碼的編寫。比如,雙擊按鈕,就會跳到代碼編寫頁面,進行按鈕點擊響應(yīng)事件代碼的編寫。這里可以編寫各種各樣的事件。
借助C#開發(fā)語言程序?qū)D層屬性數(shù)據(jù)表的格式和標準屬性數(shù)據(jù)結(jié)構(gòu)表通過Add-in插件加入至ArcGIS數(shù)據(jù)環(huán)境中,通過插件窗體的控件Click事件程序來實現(xiàn)圖層屬性數(shù)據(jù)的格式檢查。其中“檢查”控件的Click事件代碼[5]如下:
{
Var fileName=txtBox_CSV.Text;
If (File.Exists(fileName))
{
Var fldStruct = HelperClass.CSV_2_DataTable(fileName);
try
{
Var lyr = (cb_Layers.SelectedItemaslyrInfo).featureLyr;
對照組中,男性患者27例,女性患者23例,年齡區(qū)間為41.15~78.52歲,平均年齡為(59.63±1.17)歲。心功能診斷結(jié)果:Ⅰ級患者21例,Ⅱ級患者15例,Ⅲ級患者10例,Ⅳ級患者4例。觀察組中,男性患者31例,女性患者19例,年齡區(qū)間為42.22~79.63歲,平均年齡為(60.25±1.31)歲。心功能診斷結(jié)果:Ⅰ級患者22例,Ⅱ級患者14例,Ⅲ級患者9例,Ⅳ級患者5例。兩組受試者基線資料比較,差異無統(tǒng)計學(xué)意義(P>0.05),具有可比性。
If (lyr == null)
{
return;
}
String Message = "";
For (int i=0 ; I < fldStruct.Rows.Count ; i++)
{
#region讀取CSV文件中的數(shù)據(jù)結(jié)構(gòu)信息
Var fldName = fldStruct.Rows[i][0].ToString().Trim();
Var fldName2 = fldStruct.Rows[i][1].ToString().Trim();
Var fldType = fldStruct.Rows[i][2].ToString().Trim().ToUpper();
Var fldLength = fldStruct.Rows[i][3].ToString().Trim();
Var fldAlias = fldStruct.Rows[i][4].ToString().Trim();
Var fldMustCheck = fldStruct.Rows[i][5].ToString().Trim();
#endregion
//根據(jù)字段名查找其在矢量圖中的索引
Var featureFldIndex = lyr.FeatureClass.FindField(fldName);
//是否有可選字段名
If (fldName2!="")
{
Var featureFldIndex2 = lyr.FeatureClass.FindField(fldName2);
featureFldIndex = Math.Max(featureFldIndex, featureFldIndex2);
}
//字段名存在
if(featureFldIndex!=-1)
{
//字段類型是否匹配
Bool typeMatch=true;
//矢量圖中的數(shù)據(jù)類型
String RecordDataType = "";
//讀取矢量圖的字段信息
Var featureFld = lyr.FeatureClass.Fields.Field[featureFldIndex];
//判斷字段類型是否匹配
Switch (featureFld.Type)
{
Case esriFieldType.esriFieldTypeSmallInteger:
Case esriFieldType.esriFieldTypeInteger:
If (fldType !="INT")
{
typeMatch = false;
RecordDataType = "INT";
}
break;
case esriFieldType.esriFieldTypeSingle:
if (fldType != "FLOAT")
{
typeMatch = false;
RecordDataType = "FLOAT";
}
break;
case esriFieldType.esriFieldTypeDouble:
if (fldType != "DOUBLE")
{
typeMatch = false;
RecordDataType = "DOUBLE";
}
break;
case esriFieldType.esriFieldTypeString:
var len = featureFld.Length;
if (fldType != "TEXT")
{
typeMatch = false;
RecordDataType = "TEXT";
}
else
{
//判斷數(shù)據(jù)長度是否匹配
Var sdLen = Int32.Parse(fldLength);
if (len != sdLen)
{
Message = Message + fldName + ",” + fldType +", " fldLength + "," + fldAlias + "," + fldMustCheck + ","+ len.ToString() + " , 字段長度不對 ";
}
}
break;
default:
typeMatch = false;
break;
}
If (typeMatch == false)
{
Message = Message + fldName + "," + fldType + "," + fldLength + "," + fldAlias + "," + fldMustCheck + "," + RecordDataType + ",數(shù)據(jù)類型不匹配 ";
}
}
//未找到相應(yīng)字段名
else
{
Message = Message + fldName + "," + fldType + "," + fldLength + "," + fldAlias + "," + fldMustCheck + ",, 未找到 ";
}
}
If (Message!="")
{
//錯誤信息文件名
Var fn = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString() + System.DateTime.Now.Hour.ToString() + System.DateTime.Now.Minute.ToString() + System.DateTime.Now.Second.ToString();
//錯誤信息輸出目錄
Var path = System.IO.Path.GetDirectoryName(fileName);
//錯誤信息文件全名
varoutName=path+"\數(shù)據(jù)結(jié)構(gòu)錯誤_"+fn+".csv";
//將錯誤信息寫入文件
StreamWritersw = newStreamWriter(outName,false,Encoding.Default);
sw.WriteLine("字段名,數(shù)據(jù)類型,字段長度,中文名,備注,使用的數(shù)據(jù)類型或長度,錯誤類型");
sw.Write(Message);
sw.Flush();
sw.Close();
//用記事本打開保存的IP信息
System.Diagnostics.Process.Start("EXCEL.exe", outName);
基本的控件和代碼完成之后,就需要進行調(diào)試運行。點擊上方的調(diào)試按鈕,就可以就行窗體應(yīng)用程序的生成、運行和調(diào)試。如果沒有報錯,就說明編譯成功了,能夠運行。
因為Add-in程序是ArcGIS的插件程序,本身沒有單獨的主程序,調(diào)試時,選擇附加到進程(選擇ArcMap,第一次要打開一個ArcMap[6]。當(dāng)然,如果程序沒有問題,可直接生成*.esriAddIn文件在ArcMap中加載使用。
點擊生成好的Add-in插件,安裝到ArcGIS中去,再打開ArcMap,打開擴展管理,選擇Commands選項卡,找到Add-in Controls,這時候會發(fā)現(xiàn)編寫的工具會出現(xiàn)在這一組中。
在ArcMap窗口菜單欄的右下角出現(xiàn)相應(yīng)的插件圖標,如下圖:
浙江省二類調(diào)查成果標準小班數(shù)據(jù)表有95個字段,相應(yīng)的字段名稱、數(shù)據(jù)類型、最小長度和中文名等都有具體要求[7],利用本插件程序?qū)@些格式進行檢查,操作簡單、快捷、準確、方便,且不會出現(xiàn)漏查和誤查的情況。現(xiàn)對溫州市蒼南縣的調(diào)查成果數(shù)據(jù)進行檢查,耗時不到十秒鐘,遠遠快于人工檢查,且準確性高。檢查結(jié)果如下表:
字段名數(shù)據(jù)類型最少長度中文名規(guī)程是否要求使用數(shù)據(jù)類型或長度錯誤類型 PINGJUN_XJFLOAT 平均胸徑(cm)YINT數(shù)據(jù)類型不匹配 PINGJUN_GFLOAT 平均高(m)YDOUBLE數(shù)據(jù)類型不匹配 YU_BI_DUFLOAT 郁閉度/覆蓋度YDOUBLE數(shù)據(jù)類型不匹配 SMDFLOAT 疏密度YDOUBLE數(shù)據(jù)類型不匹配 HUO_LMXJFLOAT 每畝蓄積(m?)YDOUBLE數(shù)據(jù)類型不匹配 REMARKSTEXT200附記Y50字段長度不對 ZHAO_NDTEXT6造林年度Y10字段長度不對 HUOZAI_DJTEXT1森林火災(zāi)等級Y2字段長度不對 TRGX_QKTEXT1天然更新生長情況Y30字段長度不對 SZ_ZCⅡTEXT23樹種組成Ⅱ 30字段長度不對 DXSWTEXT3地下水位 未找到 HFFLTEXT3海風(fēng)風(fēng)力 未找到 TRHYLTEXT3土壤含鹽量 未找到
基于 VS2015的ArcGIS Add-in生成的格式檢查插件安裝簡單快捷,檢查速度快,檢查正確性高,在二類調(diào)查成果格式檢查工作中,節(jié)約了生產(chǎn)成本,提高了生產(chǎn)效率,獲得了比較好的效果?;谶@次成功的開發(fā)經(jīng)驗,接下來可以進一步開發(fā)相關(guān)檢查的功能插件,比如:拓撲錯誤檢查插件和屬性邏輯檢查插件等,從而更好地實現(xiàn)成果檢查驗收工作的批量化和自動化,這樣能有效提高二類調(diào)查成果檢驗的準確性和工作效率,對提高二類調(diào)查成果質(zhì)量有重要的意義。
[1] 朱旭紅,許國安,陳咬根.基于 ArcObjects 組件的地理數(shù)據(jù)檢查軟件的實現(xiàn)的數(shù)字校園導(dǎo)航系統(tǒng)的研究與實現(xiàn)[J].測繪工程,2010,19(2):49-52.
[2] 蘇旭明.組件式地理信息系統(tǒng)的特點及開發(fā)方法[J].北京測繪,2002,(4):40-41.
[3] 趙文峰,劉南,劉仁義.基于ArcObjects的系統(tǒng)開發(fā)技術(shù)剖析[J].計算機應(yīng)用研究,2014,(3): 130-132.
[4] 劉亞珺,李兵,李增揚,等.軟件集成開發(fā)環(huán)境的技術(shù)債務(wù)管理研究[J].計算機科學(xué),2017,44(11): 16-18.
[5] 崔群法,唐有朋,王俊偉.Visual C#2008從入門到精通[M].北京:電子工業(yè)出版社,2009.
[6] ESRI Corp, Arcobjects DeveIoper’s Help[R].2015.
[7] 浙江省林業(yè)廳.浙江省森林資源規(guī)劃設(shè)計調(diào)查技術(shù)操作細則[S].2014.
2018-07-28
TP319
B
1004-7743(2018)04-0075-6