001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/feature/DefaultFeatureCollection.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 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.Arrays;
048: import java.util.Iterator;
049: import java.util.List;
050: import java.util.UUID;
051:
052: import org.deegree.datatypes.QualifiedName;
053: import org.deegree.io.datastore.PropertyPathResolvingException;
054: import org.deegree.model.feature.schema.FeatureType;
055: import org.deegree.model.spatialschema.Envelope;
056: import org.deegree.model.spatialschema.GeometryException;
057: import org.deegree.ogcbase.PropertyPath;
058:
059: /**
060: * This interface provides services for the management of groups of features. These groups can come into being for a
061: * number of reasons: e.g. a project as a whole, for the scope of a query, as the result of a query or arbitrarily
062: * selected by a user for some common manipulation. A feature's membership of a particular FeatureCollection does not
063: * necessarily imply any relationship with other member features. Composite or compound features which own constituent
064: * member Features (e.g. an Airport composed of Terminals, Runways, Aprons, Hangars, etc) may also support the
065: * FeatureCollection interface to provide a generic means for clients to access constituent members without needing to
066: * be aware of the internal implementation details of the compound feature.
067: * <p>
068: * -----------------------------------------------------------------------
069: * </p>
070: *
071: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
072: * @version $Revision: 10533 $ $Date: 2008-03-10 02:31:08 -0700 (Mon, 10 Mar 2008) $
073: */
074: class DefaultFeatureCollection extends AbstractFeatureCollection
075: implements Serializable {
076:
077: /**
078: *
079: */
080: private static final long serialVersionUID = 843595367254599228L;
081:
082: private List<Feature> collection = null;
083:
084: private Envelope envelope = null;
085:
086: DefaultFeatureCollection(String id, int initialCapacity) {
087: super (id);
088: collection = new ArrayList<Feature>(initialCapacity);
089: }
090:
091: /**
092: * constructor for initializing a feature collection with an id and an array of features.
093: */
094: DefaultFeatureCollection(String id, Feature[] feature) {
095: this (id, feature.length);
096: for (int i = 0; i < feature.length; i++) {
097: add(feature[i]);
098: }
099: }
100:
101: /**
102: * Constructor for initializing a feature collection with an id and an array of features. It's name will be taken
103: * from the given name.
104: *
105: * @param id
106: * of the feature collection
107: * @param features
108: * to be added
109: * @param qName
110: * of the feature collection, if <code>null</code> the default name of wfs:FeatureCollection will be
111: * given.
112: */
113: DefaultFeatureCollection(String id, Feature[] features,
114: QualifiedName qName) {
115: super (id, qName);
116: if (features != null) {
117: collection = Arrays.asList(features);
118: } else {
119: collection = new ArrayList<Feature>();
120: }
121: }
122:
123: /*
124: * (non-Javadoc)
125: *
126: * @see org.deegree.model.feature.FeatureCollection#clear()
127: */
128: public void clear() {
129: collection.clear();
130: }
131:
132: /**
133: * @return the FeatureType of this Feature(Collection)
134: */
135: @Override
136: public FeatureType getFeatureType() {
137: return this .featureType;
138: }
139:
140: /**
141: * returns an array of all features
142: */
143: public Feature[] toArray() {
144: return collection.toArray(new Feature[collection.size()]);
145: }
146:
147: /**
148: * returns an <tt>Iterator</tt> on the feature contained in a collection
149: *
150: * @return an <tt>Iterator</tt> on the feature contained in a collection
151: */
152: public Iterator<Feature> iterator() {
153: return collection.iterator();
154: }
155:
156: /**
157: * returns the feature that is assigned to the submitted index. If the submitted value for <tt>index</tt> is
158: * smaller 0 and larger then the number features within the featurecollection-1 an exeption will be thrown.
159: */
160: public Feature getFeature(int index) {
161: return collection.get(index);
162: }
163:
164: /**
165: * returns the feature that is assigned to the submitted id. If no valid feature could be found an <tt>Object[]</tt>
166: * with zero length will be returned.
167: */
168: public Feature getFeature(String id) {
169: Feature feature = null;
170: for (int i = 0; i < collection.size(); i++) {
171: feature = collection.get(i);
172: if (feature.getId().equals(id)) {
173: break;
174: }
175: }
176: return feature;
177: }
178:
179: /**
180: * removes the submitted feature from the collection
181: */
182: public Feature remove(Feature feature) {
183: int index = collection.indexOf(feature);
184: return remove(index);
185: }
186:
187: /**
188: * removes a feature identified by its index from the feature collection. The removed feature will be returned. If
189: * the submitted value for <tt>index</tt> is smaller 0 and larger then the number features within the
190: * featurecollection-1 an ArrayIndexOutOfBoundsExcpetion will raise
191: */
192: public Feature remove(int index) {
193: return collection.remove(index);
194: }
195:
196: /**
197: * Appends a feature to the collection. If the submitted feature doesn't matches the feature type defined for all
198: * features within the collection an exception will be thrown.
199: */
200: public void add(Feature feature) {
201: collection.add(feature);
202: }
203:
204: /**
205: * returns the number of features within the collection
206: */
207: public int size() {
208: return collection.size();
209: }
210:
211: public void setProperty(FeatureProperty property, int index) {
212: // TODO Auto-generated method stub
213: }
214:
215: public void addProperty(FeatureProperty property) {
216: // TODO Auto-generated method stub
217: }
218:
219: public void removeProperty(QualifiedName propertyName) {
220: // TODO Auto-generated method stub
221: }
222:
223: public void replaceProperty(FeatureProperty oldProperty,
224: FeatureProperty newProperty) {
225: // TODO Auto-generated method stub
226: }
227:
228: /**
229: * returns the envelope / boundingbox of the feature collection
230: */
231: @Override
232: public synchronized Envelope getBoundedBy()
233: throws GeometryException {
234:
235: Envelope combinedEnvelope = this .envelope;
236:
237: if (combinedEnvelope == null && this .collection.size() > 0) {
238: for (int i = 0; i < this .collection.size(); i++) {
239: Envelope nextFeatureEnvelope = this .collection.get(i)
240: .getBoundedBy();
241: if (combinedEnvelope == null) {
242: combinedEnvelope = nextFeatureEnvelope;
243: } else if (nextFeatureEnvelope != null) {
244: combinedEnvelope = combinedEnvelope
245: .merge(nextFeatureEnvelope);
246: }
247: }
248: this .envelope = combinedEnvelope;
249: }
250: return combinedEnvelope;
251: }
252:
253: @Override
254: public String toString() {
255: String ret = null;
256: ret = "collection = " + collection + "\n";
257: return ret;
258: }
259:
260: public FeatureProperty getDefaultProperty(PropertyPath path)
261: throws PropertyPathResolvingException {
262: // TODO Auto-generated method stub
263: return null;
264: }
265:
266: /**
267: * @return a shallow clone of a feature collection. Property values of contained features
268: * will not be cloned except for properties that are features (DefaultFeature) or
269: * feature collections (DefaultFeatureCollection).
270: */
271: @Override
272: public Object clone() {
273: FeatureCollection fc = FeatureFactory.createFeatureCollection(
274: UUID.randomUUID().toString(), collection.size());
275: for (Feature feature : collection) {
276: fc.add((Feature) ((DefaultFeature) feature).clone());
277: }
278: return fc;
279: }
280:
281: }
|