從ArcGIS 10開始,ArcGIS開始支持后台地理處理。使用Geoprocessor.ExecuteAsync()方法,可以在ArcGIS應用程序的后台執行工具或模型工具。也就是說當工具在后台進程中執行時,ArcGIS控件(例如,MapControl、PageLayoutControl、GlobeControl或SceneControl)保持對用戶交互的響應。換句話說,可以在工具執行時查看和查詢數據。
使用后台地理處理來執行一個工具,需要以下操作:
1、注冊事件
2、提交工具執行。
1:Geoprocessor方式
Geoprocessor類提供了以下5種事件:
- MessagesCreated
- ProgressChanged
- ToolboxChanged
- ToolExecuted
- ToolExecuting
本文主要介紹ToolExecuting和ToolExecuted事件。
1. 實例化Geoprocessor類
Geoprocessor gp = new GeoProcessor(); gp.OverwriteOutput = true;
2.注冊事件
這里根據需求,用到哪些事件就注冊哪些事件。
gp.ToolExecuting += new EventHandler<ToolExecutingEventArgs>(gp_ToolExecuting); gp.ToolExecuted += new EventHandler<ToolExecutedEventArgs>(gp_ToolExecuted);
3.創建一個隊列用於存放gp工具
private Queue<IGPProcess> _myGPToolsToExecute = new Queue<IGPProcess>();
4.事件處理函數
//此處只是為了演示,具體內容可以實際需求編寫,例如執行完畢后將結果加載到MapControl中 private void gp_ToolExecuted(object sender, ToolExecutedEventArgs e) { IGeoProcessorResult2 gpResult = (IGeoProcessorResult2)e.GPResult; if (gpResult.Status == esriJobStatus.esriJobSucceeded) { Console.WriteLine(gpResult.Process.ToolName.ToString() + "執行完畢"); //判斷隊列里是否還有工具,如果有繼續執行 if (_myGPToolsToExecute.Count > 0) { gp.ExecuteAsync(_myGPToolsToExecute.Dequeue()); } } else if (gpResult.Status == esriJobStatus.esriJobFailed) { Console.WriteLine(gpResult.Process.Tool.Name + "執行失敗"); } } private void gp_ToolExecuting(object sender, ToolExecutingEventArgs e) { IGeoProcessorResult2 gpResult = (IGeoProcessorResult2)e.GPResult; Console.WriteLine(gpResult.Process.Tool.Name + " " + gpResult.Status.ToString()); }
5.提交工具執行
此處以緩沖區分析和裁剪為例。先創建緩沖區,然后用創建的緩沖區裁剪
try { //緩沖區 ESRI.ArcGIS.AnalysisTools.Buffer bufferTool = new ESRI.ArcGIS.AnalysisTools.Buffer(); bufferTool.in_features = @"C:\Users\Demacia\Desktop\展示\控制點.shp"; bufferTool.buffer_distance_or_field = 1500; bufferTool.out_feature_class = @"C:\Users\Demacia\Desktop\展示\緩沖區.shp"; //裁剪 ESRI.ArcGIS.AnalysisTools.Clip clipTool = new ESRI.ArcGIS.AnalysisTools.Clip(); clipTool.in_features = @"C:\Users\Demacia\Desktop\展示\China_Project.shp"; clipTool.clip_features = bufferTool.out_feature_class; clipTool.out_feature_class = @"C:\Users\Demacia\Desktop\展示\Clip.shp"; //將兩個gp工具依次加入隊列 _myGPToolsToExecute.Enqueue(bufferTool); _myGPToolsToExecute.Enqueue(clipTool); gp.ExecuteAsync(_myGPToolsToExecute.Dequeue()); } catch (Exception ex) { }
2:GeoProcessorClass方式
此種方式需要使用IGeoProcessor2接口的RegisterGeoProcessorEvents3()方法注冊事件。RegisterGeoProcessorEvents3()方法的參數為一個IGeoProcessorEvents3類型的實例,AO中並沒有提供實現IGeoProcessorEvents3接口的類,所以需要我們自己創建一個類並實現IGeoProcessorEvents3接口。
1.創建一個名為GeoProcessorEvents3Class的類,並實現IGeoProcessorEvents3接口
public class GeoProcessorEvents3Class : IGeoProcessorEvents3 { IMapControl2 mapCon; public GeoProcessorEvents3Class(IMapControl2 inCon) { mapCon = inCon; } public void OnProcessMessages(IGeoProcessorResult result, ESRI.ArcGIS.Geodatabase.IGPMessages pMsgs) { //可輸出處理過程中產生的信息 } public void OnProgressMessage(IGeoProcessorResult result, string message) { //可輸出處理過程中產生的信息 } public void OnProgressPercentage(IGeoProcessorResult result, double percentage) { } public void OnProgressShow(IGeoProcessorResult result, bool Show) { } /// <summary> /// 運行結束后觸發此事件 /// </summary> /// <param name="result"></param> public void PostToolExecute(IGeoProcessorResult result) { //此處需要根據實際情況編寫 可以改進成委托或事件形式 //此示例以緩沖區分析為例,執行成功后將緩沖區分析結果添加到MapControl中 if (result.Status == esriJobStatus.esriJobSucceeded) { IGPUtilities4 gpu = new GPUtilitiesClass() as IGPUtilities4; IFeatureLayer player = new FeatureLayerClass(); player.FeatureClass = gpu.Open(result.GetOutput(0)) as IFeatureClass; mapCon.AddLayer(player as ILayer); } else if(result.Status == esriJobStatus.esriJobFailed) { Console.WriteLine("運行失敗"); } } /// <summary> /// 運行前觸發此事件 /// </summary> /// <param name="result"></param> public void PreToolExecute(IGeoProcessorResult result) { Console.WriteLine("等待運行GP工具"); } }
2.實例化GeoProcessorEvents3Class類、GeoProcessorClass類並注冊事件
IGeoProcessorEvents3 GeoProcessorEvents = new GeoProcessorEvents3Class(this.axMapControl1.Object as IMapControl2); IGeoProcessor2 gp = new GeoProcessorClass();
gp.OverwriteOutput = true; gp.RegisterGeoProcessorEvents3(GeoProcessorEvents);
3.提交工具執行
IVariantArray varParam = new VarArrayClass(); varParam.Add(@"C:\Users\Demacia\Desktop\展示\控制點.shp"); varParam.Add(@"C:\Users\Demacia\Desktop\展示\緩沖區.shp"); varParam.Add(2000); gp.ExecuteASync("Buffer_analysis", varParam);