ArcEngine|使用GP工具实现缓冲区分析与叠置分析

发布时间 2023-04-18 14:15:13作者: Weltㅤ

ArcEngine|使用GP工具实现缓冲区分析与叠置分析

GP工具简介

地理处理是ArcGIS 的一个重要概念,其目的是便于用户自动执行GIS的空间分析和建模任务。地理处理工具是将GIS中常用、可重复的操作,如提取与叠加数据、更改地图投影等封装成一个具有参数输人输出的交互式图形界面。地理处理通过脚本将一系列的工具按照一定的操作顺序结合在一起,共同完成一项地理处理任务。其工具都储存在工具箱中,ArcGIS提供了数百种工具,并根据功能将它们分别放到了十余个工具箱中。ArcToolbox是所有工具的集合, 提供工具运行的环境。在ArcGIS Engine编程过程中,可以通过调用GP工具来实现某些常用的功能。

调用GP工具主要应用了Geoprocessor类,这个类也可以调用人们自定义的工具。在使用Geoprocessor 类时,需要首先定义一个Geoprocessor 对象, Geoprocessor是简化调用Geoprocessing工具任务的主要对象。这个对象是执行ArcGIS 中任何Geoprocessing 工具的唯一访问点,它是一个粗粒度对象, 包含了许多属性和方法,在设置完相关的参数后,则通过Geoprocessor 的Excute函数来执行,Excute方法中需要一个操作对象作为参数,如lntersect、Clip 等,具体包含哪些操作类,可通过ArcToolBox和Esri的帮助文档查找。

缓冲区分析

(1)建立【缓冲区分析】窗体

该窗体用于显示及设置输入图层、缓冲半径、融合类型、输出路径以及执行缓冲区分析功能的按钮等,其界面入下图所示:

image-20230413234538280

(2)功能实现的核心代码

public partial class BufferAnalysisTool : Form
{
    public IMap pMap { get; set; }
    public AxMapControl mapControl { get; set; }
    public BufferAnalysisTool()
    {
        InitializeComponent();
    }

    private void BufferAnalysisTool_Load(object sender, EventArgs e)
    {
        pMap = mapControl.Map;
        //向图层comboBox1中预置噪音来源
        if (pMap.LayerCount > 0)
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                if (pLayer != null)
                {
                    if (pLayer is IFeatureLayer)
                    {
                        comboBox_InputDataset.Items.Add(pLayer.Name);
                    }
                }
            }
            comboBox_InputDataset.SelectedIndex = 0;

            DistanceTextBox.Text = "500";
            this.comboBox1.Items.Add("NONE");//选择项1
            this.comboBox1.Items.Add("ALL");
            comboBox1.SelectedIndex = 0;
            textEdit_Output.Text = System.Environment.CurrentDirectory + "buffer.shp";
        }
        else return;
    }

    private void button3_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        SaveFileDialog flg = new SaveFileDialog();
        flg.Title = "保存路径";
        flg.Filter = "ShpFile(*shp)|*.shp";
        flg.ShowDialog();

        textEdit_Output.Text = flg.FileName;
    }

    private ILayer GetLayerByName(IMap pMap, string layerName)
    {
        ILayer pLayer = null;
        ILayer tempLayer = null;
        try
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                tempLayer = pMap.Layer[i];
                if (tempLayer.Name.ToUpper() == layerName.ToUpper())      //判断名字大写是否一致
                {
                    pLayer = tempLayer;
                    break;
                }
            }
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.Message);
        }
        return pLayer;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        try
        {
            ILayer inputDataset = GetLayerByName(pMap, comboBox_InputDataset.Text.Trim());
            IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
            //缓冲区分析-GP工具调用
            Geoprocessor gp = new Geoprocessor();
            gp.OverwriteOutput = true;
            ESRI.ArcGIS.AnalysisTools.Buffer pBuffer = new ESRI.ArcGIS.AnalysisTools.Buffer();
            pBuffer.in_features = inputLayer;
            //设置生成结果存储路径
            pBuffer.out_feature_class = textEdit_Output.Text;
            //设置缓冲区距离
            string buffer_distance = DistanceTextBox.Text + " Meters";
            pBuffer.buffer_distance_or_field = buffer_distance;
            pBuffer.dissolve_option = comboBox1.Text;
            //执行缓冲区分析
            gp.Execute(pBuffer, null);
            //将生成结果添加到地图中
            string pPath = System.IO.Path.GetDirectoryName(textEdit_Output.Text); //获取文件路径
            string pName = System.IO.Path.GetFileName(textEdit_Output.Text); //获取文件名
            this.mapControl.AddShapeFile(pPath, pName);
            this.mapControl.MoveLayerTo(1, 0);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

(3)在 menuStrip 中添加一个geoProcessing选项,并在其子选项中BufferTool选项,为其绑定 Click 事件。在 Click 事件处理方法中添加代码,显示【裁剪】窗体。

private void bufferToolToolStripMenuItem_Click(object sender, EventArgs e)
{
    GeoProcessing.BufferAnalysisTool BF = new GeoProcessing.BufferAnalysisTool();
    BF.mapControl = this.axMapControl1;
    BF.ShowDialog();
}

叠置分析

(1)建立叠置分析窗体

该窗体用于显示及设置与参与裁剪的数据、裁剪后输出的数据路径以及执行裁剪功能的按钮等,其界面入下图所示:

image-20230414002040336

(2)在叠置分析窗体中完成裁剪功能的代码如下:

public partial class OverlayAnalysisTool : Form
{
    public OverlayAnalysisTool()
    {
        InitializeComponent();
    }

    //定义全局变量
    public IMap pMap { get; set; }
    public AxMapControl mapControl { get; set; }

    private void OverlayAnalysisTool_Load(object sender, EventArgs e)
    {
        try
        {
            pMap = mapControl.Map;
            if (pMap == null)
                return;
            //清空combobox
            comboBox_InputDataset.Items.Clear();
            comboBox_ClipDataset.Items.Clear();

            string layerName;   //用于储存图层名字

            for (int i = 0; i < pMap.LayerCount; i++)
            {
                layerName = pMap.Layer[i].Name;
                comboBox_InputDataset.Items.Add(layerName);
                comboBox_ClipDataset.Items.Add(layerName);
            }

        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.Message);
        }
    }

    private void button2_OK_Click(object sender, EventArgs e)
    {

        if (pMap == null)
            return;
        //获取数据集
        ILayer inputDataset = GetLayerByName(pMap, comboBox_InputDataset.Text.Trim());
        ILayer clipDataset = GetLayerByName(pMap, comboBox_ClipDataset.Text.Trim());

        if (inputDataset != null && clipDataset != null)
        {
            IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
            IFeatureLayer clipLayer = clipDataset as IFeatureLayer;
            //利用裁剪方法来进行叠加分析
            IBasicGeoprocessor bGP = new BasicGeoprocessorClass();
            bGP.SpatialReference = pMap.SpatialReference;   //设置空间参考
            //创建FeatureClassNameClass对象,用于获取输入数据集的一些基本信息
            IFeatureClassName pOutput = new FeatureClassName() as IFeatureClassName;   
            pOutput.FeatureType = inputLayer.FeatureClass.FeatureType;
            pOutput.ShapeFieldName = inputLayer.FeatureClass.ShapeFieldName;
            pOutput.ShapeType = inputLayer.FeatureClass.ShapeType;

            //利用IDataset获得IWorkspaceName
            string fileDirectory = System.IO.Path.GetDirectoryName(textEdit_Output.Text.Trim());
            string fileName = System.IO.Path.GetFileName(textEdit_Output.Text.Trim());

            IWorkspaceFactory pWsFc = new ShapefileWorkspaceFactory();
            IWorkspace pWs = pWsFc.OpenFromFile(fileDirectory, 0);	//创建一个工作空间对象
            IDataset pDataset = pWs as IDataset;
            IWorkspaceName pWsN = pDataset.FullName as IWorkspaceName;	//获取工作空间的信息(获取输出路径)

            IDatasetName pDatasetName = pOutput as IDatasetName;	//获取或设置数据集中成员的名称信息
            pDatasetName.Name = fileName;	//设置数据集中的数据成员的名字
            pDatasetName.WorkspaceName = pWsN;	//设置输出的工作空间(输出路径)

            IFeatureClass featureClass = bGP.Clip(inputLayer.FeatureClass as ITable, false, clipLayer.FeatureClass as ITable, false, 0.01, pOutput);

            if (featureClass != null)
            {
                IFeatureLayer featLayer = new FeatureLayerClass();
                featLayer.FeatureClass = featureClass;
                featLayer.Name = featureClass.AliasName;
                //将结果添加到控件中
                mapControl.AddLayer(featLayer);
                mapControl.Refresh();
            }
        }
    }

    private void simpleButton_Cancel_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private ILayer GetLayerByName(IMap pMap, string layerName)
    {
        ILayer pLayer = null;
        ILayer tempLayer = null;
        try
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                tempLayer = pMap.Layer[i];
                if (tempLayer.Name.ToUpper() == layerName.ToUpper())      //判断名字大写是否一致
                {
                    pLayer = tempLayer;
                    break;
                }
            }
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.Message);
        }
        return pLayer;
    }

    private void simpleButton_Output_Click(object sender, EventArgs e)
    {
        SaveFileDialog flg = new SaveFileDialog();
        flg.Title = "保存路径";
        flg.Filter = "ShpFile(*shp)|*.shp";
        flg.ShowDialog();

        textEdit_Output.Text = flg.FileName;
    }
}

(3)在主窗体调用叠置分析窗口

在 menuStrip 中添加一个geoProcessing选项,并在其子选项中添加overlapTool选项,为其绑定 Click 事件。在 Click 事件处理方法中添加代码,显示【裁剪】窗体。

private void overlapToolToolStripMenuItem_Click(object sender, EventArgs e)
{
    GeoProcessing.OverlayAnalysisTool oA = new GeoProcessing.OverlayAnalysisTool();
    oA.mapControl = this.axMapControl1;
    oA.ShowDialog();
}

结果

缓冲区分析功能

导入数据

image-20230414083711165

打开缓冲区分析工具

image-20230414003648819

设置参数

image-20230414003956807

选择输出路径

image-20230414083908144

缓冲区分析结果

image-20230414084028205

叠置分析-裁剪功能

导入数据

image-20230414004434860

打开叠置分析工具

image-20230414004525895

设置参数

image-20230414005008003

选择输出路径

image-20230414005418736

叠置分析结果

image-20230414005405511