从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:UsersDemaciaDesktop展示控制点.shp"; bufferTool.buffer_distance_or_field = 1500; bufferTool.out_feature_class = @"C:UsersDemaciaDesktop展示缓冲区.shp"; //裁剪 ESRI.ArcGIS.AnalysisTools.Clip clipTool = new ESRI.ArcGIS.AnalysisTools.Clip(); clipTool.in_features = @"C:UsersDemaciaDesktop展示China_Project.shp"; clipTool.clip_features = bufferTool.out_feature_class; clipTool.out_feature_class = @"C:UsersDemaciaDesktop展示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:UsersDemaciaDesktop展示控制点.shp"); varParam.Add(@"C:UsersDemaciaDesktop展示缓冲区.shp"); varParam.Add(2000); gp.ExecuteASync("Buffer_analysis", varParam);