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:\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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM