001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.feature.collection;
017:
018: import java.io.IOException;
019: import java.util.Iterator;
020:
021: import org.geotools.data.FeatureReader;
022: import org.geotools.data.collection.DelegateFeatureReader;
023: import org.geotools.factory.CommonFactoryFinder;
024: import org.geotools.feature.CollectionListener;
025: import org.geotools.feature.Feature;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.feature.FeatureIterator;
028: import org.geotools.feature.FeatureList;
029: import org.geotools.feature.FeatureType;
030: import org.geotools.feature.IllegalAttributeException;
031: import org.geotools.feature.visitor.FeatureVisitor;
032: import org.geotools.geometry.jts.ReferencedEnvelope;
033: import org.opengis.filter.Filter;
034: import org.opengis.filter.FilterFactory;
035: import org.opengis.filter.sort.SortBy;
036: import org.geotools.util.ProgressListener;
037:
038: import com.vividsolutions.jts.geom.Envelope;
039: import com.vividsolutions.jts.geom.Geometry;
040:
041: /**
042: * Used as a reasonable default implementation for subCollection.
043: * <p>
044: * Note: to implementors, this is not optimal, please do your own
045: * thing - your users will thank you.
046: * </p>
047: *
048: * @author Jody Garnett, Refractions Research, Inc.
049: *
050: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureCollection.java $
051: */
052: public class SubFeatureCollection extends AbstractResourceCollection
053: implements FeatureCollection {
054: /** Filter */
055: protected Filter filter;
056:
057: /** Origional Collection */
058: protected FeatureCollection collection;
059: protected FeatureState state;
060: protected FilterFactory ff = CommonFactoryFinder
061: .getFilterFactory(null);
062:
063: public SubFeatureCollection(FeatureCollection collection) {
064: this (collection, null);
065: }
066:
067: public SubFeatureCollection(FeatureCollection collection,
068: Filter subfilter) {
069: if (subfilter != null && subfilter.equals(Filter.EXCLUDE)) {
070: throw new IllegalArgumentException(
071: "A subcollection with Filter.EXCLUDE is a null operation");
072: }
073: if (subfilter != null && subfilter.equals(Filter.INCLUDE)) {
074: throw new IllegalArgumentException(
075: "A subcollection with Filter.INCLUDE should be a FeatureCollectionEmpty");
076: }
077: if (subfilter != null
078: && (collection instanceof SubFeatureCollection)) {
079: SubFeatureCollection filtered = (SubFeatureCollection) collection;
080: this .collection = filtered.collection;
081: this .filter = ff.and(filtered.filter(), subfilter);
082: } else {
083: this .collection = collection;
084: this .filter = subfilter;
085: }
086: state = new SubFeatureState(this .collection, this );
087: }
088:
089: protected Filter filter() {
090: if (filter == null) {
091: filter = createFilter();
092: }
093: return filter;
094: }
095:
096: /** Override to implement subsetting */
097: protected Filter createFilter() {
098: return Filter.INCLUDE;
099: }
100:
101: public FeatureType getFeatureType() {
102: return state.getFeatureType();
103: }
104:
105: public FeatureIterator features() {
106: return new DelegateFeatureIterator(this , iterator());
107: }
108:
109: public void closeIterator(Iterator iterator) {
110: if (iterator == null)
111: return;
112:
113: if (iterator instanceof FilteredIterator) {
114: FilteredIterator filtered = (FilteredIterator) iterator;
115: filtered.close();
116: }
117: }
118:
119: public void close(FeatureIterator close) {
120: if (close != null)
121: close.close();
122: }
123:
124: //
125: // Feature methods
126: //
127: public String getID() {
128: return state.getId();
129: }
130:
131: public ReferencedEnvelope getBounds() {
132: return ReferencedEnvelope.reference(state.getBounds());
133: }
134:
135: public Geometry getDefaultGeometry() {
136: return state.getDefaultGeometry();
137: }
138:
139: public void setDefaultGeometry(Geometry g)
140: throws IllegalAttributeException {
141: state.setDefaultGeometry(g);
142: }
143:
144: public void addListener(CollectionListener listener)
145: throws NullPointerException {
146: state.addListener(listener);
147: }
148:
149: public void removeListener(CollectionListener listener)
150: throws NullPointerException {
151: state.removeListener(listener);
152: }
153:
154: public FeatureCollection getParent() {
155: return state.getParent();
156: }
157:
158: public void setParent(FeatureCollection collection) {
159: state.setParent(collection);
160: }
161:
162: public Object[] getAttributes(Object[] attributes) {
163: return state.getAttributes(attributes);
164: }
165:
166: public Object getAttribute(String xPath) {
167: return state.getAttribute(xPath);
168: }
169:
170: public Object getAttribute(int index) {
171: return state.getAttribute(index);
172: }
173:
174: public void setAttribute(int position, Object val)
175: throws IllegalAttributeException,
176: ArrayIndexOutOfBoundsException {
177: state.setAttribute(position, val);
178: }
179:
180: public int getNumberOfAttributes() {
181: return state.getNumberOfAttributes();
182: }
183:
184: public void setAttribute(String xPath, Object attribute)
185: throws IllegalAttributeException {
186: state.setAttribute(xPath, attribute);
187: }
188:
189: //
190: //
191: //
192: public FeatureCollection subCollection(Filter filter) {
193: if (filter.equals(Filter.INCLUDE)) {
194: return this ;
195: }
196: if (filter.equals(Filter.EXCLUDE)) {
197: // TODO implement EmptyFeatureCollection( schema )
198: }
199: return new SubFeatureCollection(this , filter);
200: }
201:
202: public int size() {
203: int count = 0;
204: Iterator i = null;
205: try {
206: for (i = iterator(); i.hasNext(); count++)
207: i.next();
208: } finally {
209: close(i);
210: }
211: return count;
212: }
213:
214: public boolean isEmpty() {
215: Iterator iterator = iterator();
216: try {
217: return !iterator.hasNext();
218: } finally {
219: close(iterator);
220: }
221: }
222:
223: public Iterator openIterator() {
224: return new FilteredIterator(collection, filter());
225: }
226:
227: public FeatureType getSchema() {
228: return collection.getSchema();
229: }
230:
231: /**
232: * Accepts a visitor, which then visits each feature in the collection.
233: * @throws IOException
234: */
235: public void accepts(FeatureVisitor visitor,
236: ProgressListener progress) throws IOException {
237: Iterator iterator = null;
238: // if( progress == null ) progress = new NullProgressListener();
239: try {
240: float size = size();
241: float position = 0;
242: progress.started();
243: for (iterator = iterator(); !progress.isCanceled()
244: && iterator.hasNext(); progress.progress(position++
245: / size)) {
246: try {
247: Feature feature = (Feature) iterator.next();
248: visitor.visit(feature);
249: } catch (Exception erp) {
250: progress.exceptionOccurred(erp);
251: }
252: }
253: } finally {
254: progress.complete();
255: close(iterator);
256: }
257: }
258:
259: public FeatureReader reader() throws IOException {
260: return new DelegateFeatureReader(getSchema(), features());
261: }
262:
263: public int getCount() throws IOException {
264: return size();
265: }
266:
267: public FeatureCollection collection() throws IOException {
268: return this ;
269: }
270:
271: public FeatureList sort(SortBy order) {
272: return null;
273: }
274:
275: public void purge() {
276: collection.purge();
277: }
278: }
|