ArcGIS Engine开发之旅08--和查询相关的对象和接口

查询在GIS领域应该是一个很频繁的操作,在GIS中除了具有属性查询(和其他关系型数据库的查询类似),还提供了空间查询。在介绍查询的时候,让我们先了解下面的对象。

1.Table 对象
Table 是不含有空间信息的一张二维表,它主要实现了 ITable 接口。在这张二维表中,每一行称之为 Row(IRow),ITable 接口 定义了对这张二维表行的插入,更新,查询,以及删除等操作。 独立表(standalone table):就是一个单独的不含空间信息的表也就是只能在 ArcMap 中 Table of Contents 的 Source 选项卡中看到的。
2.对象类
对象类是在 Table 的基础上扩展起来的,因此在外观上来看,它也是一个二维表,也是用来存储非空间数据,它与 Table 的区别在于它的一行是一个 Object(对象),尽管在形式上也是一条记录,但它是具有属性和行为的一个对象,而非简单的记录了。
3.FeatureClass 对象
要素类是存储在工作空间中的一种数据组织方式,要素类是在对象类的基础上的进一步扩展,包含了现实世界中的空间实体。要素类由要素组成(Feature),要素对应要素类中的一行,要素相当于空间对象(Geometry ) +相应的属性信息。IFeatureClass 定义了对要素的查询,更新,删除等操作。关于 ROW,Table,对象类,Feature,要素类,我们可以从下面的图上得到启示:

FeatureClass 对 象 实 现 了 IFeatureClass 接 口 , IFeatureClass 对 查 询 定 义 了 两 个 方 法IFeatureClass.Search 和 IFeatureClass.Select。 Search 方法需要传入两个参数,一个是过滤器;另外一个是布尔值,用于说明放回的要素游标是否被回收,一般的,如果仅仅是为了读取数据,那么这个参数应该是 true,如果要对选择出来的要素更新,那么这个参数应该设置为 false。那么这两个参数到底有什么意义,我们从下面的代码中看一下。 

3.1 false 和 true 参数的差别 

我们定义一个 Search 函数,通过传 false 和 true 来对这两个参数进行说明,代码如下: 

 void  Search(IFeatureClass _pFeatureClass,bool _Bool)         
        {  
            IFeature pFt1, pFt2;  
           IFeatureCursor pFtCursor;            
           if (_Bool == false) 
           { 
               pFtCursor = _pFeatureClass.Search(null, _Bool);  
               pFt1 = pFtCursor.NextFeature();  
               while (pFt1 != null) 
               { 
                   pFt2 = pFtCursor.NextFeature();  
                   if (pFt1 == pFt2) 
                   { 
                       MessageBox.Show("Recycling 参数是 false"); 
                   } 
                   pFt1 = pFtCursor.NextFeature();  
               } 
           } 
           else 
           {                pFtCursor = _pFeatureClass.Search(null, _Bool);  
               pFt1 = pFtCursor.NextFeature();  
               while (pFt1 != null)                
               { 
                   pFt2 = pFtCursor.NextFeature(); 
                    if (pFt1 == pFt2) 
                   {                        MessageBox.Show("Recycling 参数是true"); 
                   } 
                   pFt1 = pFtCursor.NextFeature();  
               }            }  
        }  
        当 recycling 为 true 的时候,我们会看到程序执行到 MessageBox.Show("Recycling 参数是 true"),如
下图:

3.2 Search和 Select 方法的比较 

Search 返回游标,Select 返回选择集 游标:必须遍历游标才能得到所有的结果,不必太关注内存 选择集: 查询后既可得到,但是通常只保留 OID 字段,数据量大的时候要考虑内存压力 。

3.3 Cursor 和 FeatureCursor对象 

Cursor 中文‘游标“,它本质上是一个指向数据的指针,自身并不包含数据。游标有三类,查询游标,插入游标和更新游标,每一中游标都是有其相应的方法得到,如查询游标是由 ITable.Search 方法得到。游标是 GIS 中使用频率很高的,凡是和数据的查询,更新,删除等都跟他有关。ICursor 定义了对游标的操作。当我们通过 ITable.Search 对数据进行查询,要获取具体 Row 的信息的时候,要通过 ICursor.NextRow方法向前遍历,游标是不能后退的。游标是和 Table 相对应的。IFeatureCursor 继承了 ICursor,IFeatureCursor 是和要素类相对应。

3.4 QueryFilter 与 SpatialFilter对象 

在 ArcGIS Engine 中进行查询或者选择,都需要传给一个查找条件,或者过滤条件,这个条件就相当于一般的 SQL 语句中的 Where 语句,如 Select * from 用户 where 性别=’女’;我们知道 GIS 不仅仅有属性查询,还有一般关系型数据库不具有的空间查询。而 QueryFilter 对象和 SpatialFilter 对象分别对应了ArcGIS Engine 中的属性查询和空间查询。 IQueryFilter 被两个类实现 QueryFilterClass 和 SpatialFilterClass,前者是针对属性查询的,后者是针对空间查询的。 在介绍下这些对象后,我们现在来做一个高亮显示的查询操作。

 

3.5 IFeatureSelection接口 

IFeatureSelection 接口负责管理一个图层中的要素选择集的方法和属性。 IFeatureSelection 接口的 Add方法可以把本图层中的一个要素添加到图层的选择集中;SelectFeatures 方法则利用过滤器对象将符合条件的要素放入到图层的选择集中。使用IFeatureSelection接口可以实现要素的高亮显示。在ArcGIS Engine中有很多类实现了这个接口,如下图: 

3.5.1 使用 IFeatureSelection接口高亮显示 

在介绍 IMap 接口那一节,我们用 IMap 的 IMap.SelectFeature 方法实现了对查询的要素高亮显示,现在我们用 IFeatureSelection 接口实现查询高亮显示 

 

 IMap pMap = axMapControl1.Map;  
            IFeatureLayer pFeaturelayer = GetLayer(pMap, "Roads") as IFeatureLayer;  
           IFeatureSelection pFeatureSelection = pFeaturelayer as IFeatureSelection;  
            IQueryFilter pQuery = new QueryFilterClass();  
            pQuery.WhereClause = "TYPE=" +"'paved'"; 
             
pFeatureSelection.SelectFeatures(pQuery,esriSelectionResultEnum.esriSelectionResultNew,false
); 
axMapControl1.ActiveView.Refresh();  

 

其中 GetLayer 函数是我们写的一个根据图层的名称获取图层的方法,代码如下图: 

private ILayer GetLayer(IMap pMap, string LayerName)        
        { 
            IEnumLayer pEnunLayer; 
            pEnunLayer = pMap.get_Layers(null, false); 
            pEnunLayer.Reset(); 
            ILayer pRetureLayer;            
            pRetureLayer = pEnunLayer.Next();  
            while (pRetureLayer != null) 
            { 
                if (pRetureLayer.Name == LayerName)                 
                { 
                    break; 
                }  
                pRetureLayer = pEnunLayer.Next();             
            } 
            return pRetureLayer; 
        }  

 

posted @ 2016-08-03 19:56  虚-染D  阅读(759)  评论(0编辑  收藏  举报