package org.geotools.main;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.measure.unit.Unit;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.filter.FunctionFactory;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.text.cql2.CQLException;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.event.MapMouseEvent;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
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.capability.FunctionName;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.identity.FeatureId;
import org.opengis.geometry.BoundingBox;
import org.opengis.geometry.DirectPosition;
import org.opengis.parameter.Parameter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
/**
* This class gathers up the filter examples shown in the sphinx documentation for Filters.
*
* @author Jody Garnett
*/
public class FilterExamples {
SimpleFeatureSource 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
*/
// grabSelectedIds start
SimpleFeatureCollection 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);
}
// grabSelectedIds end
/**
* How to find a Feature by Name?
*
* CQL is very good for one off queries like this:
*
* @param name
* @return
* @throws CQLException
*/
// grabSelectedName start
FeatureCollection grabSelectedName(String name) throws Exception {
return featureSource.getFeatures(CQL.toFilter("Name = '" + name + "'"));
}
// grabSelectedName end
/**
* To select this feature while ignoring case we are going to have to use the FilterFactory (rather
* than CQL):
*/
// grabSelectedNameIgnoreCase start
SimpleFeatureCollection 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);
}
// grabSelectedNameIgnoreCase end
/**
* 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".
*/
// grabSelectedNames start
SimpleFeatureCollection 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);
}
// grabSelectedNames end
/**
* 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
*/
// grabFeaturesInBoundingBox start
SimpleFeatureCollection 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 targetCRS = schema.getGeometryDescriptor()
.getCoordinateReferenceSystem();
ReferencedEnvelope bbox = new ReferencedEnvelope(x1, y1, x2, y2, targetCRS);
Filter filter = ff.bbox(ff.property(geometryPropertyName), bbox);
return featureSource.getFeatures(filter);
}
// grabFeaturesInBoundingBox end
// grabFeaturesInPolygon start
SimpleFeatureCollection grabFeaturesInPolygon(double x1, double y1, double x2, double y2)
throws Exception {
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
FeatureType schema = featureSource.getSchema();
CoordinateReferenceSystem worldCRS = DefaultGeographicCRS.WGS84;
// usually "THE_GEOM" for shapefiles
String geometryPropertyName = schema.getGeometryDescriptor().getLocalName();
CoordinateReferenceSystem targetCRS = schema.getGeometryDescriptor()
.getCoordinateReferenceSystem();
ReferencedEnvelope click = new ReferencedEnvelope(x1, y1, x2, y2, worldCRS);
// will result in a slight larger BBOX then the original click
ReferencedEnvelope bbox = click.transform(targetCRS, true);
// will result in a polygon matching the original click
Polygon clickPolygon = JTS.toGeometry(bbox, null, 10);
MathTransform transform = CRS.findMathTransform(worldCRS, targetCRS);
Polygon polygon = (Polygon) JTS.transform(clickPolygon, transform);
Filter filter = ff.intersects(ff.property(geometryPropertyName), ff.literal(polygon));
return featureSource.getFeatures(filter);
}
// grabFeaturesInPolygon end
// grabFeaturesOnScreen start
SimpleFeatureCollection grabFeaturesOnScreen(ReferencedEnvelope screen) throws Exception {
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
FeatureType schema = featureSource.getSchema();
// usually "THE_GEOM" for shapefiles
String geometryPropertyName = schema.getGeometryDescriptor().getLocalName();
CoordinateReferenceSystem targetCRS = schema.getGeometryDescriptor()
.getCoordinateReferenceSystem();
CoordinateReferenceSystem worldCRS = screen.getCoordinateReferenceSystem();
// will result in a slight larger BBOX then the original click
ReferencedEnvelope bbox = screen.transform(targetCRS, true);
// will result in a polygon matching the original click
Polygon clickPolygon = JTS.toGeometry(bbox, null, 10);
MathTransform transform = CRS.findMathTransform(worldCRS, targetCRS);
Polygon polygon = (Polygon) JTS.transform(clickPolygon, transform);
Filter filter1 = ff.bbox(ff.property(geometryPropertyName), bbox);
Filter filter2 = ff.intersects(ff.property(geometryPropertyName), ff.literal(polygon));
Filter filter = ff.and(filter1, filter2);
return featureSource.getFeatures(filter);
}
// grabFeaturesOnScreen end
private JMapFrame mapFrame;
// click1 start
SimpleFeatureCollection click1(MapMouseEvent ev) throws Exception {
// Construct a 3x3 pixel rectangle centred on the mouse click position
java.awt.Point screenPos = ev.getPoint();
Rectangle screenRect = new Rectangle(screenPos.x - 1, screenPos.y - 1, 3, 3);
CoordinateReferenceSystem worldCRS = mapFrame.getMapContent().getCoordinateReferenceSystem();
// Transform the screen rectangle into a bounding box in the
// coordinate reference system of our map content.
AffineTransform screenToWorld = mapFrame.getMapPane().getScreenToWorldTransform();
Rectangle2D worldRect = screenToWorld.createTransformedShape(screenRect).getBounds2D();
ReferencedEnvelope worldBBox = new ReferencedEnvelope(worldRect, worldCRS);
// transform from world to target CRS
SimpleFeatureType schema = featureSource.getSchema();
CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();
String geometryAttributeName = schema.getGeometryDescriptor().getLocalName();
ReferencedEnvelope bbox = worldBBox.transform(targetCRS, true, 10);
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
// Option 1 BBOX
Filter filter = ff.bbox(ff.property(geometryAttributeName), bbox);
// Option 2 Intersects
// Filter filter = ff.intersects(ff.property(geometryAttributeName), ff.literal(bbox));
return featureSource.getFeatures(filter);
}
// click1 end
// distance start
SimpleFeatureCollection distance(MapMouseEvent ev) throws Exception {
DirectPosition2D worldPosition = ev.getMapPosition();
// get the unit of measurement
SimpleFeatureType schema = featureSource.getSchema();
CoordinateReferenceSystem crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem();
Unit<?> uom = crs.getCoordinateSystem().getAxis(0).getUnit();
MathTransform transform = CRS.findMathTransform(worldPosition.getCoordinateReferenceSystem(),
crs, true);
DirectPosition dataPosition = transform.transform(worldPosition, null);
Point point = JTS.toGeometry(dataPosition);
// threshold distance
double distance = 10.0d;
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
Filter filter = ff.dwithin(ff.property("POLYGON"), ff.literal(point), distance, uom.toString());
return featureSource.getFeatures(filter);
}
// distance end
// polygonInteraction start
private void polygonInteraction() {
SimpleFeatureCollection polygonCollection = null;
SimpleFeatureCollection fcResult = null;
final SimpleFeatureCollection found = FeatureCollections.newCollection();
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
SimpleFeature feature = null;
Filter polyCheck = null;
Filter andFil = null;
Filter boundsCheck = null;
String qryStr = null;
SimpleFeatureIterator it = polygonCollection.features();
try {
while (it.hasNext()) {
feature = it.next();
BoundingBox bounds = feature.getBounds();
boundsCheck = ff.bbox(ff.property("the_geom"), bounds);
Geometry geom = (Geometry) feature.getDefaultGeometry();
polyCheck = ff.intersects(ff.property("the_geom"), ff.literal(geom));
andFil = ff.and(boundsCheck, polyCheck);
try {
fcResult = featureSource.getFeatures(andFil);
// go through results and copy out the found features
fcResult.accepts(new FeatureVisitor() {
public void visit(Feature feature) {
found.add((SimpleFeature) feature);
}
}, null);
} catch (IOException e1) {
System.out.println("Unable to run filter for " + feature.getID() + ":" + e1);
continue;
}
}
} finally {
it.close();
}
}
// polygonInteraction end
private void expressionExamples() {
Geometry geometry = null;
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
// expressionExamples start
Expression propertyAccess = ff.property("THE_GEOM");
Expression literal = ff.literal(geometry);
Expression math = ff.add(ff.literal(1), ff.literal(2));
Expression function = ff.function("length", ff.property("CITY_NAME"));
// expressionExamples end
}
private static void functionList() {
// functionList start
Set<FunctionFactory> functionFactories = CommonFactoryFinder.getFunctionFactories(null);
for (FunctionFactory factory : functionFactories) {
System.out.println( factory.getClass().getName() );
List<FunctionName> functionNames = factory.getFunctionNames();
ArrayList<FunctionName> sorted = new ArrayList<FunctionName> ( functionNames );
Collections.sort( sorted, new Comparator<FunctionName>() {
public int compare(FunctionName o1, FunctionName o2) {
if( o1 == null && o2 == null ) return 0;
if( o1 == null && o2 != null ) return 1;
if( o1 != null && o2 == null ) return -1;
return o1.getName().compareTo( o2.getName() );
}
} );
for (FunctionName functionName : sorted ) {
System.out.print(" ");
System.out.print(functionName.getName());
System.out.print("(");
int i = 0;
for (Parameter<?> argument : functionName.getArguments()) {
if (i++ > 0) {
System.out.print(", ");
}
System.out.print(argument.getName());
if( argument.getType() == Object.class && argument.isRequired() ){
// no interesting description
}
else {
System.out.print("{");
System.out.print( argument.getType().getName() );
System.out.print(",");
if( argument.isRequired()){
System.out.print("required,");
}
else if( argument.getMinOccurs() == 0 && argument.getMaxOccurs() == 1 ) {
System.out.print("optional,");
}
else {
System.out.print(argument.getMinOccurs());
System.out.print(":");
System.out.print(argument.getMaxOccurs());
}
System.out.print("}");
}
}
System.out.print(")");
System.out.print(":"+functionName.getReturn().getName());
if( functionName.getReturn().getType() != Object.class ){
System.out.print("{");
System.out.print( functionName.getReturn().getType().getName() );
System.out.print("}");
}
System.out.println();
}
}
// functionList end
}
public static void main(String args[]) {
functionList();
}
}