ArcEngine實現要素類排序的四種方法

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

排序結果如下圖所示:
在這裏插入圖片描述

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