001: package org.geotools.data.store;
002:
003: import java.io.IOException;
004: import java.util.Collections;
005: import java.util.Set;
006: import java.util.logging.Level;
007: import java.util.logging.Logger;
008:
009: import org.geotools.data.DataSourceException;
010: import org.geotools.data.DataStore;
011: import org.geotools.data.DataUtilities;
012: import org.geotools.data.FeatureListener;
013: import org.geotools.data.FeatureSource;
014: import org.geotools.data.Query;
015: import org.geotools.feature.FeatureCollection;
016: import org.geotools.feature.FeatureType;
017: import org.geotools.feature.SchemaException;
018: import org.opengis.filter.Filter;
019: import org.opengis.referencing.crs.CoordinateReferenceSystem;
020:
021: import com.vividsolutions.jts.geom.Coordinate;
022: import com.vividsolutions.jts.geom.Envelope;
023:
024: public abstract class AbstractFeatureSource2 implements FeatureSource {
025:
026: /** The logger for the data module. */
027: protected static final Logger LOGGER = org.geotools.util.logging.Logging
028: .getLogger("org.geotools.data");
029:
030: /**
031: * the type entry
032: */
033: protected ActiveTypeEntry entry;
034:
035: public AbstractFeatureSource2(ActiveTypeEntry entry) {
036: this .entry = entry;
037: }
038:
039: public DataStore getDataStore() {
040: return entry.parent;
041: }
042:
043: public void addFeatureListener(FeatureListener listener) {
044: entry.listenerManager.addFeatureListener(this , listener);
045: }
046:
047: public void removeFeatureListener(FeatureListener listener) {
048: entry.listenerManager.removeFeatureListener(this , listener);
049: }
050:
051: public FeatureCollection getFeatures(Query query)
052: throws IOException {
053: FeatureType featureType = entry.getFeatureType();
054:
055: Filter filter = query.getFilter();
056: if (filter == null) {
057: throw new NullPointerException(
058: "getFeatureReader requires Filter: "
059: + "did you mean Filter.INCLUDE?");
060: }
061: String propertyNames[] = query.getPropertyNames();
062:
063: if (filter == Filter.EXCLUDE || filter.equals(Filter.EXCLUDE)) {
064: //return new EmptyFeatureReader(featureType);
065: return new EmptyFeatureCollection(featureType);
066: }
067: //GR: allow subclases to implement as much filtering as they can,
068: //by returning just it's unsupperted filter
069: // filter = getUnsupportedFilter( filter);
070: // if(filter == null){
071: // throw new NullPointerException("getUnsupportedFilter shouldn't return null. Do you mean Filter.INCLUDE?");
072: // }
073:
074: //filter
075: FeatureCollection features = getFeatures(filter);
076:
077: //retyping
078: if (propertyNames != null
079: || query.getCoordinateSystem() != null) {
080: try {
081: FeatureType target = DataUtilities.createSubType(
082: featureType, propertyNames, query
083: .getCoordinateSystem());
084: if (!featureType.equals(target)) {
085: LOGGER
086: .fine("Recasting feature type to subtype by using a ReTypeFeatureReader");
087: features = new ReTypingFeatureCollection(features,
088: target);
089: }
090: } catch (SchemaException e) {
091: LOGGER.log(Level.FINEST, e.getMessage(), e);
092: throw new DataSourceException(
093: "Could not create Feature Type for query", e);
094:
095: }
096: }
097:
098: //reprojection
099: if (query.getCoordinateSystemReproject() != null) {
100: if (query.getCoordinateSystem() != null) {
101: features = reproject(features, query
102: .getCoordinateSystem(), query
103: .getCoordinateSystemReproject());
104: } else {
105: features = new ReprojectingFeatureCollection(features,
106: query.getCoordinateSystemReproject());
107: }
108: }
109:
110: //max feature cap
111: if (query.getMaxFeatures() != Query.DEFAULT_MAX) {
112: features = new MaxFeaturesFeatureCollection(features, query
113: .getMaxFeatures());
114: }
115:
116: return features;
117: }
118:
119: public FeatureCollection getFeatures(Filter filter)
120: throws IOException {
121: //filter
122: if (filter != null && !filter.equals(Filter.INCLUDE)) {
123: return new FilteringFeatureCollection(getFeatures(), filter);
124: }
125:
126: return getFeatures();
127: }
128:
129: public FeatureType getSchema() {
130: return entry.getFeatureType();
131: }
132:
133: public Envelope getBounds() throws IOException {
134: return getFeatures().getBounds();
135: }
136:
137: public Envelope getBounds(Query query) throws IOException {
138: return getFeatures(query).getBounds();
139: }
140:
141: public int getCount(Query query) throws IOException {
142: return getFeatures(query).size();
143: }
144:
145: /**
146: * Template method for reprojecting a feature collection from a source crs to a target crs.
147: * <p>
148: * Subclasses may override, the default implementation wraps <param>features</param> in a
149: * {@link ReprojectingFeatureCollection}.
150: * </p>
151: * @param features The feature collection to be reprojected.
152: *
153: * @return the reprojected feature collection.
154: */
155: protected FeatureCollection reproject(FeatureCollection features,
156: CoordinateReferenceSystem source,
157: CoordinateReferenceSystem target) {
158: return new ReprojectingFeatureCollection(features, source,
159: target);
160: }
161:
162: /**
163: * By default, no Hints are supported
164: */
165: public Set getSupportedHints() {
166: return Collections.EMPTY_SET;
167: }
168: }
|