/* * 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.data.collection; // J2SE interfaces import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.logging.Logger; import org.geotools.data.DataSourceException; import org.geotools.data.FeatureReader; import org.geotools.data.Query; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.feature.CollectionEvent; import org.geotools.feature.CollectionListener; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.feature.collection.FeatureIteratorImpl; import org.geotools.feature.collection.SimpleFeatureIteratorImpl; import org.geotools.feature.collection.SubFeatureCollection; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.filter.SortBy2; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.util.NullProgressListener; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.IllegalAttributeException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.Filter; import org.opengis.filter.sort.SortBy; import org.opengis.geometry.BoundingBox; /** * Origional implementation of FeatureCollection using a TreeMap for internal storage. *
* The features are maintained in an internal TreeMap resuling in a collection that is sorted by * feature id mimicking the contents of a shapefile. *
* This implementation of FeatureCollection is painfully correct. *
* This use will result in collections that are sorted by FID, in keeping with shapefile etc... *
*/ private SortedMap
* Opportunistic reuse is encouraged, but only for the purposes of testing or other specialized
* uses. Normal creation should occur through
* org.geotools.core.FeatureCollections.newCollection()
allowing applications to
* customize any generated collections.
*
* Collections that support this operation may place limitations on what elements may be added * to this collection. In particular, some collections will refuse to add null * elements, and others will impose restrictions on the type of elements that may be added. * Collection classes should clearly specify in their documentation any restrictions on what * elements may be added. *
* ** If a collection refuses to add a particular element for any reason other than that it already * contains the element, it must throw an exception (rather than returning false * ). This preserves the invariant that a collection always contains the specified element after * this call returns. *
* * @param o * element whose presence in this collection is to be ensured. * * @return true if this collection changed as a result of the call */ public boolean add(SimpleFeature o) { return add(o, true); } protected boolean add(SimpleFeature feature, boolean fire) { // This cast is neccessary to keep with the contract of Set! if (feature == null) return false; // cannot add null! final String ID = feature.getID(); if (ID == null) return false; // ID is required! if (contents.containsKey(ID)) return false; // feature all ready present if (this.schema == null) { this.schema = feature.getFeatureType(); } SimpleFeatureType childType = (SimpleFeatureType) getSchema(); // if ( childType==null ){ // //this.childType= // }else{ if (!feature.getFeatureType().equals(childType)) LOGGER.warning("Feature Collection contains a heterogeneous" + " mix of features"); // } // TODO check inheritance with FeatureType here!!! contents.put(ID, feature); if (fire) { fireChange(feature, CollectionEvent.FEATURES_ADDED); } return true; } /** * Adds all of the elements in the specified collection to this collection (optional operation). * The behavior of this operation is undefined if the specified collection is modified while the * operation is in progress. (This implies that the behavior of this call is undefined if the * specified collection is this collection, and this collection is nonempty.) * * @param collection * elements to be inserted into this collection. * * @return true if this collection changed as a result of the call * * @see #add(Object) */ @SuppressWarnings("unchecked") public boolean addAll(Collection collection) { // TODO check inheritance with FeatureType here!!! boolean changed = false; Iterator* The returned array will be "safe" in that no references to it are maintained by this * collection. (In other words, this method must allocate a new array even if this collection is * backed by an array). The caller is thus free to modify the returned array. *
* ** This method acts as bridge between array-based and collection-based APIs. *
* * @return an array containing all of the elements in this collection */ public Object[] toArray() { return contents.values().toArray(); } /** * Returns an array containing all of the elements in this collection; the runtime type of the * returned array is that of the specified array. If the collection fits in the specified array, * it is returned therein. Otherwise, a new array is allocated with the runtime type of the * specified array and the size of this collection. * ** If this collection fits in the specified array with room to spare (i.e., the array has more * elements than this collection), the element in the array immediately following the end of the * collection is set to null. This is useful in determining the length of this * collection only if the caller knows that this collection does not contain any * null elements.) *
* ** If this collection makes any guarantees as to what order its elements are returned by its * iterator, this method must return the elements in the same order. *
* ** Like the toArray method, this method acts as bridge between array-based and * collection-based APIs. Further, this method allows precise control over the runtime type of * the output array, and may, under certain circumstances, be used to save allocation costs *
* ** Suppose l is a List known to contain only strings. The following code can * be used to dump the list into a newly allocated array of String: * *
* String[] x = (String[]) v.toArray(new String[0]); ** * * *
* Note that toArray(new Object[0]) is identical in function to toArray(). *
* * @param a * the array into which the elements of this collection are to be stored, if it is * big enough; otherwise, a new array of the same runtime type is allocated for this * purpose. * * @return an array containing the elements of this collection */ @SuppressWarnings("unchecked") public Object[] toArray(Object[] a) { return contents.values().toArray(a != null ? a : new Object[contents.size()]); } public void close(FeatureIterator
* This method is intended in a manner similar to subList, example use:
* collection.subCollection( myFilter ).clear()
*
*