在做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;
}
}
}