ArcEngine 唯一值查询

ArcEngine 唯一值查询

关键字: arcengine 唯一值 查询 distinct

转载: http://blog.csdn.net/mydriverc/archive/2007/07/26/1709210.aspx
评论;我试验了,其实可以使用IqueryFilter.subField="distinct(FiledName)"直接Search 就行

有时我们需要读取图层中某个字段的所有值的唯一值集合,或做统计用途,或作为其他功能的输入。
一般通过IDataStatistics接口来获取唯一值集合,代码如下:
Java代码 复制代码
  1. ''' <summary>   
  2. ''' 通过IDataStatistic接口获取图层指定字段的唯一值   
  3. ''' </summary>   
  4. ''' <param name="pFeatureLayer">目标图层</param>   
  5. ''' <param name="strField">目标字段名</param>   
  6. ''' <returns>目标字段的所有值的唯一值集合</returns>   
  7. ''' <remarks></remarks>   
  8. Public Function GetUVByDataStatistics()Function GetUVByDataStatistics(ByVal pFeatureLayer As IFeatureLayer, ByVal strField As String) As IList(Of String)   
  9.    Dim uvList As IList(Of String) = New List(Of String)   
  10.    Dim pQueryFilter As IQueryFilter = New QueryFilter   
  11.    Dim pFeatureCur As IFeatureCursor   
  12.    pQueryFilter.SubFields = strField   
  13.    pFeatureCur = pFeatureLayer.FeatureClass.Search(pQueryFilter, True)   
  14.    Dim pDataStatic As IDataStatistics = New DataStatistics   
  15.    pDataStatic.Field = strField   
  16.    pDataStatic.Cursor = pFeatureCur   
  17. Dim pEnumvar As System.Collections.IEnumerator = pDataStatic.UniqueValues   
  18.    pEnumvar.Reset()   
  19.    While pEnumvar.MoveNext   
  20.        Dim pObj As Object = pEnumvar.Current   
  21.        uvList.Add(pObj.ToString)   
  22.    End While   
  23.    Return uvList   
  24. nd Function  
 ''' <summary>
 ''' 通过IDataStatistic接口获取图层指定字段的唯一值
 ''' </summary>
 ''' <param name="pFeatureLayer">目标图层</param>
 ''' <param name="strField">目标字段名</param>
 ''' <returns>目标字段的所有值的唯一值集合</returns>
 ''' <remarks></remarks>
 Public Function GetUVByDataStatistics()Function GetUVByDataStatistics(ByVal pFeatureLayer As IFeatureLayer, ByVal strField As String) As IList(Of String)
    Dim uvList As IList(Of String) = New List(Of String)
    Dim pQueryFilter As IQueryFilter = New QueryFilter
    Dim pFeatureCur As IFeatureCursor
    pQueryFilter.SubFields = strField
    pFeatureCur = pFeatureLayer.FeatureClass.Search(pQueryFilter, True)
    Dim pDataStatic As IDataStatistics = New DataStatistics
    pDataStatic.Field = strField
    pDataStatic.Cursor = pFeatureCur
	Dim pEnumvar As System.Collections.IEnumerator = pDataStatic.UniqueValues
    pEnumvar.Reset()
    While pEnumvar.MoveNext
        Dim pObj As Object = pEnumvar.Current
        uvList.Add(pObj.ToString)
    End While
    Return uvList
End Function

       但当图层的数据量很大时,以上这种方法执行起来速度较慢,性能影响比较明显,得考虑使用另外一种方法。通过IQueryDef接口使用类似SQL的查询语句来获取图层字段的唯一值集合,执行速度等同于执行SQL查询语句。
Java代码 复制代码
  1. ''' <summary>   
  2. ''' 通过IQueryDef接口查询字段的唯一值   
  3. ''' </summary>   
  4. ''' <param name="pFeatureLayer">目标图层</param>   
  5. ''' <param name="strField">目标字段名</param>   
  6. ''' <returns>目标字段的所有值的唯一值集合</returns>   
  7. ''' <remarks></remarks>   
  8. Public Function GetUVByQueryDef()Function GetUVByQueryDef(ByVal pFeatureLayer As IFeatureLayer, ByVal strField As String) As IList(Of String)   
  9.     Dim uvList As IList(Of String) = New List(Of String)   
  10.     Dim pQueryDef As IQueryDef   
  11.     Dim pRow As IRow   
  12.     Dim pCursor As ICursor   
  13.     Dim pFeatureWorkspace As IFeatureWorkspace   
  14.     Dim pDataset As IDataset   
  15.     pDataset = pFeatureLayer.FeatureClass   
  16.     pFeatureWorkspace = pDataset.Workspace   
  17.     pQueryDef = pFeatureWorkspace.CreateQueryDef   
  18.     With pQueryDef   
  19.         .Tables = pDataset.Name ' Fully qualified table name   
  20.         .SubFields = "DISTINCT(" & strField & ")"  
  21.         pCursor = .Evaluate   
  22.     End With   
  23.     pRow = pCursor.NextRow   
  24.     While Not pRow Is Nothing   
  25.         Dim pObj As Object = pRow.Value(0)   
  26.         uvList.Add(pObj.ToString)   
  27.         pRow = pCursor.NextRow   
  28.     End While   
  29.     Return uvList   
  30. End Function  
''' <summary>
''' 通过IQueryDef接口查询字段的唯一值
''' </summary>
''' <param name="pFeatureLayer">目标图层</param>
''' <param name="strField">目标字段名</param>
''' <returns>目标字段的所有值的唯一值集合</returns>
''' <remarks></remarks>
Public Function GetUVByQueryDef()Function GetUVByQueryDef(ByVal pFeatureLayer As IFeatureLayer, ByVal strField As String) As IList(Of String)
    Dim uvList As IList(Of String) = New List(Of String)
    Dim pQueryDef As IQueryDef
    Dim pRow As IRow
    Dim pCursor As ICursor
    Dim pFeatureWorkspace As IFeatureWorkspace
    Dim pDataset As IDataset
    pDataset = pFeatureLayer.FeatureClass
    pFeatureWorkspace = pDataset.Workspace
    pQueryDef = pFeatureWorkspace.CreateQueryDef
    With pQueryDef
        .Tables = pDataset.Name ' Fully qualified table name
        .SubFields = "DISTINCT(" & strField & ")"
        pCursor = .Evaluate
    End With
    pRow = pCursor.NextRow
    While Not pRow Is Nothing
        Dim pObj As Object = pRow.Value(0)
        uvList.Add(pObj.ToString)
        pRow = pCursor.NextRow
    End While
    Return uvList
End Function


转载: http://www.southgis.com/bz/199.html
对于关系数据库,ArcEngine定义了几种查询接口:
1. 常规的ITable、IFeatureClass接口
    这是我们最常使用的,完成同一个表内的数据查询、更新操作。假设之前已定义IFeaturWorkspace pFWork,并已赋值。                                     
Java代码 复制代码
  1. ITablepTab=pFWork.OpenTable("DLTB");   
  2. IQueryFilter pqf=new QueryFilterClass();   
  3. pqf.WhereClause="DLBM like '01_'";   
  4. ICursor pCur=pTab.Search(pqf,true);  
ITablepTab=pFWork.OpenTable("DLTB");
IQueryFilter pqf=new QueryFilterClass();
pqf.WhereClause="DLBM like '01_'";
ICursor pCur=pTab.Search(pqf,true);

2. IWorkspace.ExecuteSQL
  能够执行关系数据库的所有DDL和DML类SQL语句。由于通过此函数执行SQL语句时会绕过ArcEngine的存储机制,可能会破坏SDE数据的一致性(主要在更新SDE的系统表记录时),因此必须慎用。
  另外,由于此函数执行后不返回结果,决定了用此函数不能执行查询语句。
//下面执行向DLJX的历史档案表中更新记录(SqlServer语法)。
//作用是:给创建时间在2009-7-13之后已删除的记录的创建时间改为2009-1-1
//假设之前已定义IWorkspace pWork,并已赋值。
Java代码 复制代码
  1. pWork.ExecuteSQL("update DLJX_H set GDB_FROM_DATE='2009-1-1'    
  2. where objectid=2andGDB_FROM_DATE>'2009-7-13' and GDB_TO_DATE<'9999-12-31' ");  
pWork.ExecuteSQL("update DLJX_H set GDB_FROM_DATE='2009-1-1' 
where objectid=2andGDB_FROM_DATE>'2009-7-13' and GDB_TO_DATE<'9999-12-31' ");

  //下面创建一个表pWork.ExecuteSQL("CREATE  TABLE  IDS(ID  BIGINT NOT NULL, BINDTYPE VARCHAR(20))");
  3. 用IQueryDef接口执行各种查询
  通过IQueryDef可以执行SQL数据库引擎所支持的所有查询,并且如果查询的表是要素类,还会正确返回要素类的最新数据(即使要素类启用了版本管理,且数据不更新到基表)。
  并且还能执行一些有用的查询。举例如下:
//查询要素类数据
//假设之前已定义IWorkspace pWork,并已赋值
Java代码 复制代码
  1. IQueryDef pQDef=pFWork.CreateQueryDef();   
  2. pQDef.Tables="DLJX";   
  3. pQDef.WhereClause="JXLX='97'";   
  4. ICursor pCur=pQDef.Evaluate();  
IQueryDef pQDef=pFWork.CreateQueryDef();
pQDef.Tables="DLJX";
pQDef.WhereClause="JXLX='97'";
ICursor pCur=pQDef.Evaluate();

//判断某个表是否存在(如果此表未登记成GeometryTable,通过IWorkspace2.NameExists可能获取不到)
Java代码 复制代码
  1. pQDef.SubFields = "id";   
  2. pQDef.Tables = "sysobjects";   
  3. pQDef.WhereClause  =  "id  =  object_id(N'IDS') and OBJECTPROPERTY(id, N'IsUserTable') = 1";   
  4. ICursor pCur=pQDef.Evaluate();   
  5. IRow pRow = pCur.NextRow();   
  6. if (pRow != null) {bExist = true;}  
pQDef.SubFields = "id";
pQDef.Tables = "sysobjects";
pQDef.WhereClause  =  "id  =  object_id(N'IDS') and OBJECTPROPERTY(id, N'IsUserTable') = 1";
ICursor pCur=pQDef.Evaluate();
IRow pRow = pCur.NextRow();
if (pRow != null) {bExist = true;}

//聚合查询
//注意:对返回字段的处理,由于ArcEngine只简单的以逗号切分了SubFields内容,//因此,如果包含有逗号时,字段名需要依次后推,且不支持字段别名定义
Java代码 复制代码
  1. pQDef.SubFields = "count(*),sum(TDZMJ),sum(KZZMJ),left(ZLDWDM,6)";   
  2. pQDef.Tables = "DLTB group by left(ZLDWDM,6)";ICursor pCur=pQDef.Evaluate();  
pQDef.SubFields = "count(*),sum(TDZMJ),sum(KZZMJ),left(ZLDWDM,6)";
pQDef.Tables = "DLTB group by left(ZLDWDM,6)";ICursor pCur=pQDef.Evaluate();

  针对上面所返回的ICursor,实际记录虽然只有四个字段,但ICursor.Fields却有五个元素,各字段名为:count(*)、sum(TDZMJ)、sum(KZZMJ)、left(ZLDWDM、6)因此要取第四个字段的值,需要这样:int iInx=pCur.FindField("left(ZLDWDM");
Java代码 复制代码
  1. IRow pRow=pCur.NextRow();   
  2. string sDM=pRow.get_Value(iInx).ToString();  
IRow pRow=pCur.NextRow();
string sDM=pRow.get_Value(iInx).ToString();

//多表联接查询
Java代码 复制代码
  1. pQDef.Tables="DLTB a left join XZQ b on   
  2. a.ZLDWDM=b.XZQDM"   
  3. ICursor pCur=pQDef.Evaluate();  
pQDef.Tables="DLTB a left join XZQ b on
a.ZLDWDM=b.XZQDM"
ICursor pCur=pQDef.Evaluate();

4. 使用ArcEngine的统计类(实现了IDataStatistics接口)
  //假设之前已定义IFeaturWorkspace  pFWork,并已赋值
Java代码 复制代码
  1. ITable pTab=pFWork.OpenTable("DLTB");   
  2. ICursor pCur=pDLTBTable.Search(null,false);   
  3. IDataStatistics pDataStat = new DataStatisticsClass();   
  4. pDataStat.Field = "MJ";   
  5. pDataStat.Cursor = pCur;   
  6. IStatisticsResults  pRes  =  dataStatistics.  
ITable pTab=pFWork.OpenTable("DLTB");
ICursor pCur=pDLTBTable.Search(null,false);
IDataStatistics pDataStat = new DataStatisticsClass();
pDataStat.Field = "MJ";
pDataStat.Cursor = pCur;
IStatisticsResults  pRes  =  dataStatistics.

Statistics;
//之后可以调用接口相关方法,比如计数:pRes.Sum
  在实际应用中,第1种和第3种方法使用最多,基本上能满足大多的数据查询需求。
  第4种方法完全用第3种方法,但如果应用需要适应多种数据库类型的话,使用第4种方法更方便,但性能肯定没有第3种方法高,并且第4种方法不能进行多表联合查询。个人认为,除了获取惟一值外,其它情况都可用第3种方法解决,如果出现不同数据库类型,查询语法格式不一致时,可以通过动态判断数据库类型实现分支实现多个版本。
  第2种方法,在一般情况下不建议使用。原因是由于没有返回值,主要用于数据库维护或记录更新操作。这在SDE体系外进行的操作,一不小心就会破坏SDE数据结构的完整性、一致性。但也不能说此方法无用武之地了,做为其它方法的补充,可以用在存贮过程、视图、SDE体系之外的自定表的创建上,另外,对SDE系统表熟悉的话,可以进行一些底层的维护,比如修改历史表记录的时间戳,修改锁等。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值