private static SpatialOperator repair( SpatialOperator o, Map<String, QName> bindings, Set<QName> validNames ) { Object[] os = o.getParams(); for ( int i = 0; i < os.length; ++i ) { if ( os[i] instanceof Expression ) { switch ( o.getSubType() ) { case BBOX: return new BBOX( (Expression) os[0], (Envelope) os[1] ); case BEYOND: Beyond b = (Beyond) o; return new Beyond( (Expression) os[0], (Geometry) os[1], b.getDistance() ); case CONTAINS: return new Contains( (Expression) os[0], (Geometry) os[1] ); case CROSSES: return new Crosses( (Expression) os[0], (Geometry) os[1] ); case DISJOINT: return new Disjoint( (Expression) os[0], (Geometry) os[1] ); case DWITHIN: DWithin d = (DWithin) o; return new DWithin( (Expression) os[0], (Geometry) os[1], d.getDistance() ); case EQUALS: return new Equals( (Expression) os[0], (Geometry) os[1] ); case INTERSECTS: return new Intersects( (Expression) os[0], (Geometry) os[1] ); case OVERLAPS: return new Overlaps( (Expression) os[0], (Geometry) os[1] ); case TOUCHES: return new Touches( (Expression) os[0], (Geometry) os[1] ); case WITHIN: return new Within( (Expression) os[0], (Geometry) os[1] );
private static BBOX extractBBox( SpatialOperator oper ) { SubType type = oper.getSubType(); switch ( type ) { case BBOX: return (BBOX) oper; case CONTAINS: // Oracle does not like zero-extent bboxes if ( !( ( (Contains) oper ).getGeometry() instanceof Point ) ) return new BBOX( ( (Contains) oper ).getParam1(), ( (Contains) oper ).getGeometry().getEnvelope() ); return null; case CROSSES: return new BBOX( ( (Crosses) oper ).getParam1(), ( (Crosses) oper ).getGeometry().getEnvelope() ); case DWITHIN: // TOOD use enlarged bbox return null; case EQUALS: return new BBOX( ( (Equals) oper ).getParam1(), ( (Equals) oper ).getGeometry().getEnvelope() ); case INTERSECTS: return new BBOX( ( (Intersects) oper ).getParam1(), ( (Intersects) oper ).getGeometry().getEnvelope() ); case OVERLAPS: return new BBOX( ( (Overlaps) oper ).getParam1(), ( (Overlaps) oper ).getGeometry().getEnvelope() ); case WITHIN: return new BBOX( ( (Within) oper ).getParam1(), ( (Within) oper ).getGeometry().getEnvelope() ); default: { return null; } } }
private static BBOX merge( BBOX bbox1, BBOX bbox2 ) { // TODO handle different SRS Envelope env = bbox1.getBoundingBox().merge( bbox2.getBoundingBox() ); Expression expr = bbox1.getParam1(); if ( expr == null || !expr.equals( bbox2.getParam1() ) ) { expr = null; } return new BBOX( expr, env ); }
QName elementName = spatialOperatorTypeToElementName.get( operator.getSubType() ); writer.writeStartElement( elementName.getNamespaceURI(), elementName.getLocalPart() ); switch ( operator.getSubType() ) { propertyName = ( (BBOX) operator ).getPropName(); geometry = ( (BBOX) operator ).getBoundingBox(); break; case BEYOND: propertyName = ( (Beyond) operator ).getPropName(); geometry = ( (Beyond) operator ).getGeometry(); distance = ( (Beyond) operator ).getDistance(); break; case CONTAINS: propertyName = ( (Contains) operator ).getPropName(); geometry = ( (Contains) operator ).getGeometry(); break; case CROSSES: propertyName = ( (Crosses) operator ).getPropName(); geometry = ( (Crosses) operator ).getGeometry(); break; case DISJOINT: propertyName = ( (Disjoint) operator ).getPropName(); geometry = ( (Disjoint) operator ).getGeometry(); break; case DWITHIN: propertyName = ( (DWithin) operator ).getPropName(); geometry = ( (DWithin) operator ).getGeometry(); distance = ( (DWithin) operator ).getDistance();
private static void export( SpatialOperator operator, XMLStreamWriter writer ) throws XMLStreamException, UnknownCRSException, TransformationException { QName elementName = spatialOperatorTypeToElementName.get( operator.getSubType() ); if ( elementName == null ) throw new IllegalArgumentException( "Encoding of spatial operator subtype " + operator.getSubType() + " is not supported yet!" ); writer.writeStartElement( elementName.getNamespaceURI(), elementName.getLocalPart() ); switch ( operator.getSubType() ) { case BBOX: geometry = ( (BBOX) operator ).getBoundingBox(); break; case BEYOND: geometry = ( (Beyond) operator ).getGeometry(); distance = ( (Beyond) operator ).getDistance(); break; case CONTAINS: geometry = ( (Contains) operator ).getGeometry(); break; case CROSSES: geometry = ( (Crosses) operator ).getGeometry(); break; case DISJOINT: geometry = ( (Disjoint) operator ).getGeometry(); break; case DWITHIN: geometry = ( (DWithin) operator ).getGeometry(); distance = ( (DWithin) operator ).getDistance(); break; case EQUALS:
spatialOperator = new BBOX( param1, (Envelope) param2 ); break; String distanceValue = xmlStream.getElementText(); Measure distance = new Measure( distanceValue, distanceUnits ); spatialOperator = new Beyond( param1, param2, distance ); break; spatialOperator = new Intersects( param1, param2 ); break; spatialOperator = new Contains( param1, param2 ); break; spatialOperator = new Crosses( param1, param2 ); break; spatialOperator = new Disjoint( param1, param2 ); break; String distanceValue = xmlStream.getElementText(); Measure distance = new Measure( distanceValue, distanceUnits ); spatialOperator = new DWithin( param1, param2, distance ); break; spatialOperator = new Equals( param1, param2 ); break; spatialOperator = new Overlaps( param1, param2 );
/** * Tries to extract an {@link Envelope} from the query {@link Filter} that can be used as a pre-filtering step to * narrow the result set. * <p> * The returned {@link Envelope} is determined by the following strategy: * <ul> * <li>If the filter is an {@link OperatorFilter}, it is attempted to extract an {@link BBOX} constraint from it.</li> * <li>If no {@link BBOX} constraint can be extracted from the filter (not presented or nested in <code>Or</code> or * <code>Not</code> expressions, <code>null</code> is returned.</li> * </ul> * </p> * * @return a {@link Envelope} suitable for pre-filtering feature candidates, can be <code>null</code> */ public Envelope getPrefilterBBoxEnvelope() { BBOX bbox = extractPrefilterBBoxConstraint( filter ); if ( bbox == null ) { return null; } return bbox.getBoundingBox(); }
private static LinkedList<Operator> findOperators( FeatureType ft, Envelope clickBox ) { LinkedList<Operator> list = new LinkedList<Operator>(); for ( PropertyType pt : ft.getPropertyDeclarations() ) { if ( pt instanceof GeometryPropertyType && ( ( (GeometryPropertyType) pt ).getCoordinateDimension() == DIM_2 || ( (GeometryPropertyType) pt ).getCoordinateDimension() == DIM_2_OR_3 ) ) { list.add( new Intersects( new ValueReference( pt.getName() ), clickBox ) ); } } return list; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.touches( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.isDisjoint( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.contains( transformedLiteral ); } } return false; }
public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.isWithin( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.overlaps( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.crosses( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode paramValue : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( paramValue ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); return geom.equals( transformedLiteral ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode param1Value : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( param1Value ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); // TODO what about the units of the distance when transforming? return geom.isBeyond( transformedLiteral, distance ); } } return false; }
@Override public <T> boolean evaluate( T obj, XPathEvaluator<T> xpathEvaluator ) throws FilterEvaluationException { for ( TypedObjectNode param1Value : propName.evaluate( obj, xpathEvaluator ) ) { Geometry geom = checkGeometryOrNull( param1Value ); if ( geom != null ) { Geometry transformedLiteral = getCompatibleGeometry( geom, geometry ); // TODO what about the units of the distance when transforming? return geom.isWithinDistance( transformedLiteral, distance ); } } return false; }
/** * Returns the type of spatial operator. Use this to safely determine the subtype of {@link SpatialOperator}. * * @return type of spatial operator */ public SubType getSubType() { return SubType.valueOf( getClass().getSimpleName().toUpperCase() ); }
SQLExpression propNameExpr = toProtoSQLSpatial( op.getPropName() ); if ( !propNameExpr.isSpatial() ) { String msg = "Cannot evaluate spatial operator on database. Targeted property name '" + op.getPropName() + "' does not denote a spatial column."; throw new FilterEvaluationException( msg ); switch ( op.getSubType() ) { case BBOX: { BBOX bbox = (BBOX) op; builder.add( propNameExpr ).add( ".STIntersects(" ); builder.add( toProtoSQL( bbox.getBoundingBox(), storageCRS, srid ) ); builder.add( ")=1" ); break; Beyond beyond = (Beyond) op; builder.add( "NOT " ).add( propNameExpr ).add( ".STDWithin(" ); builder.add( toProtoSQL( beyond.getGeometry(), storageCRS, srid ) ); builder.add( "," ); PrimitiveValue value = new PrimitiveValue( beyond.getDistance().getValue(), pt ); PrimitiveParticleConverter converter = new DefaultPrimitiveConverter( pt, null, false ); SQLArgument argument = new SQLArgument( value, converter ); Contains contains = (Contains) op; builder.add( propNameExpr ).add( ".STContains(" ); builder.add( toProtoSQL( contains.getGeometry(), storageCRS, srid ) ); builder.add( ")=1" ); break;
spatialOperator = new BBOX( param1, param2 ); break; String distanceValue = xmlStream.getElementText(); Measure distance = new Measure( distanceValue, distanceUnits ); spatialOperator = new Beyond( param1, param2, distance ); break; spatialOperator = new Intersects( param1, param2 ); break; spatialOperator = new Contains( param1, param2 ); break; spatialOperator = new Crosses( param1, param2 ); break; spatialOperator = new Disjoint( param1, param2 ); break; String distanceValue = xmlStream.getElementText(); Measure distance = new Measure( distanceValue, distanceUnits ); spatialOperator = new DWithin( param1, param2, distance ); break; spatialOperator = new Equals( param1, param2 ); break; spatialOperator = new Overlaps( param1, param2 );