田坎係數是指耕地圖斑中田坎面積與耕地圖斑面積的比例。實現方式大致如下:
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