田坎系数是指耕地图斑中田坎面积与耕地图斑面积的比例。实现方式大致如下:
1.以地块面对田坎线进行空间包含查询,查询出面中包含的所有田坎线要素
2.将查询到的田坎线的面积进行累加求和
3.将第2步获取到的田坎线面积之和除以地块面积,即可以得到该图斑的田坎系数。
源码及插件下载地址见最后
基于AddIN实现该插件,界面如下:
界面代码:
<Window x:Class="LandArrangeTemp.TKParaSetForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Title="田坎参数计算"
ResizeMode="NoResize"
Height="410" Width="400" MaxWidth="400" MaxHeight="410">
<Grid>
<GroupBox Header="图斑" HorizontalAlignment="Left" Margin="10,5,0,0" VerticalAlignment="Top" Height="161" Width="374">
<Grid>
<Label Content="图层" HorizontalAlignment="Left" Margin="45,10,0,0" VerticalAlignment="Top"/>
<ComboBox HorizontalAlignment="Left" Name="cmbPLayer" Margin="95,10,0,0" VerticalAlignment="Top" Width="260" SelectionChanged="cmbPLayer_SelectionChanged" Height="21"/>
<Label Content="扣除(田坎)系数" HorizontalAlignment="Left" Margin="1,109,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.165,0.07"/>
<ComboBox HorizontalAlignment="Left" Name="cmbKCXSFd" Margin="95,111,0,0" VerticalAlignment="Top" Width="260"/>
<Label Content="图斑面积" HorizontalAlignment="Left" Margin="30,41,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.165,0.07"/>
<ComboBox HorizontalAlignment="Left" Name="cmbTBAreaFd" Margin="95,44,0,0" VerticalAlignment="Top" Width="260" Height="21"/>
<Label Content="扣除面积" HorizontalAlignment="Left" Margin="30,75,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.165,0.07"/>
<ComboBox HorizontalAlignment="Left" x:Name="cmbKCMJFd" Margin="95,77,0,0" VerticalAlignment="Top" Width="260" Height="21"/>
</Grid>
</GroupBox>
<GroupBox Header="田坎" HorizontalAlignment="Left" Margin="7,206,0,0" VerticalAlignment="Top" Height="107" Width="374">
<Grid>
<Label Content="图层" HorizontalAlignment="Left" Margin="28,8,0,0" VerticalAlignment="Top"/>
<ComboBox HorizontalAlignment="Left" Name="cmbTKLayer" Margin="68,10,0,0" VerticalAlignment="Top" Width="284" SelectionChanged="cmbTKLayer_SelectionChanged"/>
<Label Content="面积" HorizontalAlignment="Left" Margin="28,48,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.165,0.07"/>
<ComboBox HorizontalAlignment="Left" Name="cmbTKMJFd" Margin="68,49,0,0" VerticalAlignment="Top" Width="284"/>
</Grid>
</GroupBox>
<Button Content="确定" Name="btnOK" HorizontalAlignment="Left" Margin="80,326,0,0" VerticalAlignment="Top" Width="85" Height="31" Click="btnOK_Click"/>
<Button Content="取消" Name="btnCancel" HorizontalAlignment="Left" Margin="227,326,0,0" VerticalAlignment="Top" Width="85" Height="31" Click="btnCancel_Click"/>
<Label Content="空间关系" HorizontalAlignment="Left" Margin="23,180,0,0" VerticalAlignment="Top"/>
<ComboBox HorizontalAlignment="Left" Name="cmbSpatialRel" Margin="86,180,0,0" VerticalAlignment="Top" Width="273" SelectionChanged="cmbSpatialRel_SelectionChanged">
<ComboBoxItem Content="空间包含"></ComboBoxItem>
<ComboBoxItem Content="空间相交"></ComboBoxItem>
</ComboBox>
</Grid>
</Window>
界面逻辑代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
namespace LandArrangeTemp
{
/// <summary>
/// TKParaSetForm.xaml 田坎参数计算逻辑
/// </summary>
public partial class TKParaSetForm : Window
{
private IFeatureLayer polygonFtLyr = null;
/// <summary>
/// 图斑图层
/// </summary>
public IFeatureLayer PolygonFtLyr
{
get { return polygonFtLyr; }
set { polygonFtLyr = value; }
}
/// <summary>
/// 图斑面积字段
/// </summary>
private string tb_area_Fd;
public string Tb_area_Fd
{
get { return tb_area_Fd; }
set { tb_area_Fd = value; }
}
private string kcmj_fd;
/// <summary>
/// 扣除面积字段
/// </summary>
public string Kcmj_fd
{
get { return kcmj_fd; }
set { kcmj_fd = value; }
}
private string kcxs_fd;
/// <summary>
/// 扣除系数字段
/// </summary>
public string Kcxs_fd
{
get { return kcxs_fd; }
set { kcxs_fd = value; }
}
private IFeatureLayer tkFtLyr = null;
/// <summary>
/// 田坎线图层
/// </summary>
public IFeatureLayer TkFtLyr
{
get { return tkFtLyr; }
set { tkFtLyr = value; }
}
private esriSpatialRelEnum spatialRel = esriSpatialRelEnum.esriSpatialRelContains;
/// <summary>
/// 查询关系
/// </summary>
public esriSpatialRelEnum SpatialRel
{
get { return spatialRel; }
set { spatialRel = value; }
}
private string tk_area_Fd;
/// <summary>
/// 田坎面积字段
/// </summary>
public string Tk_area_Fd
{
get { return tk_area_Fd; }
set { tk_area_Fd = value; }
}
private IMap pMap = null;
public TKParaSetForm()
{
InitializeComponent();
pMap = ArcMap.Document.FocusMap;
GISCommonHelper.CartoLyrHelper.setFeatureLyrCombox(ref cmbPLayer, pMap, esriGeometryType.esriGeometryPolygon);
GISCommonHelper.CartoLyrHelper.setFeatureLyrCombox(ref cmbTKLayer, pMap, esriGeometryType.esriGeometryPolyline);
}
private void cmbPLayer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cmbPLayer.SelectedIndex > -1)
{
polygonFtLyr = cmbPLayer.SelectedValue as IFeatureLayer;
GISCommonHelper.CartoFieldHelper.setFieldCombox(ref cmbKCMJFd, polygonFtLyr.FeatureClass.Fields);
GISCommonHelper.CartoFieldHelper.setFieldCombox(ref cmbKCXSFd, polygonFtLyr.FeatureClass.Fields);
GISCommonHelper.CartoFieldHelper.setFieldCombox(ref cmbTBAreaFd, polygonFtLyr.FeatureClass.Fields);
if (polygonFtLyr.FeatureClass.Fields.FindField("TBMJ") != -1)
{
cmbTBAreaFd.SelectedValue = "TBMJ";
}
if (polygonFtLyr.FeatureClass.Fields.FindField("KCXS") != -1)
{
cmbKCXSFd.SelectedValue = "KCXS";
}
}
}
private void cmbTKLayer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cmbTKLayer.SelectedIndex > -1)
{
tkFtLyr = cmbTKLayer.SelectedValue as IFeatureLayer;
GISCommonHelper.CartoFieldHelper.setFieldCombox(ref cmbTKMJFd, tkFtLyr.FeatureClass.Fields);
if (tkFtLyr.FeatureClass.Fields.FindField("MJ") != -1)
{
cmbTKMJFd.SelectedValue = "MJ";
}
}
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
private void btnOK_Click(object sender, RoutedEventArgs e)
{
if (cmbPLayer.SelectedIndex == -1)
{
MessageBox.Show("请设置图斑图层");
return;
}
if (cmbTKLayer.SelectedIndex == -1)
{
MessageBox.Show("请设置田坎图层");
return;
}
if (cmbKCXSFd.SelectedIndex == -1)
{
MessageBox.Show("请设置扣除(田坎)系数图层");
return;
}
else
{
kcxs_fd = cmbKCXSFd.SelectedValue.ToString();
}
if (cmbKCMJFd.SelectedIndex == -1)
{
MessageBox.Show("请设置扣除面积图层");
return;
}
else
{
kcmj_fd = cmbKCMJFd.SelectedValue.ToString();
}
if (cmbTKMJFd.SelectedIndex == -1)
{
MessageBox.Show("请设置田坎面积图层");
return;
}
else
{
tk_area_Fd = cmbTKMJFd.SelectedValue.ToString();
}
if (cmbTBAreaFd.SelectedIndex == -1)
{
MessageBox.Show("请设置图斑面积字段");
return;
}
else
{
tb_area_Fd = cmbTBAreaFd.SelectedValue.ToString();
}
if (cmbSpatialRel.SelectedIndex == -1)
{
MessageBox.Show("请设置空间关系");
return;
}
this.DialogResult = true;
}
private void cmbSpatialRel_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cmbSpatialRel.SelectedIndex == 0)
{
spatialRel = esriSpatialRelEnum.esriSpatialRelContains;
}
else if (cmbSpatialRel.SelectedIndex == 1)
{
spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
}
else
{
spatialRel = esriSpatialRelEnum.esriSpatialRelContains;
}
}
}
}
核心代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Windows;
namespace LandArrangeTemp
{
public class btnTKPara : ESRI.ArcGIS.Desktop.AddIns.Button
{
public btnTKPara()
{
}
/// <summary>
/// 图斑图层要素类
/// </summary>
IFeatureClass pPolygonFtCls = null;
/// <summary>
/// 田坎图层要素类
/// </summary>
IFeatureClass pTKFtCls = null;
protected override void OnClick()
{
//
// TODO: Sample code showing how to access button host
//
ArcMap.Application.CurrentTool = null;
try
{
TKParaSetForm tsf = new TKParaSetForm();
if (tsf.ShowDialog().Value)
{
pPolygonFtCls = tsf.PolygonFtLyr.FeatureClass;
pTKFtCls = tsf.TkFtLyr.FeatureClass;
//打开编辑模式
IWorkspaceEdit pwsEdit = (pPolygonFtCls as IDataset).Workspace as IWorkspaceEdit;
pwsEdit.StartEditing(false);
pwsEdit.StartEditOperation();
//对图斑图层进行遍历
IFeatureCursor pftCursor = pPolygonFtCls.Update(null, true);
IFeature pFeature = pftCursor.NextFeature();
while (pFeature != null)
{
//计算当前图斑中所有田坎线的面积
double tk_area = CalculateTKArea(pFeature, tsf);
//获取图斑编辑
double tb_area = (double)pFeature.get_Value(pFeature.Fields.FindField(tsf.Tb_area_Fd));
//田坎面积除以图斑面积得到田坎系数,写入图斑字段中
pFeature.set_Value(pFeature.Fields.FindField(tsf.Kcxs_fd), tk_area / tb_area);
//田坎面积写入图斑字段中
pFeature.set_Value(pFeature.Fields.FindField(tsf.Kcmj_fd), tk_area);
//更新
pftCursor.UpdateFeature(pFeature);
//遍历至下一个要素
pFeature = pftCursor.NextFeature();
}
pwsEdit.StopEditOperation();
pwsEdit.StopEditing(true);
MessageBox.Show("处理完成");
}
}
catch (Exception ex)
{
MessageBox.Show("发生未知异常:" + ex.Message);
}
}
/// <summary>
/// 计算田坎面积
/// </summary>
/// <param name="pFeature"></param>
/// <param name="tsf"></param>
/// <returns></returns>
private double CalculateTKArea(IFeature pFeature, TKParaSetForm tsf)
{
double re = 0.0;
//构建空间查询条件
ISpatialFilter psf = new SpatialFilterClass();
psf.Geometry = pFeature.ShapeCopy;
psf.SpatialRel = tsf.SpatialRel;
//以图斑面进行空间查询,查询当前面中所有的要素(条件为包含或相交,根据用户设置),并进行遍历
IFeatureCursor pftcursor = pTKFtCls.Search(psf, false);
IFeature pTkFeature = pftcursor.NextFeature();
while (pTkFeature != null)
{
//获取田坎的面积
double area = (double)pTkFeature.get_Value(pTkFeature.Fields.FindField(tsf.Tk_area_Fd));
//面积累加
re += area;
pTkFeature = pftcursor.NextFeature();
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(pftcursor);
return re;
}
protected override void OnUpdate()
{
Enabled = ArcMap.Application != null;
}
}
}
源码及插件下载地址:
链接: https://pan.baidu.com/s/1ZBuDFTFXos-4ANqQARLQfw 提取码: fud1