ArcEngine獲取字段唯一值的三種方法

在做GIS數據處理時,我們經常需要獲取某個字段的唯一值。我在這裏總結了三種方法,下面分別進行說明。

方法一:讀取表記錄

這種方法就是逐條讀取記錄,然後選用合適的數據結構進行查重,它的好處就在於:不必去考慮數據源是shp還是geodatabase,代碼如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;

namespace WindowsFormsApplication1
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            axMapControl1.LoadMxFile(@"E:\Users\dsf\Desktop\無標題.mxd");
        }

        private void btnSort_Click(object sender, EventArgs e)
        {
            IFeatureLayer pFeatureLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
            List<string> list = GetUniqueValue(pFeatureClass, "Name");
        }

        private List<string> GetUniqueValue(IFeatureClass pFeatureClass, string fieldName)
        {
            HashSet<string> hashset = new HashSet<string>();
            int fieldIndex = pFeatureClass.Fields.FindField(fieldName);

            // 屬性過濾器 
            IQueryFilter pQueryFilter = new QueryFilter();
            pQueryFilter.AddField(fieldName);

            // 要素遊標
            IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                string fieldValue = pFeature.get_Value(fieldIndex).ToString();
                if (!hashset.Contains(fieldValue))
                {
                    hashset.Add(fieldValue);
                }
                pFeature = pFeatureCursor.NextFeature();
            }

            // 釋放遊標
            System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
            return hashset.ToList();
        }
    }
}

方法二:IDataStatistics接口

其實ArcEngine爲我們提供了IDataStatistics接口,用它你也可以獲取某字段的唯一值,但是在數據量較大的情況下它會很慢,不過這種方法也有一個好處:不必去考慮數據源是shp還是geodatabase,代碼如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;

namespace WindowsFormsApplication1
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            axMapControl1.LoadMxFile(@"E:\Users\dsf\Desktop\無標題.mxd");
        }

        private void btnSort_Click(object sender, EventArgs e)
        {
            IFeatureLayer pFeatureLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
            List<string> list = GetUniqueValue(pFeatureClass, "Name");
        }

        private List<string> GetUniqueValue(IFeatureClass pFeatureClass, string fieldName)
        {
            // 屬性過濾器
            IQueryFilter pQueryFilter = new QueryFilter();
            pQueryFilter.AddField(fieldName);

            // 要素遊標
            IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
            ICursor pCursor = pFeatureCursor as ICursor;

            // 設置統計信息
            IDataStatistics pDataStatistics = new DataStatistics();
            pDataStatistics.Field = fieldName;
            pDataStatistics.Cursor = pCursor;

            // 獲取唯一值
            IEnumerator uniqueValues = pDataStatistics.UniqueValues;
            uniqueValues.Reset();

            // 遍歷唯一值
            List<string> list = new List<string>();
            while (uniqueValues.MoveNext())
            {
                list.Add(uniqueValues.Current.ToString());
            }
            return list;
        }
    }
}

方法三:IQueryDef接口

在數據量很大的情況下,使用IQueryDef接口是一個不錯的選擇,但注意:它只能用在Geodatabase數據源下,代碼如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;

namespace WindowsFormsApplication1
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            axMapControl1.LoadMxFile(@"E:\Users\dsf\Desktop\無標題.mxd");
        }

        private void btnSort_Click(object sender, EventArgs e)
        {
            IFeatureLayer pFeatureLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
            List<string> list = GetUniqueValue(pFeatureClass, "Name");
        }

        private List<string> GetUniqueValue(IFeatureClass pFeatureClass, string fieldName)
        {
            List<string> list = new List<string>();

            // 獲取工作空間
            IDataset pDataset = pFeatureClass as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;

            // 設置唯一值語句
            IQueryDef pQueryDef = pFeatureWorkspace.CreateQueryDef();
            pQueryDef.Tables = pDataset.Name;
            pQueryDef.SubFields = "distinct(" + fieldName + ")";

            // 遍歷唯一值
            ICursor pCursor = pQueryDef.Evaluate();
            IRow pRow = pCursor.NextRow();
            while (pRow != null)
            {
                list.Add(pRow.get_Value(0).ToString());
                pRow = pCursor.NextRow();
            }

            // 釋放遊標
            System.Runtime.InteropServices.Marshal.ReleaseComObject(pCursor);
            return list;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章