ArcEngine的排序方法有多种,下面介绍一下主要的四种方法。
准备数据
测试数据如下图所示:新建一个Geodatabase的要素类,其中Name为道路名称,Width为道路宽度,下面将根据Width字段进行倒序排序。
方法一:IQueryFilterDefinition接口
利用IQueryFilterDefinition
接口我们可以定义排序语句,代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
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;
DataTable dataTable = GetDataTable(pFeatureLayer.FeatureClass);
dataGridView1.DataSource = dataTable;
}
private DataTable GetDataTable(IFeatureClass pFeatureClass)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("OBJECTID");
dataTable.Columns.Add("Name");
dataTable.Columns.Add("Width");
dataTable.Columns.Add("SHAPE_Length");
// 字段索引
int fieldIndex_OBJECTID = pFeatureClass.Fields.FindField("OBJECTID");
int fieldIndex_Name = pFeatureClass.Fields.FindField("Name");
int fieldIndex_Width = pFeatureClass.Fields.FindField("Width");
int fieldIndex_SHAPE_Length = pFeatureClass.Fields.FindField("SHAPE_Length");
// 字段排序
IQueryFilter pQueryFilter = new QueryFilter();
IQueryFilterDefinition pQueryFilterDefinition = pQueryFilter as IQueryFilterDefinition;
pQueryFilterDefinition.PostfixClause = "order by Width desc";
// 要素游标
IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = pFeature.get_Value(fieldIndex_OBJECTID).ToString();
dataRow[1] = pFeature.get_Value(fieldIndex_Name).ToString();
dataRow[2] = pFeature.get_Value(fieldIndex_Width).ToString();
dataRow[3] = pFeature.get_Value(fieldIndex_SHAPE_Length).ToString();
dataTable.Rows.Add(dataRow);
pFeature = pFeatureCursor.NextFeature();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
return dataTable;
}
}
}
排序结果如下图所示:
方法二:IQueryDef2接口
利用IQueryDef2
也可以实现排序功能,该接口只对Geodatabase的数据有效,不支持shp文件。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
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;
DataTable dataTable = GetDataTable(pFeatureLayer.FeatureClass);
dataGridView1.DataSource = dataTable;
}
private DataTable GetDataTable(IFeatureClass pFeatureClass)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("OBJECTID");
dataTable.Columns.Add("Name");
dataTable.Columns.Add("Width");
dataTable.Columns.Add("SHAPE_Length");
// 字段索引
ITable pTable = pFeatureClass as ITable;
int fieldIndex_OBJECTID = pTable.Fields.FindField("OBJECTID");
int fieldIndex_Name = pTable.Fields.FindField("Name");
int fieldIndex_Width = pTable.Fields.FindField("Width");
int fieldIndex_SHAPE_Length = pTable.Fields.FindField("SHAPE_Length");
// 获取工作空间
IDataset pDataset = pFeatureClass as IDataset;
IWorkspace pWorkspace = pDataset.Workspace;
IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
// 字段排序
IQueryDef2 pQueryDef = pFeatureWorkspace.CreateQueryDef() as IQueryDef2;
pQueryDef.Tables = pFeatureClass.AliasName;
pQueryDef.PostfixClause = "order by Width desc";
// 要素游标
ICursor pCursor = pQueryDef.Evaluate2(true);
IRow pRow = pCursor.NextRow();
while (pRow != null)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = pRow.get_Value(fieldIndex_OBJECTID).ToString();
dataRow[1] = pRow.get_Value(fieldIndex_Name).ToString();
dataRow[2] = pRow.get_Value(fieldIndex_Width).ToString();
dataRow[3] = pRow.get_Value(fieldIndex_SHAPE_Length).ToString();
dataTable.Rows.Add(dataRow);
pRow = pCursor.NextRow();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(pCursor);
return dataTable;
}
}
}
排序结果如下图所示:
方法三:ITableSort接口
利用ITableSort
接口也可以实现排序效果。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
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;
DataTable dataTable = GetDataTable(pFeatureLayer.FeatureClass);
dataGridView1.DataSource = dataTable;
}
private DataTable GetDataTable(IFeatureClass pFeatureClass)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("OBJECTID");
dataTable.Columns.Add("Name");
dataTable.Columns.Add("Width");
dataTable.Columns.Add("SHAPE_Length");
// 字段索引
ITable pTable = pFeatureClass as ITable;
int fieldIndex_OBJECTID = pTable.Fields.FindField("OBJECTID");
int fieldIndex_Name = pTable.Fields.FindField("Name");
int fieldIndex_Width = pTable.Fields.FindField("Width");
int fieldIndex_SHAPE_Length = pTable.Fields.FindField("SHAPE_Length");
// 字段排序
ITableSort pTableSort = new TableSort();
pTableSort.Table = pFeatureClass as ITable;
pTableSort.Fields = "Width";
pTableSort.set_Ascending("Width", false);
pTableSort.Sort(null);
// 要素游标
ICursor pCursor = pTableSort.Rows;
IRow pRow = pCursor.NextRow();
while (pRow != null)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = pRow.get_Value(fieldIndex_OBJECTID).ToString();
dataRow[1] = pRow.get_Value(fieldIndex_Name).ToString();
dataRow[2] = pRow.get_Value(fieldIndex_Width).ToString();
dataRow[3] = pRow.get_Value(fieldIndex_SHAPE_Length).ToString();
dataTable.Rows.Add(dataRow);
pRow = pCursor.NextRow();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(pCursor);
return dataTable;
}
}
}
排序结果如下图所示:
方法四:ITableSort + ITableSortCallBack实现自定义排序
很多情况下我们需要定义我们自己的排序规则,现在将数据表修改一下,如下图所示:Info字段记录了每条道路的名称和宽度,中间以"_"进行分隔。
现在我们希望只根据每条道路的宽度进行倒序排序,如果还是采用上述方法,你可能会得到这样的结果:
很明显这不是我们想要的结果,不过还好ArcEngine给我们提供了一个ITableSortCallBack
接口,利用这个接口我们可以自己定义排序规则,代码如下所示:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
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;
DataTable dataTable = GetDataTable(pFeatureLayer.FeatureClass);
dataGridView1.DataSource = dataTable;
}
private DataTable GetDataTable(IFeatureClass pFeatureClass)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("OBJECTID");
dataTable.Columns.Add("SHAPE_Length");
dataTable.Columns.Add("Info");
// 字段索引
ITable pTable = pFeatureClass as ITable;
int fieldIndex_OBJECTID = pTable.Fields.FindField("OBJECTID");
int fieldIndex_SHAPE_Length = pTable.Fields.FindField("SHAPE_Length");
int fieldIndex_Info = pTable.Fields.FindField("Info");
// 字段排序
ITableSort pTableSort = new TableSort();
pTableSort.Table = pFeatureClass as ITable;
pTableSort.Compare = new CustomerSortRole();
pTableSort.Fields = "Info";
pTableSort.set_Ascending("Info", false);
pTableSort.Sort(null);
// 要素游标
ICursor pCursor = pTableSort.Rows;
IRow pRow = pCursor.NextRow();
while (pRow != null)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = pRow.get_Value(fieldIndex_OBJECTID).ToString();
dataRow[1] = pRow.get_Value(fieldIndex_SHAPE_Length).ToString();
dataRow[2] = pRow.get_Value(fieldIndex_Info).ToString();
dataTable.Rows.Add(dataRow);
pRow = pCursor.NextRow();
}
// 释放游标
System.Runtime.InteropServices.Marshal.ReleaseComObject(pCursor);
return dataTable;
}
}
// 自定义排序规则
public class CustomerSortRole : ITableSortCallBack
{
public int Compare(object value1, object value2, int FieldIndex, int fieldSortIndex)
{
double a = double.Parse(value1.ToString().Substring(value1.ToString().IndexOf("_") + 1));
double b = double.Parse(value2.ToString().Substring(value2.ToString().IndexOf("_") + 1));
if (a < b)
{
return -1;
}
else if (a == b)
{
return 0;
}
else
{
return 1;
}
}
}
}
排序结果如下图所示: