zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    Java 递归算法,遍历文件夹下的所有文件。
    基于appium的移动端自动化测试,密码键盘无法识别问题
    第一个脚印
    最简单ajax,$.post()用法
    关于图片title与alt
    iframe loading 效果
    iframe 跨域的高度自适应
    练习卷动式新闻广告牌
    JS学习笔记《数值与字符串相加篇》
    解决FLASH的层级问题
  • 原文地址:https://www.cnblogs.com/songqingguo/p/12640096.html
Copyright © 2011-2022 走看看