SelectByAttributes and CopySubset not working?

May 28, 2014 at 4:40 PM
Trying to select a subset of features from a shapefile using code, neither
IFeatureSet polygons;
polygons = new PolygonShapefile(path);
string stri = "[status_ter]='Concluído'";
polygons = polygons.SelectByAttribute(stri);
or
IFeatureSet polygons;
polygons = new PolygonShapefile(path);
string stri = "[status_ter]='Concluído'";
List<int> inds = polygons.SelectIndexByAttribute(stri);
FeatureSet polis= (FeatureSet)polygons.CopySubset(inds);
worked. The first block throws an exception saying it cannot find the field status_ter in my shapefile, but the expression works fine in the second block. Also, It happens with any other field of the table.
In the second block, inds stores the correct number of indexes I need, but CopySubset ignores it, and ends up copying every shape, not just the ones in inds. Couldn't find where the proble is.

In addition, is there a method to open just a subset of a shapefile from disk in first place?Someting like using a where expression when opening or loading the shapefile?

Marcio
Developer
May 29, 2014 at 7:36 AM
The first block throws an exception saying it cannot find the field status_ter in my shapefile, but the expression works fine in the second block. Also, It happens with any other field of the table.
It's strange. I just tried SelectByAttribute() - it throws exception only when column not exists. If you are specifying correct name - it should return empty list (yes, it is a bug). As workaround add this line:
polygons = new PolygonShapefile(path);
polygons.IndexMode = false;
// continue your code...
In the second block, inds stores the correct number of indexes I need, but CopySubset ignores it, and ends up copying every shape, not just the ones in inds. Couldn't find where the proble is.
Yes, it is a bug in CopySubset().
In addition, is there a method to open just a subset of a shapefile from disk in first place?Someting like using a where expression when opening or loading the shapefile?
Good suggestion. At the moment there is no such possibility. I'll create feature request for this.

Maxim.
May 29, 2014 at 4:14 PM
Thanks for your response Maxim,

In the first block, when I change polygons by a list of IFeatures, it returns an empty list, as you said. When I add polygons.IndexMode = false, however, it gives an exception saying that an index was out of range:

"Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"

Code:
polygons = new PolygonShapefile(path);
polygons.IndexMode = false;
string stri = "[status_ter]='Concluído'";
List<IFeature>  feats = polygons.SelectByAttribute(stri); //error here
for feedback, I manage to proceed with the following:
polygons = new PolygonShapefile(path);
polygons.FillAttributes();
string stri = "[status_ter]<>'Concluído'";
List<int>  inds = polygons.SelectIndexByAttribute(stri);
polygons.RemoveShapesAt(inds);
Using that code, I remove the polygons and corresponding lines from AttributeTable I don't want. I had to include polygons.FillAttributes(), otherwise it would only remove the polygons, and keep the corresponding lines in the attribute table.

Marcio
Developer
May 29, 2014 at 4:42 PM
Yes, maybe just simply set IndexMode = false will not help (i not tested this), Anyways, i already fixed issue with SelectByAttribute() in trunk - now it works fine with your initial code.
Regarding to others - i created
https://dotspatial.codeplex.com/workitem/25512 and
https://dotspatial.codeplex.com/workitem/25513