Permalink
Browse files

Additional helper methods for DataUtilities taken from ProcessingColl…

…ection class. ProcessingCollection now extends BaseFeatureCollection to avoid code duplication.
  • Loading branch information...
1 parent 5dd8f4a commit 9c9d5b71548e65f5f7f35df114be1359141d7da2 @jodygarnett jodygarnett committed Nov 4, 2012
@@ -2649,11 +2649,89 @@ static AttributeDescriptor createAttribute(String typeSpec) throws SchemaExcepti
}
/**
- * Manually calculates the bounds of a feature collection.
+ * Manually count the number of features from the provided FeatureIterator
*
* @param collection
+ * @return number of featuers in feature collection
+ */
+ public static int count( FeatureIterator<?> iterator) {
+ int count = 0;
+ if( iterator != null ){
+ try {
+ while (iterator.hasNext()) {
+ @SuppressWarnings("unused")
+ Feature feature = iterator.next();
+ count++;
+ }
+ return count;
+ }
+ finally {
+ iterator.close();
+ }
+ }
+ return count;
+ }
+ /**
+ * Manually count the number of features in a feature collection using using {@link FeatureCollection#features()}.
+ *
+ * @param collection
+ * @return number of featuers in feature collection
+ */
+ public static int count(
+ FeatureCollection<? extends FeatureType, ? extends Feature> collection) {
+ int count = 0;
+ FeatureIterator<? extends Feature> i = collection.features();
+ try {
+ while (i.hasNext()) {
+ @SuppressWarnings("unused")
+ Feature feature = (Feature) i.next();
+ count++;
+ }
+ return count;
+ }
+ finally {
+ if( i != null ){
+ i.close();
+ }
+ }
+ }
+ /**
+ * Manually calculate the bounds from the provided FeatureIteator
+ * @param iterator
* @return
*/
+ public static ReferencedEnvelope bounds( FeatureIterator<?> iterator ){
+ if( iterator == null ){
+ return null;
+ }
+ try {
+ ReferencedEnvelope bounds = null;
+ while (iterator.hasNext()) {
+ Feature feature = iterator.next();
+ ReferencedEnvelope featureEnvelope = null;
+ if(feature != null && feature.getBounds() != null) {
+ featureEnvelope = ReferencedEnvelope.reference(feature.getBounds());
+ }
+
+ if(featureEnvelope != null) {
+ if(bounds == null) {
+ bounds = new ReferencedEnvelope(featureEnvelope);
+ } else {
+ bounds.expandToInclude(featureEnvelope);
+ }
+ }
+ }
+ return bounds;
+ } finally {
+ iterator.close();
+ }
+ }
+ /**
+ * Manually calculates the bounds of a feature collection using {@link FeatureCollection#features()}.
+ *
+ * @param collection
+ * @return bounds of features in feature collection
+ */
public static ReferencedEnvelope bounds(
FeatureCollection<? extends FeatureType, ? extends Feature> collection) {
FeatureIterator<? extends Feature> i = collection.features();
@@ -2663,11 +2741,14 @@ public static ReferencedEnvelope bounds(
ReferencedEnvelope bounds = new ReferencedEnvelope(crs);
while (i.hasNext()) {
- BoundingBox geomBounds = ((SimpleFeature) i.next()).getBounds();
+ Feature feature = i.next();
+ if( feature == null ) continue;
+
+ BoundingBox geomBounds = feature.getBounds();
// IanS - as of 1.3, JTS expandToInclude ignores "null" Envelope
// and simply adds the new bounds...
// This check ensures this behavior does not occur.
- if ( ! geomBounds.isEmpty() ) {
+ if ( geomBounds != null && !geomBounds.isEmpty() ) {
bounds.include(geomBounds);
}
}
@@ -16,14 +16,19 @@
*/
package org.geotools.feature.collection;
+import java.io.IOException;
import java.util.Collection;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.store.FilteringFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.util.NullProgressListener;
import org.opengis.feature.Feature;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.FeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
@@ -56,7 +61,13 @@
protected String id;
protected T schema;
+ protected BaseFeatureCollection(){
+ this( null, null );
+ }
protected BaseFeatureCollection(T schema) {
+ this( schema, null );
+ }
+ protected BaseFeatureCollection(T schema, String id) {
this.id = id == null ? "featureCollection" : id;
this.schema = schema;
}
@@ -186,7 +197,7 @@ public boolean isEmpty() {
}
public void accepts(org.opengis.feature.FeatureVisitor visitor,
- org.opengis.util.ProgressListener progress) {
+ org.opengis.util.ProgressListener progress) throws IOException {
FeatureIterator<F> iterator = null;
if (progress == null)
progress = new NullProgressListener();
@@ -216,15 +227,40 @@ public void accepts(org.opengis.feature.FeatureVisitor visitor,
//
// Feature Collections API
//
+ /**
+ * Convenience implementation that just wraps this collection into a
+ * {@link FilteringFeatureCollection}. Subclasses might want to override this in case the filter
+ * can be cascaded to their data sources.
+ *
+ * @param filter
+ * @return
+ */
public FeatureCollection<T,F> subCollection(Filter filter) {
if (filter == Filter.INCLUDE) {
return this;
}
return new FilteringFeatureCollection<T, F>(this, filter);
}
-
+ /**
+ * Obtained sorted contents, only implemented for SimpleFeature at present.
+ * <p>
+ * This method only supports SimpleFeature at present, consider use of FeatureSource.features( Query ).
+ *
+ * @param order Sort order
+ * @return FeatureCollection sorted in the indicated order
+ */
+ @SuppressWarnings("unchecked")
public FeatureCollection<T,F> sort(SortBy order) {
- throw new UnsupportedOperationException("Cannot sort on complex features at the moment");
+ if (getSchema() instanceof SimpleFeatureType) {
+ // go for the most efficient way if possible, otherwise rely on pure in memory
+ // sorting...
+ SimpleFeatureCollection simple = DataUtilities.simple((FeatureCollection<SimpleFeatureType, SimpleFeature>) this);
+ return (FeatureCollection<T, F>) new SortedSimpleFeatureCollection(simple,new SortBy[] { order });
+ } else {
+ // hmm... we don't even have a basic non simple collection... need to implement one
+ // before going here
+ throw new UnsupportedOperationException("Cannot sort on complex features at the moment");
+ }
}
/**
@@ -24,6 +24,7 @@
import org.geotools.process.factory.DescribeProcess;
import org.geotools.process.factory.DescribeResult;
import org.geotools.process.gs.WrappingIterator;
+import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.AttributeTypeBuilder;
@@ -117,7 +118,7 @@ public ReferencedEnvelope getBounds() {
return re;
} else {
// unlucky case, we need to actually compute by hand...
- return getFeatureBounds();
+ return DataUtilities.bounds(features());
}
}
@@ -70,7 +70,7 @@ public SimpleFeatureIterator features() {
@Override
public ReferencedEnvelope getBounds() {
- return getFeatureBounds();
+ return DataUtilities.bounds( features() );
}
@Override
Oops, something went wrong.

0 comments on commit 9c9d5b7

Please sign in to comment.