AE+C# 缓冲区的实现(GeoProcessor的用法)

最近在做一个地理信息系统,需要实现缓冲区分析的功能。在网上、参考书上参考别人的代码。发现了一个大bug,一直解决不了,遂奋战至凌晨三点半。终于解决啦~

先搭建窗体:
AE+C# 缓冲区的实现(GeoProcessor的用法)_第1张图片
选择图层 :comboBox1
缓冲距离 :textBox1
输出路径 :textBox2
确认:button1
取消:button2

(一)变量以及构造函数的的定义

        //变量的定义
        private IActiveView pActiveView;
        private AxMapControl mapControl;

        public Buffer()
        {
            InitializeComponent();
        }

        //构建含参构造函数,将主窗体的AxMapControl传进来
        public Buffer(AxMapControl mainMapControl):this()
        {
            mapControl = mainMapControl;
            pActiveView = mainMapControl.ActiveView;
        }
        
        //窗体加载
        private void Buffer_Load(object sender, EventArgs e)
        {
            if (mapControl == null || pActiveView.FocusMap.LayerCount == 0)
            {
                return;
            }
            
            IEnumLayer layers = pActiveView.FocusMap.get_Layers();
            layers.Reset();
            ILayer layer = layers.Next();
            
            while (layer != null)
            {
                comboBox1.Items.Add(layer.Name);
                layer = layers.Next();
            }
        }
        
        //设置输出路径
        private void textBox2_MouseDown(object sender, MouseEventArgs e)
        {
            //set the output layer
            SaveFileDialog saveDlg = new SaveFileDialog();
            saveDlg.CheckPathExists = true;
            saveDlg.Filter = "Shapefile (*.shp)|*.shp";
            saveDlg.OverwritePrompt = true;
            saveDlg.Title = "Output Layer";
            saveDlg.RestoreDirectory = true;
            saveDlg.FileName = (string)comboBox1.SelectedItem + "_buffer.shp";

            DialogResult dr = saveDlg.ShowDialog();
            if (dr == DialogResult.OK)
                textBox2.Text = saveDlg.FileName;
        }
        
        //取消
        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        
        //获取图层源路径
        public static string getLayerPath(ILayer pLayer)
        {
            IDatasetName pDatasetName = (pLayer as IDataLayer2).DataSourceName as IDatasetName;
            IWorkspaceName pWorkspaceName = pDatasetName.WorkspaceName;
            return pWorkspaceName.PathName + "\\" + pLayer.Name + ".shp";
        }
        
        //确认
        private void button1_Click(object sender, EventArgs e)
        {

            double bufferDistance = Convert.ToDouble(textBox1.Text.Trim());

            if (bufferDistance == 0.0)
            {
                MessageBox.Show("缓冲区距离有误!");
                return;
            }

            if (comboBox1.Text == string.Empty)
            {
                MessageBox.Show("输入图层不能为空!");
                return;
            }

            if (textBox2.Text == string.Empty)
            {
                MessageBox.Show("输出路径不能为空!");
                return;
            }
            int index = comboBox1.SelectedIndex;
            string name = getLayerPath(pActiveView.FocusMap.get_Layer(index));
            string outPath = textBox2.Text;

            //Geoprocessor对象的定义
            ESRI.ArcGIS.Geoprocessor.Geoprocessor pGp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
            //以下两种情况下会报错。
            //GeoProcessor pGp = new GeoProcessor();
            //IGeoProcessor2 pGp = new GeoProcessorClass();
            pGp.OverwriteOutput = true; //允许运算结果覆盖现有文件,可无
            ESRI.ArcGIS.AnalysisTools.Buffer pBuffer = new ESRI.ArcGIS.AnalysisTools.Buffer();

            //获取缓冲区分析图层
            ILayer pLayer = pActiveView.FocusMap.get_Layer(index);
            IFeatureLayer featLayer = pLayer as IFeatureLayer;
            //IFeatureCursor cursor = featLayer.Search(null, false);
            //IFeature feaClass = cursor.NextFeature();

            pBuffer.in_features = featLayer;
            pBuffer.out_feature_class = outPath; //输出路径
            pBuffer.buffer_distance_or_field = bufferDistance; //缓冲区参数
            pBuffer.dissolve_option = "NONE"; //融合缓冲区重叠交叉部分,如果不融合填"ALL"
            pGp.Execute(pBuffer, null); //执行

            string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夹位置
            string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
            mapControl.AddShapeFile(pFolder, pFileName); //往地图控件里添加文件
            mapControl.ActiveView.Refresh(); //激活窗口刷新
            this.Close();
        }

对于我上面提到的bug,就是在我在执行GeoProcessor.Excute()方法时,一直弹出以下错误:
在这里插入图片描述
昨天遇到这个问题,当时差点崩溃,因为查了一天资料,别人的用法都是这样。差点想重装VS。突然灵机一动,去对象浏览器里看了一下:

解决方法:
定义Geoprocessor对象时,要用:

ESRI.ArcGIS.Geoprocessor.Geoprocessor pGp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();

而不能直接用:

GeoProcessor pGp = new GeoProcessor();

补充:
在写这篇博客时,我突然灵机一动,是不是我加的引用不对,我昨天其实已经加了下面的引用,后来发现没用到,就注释掉了,但是我发现:将GeoProcessor改成小写p的Geoprocessor,就不用向我上面那么麻烦了。

using ESRI.ArcGIS.Geoprocessor;
Geoprocessor GP = new Geoprocessor();

emmmm…无语。

你可能感兴趣的:(ArcGis,AE,VS)