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+数据测试方法二比方法一效率跟高!