该功能实现将一幅影像按照矢量数据定义的区域,裁剪成不同的区域图像。比如,可以将一整幅影像,按照行政区划,切割成不同行政区的影像,或者按照标准分幅,切割成不同图幅的影像。
窗体端代码 主要实现对影像裁剪功能相关参数的获取。
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任务的委托。上述代码不影响影像分割功能的实现。