IQueryFilter與ISpatialFilter接口的使用

       在ArcGIS二次開發中,IQueryFilter和ISpatialFilter是最常用的查詢接口。

一、IQueryFilter接口

        IQueryFilter接口用於屬性查詢。該接口提供了1個方法和3個屬性。如AddField方法用於向輸出字段集中添加一個字段,OutputSpatialReference屬性用於獲取給定字段的輸出幾何圖形的空間參考,SubFields用於獲取或設置輸出幾何圖形的字段名稱清單,WhereClause用於獲取或設置查詢過濾條件。

       對於IQueryFilter.SubFields這個屬性之前一直是被我忽略的,後來在實際應用時才發現,SubFields屬性可以用來提高性能。主要原理是:性能增益來自於獲取所需的字段值,而不是每行的所有數據。

    SubFields的默認值爲“*”,表示將返回所有字段值。將其設置回原始(默認)“*”可以通過將其設置爲“*”或“”來完成。還可以是使用IQueryFilter.AddField方法向篩選字段集合中(SubFields)添加字段名。

/// <summary>
/// 
/// </summary>
/// <param name="pFeatureClass"></param>
public static void Test(IFeatureClass pFeatureClass)
{
    List<int> lisOids = new List<int>();
    using (ComReleaser comReleaser=new ComReleaser())
    {
        IQueryFilter queryFilter = new QueryFilterClass();
        queryFilter.SubFields = $"{pFeatureClass.ShapeFieldName},{pFeatureClass.OIDFieldName}";   //篩選器的字段名使用逗號分隔,此處設置的是獲取“shape”和“OID”
        //queryFilter.AddField(pFeatureClass.OIDFieldName);   向篩選字段集合中添加字段名
        //queryFilter.WhereClause = $"{pFeatureClass.OIDFieldName}<1000"; 過濾條件
        IFeatureCursor pFeatureCursor = pFeatureClass.Search(queryFilter, true);
        IFeature pFeature = null;
        while ((pFeature = pFeatureCursor.NextFeature()) != null)
        {
            lisOids.Add(pFeature.OID);
        }
    }
}

當設置了SubFields後就獲取不到被過濾掉的字段值了。

二、 ISpatialFilter接口

          ISpatialFilter繼承了接口IQueryFilter,在屬性查詢的基礎上加了要素與要素的空間關係進行查詢。Geometry用於設置查詢幾何;SpatialRel設置查詢的空間關係,具體可參考:GIS空間查詢(SpatialFilter)時各種空間關係總結
GeometryField設置查詢的幾何字段的名稱;SearchOrder屬性用於設置搜索順序,僅僅在ArcSDE中起作用,通常空間查詢優先於屬性查詢。

     其中SpatialFilterClass還繼承了接口IQueryFilterDefinition2。

/// <summary>
/// 空間查詢
/// </summary>
/// <param name="pFeatureClass">要素圖層</param>
/// <param name="pGeometry">查詢幾何</param>
public static void UsingISpatialFilter(IFeatureClass pFeatureClass, IGeometry pGeometry)
{
    //創建屬性查詢
    ISpatialFilter pSpatialFilter = new SpatialFilterClass()
    {
        SubFields = "",  //設置查詢字段
        WhereClause = "",  //過濾條件

        Geometry = pGeometry,   //設置查詢幾何
        SpatialRel = esriSpatialRelEnum.esriSpatialRelContains, //設置查詢的空間關係
        GeometryField = pFeatureClass.ShapeFieldName,

        PostfixClause = $"ORDER BY {pFeatureClass.OIDFieldName} desc", //排序
    };

    //ISpatialFilter轉爲IQueryFilterDefinition接口後設置
    //IQueryFilterDefinition2 pQueryFilterDef2 = (IQueryFilterDefinition2)pSpatialFilter;
    //pQueryFilterDef2.PostfixClause = $"ORDER BY {pFeatureClass.OIDFieldName} desc";

    using (ComReleaser comReleaser = new ComReleaser())
    {
        IFeatureCursor pFeatureCursor = pFeatureClass.Search(pSpatialFilter, true);
        comReleaser.ManageLifetime(pFeatureCursor);
        IFeature pFeature = null;
        while ((pFeature = pFeatureCursor.NextFeature()) != null)
        {
            //
        }
    }
}

 

三、IQueryFilterDefinition接口

         可見IQueryFilter和ISpatialFilter只能執行簡單的屬性查詢。若要執行復雜點的就需要使用IQueryDef接口查詢或則轉爲IQueryFilterDefinition接口。IQueryFilterDefinition接口可設置Order By和Group By語句。

public void UsingIQueryFilterDefinition(IFeatureClass pFeatureClass)
{
    //創建屬性查詢
    IQueryFilter pQueryFilter = new QueryFilterClass();
    //轉爲IQueryFilterDefinition接口
    IQueryFilterDefinition2 pQueryFilterDef2 = (IQueryFilterDefinition2)pQueryFilter;
    pQueryFilterDef2.PostfixClause = $"ORDER BY {pFeatureClass.OIDFieldName} desc";  //追加查詢子句
    using (ComReleaser comReleaser = new ComReleaser())
    {
        IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
        comReleaser.ManageLifetime(pFeatureCursor);
        IFeature pFeature = null;
        while ((pFeature = pFeatureCursor.NextFeature()) != null)
        {
            //
        }
    }
}

 

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