Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public interface SimpleFeatureCollection extends FeatureCollection<SimpleFeatureType,SimpleFeature> {
  SimpleFeatureIterator features();
  String getID();
  SimpleFeatureType getSchema();
  ReferencedEnvelope getBounds();
  boolean isEmpty();
  int size();
}

DataUtilities 

During the review process many additional utility methods were added to DataUtilities in order to ensure all FeatureCollections handled things in a similar fashion.

Specific changes to functionality:

  • visit( FeatureVisitor, Progress ) now throws an IOException in the case of problems, rather then just reporting via the supplied progress
Here are the new DataUtilities methods:

 

Code Block
DataUtilities.visit( FeatureCollection, FeatureVisitor, ProgerssListener )
DataUtilities.bounds( FeatureCollection ) <-- already existed
DataUtilities.bounds( FeatureIterator ) 
DataUtilities.count( FeatureCollection ) 
DataUtilities.count( FeatureIterator ) 
DataUtilities.close( Iterator )
DataUtilities.first( SimpleFeatureCollection ): SimpleFeature
DataUtilities.first( FeatureCollection<?,F> ): F
DataUtilities.list( FeatureCollection<?,F> ): List<F>  // Already existed 
DataUtilities.list( FeatureCollection<?,F>, int ): List<F>
DataUtilities.iterator( FeatureIterator ): Iterator // also Closable 
DataUtilities.collectionCast( FeatureCollection ): Collection 

FeatureCollection Implementations

Base FeatureCollection classes available for extending:

  • AbstractFeatureCollection - requires an openIterator method and attempts to track all the outstanding iterators and clean up after them with a purge method.
  • BaseFeatureCollection / BaseSimpleFeatureCollection - requires a features() method, all other methods are implemented by calling features(), recommend supply size() and bounds() methods.
    • ProcessingCollection / SimpleProcessingCollection - requires features()getBounds()size(), and buildTargetFeatureType()
  • DecoratingFeatureCollection / DecoratingSimpleFeatureCollection - each method calls through to an internal delegate FeatureCollection
  • AdaptorFeatureCollection -  copy of AbstractFeatureCollection used as a base class by uDig (should replace with BaseFeatureCollection )
  • DataFeatureCollection - requires a reader() method and implementation of FeatureReader, also getSchema(), getBounds(), getCount() and collection()

Working FetaureCollection implementations for day to day use in your own code:

  • DefaultFeatureCollection - uses a TreeSet sorted by FeatureId internally 
  • ListFeatureCollection
  • SpatialIndexFeatureCollection
  • TreeSetFeatureCollection

Implementation specific FeatureCollection classes:

  • MemoryFeatureCollection - used internally by MemoryDataStore storing Features in a TreeSet sorted by FeatureId
  • SubFeatureCollection - uses a Filter to reduce the number of features returned
    • SubFeatureList - tries to implement SortBy using a List<FeatureId> with determined order
  • ContentFeatureCollection - delegates most work to ContentFeatureSource for the win
  • DefaultVersionedFeatureCollection - does not appear complete
  • SimpleFeatureCollectionBridge - wraps a FeatureCollection<SimpleFeatureType,SimpleFeature> up as a SimpleFeatureCollection

Status

This proposal is the subject of a grass roots revolution on the geotools-devel list; indeed the revolution is on going and will not be televised.

...

  1. (tick) JG: Deprecate methods for 8.0 release
    • (tick) FeatureCollection Deprecate Collection methods
    • (tick) FeatureCollection Deprecate CollectionListener (and methods)
    • (tick) FeatureCollection Deprecate FeatureCollection Iterator methods
  2. JG: Changes for 9.0 master
    • (tick) FeatureCollection Remove Collection methods
    • (tick) FeatureCollection Remove CollectionListener (and methods)
    • (tick) FeatureCollection Remove FeatureCollection Iterator methods
    • (tick) Deprecate FeatureCollections factory
  3. Fix support classes ((warning) used to mark anything that did not go smoothly)
    • (tick) DataFeatureCollection remains based on FeatureReader
    • (tick) AbstractFeatureCollection will remain based on iteartor()
      • ForceCoordinateSystemFeatureResults
      • MemoryFeatureCollection
      • ReprojectFeatureResults
      • TransformFeatureCollection
    • (tick) BaseFeatureCollection created to be based on features()
      • (tick) SubCollection migrated to BaseFeatureCollection
      • (tick) SortFeatureList migrated to BaseFeatureCollection
    • AdaptorFeatureCollection - base class used by uDig
    • (tick)ContentFeatureCollection
    • DecoratingSimpleFeatureCollection
      • (tick)FilteringSimpleFeatureCollection: migrated to FilteringFeatureIterator (from FilteringIterator)
      • (tick)MaxSimpleFeatureCollection: migrated to MaxFeaturesSimpleFeatureIterator (from MaxFeaturesIterator)
      • (tick) ReprojectingFeatureCollection: migrated to ReprojectingFeatureIterator (from ReprojectingIterator)
      • (tick) ReTypingFeatureCollection: migrated to ReTypingFeatureIterator (from ReTypingIterator)
    • (tick)DefaultFeatureCollection - remains based on TreeSet
      • GMLFeatureCollection: subclass of DefaultFeatureCollection
      • (tick) MemoryFeatureCollection: copy of DefaultFeatureCollection
      • (warning) TreeSetFeatureCollection: copy of DefaultFeatureCollection changed to no longer implement Collection
    • (tick) DefaultVersionedFeatureCollection: add is now protected and use during init to populate the collection
    • (warning) PropertyValueCollection - this is not a FeatureCollection it was being used to return Collection<Attribute> I have changed it to return a Feature (containing the expected Attribute) but cannot untangle the Encoder well enough to make the test pass.
  4. Fix geotools modules (notes on any thing interesting, also check commit logs)
    • (tick) In general pretty smooth transition
    • (warning) app-schema makes "dangerous" use of feature collection support classes (that internally assume SimpleFeature)
    • (warning) StreamingRenderer required code duplication to handle Collection.iterator() and FeatureCollection.features()
    • (tick) Many cases where try/finally was used to ensure featureIterator.close() was called
    • (error)(warning) PropertyValueCollection and ValueCollectionTypeBindingTest is broken !as is conflicted between FeatureCollection and Collection<Attribute>
      • (tick) Thanks to Justin for redoing the EMF bindings to support a Collection<Attribute> so this could be handled
  5. Documentation - see Documentation Changes below 
  6. Integration party
    1. (tick) JG: Stage work on branch: https://github.com/geotools/geotools/tree/featurecollection_cleanup
    2. (tick) JG: Submit pull request: https://github.com/geotools/geotools/pull/44
    3. (tick) JG: deploy 9.0-M0-SNAPSHOT as a migration target
    4. (tick) JD: GeoServer pull request: https://github.com/geoserver/geoserver/pull/61
    5. (tick) JG: uDig pull request: https://github.com/uDig/udig-platform/pull/161

...

FeatureCollection Iterator

The deprecated FeatureCollection.iterator() method is no longer available, please use FeatureCollection.features() as shown below.

BEFORE:

Code Block
Iterator i=featureCollection.iterator();
try {
    while( i.hasNext(); ){
       SimpleFeature feature = i.next();
       ...
    }
}
finally {
    featureCollection.close( i );
}

AFTER:

Code Block
FeatureIterator i=featureCollection.features();
try {
     while( i.hasNext(); ){
         SimpleFeature feature = i.next();
         ...
     }
}
finally {
     i.close();
}

JAVA7 (using try-with-resource):

Code Block
try ( FeatureIterator i=featureCollection.features()){
    while( i.hasNext() ){
         SimpleFeature feature = i.next();
         ...
    }
}

 

FeatureCollection close method

We have made FeatureCollection implement closable (for Java 7 try-with-resource compatibility). This also provides an excellent replacement for FeatureCollection.close( Iterator ).

For other code that relied on FeatureCollection.close( Iterator ) to clean up after things, please make sure your Iterator implements Closeable.

BEFORE:

Code Block
Iterator iterator = collection.iterator();
try {
   ...
} finally {
    if (collection instanceof SimpleFeatureCollection) {
        ((SimpleFeatureCollection) collection).close(iterator);
    }
}

AFTER:

Code Block
Iterator iterator = collection.iterator();
try {
   ...
} finally {
    if (iterator instanceof Closeable) {
        try {
           ((Closeable)iterator).close();
        }
        catch( IOException e){
            Logger log = Logger.getLogger( collection.getClass().getPackage().toString() );
            log.log(Level.FINE, e.getMessage(), e );
        }
    }
}

Utility method for the above logic:

Code Block
Iterator iterator = collection.iterator();
try {
   ...
} finally {
   DataUtilities.close( iterator, collection );
}

JAVA7 (using try-with-resource):

Code Block
try ( FeatureIterator i=featureCollection.features()){
    ...
}