001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/feature/DefaultFeatureCollection.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2007 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstraße 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041     
042     ---------------------------------------------------------------------------*/
043    package org.deegree.model.feature;
044    
045    import java.io.Serializable;
046    import java.util.ArrayList;
047    import java.util.Iterator;
048    import java.util.List;
049    
050    import org.deegree.datatypes.QualifiedName;
051    import org.deegree.io.datastore.PropertyPathResolvingException;
052    import org.deegree.model.feature.schema.FeatureType;
053    import org.deegree.model.spatialschema.Envelope;
054    import org.deegree.model.spatialschema.GeometryException;
055    import org.deegree.ogcbase.PropertyPath;
056    
057    /**
058     * This interface provides services for the management of groups of features. These groups can come
059     * into being for a number of reasons: e.g. a project as a whole, for the scope of a query, as the
060     * result of a query or arbitrarily selected by a user for some common manipulation. A feature's
061     * membership of a particular FeatureCollection does not necessarily imply any relationship with
062     * other member features. Composite or compound features which own constituent member Features (e.g.
063     * an Airport composed of Terminals, Runways, Aprons, Hangars, etc) may also support the
064     * FeatureCollection interface to provide a generic means for clients to access constituent members
065     * without needing to be aware of the internal implementation details of the compound feature.
066     * <p>
067     * -----------------------------------------------------------------------
068     * </p>
069     * 
070     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
071     * @version $Revision: 6840 $ $Date: 2007-05-07 10:27:43 +0200 (Mo, 07 Mai 2007) $
072     */
073    class DefaultFeatureCollection extends AbstractFeatureCollection implements Serializable {
074    
075        private List<Feature> collection = null;
076    
077        private Envelope envelope = null;
078    
079        DefaultFeatureCollection( String id, int initialCapacity ) {
080            super( id );
081            collection = new ArrayList<Feature>( initialCapacity );
082        }
083    
084        /**
085         * constructor for initializing a featur collection with an id and an array of features.
086         */
087        DefaultFeatureCollection( String id, Feature[] feature ) {
088            this( id, feature.length );
089            for ( int i = 0; i < feature.length; i++ ) {
090                add( feature[i] );
091            }
092        }
093    
094        /**
095         * returns the FeatureType of this Feature(Collection)
096         */
097        public FeatureType getFeatureType() {
098            return this.featureType;
099        }
100    
101        /**
102         * returns an array of all features
103         */
104        public Feature[] toArray() {
105            return collection.toArray( new Feature[collection.size()] );
106        }
107    
108        /**
109         * returns an <tt>Iterator</tt> on the feature contained in a collection
110         * 
111         * @return an <tt>Iterator</tt> on the feature contained in a collection
112         */
113        public Iterator iterator() {
114            return collection.iterator();
115        }
116    
117        /**
118         * returns the feature that is assigned to the submitted index. If the submitted value for
119         * <tt>index</tt> is smaller 0 and larger then the number features within the
120         * featurecollection-1 an exeption will be thrown.
121         */
122        public Feature getFeature( int index ) {
123            return collection.get( index );
124        }
125    
126        /**
127         * returns the feature that is assigned to the submitted id. If no valid feature could be found
128         * an <tt>Object[]</tt> with zero length will be returned.
129         */
130        public Feature getFeature( String id ) {
131            Feature feature = null;
132            for ( int i = 0; i < collection.size(); i++ ) {
133                feature = collection.get( i );
134                if ( feature.getId().equals( id ) ) {
135                    break;
136                }
137            }
138            return feature;
139        }
140    
141        /**
142         * removes the submitted feature from the collection
143         */
144        public Feature remove( Feature feature ) {
145            int index = collection.indexOf( feature );
146            return remove( index );
147        }
148    
149        /**
150         * removes a feature identified by its index from the feature collection. The removed feature
151         * will be returned. If the submitted value for <tt>index</tt> is smaller 0 and larger then
152         * the number features within the featurecollection-1 an ArrayIndexOutOfBoundsExcpetion will
153         * raise
154         */
155        public Feature remove( int index ) {
156            return collection.remove( index );
157        }
158    
159        /**
160         * Appends a feature to the collection. If the submitted feature doesn't matches the feature
161         * type defined for all features within the collection an exception will be thrown.
162         */
163        public void add( Feature feature ) {
164            collection.add( feature );
165        }
166    
167        /**
168         * returns the number of features within the collection
169         */
170        public int size() {
171            return collection.size();
172        }
173    
174        public void setProperty( FeatureProperty property, int index ) {
175            // TODO Auto-generated method stub
176        }
177    
178        public void addProperty( FeatureProperty property ) {
179            // TODO Auto-generated method stub
180        }
181    
182        public void removeProperty( QualifiedName propertyName ) {
183            // TODO Auto-generated method stub
184        }
185    
186        public void replaceProperty( FeatureProperty oldProperty, FeatureProperty newProperty ) {
187            // TODO Auto-generated method stub
188        }
189    
190        /**
191         * returns the envelope / boundingbox of the feature collection
192         */
193        @Override
194        public synchronized Envelope getBoundedBy()
195                                throws GeometryException {
196    
197            Envelope combinedEnvelope = this.envelope;
198    
199            if ( combinedEnvelope == null && this.collection.size() > 0 ) {            
200                for ( int i = 0; i < this.collection.size(); i++ ) {                        
201                    Envelope nextFeatureEnvelope = this.collection.get( i ).getBoundedBy();
202                    if ( combinedEnvelope == null ) {
203                        combinedEnvelope = nextFeatureEnvelope;
204                    } else if ( nextFeatureEnvelope != null ) {
205                        combinedEnvelope = combinedEnvelope.merge( nextFeatureEnvelope );
206                    }
207                }
208                this.envelope = combinedEnvelope;
209            }
210            return combinedEnvelope;
211        }
212    
213        @Override
214        public String toString() {
215            String ret = null;
216            ret = "collection = " + collection + "\n";
217            return ret;
218        }
219    
220        public FeatureProperty getDefaultProperty( PropertyPath path )
221                                throws PropertyPathResolvingException {
222            // TODO Auto-generated method stub
223            return null;
224        }
225    
226    }