/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.feature; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import org.geotools.data.FeatureSource; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.type.FeatureType; import org.opengis.filter.Filter; import org.opengis.filter.sort.SortBy; import org.opengis.util.ProgressListener; /** * Collection of features, often handled as a result set. * <p> * Where possible FeatureCollection is method compatible with {@link Collection}. * </p> * <p> * SimpleFeatureCollection house rules: * <ul> * <li>Each iterator is considered a live connection which must be closed (see example below)</li> * <li>Features are not specifically ordered within the SimpleFeatureCollection</li> * <li>Two Feature instances cannot exist with the same {@link FeatureId}</li> * </ul> * </p> * <p> * <h3>FeatureIterator close</h3> * <p> * FeatureCollection provides streaming access with the following restriction * on the use of {@link FeatureIterator}: You must call * {@link FeatureIterator#close()}. This allows FeatureCollection * to clean up any operating system resources used to access information. * </p> * <p> * Example (safe) use:<pre><code> * FeatureIterator iterator = featureCollection.features(); * try { * while( iterator.hasNext() ){ * Feature feature = iterator.next(); * System.out.println( feature.getID() ); * } * } * finally { * iterator.close(); * } * </code></pre> * </p> * And in Java 7:<pre><code> * try ( FeatureIterator iterator = featureCollection.features() ){ * while( iterator.hasNext() ){ * Feature feature = iterator.next(); * System.out.println( feature.getID() ); * } * } * </code></pre> * <p> * Handy Tip: Although many resource backed collections will choose * to release resources at when the iterator has reached the end of its contents * this is not something you should rely on. * </p> * <h2>FeatureCollection Implementation Tips</h2> * <p> * Auto close: Try and close up resources when you can detect that an Iterator is no * longer in use. * </p> * <p> * Lazy Connect: FeatureCollection is used in two fashions, as a result set, where each iterator acts * as a cursor over the content. Also as a predefined query which can be refined * further. An example is using featureCollection.subCollection( Filter ) or * featureCollection.sort( SortBy ) before listing features out of a FeatureCollection. * </p> * * @see org.geotools.Feature * @author Ian Turton, CCG * @author Rob Hranac, VFNY * @author Ian Schneider, USDA-ARS * @author Jody Garnett, LISAsoft * * @source $URL$ * @version $Id$ */ public interface FeatureCollection<T extends FeatureType, F extends Feature> { /** * Obtain a FeatureIterator<SimpleFeature> of the Features within this FeatureCollection. * <p> * The implementation of FeatureIterator must adhere to the rules of * fail-fast concurrent modification. In addition (to allow for * resource backed collections) the <code>FeatureIterator.close()</code> * method must be called. * <p> * Example use:<pre><code> * FeatureIterator<SimpleFeature> iterator=collection.features(); * try { * while( iterator.hasNext() ){ * Feature feature = iterator.next(); * System.out.println( feature.getID() ); * } * } * finally { * iterator.close(); * } * </code></pre> * </p> * * <p> * GML Note: The contents of this iterator are considered to be defined by * <b>featureMember</b> tags (and/or the single allowed <b>FeatureMembers</b> tag). * Please see getFeatureType for more details. * </p> * * @return A FeatureIterator. */ FeatureIterator<F> features(); /** * The schema for the child feature members of this collection. * <p> * Represents the most general FeatureType in common to all the features in this * collection. * <ul> * <li>For a collection backed by a shapefiles (or database tables) the FeatureType returned by getSchema() will * complete describe each and every child in the collection. * <li>For mixed content FeatureCollections you will need to check the FeatureType of each Feature as it * is retrived from the collection * <li>The degenerate case returns the "_Feature" FeatureType, where the * only thing known is that the contents are Features. * </ul> * </p> * @return FeatureType describing the "common" schema to all child features of this collection */ T getSchema(); /** * ID used when serializing to GML */ String getID(); /** * Visit the contents of a feature collection. * <p> * The order of traversal is dependent on the FeatureCollection implementation; some * collections are able to make efficient use of an internal index in order to quickly * visit features located in the same region. * </p> * * @param visitor Closure applied to each feature in turn. * @param progress Used to report progress, may be used to interrupt the operation * * @since 2.5 */ void accepts(FeatureVisitor visitor, ProgressListener progress) throws IOException; /** * SimpleFeatureCollection "view" indicated by provided filter. * <p> * The contents of the returned SimpleFeatureCollection are determined by * applying the provider Filter to the entire contents of this * FeatureCollection. The result is "live" and modifications will * be shared. * <p> * This method is used cut down on the number of filter based methods * required for a useful SimpleFeatureCollection construct. The FeatureCollections * returned really should be considered as a temporary "view" used to * control the range of a removeAll, or modify operation. * <p> * Example Use: * <pre><code> * collection.subCollection( filter ).clear(); * </code></pre> * The above recommended use is agreement with the Collections API precident of * List.subList( start, end ). * <p> * The results of subCollection: * <ul> * <li>are to be considered unordered * <li>may be an ordered FeatureList if requested when sortBy is indicated * </ul> * </p> * @see FeatureList * @param filter * @return SimpleFeatureCollection identified as subset. */ public FeatureCollection<T, F> subCollection(Filter filter); /** * Obtained sorted contents. * <p> * This method may not be supported by all implementations, consider * the use of FeatureSource.features( Query ). * * @param order Sort order * @return FeatureCollection sorted in the indicated order */ public FeatureCollection<T, F> sort(SortBy order); /** * Get the total bounds of this collection which is calculated by doing a * union of the bounds of each feature inside of it * * @return An Envelope containing the total bounds of this collection. */ ReferencedEnvelope getBounds(); // // ResourceCollection methods // /** * @see java.util.Collection#contains(Object) */ boolean contains(Object o); /** * @see java.util.Collection#containsAll(Collection) */ boolean containsAll(Collection<?> o); /** * Returns <tt>true</tt> if this feature collection contains no features. * * @return <tt>true</tt> if this collection contains no features */ boolean isEmpty(); /** * Please note this operation may be expensive when working with remote content. * * @see java.util.Collection#size() */ int size(); /** @see java.util.Collection#toArray() */ Object[] toArray(); /** @see java.util.Collection#toArray(Object[]) */ <O> O[] toArray(O[] a); }