/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.feature; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.geotools.data.DataUtilities; import org.geotools.data.store.DataFeatureCollection; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.identity.FeatureId; /** * Wraps multiple feature collections into a single. * * @author Justin Deoliveira, The Open Planning Project * */ public class CompositeFeatureCollection extends DataFeatureCollection { /** * wrapped collecitons */ List<FeatureCollection> collections; public CompositeFeatureCollection(List collections) { this.collections = collections; } protected Iterator openIterator() throws IOException { return new CompositeIterator(); } public SimpleFeatureType getSchema() { return null; } public ReferencedEnvelope getBounds() { return DataUtilities.bounds(this); } public int getCount() throws IOException { int count = 0; Iterator i = iterator(); try { while (i.hasNext()) { i.next(); count++; } } finally { close(i); } return count; } class CompositeIterator implements Iterator { int index; FeatureIterator iterator; public CompositeIterator() { index = 0; } public void remove() { } public boolean hasNext() { //is there a current iterator that has another element if ((iterator != null) && iterator.hasNext()) { return true; } //get the next iterator while (index < collections.size()) { //close current before we move to next if (iterator != null) { iterator.close(); } //grap next iterator = collections.get(index++).features(); if (iterator.hasNext()) { return true; } } //no more if (iterator != null) { //close the last iterator iterator.close(); } return false; } public Object next() { return iterator.next(); } } public Object[] toArray(Object[] arg0) { List list = new ArrayList(); Iterator it = collections.iterator(); while(it.hasNext()){ FeatureCollection col = (FeatureCollection)it.next(); FeatureIterator it2 = col.features(); while (it2.hasNext()){ list.add(it.next()); } it2.close(); } return list.toArray(arg0); } public FeatureId getIdentifier() { throw new RuntimeException("Can't get the id for a composite featurecollection; you need to identify the consituent collections directly."); } /** * @return the collections */ public List<FeatureCollection> getCollections() { return collections; } }