001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/feature/DefaultFeatureCollection.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.model.feature;
037
038 import java.io.Serializable;
039 import java.util.ArrayList;
040 import java.util.Iterator;
041 import java.util.LinkedList;
042 import java.util.List;
043 import java.util.UUID;
044
045 import org.deegree.datatypes.QualifiedName;
046 import org.deegree.io.datastore.PropertyPathResolvingException;
047 import org.deegree.model.feature.schema.FeatureType;
048 import org.deegree.model.spatialschema.Envelope;
049 import org.deegree.model.spatialschema.GeometryException;
050 import org.deegree.ogcbase.PropertyPath;
051
052 /**
053 * This interface provides services for the management of groups of features. These groups can come into being for a
054 * number of reasons: e.g. a project as a whole, for the scope of a query, as the result of a query or arbitrarily
055 * selected by a user for some common manipulation. A feature's membership of a particular FeatureCollection does not
056 * necessarily imply any relationship with other member features. Composite or compound features which own constituent
057 * member Features (e.g. an Airport composed of Terminals, Runways, Aprons, Hangars, etc) may also support the
058 * FeatureCollection interface to provide a generic means for clients to access constituent members without needing to
059 * be aware of the internal implementation details of the compound feature.
060 * <p>
061 * -----------------------------------------------------------------------
062 * </p>
063 *
064 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
065 * @version $Revision: 18195 $ $Date: 2009-06-18 17:55:39 +0200 (Thu, 18 Jun 2009) $
066 */
067 class DefaultFeatureCollection extends AbstractFeatureCollection implements Serializable {
068
069 /**
070 *
071 */
072 private static final long serialVersionUID = 843595367254599228L;
073
074 private List<Feature> collection = new LinkedList<Feature>();
075
076 private Envelope envelope = null;
077
078 DefaultFeatureCollection( String id, int initialCapacity ) {
079 super( id );
080 collection = new ArrayList<Feature>( initialCapacity );
081 }
082
083 /**
084 * constructor for initializing a feature collection with an id and an array of features.
085 */
086 DefaultFeatureCollection( String id, Feature[] features ) {
087 this( id, features, null );
088 }
089
090 /**
091 * Constructor for initializing a feature collection with an id and an array of features. It's name will be taken
092 * from the given name.
093 *
094 * @param id
095 * of the feature collection
096 * @param features
097 * to be added
098 * @param qName
099 * of the feature collection, if <code>null</code> the default name of wfs:FeatureCollection will be
100 * given.
101 */
102 DefaultFeatureCollection( String id, Feature[] features, QualifiedName qName ) {
103 super( id, qName );
104 if ( features != null ) {
105 for ( int i = 0; i < features.length; i++ ) {
106 add( features[i] );
107 }
108 }
109 }
110
111 /*
112 * (non-Javadoc)
113 *
114 * @see org.deegree.model.feature.FeatureCollection#clear()
115 */
116 public void clear() {
117 collection.clear();
118 }
119
120 /**
121 * @return the FeatureType of this Feature(Collection)
122 */
123 @Override
124 public FeatureType getFeatureType() {
125 return this.featureType;
126 }
127
128 /**
129 * returns an array of all features
130 */
131 public Feature[] toArray() {
132 return collection.toArray( new Feature[collection.size()] );
133 }
134
135 /**
136 * returns an <tt>Iterator</tt> on the feature contained in a collection
137 *
138 * @return an <tt>Iterator</tt> on the feature contained in a collection
139 */
140 public Iterator<Feature> iterator() {
141 return collection.iterator();
142 }
143
144 /**
145 * returns the feature that is assigned to the submitted index. If the submitted value for <tt>index</tt> is smaller
146 * 0 and larger then the number features within the featurecollection-1 an exeption will be thrown.
147 */
148 public Feature getFeature( int index ) {
149 return collection.get( index );
150 }
151
152 /**
153 * @return the feature that is assigned to the submitted id. If no valid feature could be found <code>null</code>
154 * will be returned.
155 */
156 public Feature getFeature( String id ) {
157 for ( int i = 0; i < collection.size(); i++ ) {
158 Feature feature = collection.get( i );
159 if ( feature.getId().equals( id ) ) {
160 return feature;
161 }
162 }
163 return null;
164 }
165
166 /**
167 * removes the submitted feature from the collection
168 */
169 public Feature remove( Feature feature ) {
170 int index = collection.indexOf( feature );
171 return remove( index );
172 }
173
174 /**
175 * removes a feature identified by its index from the feature collection. The removed feature will be returned. If
176 * the submitted value for <tt>index</tt> is smaller 0 and larger then the number features within the
177 * featurecollection-1 an ArrayIndexOutOfBoundsExcpetion will raise
178 */
179 public Feature remove( int index ) {
180 return collection.remove( index );
181 }
182
183 /**
184 * Appends a feature to the collection. If the submitted feature doesn't matches the feature type defined for all
185 * features within the collection an exception will be thrown.
186 */
187 public void add( Feature feature ) {
188 collection.add( feature );
189 }
190
191 /**
192 * returns the number of features within the collection
193 */
194 public int size() {
195 return collection.size();
196 }
197
198 public void setProperty( FeatureProperty property, int index ) {
199 // TODO Auto-generated method stub
200 }
201
202 public void addProperty( FeatureProperty property ) {
203 // TODO Auto-generated method stub
204 }
205
206 public void removeProperty( QualifiedName propertyName ) {
207 // TODO Auto-generated method stub
208 }
209
210 public void replaceProperty( FeatureProperty oldProperty, FeatureProperty newProperty ) {
211 // TODO Auto-generated method stub
212 }
213
214 @Override
215 public synchronized Envelope getBoundedBy()
216 throws GeometryException {
217
218 Envelope combinedEnvelope = this.envelope;
219
220 if ( this.collection.size() > 0 ) {
221 for ( Feature f : this.collection ) {
222 Envelope nextFeatureEnvelope = f.getBoundedBy();
223 if ( combinedEnvelope == null ) {
224 combinedEnvelope = nextFeatureEnvelope;
225 } else if ( nextFeatureEnvelope != null ) {
226 combinedEnvelope = combinedEnvelope.merge( nextFeatureEnvelope );
227 }
228 }
229 this.envelope = combinedEnvelope;
230 }
231 return combinedEnvelope;
232 }
233
234 @Override
235 public void setEnvelopesUpdated() {
236 this.envelope = null;
237 }
238
239 @Override
240 public String toString() {
241 String ret = null;
242 ret = "collection = " + collection + "\n";
243 return ret;
244 }
245
246 public FeatureProperty getDefaultProperty( PropertyPath path )
247 throws PropertyPathResolvingException {
248 // TODO Auto-generated method stub
249 return null;
250 }
251
252 /**
253 * @return a shallow clone of a feature collection. Property values of contained features will not be cloned except
254 * for properties that are features (DefaultFeature) or feature collections (DefaultFeatureCollection).
255 */
256 @Override
257 public Object clone()
258 throws CloneNotSupportedException {
259 FeatureCollection fc = FeatureFactory.createFeatureCollection( UUID.randomUUID().toString(), collection.size() );
260 for ( Feature feature : collection ) {
261 fc.add( (Feature) ( (DefaultFeature) feature ).clone() );
262 }
263 return fc;
264
265 }
266
267 /*
268 * (non-Javadoc)
269 *
270 * @see org.deegree.model.feature.Feature#cloneDeep()
271 */
272 public Feature cloneDeep()
273 throws CloneNotSupportedException {
274 FeatureCollection fc = FeatureFactory.createFeatureCollection( UUID.randomUUID().toString(), collection.size() );
275 for ( Feature feature : collection ) {
276 fc.add( feature.cloneDeep() );
277 }
278 return fc;
279 }
280
281 }