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