Arcengine查询翻页

*** Arcengine提供了IQueryFilterDefinition3的方法进行查询分页,但是这个方法是有版本要求的,我知道10.1和10.2版本没有这个接口,10.3和10.4版本没了解过,10.5版本以上是有的。但是用10.1版本怎么做翻页呢?我这里提供了两个思路:***
方法一:

//调转事件
  /// <summary>
        /// 跳转到第一页
        /// </summary>
        private void ToFirstPage()
        {
            _currentPageIndex = 1;
            GetAttribute(FirstDataOID, FirstDataOID + PageMaxSize, PageMaxSize, FirstDataOID, LastDataOID, false, true);
        }

        /// <summary>
        /// 上一页
        /// </summary>
        private void ToPreviousPage()
        {
            if (_currentPageIndex > 1)
            {
                _currentPageIndex--;
            }
            GetAttribute(_pageFirstOID, _pageLastOID, PageMaxSize, FirstDataOID, LastDataOID, false, false);
        }

        /// <summary>
        /// 下一页
        /// </summary>
        private void ToNextPage()
        {
            if (_currentPageIndex < _pageCount)
            {
                _currentPageIndex++;
                GetAttribute(_pageFirstOID, _pageLastOID, PageMaxSize, FirstDataOID, LastDataOID, true, false);
            }
        }

        /// <summary>
        /// 跳转到最后一页
        /// </summary>
        private void ToLastPage()
        {
            _currentPageIndex = _pageCount;
            GetPageFirstDataOID(_featureLayer.FeatureClass, _currentPageIndex, PageMaxSize, FirstDataOID, LastDataOID);
            GetAttribute(_pageFirstOID, _pageFirstOID + PageMaxSize, PageMaxSize, FirstDataOID, LastDataOID, true, true);
        }
  //二分法获取每一页的第一个OID,测试了10w+的数据,大概需要10s
  /// <summary>
        /// 获取跳转页的PageFirstOID
        /// </summary>
        /// <param name="featureClass"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageMaxSize"></param>
        private void GetPageFirstDataOID(IFeatureClass featureClass, int pageIndex, int pageMaxSize, int firstDataOID, int lastDataOID)
        {
            try
            {
                if (null != featureClass)
                {

                    //二分法获取翻页的pageFirstOID
                    int previousDataCount = (pageIndex - 1) * pageMaxSize + 1;
                    int thisPageFirstDataOID = (pageIndex - 1) * pageMaxSize;
                    int thisPageLastDataOID = lastDataOID;
                    int thisMiddleDataOID = (int)Math.Floor((thisPageFirstDataOID + thisPageLastDataOID) * 1.0 / 2);

                    IQueryFilter queryFilter = new QueryFilter();
                    IDataset dataset = _featureLayer.FeatureClass as IDataset;
                    IWorkspaceName workSpaceName = ((IDatasetName)dataset.FullName).WorkspaceName;
                    int _thisPageDataCount = 0;

                    //对GDB和shape文件分别处理
                    while (_thisPageDataCount != previousDataCount)
                    {
                        if (workSpaceName.WorkspaceFactoryProgID.IndexOf("FileGDBWorkspaceFactory") > -1)
                        {
                            queryFilter.WhereClause = $" {featureClass.OIDFieldName} between {firstDataOID} and {thisMiddleDataOID} ORDER BY {featureClass.OIDFieldName} ";
                        }
                        else if (workSpaceName.WorkspaceFactoryProgID.IndexOf("ShapefileWorkspaceFactory") > -1)
                        {
                            queryFilter.WhereClause = "\"" + $"{featureClass.OIDFieldName}" + "\"" + $" >= {firstDataOID} AND " + "\"" + $"{featureClass.OIDFieldName}" + "\"" + $" <= {thisMiddleDataOID} ORDER BY " + "\"" + $"{featureClass.OIDFieldName}" + "\"";
                        }
                        _thisPageDataCount = _featureLayer.FeatureClass.FeatureCount(queryFilter);
                        if (_thisPageDataCount > previousDataCount)
                        {

                            if (thisPageLastDataOID - thisPageFirstDataOID == 1)
                            {
                                thisPageLastDataOID = thisPageFirstDataOID;
                            }
                            else
                            {
                                thisPageLastDataOID = thisMiddleDataOID;
                            }
                        }
                        else if (_thisPageDataCount < previousDataCount)
                        {
                            if (thisPageLastDataOID - thisPageFirstDataOID == 1)
                            {
                                thisPageFirstDataOID = thisPageLastDataOID;
                            }
                            else
                            {
                                thisPageFirstDataOID = thisMiddleDataOID;
                            }
                        }
                        else
                        {
                            _pageFirstOID = thisMiddleDataOID;//_pageFirstOID 是全局变量
                        }
                        thisMiddleDataOID = (int)Math.Floor((thisPageFirstDataOID + thisPageLastDataOID) * 1.0 / 2);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("翻页失败", "错误提示:", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
//根据每一页第一个OID遍历数据,每次OID加上pageMaxSize,直到两个OID之间数据大于pageMaxSize时,遍历只取其中pageMaxSize个数据,记录pageLastOID
   /// <summary>
        /// 获取属性表数据
        /// <param name="pageFirstOID">当前页最小OID</param>  
        /// <param name="pageLastOID">当前页最大OID</param> 
        /// <param name="pageMaxSize">页面大小</param>  
        /// <param name="firstDataOID">所有数据最小OID</param>  
        /// <param name="lastDataOID">所有数据最大OID</param>  
        /// <param name="downFlag">是否向下查询</param>  
        /// <param name="firstOrLastFlag">是否是第一页或者最后一页</param>
        /// </summary>
        private void GetAttribute(int pageFirstOID, int pageLastOID, int pageMaxSize, int firstDataOID, int lastDataOID, bool downFlag, bool firstOrLastFlag)
        {
            DataTable dataTable = new DataTable();
            if (null != _featureLayer.FeatureClass)
            {
                ITable lyrtable = (ITable)_featureLayer;
                IQueryFilter queryFilter = new QueryFilter();
                IDataset dataset = _featureLayer.FeatureClass as IDataset;
                IWorkspaceName workSpaceName = ((IDatasetName)dataset.FullName).WorkspaceName;
                if (downFlag)
                {
                    int _thisPageDataCount = 0;
                    if (!firstOrLastFlag && pageLastOID < lastDataOID)
                    {
                        pageFirstOID = pageLastOID + 1;
                    }
                    if (workSpaceName.WorkspaceFactoryProgID.IndexOf("FileGDBWorkspaceFactory") > -1)
                    {
                        while (_thisPageDataCount < pageMaxSize && pageLastOID < lastDataOID)
                        {
                            queryFilter.WhereClause = $"{lyrtable.OIDFieldName} between {pageFirstOID} and {pageLastOID + pageMaxSize} ORDER BY {lyrtable.OIDFieldName}";
                            _thisPageDataCount = _featureLayer.FeatureClass.FeatureCount(queryFilter);
                            pageLastOID = pageLastOID + pageMaxSize;
                        }
                    }
                    else if (workSpaceName.WorkspaceFactoryProgID.IndexOf("ShapefileWorkspaceFactory") > -1)
                    {
                        while (_thisPageDataCount < pageMaxSize && pageLastOID < lastDataOID)
                        {
                            queryFilter.WhereClause = "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" >= {pageFirstOID} AND " + "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" <= { pageLastOID + pageMaxSize} ORDER BY " + "\"" + $"{lyrtable.OIDFieldName}" + "\"";
                            _thisPageDataCount = _featureLayer.FeatureClass.FeatureCount(queryFilter);
                            pageLastOID = pageLastOID + pageMaxSize;
                        }
                    }
                }
                else
                {
                    int _thisPageDataCount = 0;
                    if (!firstOrLastFlag && pageFirstOID > firstDataOID)
                    {
                        pageLastOID = pageFirstOID - 1;
                    }
                    if (workSpaceName.WorkspaceFactoryProgID.IndexOf("FileGDBWorkspaceFactory") > -1)
                    {
                        while (_thisPageDataCount < pageMaxSize && pageFirstOID > firstDataOID)
                        {
                            queryFilter.WhereClause = $" {lyrtable.OIDFieldName} between {pageFirstOID - pageMaxSize} and {pageLastOID} ORDER BY {lyrtable.OIDFieldName} ";
                            _thisPageDataCount = _featureLayer.FeatureClass.FeatureCount(queryFilter);
                            pageFirstOID = pageFirstOID - pageMaxSize;
                        }
                    }
                    else if (workSpaceName.WorkspaceFactoryProgID.IndexOf("ShapefileWorkspaceFactory") > -1)
                    {
                        while (_thisPageDataCount < pageMaxSize && pageLastOID < lastDataOID)
                        {
                            queryFilter.WhereClause = "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" >= {pageFirstOID - pageMaxSize} AND " + "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" <= {pageLastOID} ORDER BY " + "\"" + $"{lyrtable.OIDFieldName}" + "\"";
                            _thisPageDataCount = _featureLayer.FeatureClass.FeatureCount(queryFilter);
                            pageFirstOID = pageFirstOID - pageMaxSize;
                        }
                    }
                }
                dataTable = ToDataTable(lyrtable, _featureLayer.FeatureClass.Fields, _dataCount, pageFirstOID, pageLastOID, pageMaxSize, firstDataOID, lastDataOID, downFlag, firstOrLastFlag);//获取数据
                _attributeTableData = dataTable;
                RaisePropertyChanged(nameof(AttributeTableData));
            }
        }
        
        /// <summary>  
        /// 将ITable转换为DataTable  
        /// </summary>  
        /// <param name="mTable">数据</param>  
        /// <param name="fields">字段</param>  
        /// <param name="pageDataCount">总数据个数</param>  
        /// <param name="pageFirstOID">当前一页最小OID</param>  
        /// <param name="pageLastOID">当前页最大OID</param>  
        /// <param name="pageMaxSize">页面大小</param>  
        /// <param name="firstDataOID">所有数据最小OID</param>  
        /// <param name="lastDataOID">所有数据最大OID</param>  
        /// <param name="downFlag">是否向下查询</param>  
        /// <param name="firstOrLastFlag">是否是第一页或者最后一页</param>  
        /// <returns></returns>  
        public DataTable ToDataTable(ITable lyrtable, IFields fields, int pageDataCount, int pageFirstOID, int pageLastOID, int pageMaxSize, int firstDataOID, int lastDataOID, bool downFlag, bool firstOrLastFlag)
        {
            DataTable pTable = new DataTable();
            string queryFilterSubFilds = "";
            string geometryType = GetEsriGeometryType(((IFeatureLayer)lyrtable).FeatureClass.ShapeType);
            for (int i = 0; i < fields.FieldCount; i++)
            {
                pTable.Columns.Add(fields.get_Field(i).Name);
                if (fields.get_Field(i).Name.ToLower() != ((IFeatureLayer)lyrtable).FeatureClass.ShapeFieldName.ToLower())
                {
                    queryFilterSubFilds += fields.get_Field(i).Name + ",";
                }
            }
            if (queryFilterSubFilds.Length > 0)
            {
                queryFilterSubFilds = queryFilterSubFilds.Substring(0, queryFilterSubFilds.Length - 1);
            }
            try
            {
                IQueryFilter queryFilter = new QueryFilter();
                queryFilter.SubFields = queryFilterSubFilds;
                IDataset dataset = lyrtable as IDataset;
                IWorkspaceName workSpaceName = ((IDatasetName)dataset.FullName).WorkspaceName;
                if (workSpaceName.WorkspaceFactoryProgID.IndexOf("FileGDBWorkspaceFactory") > -1)
                {
                    queryFilter.WhereClause = $" {lyrtable.OIDFieldName} between {pageFirstOID} and {pageLastOID} ORDER BY {lyrtable.OIDFieldName} ";
                }
                else if (workSpaceName.WorkspaceFactoryProgID.IndexOf("ShapefileWorkspaceFactory") > -1)
                {
                    queryFilter.WhereClause = "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" >= {pageFirstOID} AND " + "\"" + $"{lyrtable.OIDFieldName}" + "\"" + $" <= {pageLastOID} ORDER BY " + "\"" + $"{lyrtable.OIDFieldName}" + "\"";

                }

                ICursor pCursor = lyrtable.Search(queryFilter, true);
                IRow pRrow = pCursor.NextRow();
                int pRrowSize = pageMaxSize;
                int OIDIndex = -1;

                //获取OIDindex和当前页第一个值的OID
                if (pRrow != null)
                {
                    for (int i = 0; i < pRrow.Fields.FieldCount; i++)
                    {
                        if (lyrtable.Fields.Field[i].Name == lyrtable.OIDFieldName)
                        {
                            OIDIndex = i;
                            break;
                        }
                    }
                    _pageFirstOID = Convert.ToInt32(pRrow.OID);
                }

                //遍历数据,获得Table
                while (pRrow != null && pRrowSize > 0)
                {
                    DataRow pRow = pTable.NewRow();
                    string[] StrRow = new string[pRrow.Fields.FieldCount];
                    for (int i = 0; i < pRrow.Fields.FieldCount; i++)
                    {
                        if (pRrow.Fields.Field[i].Name.ToLower() != ((IFeatureLayer)lyrtable).FeatureClass.ShapeFieldName.ToLower())
                        {
                            StrRow[i] = pRrow.get_Value(i).ToString();
                        }
                        else
                        {
                            StrRow[i] = geometryType;
                        }
                    }
                    pRow.ItemArray = StrRow;
                    pTable.Rows.Add(pRow);
                    pRrow = pCursor.NextRow();
                    --pRrowSize;
                    if (pRrowSize <= 0 || pRrow == null)//获取当前页最后一个值的OID
                    {
                        _pageLastOID = Convert.ToInt32(pRow[OIDIndex]);
                    }
                }
                return pTable;
            }
            catch (Exception ex)
            {
                return pTable;
            }
        }

方法二:

//翻页
  /// <summary>
        /// 跳转到第一页
        /// </summary>
        private void ToFirstPage()
        {
            _currentPageIndex = 1;
            ChangePage(_currentPageIndex - 1);
        }
   /// <summary>
        /// 上一页
        /// </summary>
        private void ToPreviousPage()
        {
            if (_currentPageIndex > 1)
            {
                _currentPageIndex--;
                ChangePage(_currentPageIndex - 1);
            }
        }

        /// <summary>
        /// 下一页
        /// </summary>
        private void ToNextPage()
        {
            if (_currentPageIndex < _pageCount)
            {
                _currentPageIndex++;
                ChangePage(_currentPageIndex - 1);
            }
        }

        /// <summary>
        /// 跳转到最后一页
        /// </summary>
        private void ToLastPage()
        {
            _currentPageIndex = _pageCount;
            ChangePage(_currentPageIndex - 1);
        }
//先找到每一页的第一个OBJECTID储存起来。测试list只存一个OBJECTID字段时能储存1.2亿条,与OBJECTID字段的复杂度有关,如果只存每一页的OBJECTID是够用了(数据量大也可以做两层list嵌套,这里不做考虑)
   private void GetUniqueValue(IFeatureClass pFeatureClass, string fieldName)
        {
            OIDListArry = new List<string>();
            int fieldIndex = pFeatureClass.Fields.FindField(fieldName);

            // 属性过滤器 
            IQueryFilter pQueryFilter = new QueryFilter();
            pQueryFilter.AddField(fieldName);

            // 要素游标
            IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
            IFeature pFeature = pFeatureCursor.NextFeature();
            int pageSizeCount = 1;
            try
            {
                while (pFeature != null)
                {
                    if (pageSizeCount % PageMaxSize == 1)
                    {
                        OIDListArry.Add(pFeature.Value[fieldIndex].ToString());
                        pageSizeCount = 1;
                    }
                    pageSizeCount++;
                    pFeature = pFeatureCursor.NextFeature();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("数据溢出!", "错误提示:", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            // 释放游标
            System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
        }
        
        //取得当前页firstOID和lastOID(lastOID为下一页firstOID-1,可能不存在,但是我们这里只是需要取到包含有pageSizeMax个数据的这个范围就行了)
  public void ChangePage(int pageIndex)
        {
            if (null != _featureLayer.FeatureClass)
            {
                DataTable pTable = new DataTable();
                string queryFilterSubFilds = "";
                string geometryType = GetEsriGeometryType(_featureLayer.FeatureClass.ShapeType);
                IFields fields = _featureLayer.FeatureClass.Fields;
                for (int i = 0; i < fields.FieldCount; i++)
                {
                    pTable.Columns.Add(fields.get_Field(i).Name);
                    if (fields.get_Field(i).Name.ToLower() != _featureLayer.FeatureClass.ShapeFieldName.ToLower())
                    {
                        queryFilterSubFilds += fields.get_Field(i).Name + ",";
                    }
                }
                if (queryFilterSubFilds.Length > 0)
                {
                    queryFilterSubFilds = queryFilterSubFilds.Substring(0, queryFilterSubFilds.Length - 1);
                }
                try
                {
                    IQueryFilter queryFilter = new QueryFilter();
                    queryFilter.SubFields = queryFilterSubFilds;
                    IDataset dataset = _featureLayer as IDataset;
                    IWorkspaceName workSpaceName = ((IDatasetName)dataset.FullName).WorkspaceName;

                    int firtOID = Convert.ToInt32(OIDListArry[pageIndex]);
                    int lastOID = firtOID + PageMaxSize;
                    if (pageIndex < (OIDListArry.Count - 1))
                    {
                        lastOID = Convert.ToInt32(OIDListArry[pageIndex + 1]) - 1;
                    }
                    else
                    {
                        lastOID = 0;
                    }

                    if (workSpaceName.WorkspaceFactoryProgID.IndexOf("FileGDBWorkspaceFactory") > -1)
                    {
                        queryFilter.WhereClause = $" {_featureLayer.FeatureClass.OIDFieldName} >= {firtOID} " + (lastOID == 0 ? "" : $" and {_featureLayer.FeatureClass.OIDFieldName} <= {lastOID} ") + $" ORDER BY {_featureLayer.FeatureClass.OIDFieldName} ";
                    }
                    else if (workSpaceName.WorkspaceFactoryProgID.IndexOf("ShapefileWorkspaceFactory") > -1)
                    {
                        queryFilter.WhereClause = "\"" + $"{_featureLayer.FeatureClass.OIDFieldName}" + "\"" + $" >= {firtOID} " + (lastOID == 0 ? "" : " AND\"" + $"{_featureLayer.FeatureClass.OIDFieldName}" + "\"" + $" <= {lastOID} ") + $" ORDER BY " + "\"" + $"{_featureLayer.FeatureClass.OIDFieldName}" + "\"";
                    }

                    ICursor pCursor = _featureLayer.FeatureClass.Search(queryFilter, true) as ICursor;
                    IRow pRrow = pCursor.NextRow();

                    //获取目标数据集对应源数据集索引字典
                    Dictionary<int, TargetFieldsModel> targetsource = new Dictionary<int, TargetFieldsModel>();
                    for (int i = 0; i < fields.FieldCount; i++)
                    {
                        IField tField = fields.get_Field(i);
                        targetsource.Add(i, new TargetFieldsModel { Name = tField.Name, TargetType = tField.Type });
                    }

                    //遍历数据,获得Table
                    while (pRrow != null)
                    {
                        DataRow pRow = pTable.NewRow();
                        string[] StrRow = new string[pRrow.Fields.FieldCount];
                        foreach (KeyValuePair<int, TargetFieldsModel> keyValue in targetsource)
                        {
                            if (keyValue.Value.Name.ToLower() != _featureLayer.FeatureClass.ShapeFieldName.ToLower())
                            {
                                StrRow[keyValue.Key] = pRrow.Value[keyValue.Key].ToString();
                            }
                            else
                            {
                                StrRow[keyValue.Key] = geometryType;
                            }
                        }
                        pRow.ItemArray = StrRow;
                        pTable.Rows.Add(pRow);
                        pRrow = pCursor.NextRow();
                    }
                }
                catch (Exception ex)
                {

                }
                _attributeTableData = pTable;
                RaisePropertyChanged(nameof(AttributeTableData));
            }
        }

10w+数据测试方法二比方法一效率跟高!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值