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 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章