/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.data.store; import java.io.IOException; import java.util.Collections; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.geotools.data.DataSourceException; import org.geotools.data.DataStore; import org.geotools.data.DataUtilities; import org.geotools.data.FeatureListener; import org.geotools.data.FeatureSource; import org.geotools.data.Query; import org.geotools.feature.FeatureCollection; import org.geotools.feature.SchemaException; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.Filter; import org.opengis.referencing.crs.CoordinateReferenceSystem; public abstract class AbstractFeatureSource2 implements FeatureSource<SimpleFeatureType, SimpleFeature> { /** The logger for the data module. */ protected static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data"); /** * the type entry */ protected ActiveTypeEntry entry; public AbstractFeatureSource2( ActiveTypeEntry entry ) { this.entry = entry; } public DataStore getDataStore() { return entry.parent; } public void addFeatureListener(FeatureListener listener) { entry.listenerManager.addFeatureListener( this, listener ); } public void removeFeatureListener(FeatureListener listener) { entry.listenerManager.removeFeatureListener( this, listener ); } public FeatureCollection<SimpleFeatureType, SimpleFeature> getFeatures(Query query) throws IOException { SimpleFeatureType featureType = entry.getFeatureType(); Filter filter = query.getFilter(); if (filter == null) { throw new NullPointerException("getFeatureReader requires Filter: " + "did you mean Filter.INCLUDE?"); } String propertyNames[] = query.getPropertyNames(); if ( filter == Filter.EXCLUDE || filter.equals( Filter.EXCLUDE )) { //return new EmptyFeatureReader(featureType); return new EmptyFeatureCollection( featureType ); } //GR: allow subclases to implement as much filtering as they can, //by returning just it's unsupperted filter // filter = getUnsupportedFilter( filter); // if(filter == null){ // throw new NullPointerException("getUnsupportedFilter shouldn't return null. Do you mean Filter.INCLUDE?"); // } //filter FeatureCollection<SimpleFeatureType, SimpleFeature> features = getFeatures( filter ); //retyping if( propertyNames != null || query.getCoordinateSystem() != null ){ try { SimpleFeatureType target = DataUtilities.createSubType( featureType, propertyNames, query.getCoordinateSystem() ); if ( !featureType.equals( target ) ) { LOGGER.fine("Recasting feature type to subtype by using a ReTypeFeatureReader"); features = new ReTypingFeatureCollection(features, target); } } catch (SchemaException e) { LOGGER.log( Level.FINEST, e.getMessage(), e); throw new DataSourceException( "Could not create Feature Type for query", e ); } } //reprojection if ( query.getCoordinateSystemReproject() != null ) { if ( query.getCoordinateSystem() != null ) { features = reproject( features, query.getCoordinateSystem(), query.getCoordinateSystemReproject() ); } else { features = new ReprojectingFeatureCollection( features, query.getCoordinateSystemReproject() ); } } //max feature cap if (query.getMaxFeatures() != Query.DEFAULT_MAX) { features = new MaxFeaturesFeatureCollection<SimpleFeatureType, SimpleFeature>( features, query.getMaxFeatures() ); } return features; } public FeatureCollection<SimpleFeatureType, SimpleFeature> getFeatures(Filter filter) throws IOException { //filter if ( filter != null && !filter.equals( Filter.INCLUDE ) ) { return new FilteringFeatureCollection<SimpleFeatureType, SimpleFeature>( getFeatures() , filter ); } return getFeatures(); } public SimpleFeatureType getSchema() { return entry.getFeatureType(); } public ReferencedEnvelope getBounds() throws IOException { return getFeatures().getBounds(); } public ReferencedEnvelope getBounds(Query query) throws IOException { return getFeatures( query ).getBounds(); } public int getCount(Query query) throws IOException { return getFeatures( query ).size(); } /** * Template method for reprojecting a feature collection from a source crs to a target crs. * <p> * Subclasses may override, the default implementation wraps <param>features</param> in a * {@link ReprojectingFeatureCollection}. * </p> * @param features The feature collection to be reprojected. * * @return the reprojected feature collection. */ protected FeatureCollection<SimpleFeatureType, SimpleFeature> reproject( FeatureCollection<SimpleFeatureType, SimpleFeature> features, CoordinateReferenceSystem source, CoordinateReferenceSystem target ) { return new ReprojectingFeatureCollection( features, source, target ); } /** * By default, no Hints are supported */ public Set getSupportedHints() { return Collections.EMPTY_SET; } }