ArcEngine——异步执行GP工具(Background geoprocessing)

Posted songqingguo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArcEngine——异步执行GP工具(Background geoprocessing)相关的知识,希望对你有一定的参考价值。

从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);

 

以上是关于ArcEngine——异步执行GP工具(Background geoprocessing)的主要内容,如果未能解决你的问题,请参考以下文章

ArcEngine尝试读取或写入受保护的内存

ArcEngine GP工具使用心得

ArcEngine GP工具使用心得

Arcengine调用GP服务

我在做C#+ArcEngine开发,调用GP服务时,使用geodatabase中数据库中的数据怎么不行??请高人指点!!!!

ArcEngine 拓扑检查 总结