Incorrect list of features in calling function

993
5
Jump to solution
09-18-2020 03:52 AM
BarbaraSchneider2
Occasional Contributor II

I have a function that calls another (static) function which returns a list of features:

private Feature GetNextFeature(FeatureLayer featLayer, MapPoint point)
{
    await QueuedTask.Run(() =>
    {
        var featList = Utils.GetFeaturesThatIntersectPoint(point, featLayer);// Do some more with the feature list
        ....
    });‍‍‍‍‍‍‍
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

public static List<Feature> GetFeaturesThatIntersectPoint(MapPoint point, FeatureLayer featLayer)
{
    List<Feature> featList = new List<Feature>();

    // Create spatial query filter
    SpatialQueryFilter spatialFilter = new SpatialQueryFilter()
    {                
        FilterGeometry = point,
        SpatialRelationship = SpatialRelationship.Intersects,
    };
    // Query the feature layer
    using (RowCursor rowCursor = featLayer.Search(spatialFilter))
    {
        while (rowCursor.MoveNext())
        {
            Row row = rowCursor.Current;
            featList.Add((Feature)row);
        }
    }
    return featList;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In the method "GetFeaturesThatIntersectPoint", the feature list is correct. However, in the calling function "GetNextFeature", the features in the list are not the same any more. What am I doing wrong?

As a workaround, I don't return a list of features, but a list of oids (of the features). This list is correct.

0 Kudos
1 Solution

Accepted Solutions
RichRuh
Esri Regular Contributor

Hi Barbara,

By default, the FeatureClass.Search() method uses what is called a recycling cursor.  Recycling cursors will reuse the same Feature object every time MoveNext is called.  Obviously that isn't what you want here.

Change this line:

using (RowCursor rowCursor = featLayer.Search(spatialFilter))

To this line:

using (RowCursor rowCursor = featLayer.Search(spatialFilter, false))

I hope this helps,

--Rich

View solution in original post

5 Replies
RichRuh
Esri Regular Contributor

Hi Barbara,

By default, the FeatureClass.Search() method uses what is called a recycling cursor.  Recycling cursors will reuse the same Feature object every time MoveNext is called.  Obviously that isn't what you want here.

Change this line:

using (RowCursor rowCursor = featLayer.Search(spatialFilter))

To this line:

using (RowCursor rowCursor = featLayer.Search(spatialFilter, false))

I hope this helps,

--Rich

BarbaraSchneider2
Occasional Contributor II

Hi Rich,

this makes sense, thank you. However, the Search method on the feature layer doesn't have a parameter for the recycling option, only the Search method on the feature class. I have to search the feature layer because I take into consideration its definition query.

Is there a way to search the feature layer with the recycling option set to false? I guess I just have to use the workaround I've described above.

Barbara

BarbaraSchneider2
Occasional Contributor II

I could also search the feature class instead of the layer and add the layer's definition query to the SpatialQueryFilter:

SpatialQueryFilter spQueryFilter = new SpatialQueryFilter()
{
    WhereClause = featLayer.DefinitionQuery,
    FilterGeometry = point,
    SpatialRelationship = SpatialRelationship.Intersects,
};‍‍‍‍‍‍
using (RowCursor rowCursor = featLayer.GetFeatureClass().Search(spQueryFilter,false))‍‍‍‍‍‍‍
0 Kudos
RichRuh
Esri Regular Contributor

Yes, that should work.  Sorry, I didn't notice you were searching from the layer rather than the feature class.

--Rich

0 Kudos
anonymous_geographer
Occasional Contributor

Hey Rich, I'm super late to this party but was hitting a similar snag as Barbara here. I deal with quite a few layers in Pro that are created from selections of a feature class. Searching the Feature Class allows me to define useRecyclingCursor true/false. However, a Feature Class search will iterate the entire feature class table. I'd like to just perform a search on the feature layer (created from a table selection). The search option with feature layers is limited and won't allow me to set a recycling cursor. This is causing the output to repeat and not be unique values. Barbara's workaround may work, but that is not a desirable workflow. Is there no convenient, native way to search a Feature Layer similarly to how a Feature Class is searched?

Interestingly enough, I'm allowed to use the useRecyclingCursor during a Select().Search() instead. I've used featureLayer.Select().Search(null, useReyclingCursor: false) with more desireable outcomes, but it will also select all of the features within Pro. I immediately have to utilize featureLayer.ClearSelection() to undo that afterwards. My choices for feature layer search just seem...surprisingly clunky. Any better ideas are welcomed!