ArcGIS AddIN 田坎系数计算

田坎系数是指耕地图斑中田坎面积与耕地图斑面积的比例。实现方式大致如下:

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 

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

猜你喜欢

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