DayDreamInGIS ArcGIS-AddIn 之影像批量裁剪功能

该功能实现将一幅影像按照矢量数据定义的区域,裁剪成不同的区域图像。比如,可以将一整幅影像,按照行政区划,切割成不同行政区的影像,或者按照标准分幅,切割成不同图幅的影像。

窗体端代码 主要实现对影像裁剪功能相关参数的获取。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using AddInAssiter;
using GISCommonHelper;

namespace DayDreamInGISTool.ImageClip
{
    public partial class frmSet : Form
    {
        IMap pMap = null;
        List<name_Layer> imglyr_list;
        List<name_Layer> vector_list;

        private IFeatureLayer pVectorLyr = null;

        public IFeatureLayer PVectorLyr
        {
            get { return pVectorLyr; }
            set { pVectorLyr = value; }
        }
        private IRasterLayer pRstLyr = null;

        public IRasterLayer PRstLyr
        {
            get { return pRstLyr; }
            set { pRstLyr = value; }
        }

        private double bufferDis;

        public double BufferDis
        {
            get { return bufferDis; }
            set { bufferDis = value; }
        }

        private string clipField;

        public string ClipField
        {
            get { return clipField; }
            set { clipField = value; }
        }

        private string exportFormat;

        public string ExportFormat
        {
            get { return exportFormat; }
            set { exportFormat = value; }
        }

        private string savedPath;

        public string SavedPath
        {
            get { return savedPath; }
            set { savedPath = value; }
        }

        private bool useExtent;

        public bool UseExtent
        {
            get { return useExtent; }
            set { useExtent = value; }
        }

        public frmSet()
        {
            InitializeComponent();
        }

        private void frmSet_Load(object sender, EventArgs e)
        {
            cmbExportFormat.SelectedIndex = 0;
            pMap = ArcMap.Document.FocusMap;
            imglyr_list = new List<name_Layer>();
            vector_list = new List<name_Layer>();

            CartoLyrHelper.getAllLayer<IFeatureLayer>(ref vector_list, pMap);
            CartoLyrHelper.getAllLayer<IRasterLayer>(ref imglyr_list, pMap);

            cmbRasterLyr.DataSource = imglyr_list;
            cmbClipLyr.DataSource = vector_list;
            cmbRasterLyr.ValueMember = "layer";
            cmbRasterLyr.DisplayMember = "name";
            cmbClipLyr.ValueMember = "layer";
            cmbClipLyr.DisplayMember = "name";
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            pRstLyr = cmbRasterLyr.SelectedValue as IRasterLayer;
            clipField = cmbClipField.SelectedValue.ToString();
            if(!double.TryParse(txtBufferDis.Text,out bufferDis))
            {
                MessageBox.Show("缓冲距离请输入数字");
                return;
            }
            if (string.IsNullOrEmpty(txtSavePath.Text))
            {
                MessageBox.Show("请设置存储路径");
                return;
            }
            savedPath = txtSavePath.Text;
            exportFormat = cmbExportFormat.Items[cmbExportFormat.SelectedIndex].ToString();
            this.DialogResult = DialogResult.OK;
        }

        private void cmbClipLyr_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbClipField.Items.Clear();
            pVectorLyr = cmbClipLyr.SelectedValue as IFeatureLayer;
            if (pVectorLyr == null)
                return;
            IFields pFields = pVectorLyr.FeatureClass.Fields;
            List<Name_AliasName> filedlist = new List<Name_AliasName>();
            for (int i = 0; i < pFields.FieldCount; i++)
            {
                filedlist.Add(new Name_AliasName(pFields.get_Field(i).Name,pFields.get_Field(i).AliasName));
            }
            cmbClipField.DataSource=filedlist;
            cmbClipField.DisplayMember="alias_name";
            cmbClipField.ValueMember="name";
        }

        private void btnSelectPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                txtSavePath.Text = fbd.SelectedPath;
            }
        }
    }
}

Button代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using AddInAssiter;

namespace DayDreamInGISTool.ImageClip
{
    public class ImageClipCmd : ESRI.ArcGIS.Desktop.AddIns.Button
    {
        public ImageClipCmd()
        {
        }

        protected override void OnClick()
        {
            try
            {
                

                frmSet fs = new frmSet();
                if (fs.ShowDialog() == DialogResult.OK)
                {
                    RasterHelper rsh = new RasterHelper();

                    rsh.ClipRasterByFeatureLayer(fs.PRstLyr, fs.PVectorLyr, fs.ClipField, fs.BufferDis, fs.ExportFormat, fs.SavedPath, fs.UseExtent);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("发生未知异常");
            }          
        }

        protected override void OnUpdate()
        {
        }
    }
}

影像分割功能实现:

影像分割使用Geoprocessor中Clip工具实现,本质上通过代码调用该工具

该工具界面如下:


由于该工具是对影像数据图层按照某个范围进行分割,因此,只需要在代码中,对分割的范围要素进行遍历,以每个矢量范围作为范围调用该工具执行即可。

影像分割核心代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.DataManagementTools;
using System.IO;
using System.Windows.Forms;
using GISCommonHelper;
using AddInAssiter.Frms;

namespace AddInAssiter
{
    public class RasterHelper
    {
        private Geoprocessor gp;
        private Clip clp;
        private string txt_result;
        /// <summary>
        /// 处理后的结果
        /// </summary>
        public string Txt_result
        {
            get { return txt_result; }
            set { txt_result = value; }
        }

        private updateProgressDelegate updateProgress;
        /// <summary>
        /// 更新进度
        /// </summary>
        public updateProgressDelegate UpdateProgress
        {
            get { return updateProgress; }
            set { updateProgress = value; }
        }

        private comleteTaskDelegate completeTask;
        /// <summary>
        /// 完成操作
        /// </summary>
        public comleteTaskDelegate CompleteTask
        {
            get { return completeTask; }
            set { completeTask = value; }
        }

        /// <summary>
        /// 使用要素图层裁剪栅格图层
        /// </summary>
        /// <param name="pRstLyr"></param>
        /// <param name="pftlyr"></param>
        /// <param name="fieldname"></param>
        /// <param name="bufferDis"></param>
        /// <param name="exportFormat"></param>
        /// <param name="savePath"></param>
        public void ClipRasterByFeatureLayer(IRasterLayer pRstLyr,IFeatureLayer pftlyr,string fieldname,double bufferDis,string exportFormat,string savePath,bool useExtent)
        {
            //遍历
            int featurecount = pftlyr.FeatureClass.FeatureCount(null);

            Frms.frmProgress fp = new Frms.frmProgress("裁剪栅格中。。。", featurecount);
            Frms.updateProgressDelegate updateProgressDelegate = fp.updateProgressValue;
            Frms.comleteTaskDelegate acomplishTaskDelegate = fp.Complete;
            fp.Show();

            IFeatureCursor pftCursor = pftlyr.FeatureClass.Search(null, false);
            IFeature pFeature = pftCursor.NextFeature();
            int n = 1;
            while (pFeature != null)
            {
                if (updateProgressDelegate != null)
                    updateProgressDelegate(n, "正在裁剪第" + n.ToString() + "个影像");
                IPolygon pPolygon = pFeature.Shape as IPolygon;
                string savefilename = System.IO.Path.Combine(savePath, pFeature.get_Value(pFeature.Fields.FindField(fieldname)).ToString() + exportFormat);

                ITopologicalOperator ptop;
                if (useExtent)
                {
                    IEnvelope penv = pPolygon.Envelope;
                    ptop = GeometryHelper.envelope2Polygon(penv) as ITopologicalOperator;
                }
                else
                    ptop= pPolygon as ITopologicalOperator;
                IPolygon pLPolygon;
                if (bufferDis != 0)
                {
                    pLPolygon = (IPolygon)ptop.Buffer(bufferDis);
                }
                else
                    pLPolygon =(IPolygon)ptop;

                RstClipExcute(pRstLyr, pLPolygon, savefilename);
                System.Diagnostics.Debug.WriteLine("正在处理:"+n.ToString());
                updateProgressDelegate(n, "第" + n.ToString() + "个影像裁剪完毕" + System.DateTime.Now.ToLocalTime());
                pFeature=pftCursor.NextFeature();
                n++;
            }
            if (acomplishTaskDelegate != null)
                acomplishTaskDelegate(txt_result);
            System.Diagnostics.Debug.WriteLine(txt_result);
        }

        /// <summary>
        /// 执行栅格裁剪
        /// </summary>
        /// <param name="pRstLyr"></param>
        /// <param name="pLPolygon"></param>
        /// <param name="savefilename"></param>
        public void RstClipExcute(IRasterLayer pRstLyr, IPolygon pLPolygon, string savefilename)
        {
            if (gp == null)
            {
                gp = new Geoprocessor();
                gp.OverwriteOutput = true;
                gp.AddOutputsToMap = false;
                
            }

            if (clp == null)
                clp = new Clip();

            
            if (File.Exists(savefilename))
            {
                txt_result = string.Format("影像{0}已经存在,没有执行裁剪 {1}"+System.Environment.NewLine,System.IO.Path.GetFileName(savefilename),
                    DateTime.Now.ToLongTimeString());
                return;
                //File.Delete(savefilename);
            }
            
            IFeatureClass pftcls = GISCommonHelper.GeoDatabaseHelper.Geometry2FeatureClass(pLPolygon);

            clp.in_raster = pRstLyr;
            clp.out_raster = savefilename;
            clp.clipping_geometry = "ClippingGeometry";
            clp.in_template_dataset = pftcls;

            IGeoProcessorResult result = (IGeoProcessorResult)gp.Execute(clp, null);
            if (result.Status == ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded)
            {

            }
            else
            {
                txt_result = string.Format("影像{0}执行裁剪失败 {1}" + System.Environment.NewLine, System.IO.Path.GetFileName(savefilename),
                    DateTime.Now.ToLongTimeString());
            }
        }
    }
}

注意,frmProgress为进度窗体,updateProgressDelegate为进度更新委托,comleteTaskDelegate为完成所有GP任务的委托。上述代码不影响影像分割功能的实现。

发布了22 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u012839776/article/details/97978589