package org.geotools.demo.filter; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.geotools.data.FeatureSource; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.FeatureCollection; import org.geotools.filter.text.cql2.CQL; import org.geotools.filter.text.cql2.CQLException; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.FeatureType; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.opengis.filter.identity.FeatureId; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * This class refers to the the wiki <a * href="http://docs.codehaus.org/display/GEOTDOC/Filter+Examples" * >FilterExamples</a>. * * @author Jody Garnett * * @source $URL$ */ public class FilterExamples { FeatureSource<SimpleFeatureType, SimpleFeature> featureSource; /** * How to find Features using IDs? * * Each Feature has a FeatureID; you can use these FeatureIDs to request the * feature again later. * * If you have a Set<String> of feature IDs, which you would like to query * from a shapefile: * * @param selection * Set of FeatureIDs identifying requested content * @return Selected Features * @throws IOException */ FeatureCollection<SimpleFeatureType, SimpleFeature> grabSelectedIds( Set<String> selection) throws IOException { FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null); Set<FeatureId> fids = new HashSet<FeatureId>(); for (String id : selection) { FeatureId fid = ff.featureId(id); fids.add(fid); } Filter filter = ff.id(fids); return featureSource.getFeatures(filter); } /** * How to find a Feature by Name? * * CQL is very good for one off queries like this: * * @param name * @return * @throws CQLException */ FeatureCollection grabSelectedName(String name) throws Exception { return featureSource.getFeatures(CQL.toFilter("Name = '" + name + "'")); } /** To select this feature while ignoring case we are going to have to use the FilterFactory (rather than CQL): */ FeatureCollection grabSelectedNameIgnoreCase( String name ) throws Exception { FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2( null ); Filter filter = ff.equal( ff.property( "Name"), ff.literal( name ), false ); return featureSource.getFeatures( filter ); } /** * How to find Features using a Set of Names? * * If you have a Set<String> of "names" which you would like to query from PostGIS. In this case we are doing a check for an attribute called "Name". */ FeatureCollection grabSelectedNames( Set<String> selectedNames ) throws Exception { FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2( null ); List<Filter> match = new ArrayList<Filter>(); for( String name : selectedNames ){ Filter aMatch = ff.equals( ff.property( "Name"), ff.literal( name ) ); match.add( aMatch ); } Filter filter = ff.or( match ); return featureSource.getFeatures( filter ); } /** * What features on in this bounding Box? * * You can make a bounding box query as shown below: * * @param x1 * @param y1 * @param x2 * @param y2 * @return * @throws Exception */ FeatureCollection grabFeaturesInBoundingBox( double x1, double y1, double x2, double y2) throws Exception { FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2( null ); FeatureType schema = featureSource.getSchema(); // usually "THE_GEOM" for shapefiles String geometryPropertyName = schema.getGeometryDescriptor().getLocalName(); CoordinateReferenceSystem crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem(); ReferencedEnvelope bbox = new ReferencedEnvelope( x1,y1, x2, y2, crs ); Filter filter = ff.bbox( ff.property( geometryPropertyName ), bbox ); return featureSource.getFeatures( filter ); } }