/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2008 - 2009, Geomatys
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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.geotoolkit.filter;
// JTS dependencies
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
// J2SE dependencies
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;
// Geotoolkit dependencies
import org.geotoolkit.gml.xml.v311.AbstractGeometryType;
import org.geotoolkit.gml.xml.v311.CoordinatesType;
import org.geotoolkit.gml.xml.v311.DirectPositionType;
import org.geotoolkit.gml.xml.v311.EnvelopeType;
import org.geotoolkit.gml.xml.v311.LineStringType;
import org.geotoolkit.gml.xml.v311.PointType;
import org.geotoolkit.ogc.xml.v110.AndType;
import org.geotoolkit.ogc.xml.v110.ArithmeticOperatorsType;
import org.geotoolkit.ogc.xml.v110.BBOXType;
import org.geotoolkit.ogc.xml.v110.BeyondType;
import org.geotoolkit.ogc.xml.v110.ComparisonOperatorsType;
import org.geotoolkit.ogc.xml.v110.ContainsType;
import org.geotoolkit.ogc.xml.v110.CrossesType;
import org.geotoolkit.ogc.xml.v110.DWithinType;
import org.geotoolkit.ogc.xml.v110.DisjointType;
import org.geotoolkit.ogc.xml.v110.EqualsType;
import org.geotoolkit.ogc.xml.v110.ExpressionType;
import org.geotoolkit.ogc.xml.v110.FeatureIdType;
import org.geotoolkit.ogc.xml.v110.FunctionNameType;
import org.geotoolkit.ogc.xml.v110.FunctionNamesType;
import org.geotoolkit.ogc.xml.v110.FunctionType;
import org.geotoolkit.ogc.xml.v110.GmlObjectIdType;
import org.geotoolkit.ogc.xml.v110.IdCapabilitiesType;
import org.geotoolkit.ogc.xml.v110.IntersectsType;
import org.geotoolkit.ogc.xml.v110.LiteralType;
import org.geotoolkit.ogc.xml.v110.LowerBoundaryType;
import org.geotoolkit.ogc.xml.v110.NotType;
import org.geotoolkit.ogc.xml.v110.ObjectFactory;
import org.geotoolkit.ogc.xml.v110.OrType;
import org.geotoolkit.ogc.xml.v110.OverlapsType;
import org.geotoolkit.ogc.xml.v110.PropertyIsBetweenType;
import org.geotoolkit.ogc.xml.v110.PropertyIsEqualToType;
import org.geotoolkit.ogc.xml.v110.PropertyIsGreaterThanOrEqualToType;
import org.geotoolkit.ogc.xml.v110.PropertyIsGreaterThanType;
import org.geotoolkit.ogc.xml.v110.PropertyIsLessThanOrEqualToType;
import org.geotoolkit.ogc.xml.v110.PropertyIsLessThanType;
import org.geotoolkit.ogc.xml.v110.PropertyIsLikeType;
import org.geotoolkit.ogc.xml.v110.PropertyIsNotEqualToType;
import org.geotoolkit.ogc.xml.v110.PropertyIsNullType;
import org.geotoolkit.ogc.xml.v110.PropertyNameType;
import org.geotoolkit.ogc.xml.v110.ScalarCapabilitiesType;
import org.geotoolkit.ogc.xml.v110.SortPropertyType;
import org.geotoolkit.ogc.xml.v110.SpatialCapabilitiesType;
import org.geotoolkit.ogc.xml.v110.SpatialOperatorType;
import org.geotoolkit.ogc.xml.v110.SpatialOperatorsType;
import org.geotoolkit.ogc.xml.v110.TemporalCapabilitiesType;
import org.geotoolkit.ogc.xml.v110.TimeAfterType;
import org.geotoolkit.ogc.xml.v110.TimeAnyInteractsType;
import org.geotoolkit.ogc.xml.v110.TimeBeforeType;
import org.geotoolkit.ogc.xml.v110.TimeBeginsType;
import org.geotoolkit.ogc.xml.v110.TimeBegunByType;
import org.geotoolkit.ogc.xml.v110.TimeContainsType;
import org.geotoolkit.ogc.xml.v110.TimeDuringType;
import org.geotoolkit.ogc.xml.v110.TimeEndedByType;
import org.geotoolkit.ogc.xml.v110.TimeEndsType;
import org.geotoolkit.ogc.xml.v110.TimeEqualsType;
import org.geotoolkit.ogc.xml.v110.TimeMeetsType;
import org.geotoolkit.ogc.xml.v110.TimeMetByType;
import org.geotoolkit.ogc.xml.v110.TimeOverlappedByType;
import org.geotoolkit.ogc.xml.v110.TimeOverlapsType;
import org.geotoolkit.ogc.xml.v110.TouchesType;
import org.geotoolkit.ogc.xml.v110.UpperBoundaryType;
import org.geotoolkit.ogc.xml.v110.WithinType;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.util.logging.Logging;
import org.geotoolkit.ogc.xml.FilterXmlFactory;
// Types dependencies
import org.opengis.filter.And;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.Id;
import org.opengis.filter.MatchAction;
import org.opengis.filter.Not;
import org.opengis.filter.Or;
import org.opengis.filter.PropertyIsBetween;
import org.opengis.filter.PropertyIsEqualTo;
import org.opengis.filter.PropertyIsGreaterThan;
import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
import org.opengis.filter.PropertyIsLessThan;
import org.opengis.filter.PropertyIsLessThanOrEqualTo;
import org.opengis.filter.PropertyIsLike;
import org.opengis.filter.PropertyIsNil;
import org.opengis.filter.PropertyIsNotEqualTo;
import org.opengis.filter.PropertyIsNull;
import org.opengis.filter.capability.ArithmeticOperators;
import org.opengis.filter.capability.ComparisonOperators;
import org.opengis.filter.capability.FilterCapabilities;
import org.opengis.filter.capability.FunctionName;
import org.opengis.filter.capability.Functions;
import org.opengis.filter.capability.GeometryOperand;
import org.opengis.filter.capability.IdCapabilities;
import org.opengis.filter.capability.Operator;
import org.opengis.filter.capability.ScalarCapabilities;
import org.opengis.filter.capability.SpatialCapabilities;
import org.opengis.filter.capability.SpatialOperator;
import org.opengis.filter.capability.SpatialOperators;
import org.opengis.filter.capability.TemporalCapabilities;
import org.opengis.filter.capability.TemporalOperand;
import org.opengis.filter.capability.TemporalOperators;
import org.opengis.filter.expression.Add;
import org.opengis.filter.expression.Divide;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Function;
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.Multiply;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.expression.Subtract;
import org.opengis.filter.identity.FeatureId;
import org.opengis.filter.identity.GmlObjectId;
import org.opengis.filter.identity.Identifier;
import org.opengis.filter.sort.SortBy;
import org.opengis.filter.sort.SortOrder;
import org.opengis.filter.spatial.BBOX;
import org.opengis.filter.spatial.Beyond;
import org.opengis.filter.spatial.Contains;
import org.opengis.filter.spatial.Crosses;
import org.opengis.filter.spatial.DWithin;
import org.opengis.filter.spatial.Disjoint;
import org.opengis.filter.spatial.Equals;
import org.opengis.filter.spatial.Intersects;
import org.opengis.filter.spatial.Overlaps;
import org.opengis.filter.spatial.Touches;
import org.opengis.filter.spatial.Within;
import org.opengis.filter.temporal.After;
import org.opengis.filter.temporal.AnyInteracts;
import org.opengis.filter.temporal.Before;
import org.opengis.filter.temporal.Begins;
import org.opengis.filter.temporal.BegunBy;
import org.opengis.filter.temporal.During;
import org.opengis.filter.temporal.EndedBy;
import org.opengis.filter.temporal.Ends;
import org.opengis.filter.temporal.Meets;
import org.opengis.filter.temporal.MetBy;
import org.opengis.filter.temporal.OverlappedBy;
import org.opengis.filter.temporal.TContains;
import org.opengis.filter.temporal.TEquals;
import org.opengis.filter.temporal.TOverlaps;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.Geometry;
import org.opengis.util.GenericName;
/**
* A factory used by a CQL parser to build filter.
*
* @author Guilhem Legal
* @module
*/
public class FilterFactoryImpl implements FilterFactory2 {
private static final Logger LOGGER = Logging.getLogger("org.geotoolkit.filter");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
static {
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public FeatureId featureId(final String id) {
return new FeatureIdType(id);
}
@Override
public GmlObjectId gmlObjectId(final String id) {
return new GmlObjectIdType(id);
}
@Override
public And and(final Filter f, final Filter g) {
final List<Filter> filterList = new ArrayList<>();
boolean factorized = false;
// factorize OR filter
if (g instanceof And) {
factorized = true;
filterList.addAll(((And)g).getChildren());
} else {
filterList.add(g);
}
if (f instanceof And) {
factorized = true;
filterList.addAll(((And)f).getChildren());
} else {
filterList.add(f);
}
if (factorized) {
return new AndType(filterList.toArray());
} else {
return new AndType(f, g);
}
}
@Override
public And and(final List<Filter> f) {
return new AndType(f.toArray());
}
@Override
public Or or(final Filter f, final Filter g) {
final List<Filter> filterList = new ArrayList<>();
boolean factorized = false;
// factorize OR filter
if (g instanceof Or) {
factorized = true;
filterList.addAll(((Or)g).getChildren());
} else {
filterList.add(g);
}
if (f instanceof Or) {
factorized = true;
filterList.addAll(((Or)f).getChildren());
} else {
filterList.add(f);
}
if (factorized) {
return new OrType(filterList.toArray());
} else {
return new OrType(f, g);
}
}
@Override
public Or or(final List<Filter> filterList) {
return new OrType(filterList.toArray());
}
@Override
public Not not(final Filter f) {
return new NotType(f);
}
@Override
public Id id(final Set<? extends Identifier> ids) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public PropertyName property(final String name) {
return new PropertyNameType(name);
}
@Override
public PropertyIsBetween between(final Expression expr, Expression lower, Expression upper) {
if (lower instanceof LiteralType) {
lower = new LowerBoundaryType((LiteralType)lower);
}
if (upper instanceof LiteralType) {
upper = new UpperBoundaryType((LiteralType)upper);
}
if (expr instanceof PropertyNameType) {
ObjectFactory factory = new ObjectFactory();
return new PropertyIsBetweenType( factory.createPropertyName((PropertyNameType) expr),
(LowerBoundaryType) lower,
(UpperBoundaryType) upper);
} else {
return new PropertyIsBetweenType( (ExpressionType) expr,
(LowerBoundaryType) lower,
(UpperBoundaryType) upper);
}
}
@Override
public PropertyIsEqualTo equals(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsEqualToType(lit, propName, null);
}
@Override
public PropertyIsEqualTo equal(final Expression expr1, final Expression expr2, final boolean matchCase,final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsEqualToType(lit, propName, matchCase);
}
@Override
public PropertyIsNotEqualTo notEqual(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsNotEqualToType(lit, propName, null);
}
@Override
public PropertyIsNotEqualTo notEqual(final Expression expr1, final Expression expr2, final boolean matchCase,final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsNotEqualToType(lit, propName, matchCase);
}
@Override
public PropertyIsGreaterThan greater(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsGreaterThanType(lit, propName, null);
}
@Override
public PropertyIsGreaterThan greater(final Expression expr1, final Expression expr2, final boolean matchCase, final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsGreaterThanType(lit, propName, matchCase);
}
@Override
public PropertyIsGreaterThanOrEqualTo greaterOrEqual(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsGreaterThanOrEqualToType(lit, propName, null);
}
@Override
public PropertyIsGreaterThanOrEqualTo greaterOrEqual(final Expression expr1, final Expression expr2, final boolean matchCase, final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsGreaterThanOrEqualToType(lit, propName, matchCase);
}
@Override
public PropertyIsLessThan less(final Expression expr1, final Expression expr2, final boolean matchCase, final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsLessThanType(lit, propName, matchCase);
}
@Override
public PropertyIsLessThan less(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsLessThanType(lit, propName, null);
}
@Override
public PropertyIsLessThanOrEqualTo lessOrEqual(final Expression expr1, final Expression expr2, final boolean matchCase, final MatchAction action) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsLessThanOrEqualToType(lit, propName, matchCase);
}
@Override
public PropertyIsLessThanOrEqualTo lessOrEqual(final Expression expr1, final Expression expr2) {
LiteralType lit = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
}
if (expr1 instanceof LiteralType) {
lit = (LiteralType) expr1;
} else if (expr2 instanceof LiteralType) {
lit = (LiteralType) expr2;
}
return new PropertyIsLessThanOrEqualToType(lit, propName, null);
}
@Override
public PropertyIsLike like(final Expression expr, final String pattern) {
return like(expr, pattern, "*", "?", "\\");
}
public PropertyIsLike like(final Expression expr, final String pattern, final boolean isMatchingCase) {
return like(expr, pattern, "*", "?", "\\", isMatchingCase);
}
@Override
public PropertyIsLike like(final Expression expr, String pattern, final String wildcard, final String singleChar, final String escape) {
//SQLBuilder add a white space at then end of the pattern we remove it
if (pattern != null && pattern.lastIndexOf(' ') == pattern.length() -1) {
pattern = pattern.substring(0, pattern.length() -1);
}
return new PropertyIsLikeType(expr, pattern, wildcard, singleChar, escape);
}
@Override
public PropertyIsLike like(final Expression expr, String pattern, final String wildcard, final String singleChar, final String escape, final boolean isMatchingCase) {
//SQLBuilder add a white space at then end of the pattern we remove it
if (pattern != null && pattern.lastIndexOf(' ') == pattern.length() -1) {
pattern = pattern.substring(0, pattern.length() -1);
}
return new PropertyIsLikeType(expr, pattern, wildcard, singleChar, escape, isMatchingCase);
}
@Override
public PropertyIsNull isNull(final Expression expr) {
return new PropertyIsNullType((PropertyNameType)expr);
}
@Override
public BBOX bbox(final String propertyName, final double minx, final double miny, final double maxx, final double maxy, String srs) {
if (srs == null || srs.equals("")) {
srs = "CRS:84"; // default CRS used is normally EPSG 4326 but most of the implementation use this one by default
}
return new BBOXType(propertyName, minx, miny, maxx, maxy, srs);
}
@Override
public BBOX bbox(final Expression geometry, final double minx, final double miny, final double maxx, final double maxy, String srs) {
String propertyName = "";
if (geometry instanceof PropertyNameType) {
propertyName = ((PropertyNameType)geometry).getPropertyName();
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry.getClass().getSimpleName());
}
if (srs == null || srs.equals("")) {
srs = "CRS:84"; // default CRS used is normally EPSG 4326 but most of the implementation use this one by default
}
return new BBOXType(propertyName, minx, miny, maxx, maxy, srs);
}
@Override
public BBOX bbox(final Expression geometry, final Envelope bounds) {
String propertyName = "";
final String CRSName;
if (geometry instanceof PropertyNameType) {
propertyName = ((PropertyNameType)geometry).getPropertyName();
}
if (bounds.getCoordinateReferenceSystem() != null) {
CRSName = IdentifiedObjects.getIdentifierOrName(bounds.getCoordinateReferenceSystem());
} else {
CRSName = "CRS:84";
}
return new BBOXType(propertyName, bounds.getMinimum(0), bounds.getMinimum(1),
bounds.getMaximum(0), bounds.getMaximum(1), CRSName);
}
@Override
public Beyond beyond(final String propertyName, final Geometry geometry, final double distance, final String units) {
return new BeyondType(propertyName, (AbstractGeometryType) geometry, distance, units);
}
@Override
public Beyond beyond(final Expression geometry1, final Expression geometry2, final double distance, String units) {
String propertyName = "";
if (geometry1 instanceof PropertyNameType) {
propertyName = ((PropertyNameType)geometry1).getPropertyName();
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
// we formats the units (CQL parser add a white space at the end)
if (units.indexOf(' ') == units.length() -1) {
units = units.substring(0, units.length() - 1);
}
return new BeyondType(propertyName, (AbstractGeometryType) geom, distance, units);
}
@Override
public DWithin dwithin(final String propertyName, final Geometry geometry, final double distance, final String units) {
return new DWithinType(propertyName, (AbstractGeometryType) geometry, distance, units);
}
@Override
public DWithin dwithin(final Expression geometry1, final Expression geometry2, final double distance, String units) {
String propertyName = "";
// we get the propertyName
if (geometry1 instanceof PropertyNameType) {
propertyName = ((PropertyNameType)geometry1).getPropertyName();
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
// we formats the units (CQL parser add a white space at the end)
if (units.indexOf(' ') == units.length() -1) {
units = units.substring(0, units.length() - 1);
}
return new DWithinType(propertyName, (AbstractGeometryType) geom, distance, units);
}
@Override
public Contains contains(final String propertyName, final Geometry geometry) {
return new ContainsType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Contains contains(final Expression geometry1, final Expression geometry2) {
// we get the propertyName
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new ContainsType(propertyName, geom);
}
@Override
public Crosses crosses(final String propertyName, final Geometry geometry) {
return new CrossesType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Crosses crosses(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new CrossesType(propertyName, geom);
}
@Override
public Disjoint disjoint(final String propertyName, final Geometry geometry) {
return new DisjointType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Disjoint disjoint(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new DisjointType(propertyName, geom);
}
@Override
public Equals equals(final String propertyName, final Geometry geometry) {
return new EqualsType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Equals equal(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
// we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new EqualsType(propertyName, geom);
}
@Override
public Intersects intersects(final String propertyName, final Geometry geometry) {
return new IntersectsType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Intersects intersects(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
//we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new IntersectsType(propertyName, geom);
}
@Override
public Overlaps overlaps(final String propertyName, final Geometry geometry) {
return new OverlapsType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Overlaps overlaps(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
//we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new OverlapsType(propertyName, geom);
}
@Override
public Touches touches(final String propertyName, final Geometry geometry) {
return new TouchesType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Touches touches(final Expression propertyName1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (propertyName1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)propertyName1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + propertyName1.getClass().getSimpleName());
}
//we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new TouchesType(propertyName, geom);
}
@Override
public Within within(final String propertyName, final Geometry geometry) {
return new WithinType(propertyName, (AbstractGeometryType) geometry);
}
@Override
public Within within(final Expression geometry1, final Expression geometry2) {
PropertyNameType propertyName = null;
if (geometry1 instanceof PropertyNameType) {
propertyName = (PropertyNameType)geometry1;
} else {
throw new IllegalArgumentException("unexpected type instead of propertyNameType: " + geometry1.getClass().getSimpleName());
}
//we transform the JTS geometry into a GML geometry
Object geom = null;
if (geometry2 instanceof LiteralType) {
geom = ((LiteralType)geometry2).getValue();
geom = GeometryToGML(geom);
}
return new WithinType(propertyName, geom);
}
@Override
public Add add(final Expression expr1, final Expression expr2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Divide divide(final Expression expr1, final Expression expr2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Multiply multiply(final Expression expr1, final Expression expr2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Subtract subtract(final Expression expr1, final Expression expr2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Function function(final String name, final Expression[] args) {
return new FunctionType(name, args);
}
public Function function(final String name, final Expression arg1) {
return new FunctionType(name, arg1);
}
public Function function(final String name, final Expression arg1, final Expression arg2) {
return new FunctionType(name, arg1, arg2);
}
public Function function(final String name, final Expression arg1, final Expression arg2, final Expression arg3) {
return new FunctionType(name, arg1, arg2, arg3);
}
@Override
public Literal literal(Object obj) {
if (obj instanceof Date) {
Date d = (Date) obj;
synchronized(DATE_FORMAT) {
obj = DATE_FORMAT.format(d);
}
}
return new LiteralType(obj);
}
@Override
public Literal literal(final byte b) {
return new LiteralType(b);
}
@Override
public Literal literal(final short s) {
return new LiteralType(s);
}
@Override
public Literal literal(final int i) {
return new LiteralType(i);
}
@Override
public Literal literal(final long l) {
return new LiteralType(l);
}
@Override
public Literal literal(final float f) {
return new LiteralType(f);
}
@Override
public Literal literal(final double d) {
return new LiteralType(d);
}
@Override
public Literal literal(final char c) {
return new LiteralType(c);
}
@Override
public Literal literal(final boolean b) {
return new LiteralType(b);
}
@Override
public SortBy sort(final String propertyName, final SortOrder order) {
return new SortPropertyType(propertyName, order);
}
@Override
public Operator operator(final String name) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public SpatialOperator spatialOperator(final String name, final GeometryOperand[] geometryOperands) {
return new SpatialOperatorType(name, geometryOperands);
}
@Override
public FunctionName functionName(final String name, final int nargs) {
return new FunctionNameType(name, nargs);
}
@Override
public Functions functions(final FunctionName[] functionNames) {
return new FunctionNamesType(Arrays.asList((FunctionNameType[])functionNames));
}
@Override
public SpatialOperators spatialOperators(final SpatialOperator[] spatialOperators) {
return new SpatialOperatorsType( spatialOperators );
}
@Override
public ComparisonOperators comparisonOperators(final Operator[] comparisonOperators) {
return new ComparisonOperatorsType(comparisonOperators);
}
@Override
public ArithmeticOperators arithmeticOperators(final boolean simple, final Functions functions) {
return new ArithmeticOperatorsType(simple, functions);
}
@Override
public ScalarCapabilities scalarCapabilities(final ComparisonOperators comparison, final ArithmeticOperators arithmetic, final boolean logical) {
return new ScalarCapabilitiesType(comparison, arithmetic, logical);
}
@Override
public SpatialCapabilities spatialCapabilities(final GeometryOperand[] geometryOperands, final SpatialOperators spatial) {
return new SpatialCapabilitiesType(geometryOperands, spatial);
}
@Override
public IdCapabilities idCapabilities(final boolean eid, final boolean fid) {
return new IdCapabilitiesType(eid, fid);
}
public FilterCapabilities capabilities(final String version, final ScalarCapabilities scalar, final SpatialCapabilities spatial, final IdCapabilities id) {
return FilterXmlFactory.buildFilterCapabilities(version, scalar, spatial, id, null, null);
}
@Override
public PropertyName property(final GenericName name) {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Transform a JTS geometric object into a GML marshallable object
* @param geom
* @return
*/
public Object GeometryToGML(final Object geom) {
Object result = null;
if (geom instanceof Polygon) {
final Polygon p = (Polygon) geom;
final Coordinate[] coord = p.getCoordinates();
// an envelope
if (coord.length == 5) {
final DirectPositionType lowerCorner = new DirectPositionType(coord[0].y, coord[0].x);
final DirectPositionType upperCorner = new DirectPositionType(coord[2].y, coord[2].x);
result = new EnvelopeType(null, lowerCorner, upperCorner, "EPSG:4326");
}
} else if (geom instanceof Point){
final Point p = (Point) geom;
final Coordinate[] coord = p.getCoordinates();
result = new PointType(null, new DirectPositionType(coord[0].x, coord[0].y, coord[0].z));
((PointType)result).setSrsName("EPSG:4326");
} else if (geom instanceof LineString){
final LineString ls = (LineString) geom;
final Coordinate[] coord = ls.getCoordinates();
result = new LineStringType(new CoordinatesType(coord[0].x + "," + coord[0].y + " " + coord[1].x + "," + coord[1].y ));
((LineStringType)result).setSrsName("EPSG:4326");
} else {
LOGGER.severe("unable to create GML geometry with: " + geom.getClass().getSimpleName());
}
return result;
}
@Override
public PropertyIsNil isNil(final Expression exprsn) {
throw new UnsupportedOperationException("Not supported in filter v110.");
}
@Override
public After after(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeAfterType(propName.getPropertyName(), temporal);
}
@Override
public AnyInteracts anyInteracts(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeAnyInteractsType(propName.getPropertyName(), temporal);
}
@Override
public Before before(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeBeforeType(propName.getPropertyName(), temporal);
}
@Override
public Begins begins(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeBeginsType(propName.getPropertyName(), temporal);
}
public BegunBy begunBy(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeBegunByType(propName.getPropertyName(), temporal);
}
public During during(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeDuringType(propName.getPropertyName(), temporal);
}
public Ends ends(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeEndsType(propName.getPropertyName(), temporal);
}
public EndedBy endedBy(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeEndedByType(propName.getPropertyName(), temporal);
}
public Meets meets(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeMeetsType(propName.getPropertyName(), temporal);
}
public MetBy metBy(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeMetByType(propName.getPropertyName(), temporal);
}
public OverlappedBy overlappedBy(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeOverlappedByType(propName.getPropertyName(), temporal);
}
public TContains tcontains(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeContainsType(propName.getPropertyName(), temporal);
}
public TEquals tequals(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeEqualsType(propName.getPropertyName(), temporal);
}
public TOverlaps toverlaps(final Expression expr1, final Expression expr2) {
Object temporal = null;
PropertyNameType propName = null;
if (expr1 instanceof PropertyNameType) {
propName = (PropertyNameType) expr1;
temporal = expr2;
} else if (expr2 instanceof PropertyNameType) {
propName = (PropertyNameType) expr2;
temporal = expr1;
}
return new TimeOverlapsType(propName.getPropertyName(), temporal);
}
public TemporalCapabilities temporalCapabilities(final TemporalOperand[] tos, final TemporalOperators to) {
return new TemporalCapabilitiesType(tos, to);
}
public FilterCapabilities capabilities(final String string, final ScalarCapabilities sc, final SpatialCapabilities sc1, final TemporalCapabilities tc, final IdCapabilities ic) {
return FilterXmlFactory.buildFilterCapabilities("1.1.0", sc, sc1, ic, tc, null);
}
}