ThinkGeo.com    |     Documentation    |     Premium Support

Getting Features row-by-row

I'm trying to GetAllFeatures from a given FeatureLayer, but I don't want to load it all into memory first. Ideally I need some sort stepping through each Feature without first loading them in. Anyone know of a way for me to do this?


Lets say I have a Shape file with 200,000 rows. I want to grab the first 10,000, run them through a method and inject them into a SQL database, then repeat this process for the next 10,000.


Currently i'm using FeatureLayer.GetAllFeatures(ReturningColumnsType.AllColumns) but my application throws an out of memory exception on large datasets.


 




After thinking about the problem further... Is there a way to grab a list of all ID's in the FeatureLayer/FeatureSource and use that list later to query the source in bite sized chunks?



        
  1. Open the FeatureSource

  2.     
  3. *Grab all feature ID's (new method?)

  4.     
  5. Grab first 10,000 features and associated attribute columns based on the ID's and GetFeaturesByIds(ids)


All three stages would be fast (and manageable), and would suit me quite well. Although stepping through each feature 1 at a time would be better.



Hi David,


In ShapeFileFeatureSource, we use Record Index as the feature Id (from 1 to record count). In your scenario, you just need to loop the record count and get features piece by piece. Here I provide some code snippet for your reference.


var interval = 10;
yourLayer.Open();
int recordCount = yourLayer.QueryTools.GetCount();
for (int i = 0; i <= recordCount / interval; i++)
{
    Collection<string> ids = new Collection<string>();
    int startIndex = i * interval + 1;
    int endIndex = (i + 1) * interval > recordCount ? recordCount : (i + 1) * interval;
    for (int j = startIndex; j <= endIndex; j++)
    {
        ids.Add(j.ToString());
    }
    Collection<Feature> features = yourLayer.QueryTools.GetFeaturesByIds(ids, ReturningColumnsType.AllColumns);
}
yourLayer.Close();


Please let us know if you have further questions.


Regards,


Ivan



Hi Ivan,


Thanks for your reply. Your example works perfectly for Shape files, but I will also be importing Tab files and possibly other sources as well. Using this consecutive ID's method fails when the either the ID column does not exist, or is not consecutive.


Any thoughts?


David



My previous statement… Using this consecutive ID’s method fails when the either the ID column does not exist, or is not consecutive. was incorrect. 
  
 I’ve run a few experiments and concluded that there is a problem somewhere within the reading of *.tab files (I haven’t test any other formats yet) 
  
 The process explained in Ivan’s post above works fine for *.shp files, but if you tried the same on *.tab files it would fail with an internal exception:- 
 Exception has been thrown by the target of an invocation. 
  
 I experimented further and found that if the chunk/interval size was <= 256, then it would work.  
  
 It seems that this magic number 256 is the limit of ID’s which you can pass to GetFeaturesByIds() for *.tab files. Can anyone confirm my findings, and possible offer an alternative? I was thinking that if FeatureSource or FeatureLayer exposed an IDataSource object that we could use to iterate over the data, it would solve alot of my problems. 
  
 David

David,


Please check the following answers for your questions:


1. It seems that this magic number 256 is the limit of ID's which you can pass to GetFeaturesByIds() for *.tab files. Can anyone confirm my findings, and possible offer an alternative?


I have checked the source code for "TabFileFeatureLayer" (in "FdoExtension.dll") and there isn't any limitation about method GetFeaturesByIds(). In the next main release (May 2011 Release), we will integrate *.tab file support into "MapSuiteCore.dll" and provide a new FeatureLayer named "TabFeatureLayer", at that time you can use this new featurelayer to have another try.


2.  I was thinking that if FeatureSource or FeatureLayer exposed an IDataSource object that we could use to iterate over the data, it would solve alot of my problems. 


Thank you for your suggestion, we'll carefully consider your requirement. Hopefully we can integrate this new feature into our products in the near future.


Regards,


Ivan