Search in sources :

Example 1 with FilterGeometryContext

use of org.geotoolkit.cql.CQLParser.FilterGeometryContext in project geotoolkit by Geomatys.

the class CQL method convertFilter.

/**
 * Convert the given tree in a Filter.
 */
private static Filter convertFilter(ParseTree tree, FilterFactory2 ff) throws CQLException {
    if (tree instanceof FilterContext) {
        // : filter (AND filter)+
        // | filter (OR filter)+
        // | LPAREN filter RPAREN
        // | NOT filterTerm
        // | filterTerm
        final FilterContext exp = (FilterContext) tree;
        // | filterTerm
        if (exp.getChildCount() == 1) {
            return convertFilter(tree.getChild(0), ff);
        } else if (exp.NOT() != null) {
            // | NOT (filterTerm | ( LPAREN filter RPAREN ))
            if (exp.filterTerm() != null) {
                return ff.not(convertFilter(exp.filterTerm(), ff));
            } else {
                return ff.not(convertFilter(exp.filter(0), ff));
            }
        } else if (!exp.AND().isEmpty()) {
            // : filter (AND filter)+
            final List<Filter<Object>> subs = new ArrayList<>();
            for (FilterContext f : exp.filter()) {
                final Filter sub = convertFilter(f, ff);
                if (sub.getOperatorType() == LogicalOperatorName.AND) {
                    subs.addAll(((LogicalOperator) sub).getOperands());
                } else {
                    subs.add(sub);
                }
            }
            return ff.and(subs);
        } else if (!exp.OR().isEmpty()) {
            // | filter (OR filter)+
            final List<Filter<Object>> subs = new ArrayList<>();
            for (FilterContext f : exp.filter()) {
                final Filter sub = convertFilter(f, ff);
                if (sub.getOperatorType() == LogicalOperatorName.OR) {
                    subs.addAll(((LogicalOperator) sub).getOperands());
                } else {
                    subs.add(sub);
                }
            }
            return ff.or(subs);
        } else if (exp.LPAREN() != null) {
            // | LPAREN filter RPAREN
            return convertFilter(exp.filter(0), ff);
        }
    } else if (tree instanceof FilterTermContext) {
        // : expression
        // (
        // COMPARE  expression
        // | NOT? IN LPAREN (expressionFctParam )?  RPAREN
        // | BETWEEN expression AND expression
        // | NOT? LIKE expression
        // | NOT? ILIKE expression
        // | IS NOT? NULL
        // | AFTER expression
        // | ANYINTERACTS expression
        // | BEFORE expression
        // | BEGINS expression
        // | BEGUNBY expression
        // | DURING expression
        // | ENDEDBY expression
        // | ENDS expression
        // | MEETS expression
        // | METBY expression
        // | OVERLAPPEDBY expression
        // | TCONTAINS expression
        // | TEQUALS expression
        // | TOVERLAPS expression
        // )
        // | filterGeometry
        final FilterTermContext exp = (FilterTermContext) tree;
        final List<ExpressionContext> exps = exp.expression();
        if (exp.COMPARE() != null) {
            // expression COMPARE expression
            final String text = exp.COMPARE().getText();
            final Expression<Object, ?> left = convertExpression(exps.get(0), ff);
            final Expression<Object, ?> right = convertExpression(exps.get(1), ff);
            if ("=".equals(text)) {
                return ff.equal(left, right);
            } else if ("<>".equals(text)) {
                return ff.notEqual(left, right);
            } else if (">".equals(text)) {
                return ff.greater(left, right);
            } else if ("<".equals(text)) {
                return ff.less(left, right);
            } else if (">=".equals(text)) {
                return ff.greaterOrEqual(left, right);
            } else if ("<=".equals(text)) {
                return ff.lessOrEqual(left, right);
            } else if ("<=".equals(text)) {
                return ff.lessOrEqual(left, right);
            }
        } else if (exp.IN() != null) {
            // expression NOT? IN LPAREN (expressionFctParam )?  RPAREN
            final Expression val = convertExpression(exps.get(0), ff);
            final ExpressionFctParamContext prm = exp.expressionFctParam();
            final List<ExpressionContext> params = prm.expression();
            final List<Expression> subexps = new ArrayList<Expression>();
            for (int i = 0, n = params.size(); i < n; i++) {
                subexps.add(convertExpression(params.get(i), ff));
            }
            final int size = subexps.size();
            final Filter selection;
            if (size == 0) {
                selection = Filter.exclude();
            } else if (size == 1) {
                selection = ff.equal(val, subexps.get(0));
            } else {
                final List<Filter<Object>> filters = new ArrayList<>();
                for (Expression e : subexps) {
                    filters.add(ff.equal(val, e));
                }
                selection = ff.or(filters);
            }
            if (exp.NOT() != null) {
                return ff.not(selection);
            } else {
                return selection;
            }
        } else if (exp.BETWEEN() != null) {
            // expression BETWEEN expression AND expression
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            final Expression exp3 = convertExpression(exps.get(2), ff);
            return ff.between(exp1, exp2, exp3);
        } else if (exp.LIKE() != null) {
            // expression NOT? LIKE expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            if (exp.NOT() != null) {
                return ff.not(ff.like(left, right.apply(null).toString(), '%', '_', '\\', true));
            } else {
                return ff.like(left, right.apply(null).toString(), '%', '_', '\\', true);
            }
        } else if (exp.ILIKE() != null) {
            // expression NOT? LIKE expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            if (exp.NOT() != null) {
                return ff.not(ff.like(left, right.apply(null).toString(), '%', '_', '\\', false));
            } else {
                return ff.like(left, right.apply(null).toString(), '%', '_', '\\', false);
            }
        } else if (exp.IS() != null) {
            // expression IS NOT? NULL
            final Expression exp1 = convertExpression(exps.get(0), ff);
            if (exp.NOT() != null) {
                return ff.not(ff.isNull(exp1));
            } else {
                return ff.isNull(exp1);
            }
        } else if (exp.AFTER() != null) {
            // expression AFTER expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.after(left, right);
        } else if (exp.ANYINTERACTS() != null) {
            // expression ANYINTERACTS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.anyInteracts(left, right);
        } else if (exp.BEFORE() != null) {
            // expression BEFORE expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.before(left, right);
        } else if (exp.BEGINS() != null) {
            // expression BEGINS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.begins(left, right);
        } else if (exp.BEGUNBY() != null) {
            // expression BEGUNBY expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.begunBy(left, right);
        } else if (exp.DURING() != null) {
            // expression DURING expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.during(left, right);
        } else if (exp.ENDEDBY() != null) {
            // expression ENDEDBY expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.endedBy(left, right);
        } else if (exp.ENDS() != null) {
            // expression ENDS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.ends(left, right);
        } else if (exp.MEETS() != null) {
            // expression MEETS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.meets(left, right);
        } else if (exp.METBY() != null) {
            // expression METBY expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.metBy(left, right);
        } else if (exp.OVERLAPPEDBY() != null) {
            // expression OVERLAPPEDBY expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.overlappedBy(left, right);
        } else if (exp.TCONTAINS() != null) {
            // expression TCONTAINS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.tcontains(left, right);
        } else if (exp.TEQUALS() != null) {
            // expression TEQUALS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.tequals(left, right);
        } else if (exp.TOVERLAPS() != null) {
            // expression TOVERLAPS expression
            final Expression left = convertExpression(exps.get(0), ff);
            final Expression right = convertExpression(exps.get(1), ff);
            return ff.toverlaps(left, right);
        } else if (exp.filterGeometry() != null) {
            // expression filterGeometry
            return convertFilter(exp.filterGeometry(), ff);
        }
    } else if (tree instanceof FilterGeometryContext) {
        // : BBOX LPAREN (PROPERTY_NAME|NAME) COMMA expressionUnary COMMA expressionUnary COMMA expressionUnary COMMA expressionUnary (COMMA TEXT)? RPAREN
        // | BEYOND LPAREN expression COMMA expression COMMA expression COMMA expression RPAREN
        // | CONTAINS LPAREN expression COMMA expression RPAREN
        // | CROSSES LPAREN expression COMMA expression RPAREN
        // | DISJOINT LPAREN expression COMMA expression RPAREN
        // | DWITHIN LPAREN expression COMMA expression COMMA expression COMMA expression RPAREN
        // | EQUALS LPAREN expression COMMA expression RPAREN
        // | INTERSECTS LPAREN expression COMMA expression RPAREN
        // | OVERLAPS LPAREN expression COMMA expression RPAREN
        // | TOUCHES LPAREN expression COMMA expression RPAREN
        // | WITHIN LPAREN expression COMMA expression RPAREN
        final FilterGeometryContext exp = (FilterGeometryContext) tree;
        final List<ExpressionContext> exps = exp.expression();
        if (exp.BBOX() != null) {
            final Expression prop = convertExpression(exps.get(0), ff);
            final double v1 = unaryAsNumber(exp.expressionUnary(0)).doubleValue();
            final double v2 = unaryAsNumber(exp.expressionUnary(1)).doubleValue();
            final double v3 = unaryAsNumber(exp.expressionUnary(2)).doubleValue();
            final double v4 = unaryAsNumber(exp.expressionUnary(3)).doubleValue();
            String crs = null;
            if (exp.TEXT() != null) {
                crs = convertExpression(exp.TEXT(), ff).apply(null).toString();
            }
            return ff.bbox(prop, v1, v2, v3, v4, crs);
        } else if (exp.BEYOND() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            final double distance = ((Number) convertExpression(exps.get(2), ff).apply(null)).doubleValue();
            final Expression unitExp = convertExpression(exps.get(3), ff);
            final String unit = (unitExp instanceof ValueReference) ? ((ValueReference) unitExp).getXPath() : unitExp.apply(null).toString();
            return ff.beyond(exp1, exp2, distance, unit);
        } else if (exp.CONTAINS() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.contains(exp1, exp2);
        } else if (exp.CROSSES() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.crosses(exp1, exp2);
        } else if (exp.DISJOINT() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.disjoint(exp1, exp2);
        } else if (exp.DWITHIN() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            final double distance = ((Number) convertExpression(exps.get(2), ff).apply(null)).doubleValue();
            final Expression unitExp = convertExpression(exps.get(3), ff);
            final String unit = (unitExp instanceof ValueReference) ? ((ValueReference) unitExp).getXPath() : unitExp.apply(null).toString();
            return ff.dwithin(exp1, exp2, distance, unit);
        } else if (exp.EQUALS() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.equals(exp1, exp2);
        } else if (exp.INTERSECTS() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.intersects(exp1, exp2);
        } else if (exp.OVERLAPS() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.overlaps(exp1, exp2);
        } else if (exp.TOUCHES() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.touches(exp1, exp2);
        } else if (exp.WITHIN() != null) {
            final Expression exp1 = convertExpression(exps.get(0), ff);
            final Expression exp2 = convertExpression(exps.get(1), ff);
            return ff.within(exp1, exp2);
        }
    }
    throw new CQLException("Unreconized filter : type=" + tree.getText());
}
Also used : ExpressionFctParamContext(org.geotoolkit.cql.CQLParser.ExpressionFctParamContext) LogicalOperator(org.opengis.filter.LogicalOperator) ArrayList(java.util.ArrayList) LineString(org.locationtech.jts.geom.LineString) Filter(org.opengis.filter.Filter) Expression(org.opengis.filter.Expression) FilterOrExpressionContext(org.geotoolkit.cql.CQLParser.FilterOrExpressionContext) ExpressionContext(org.geotoolkit.cql.CQLParser.ExpressionContext) FilterGeometryContext(org.geotoolkit.cql.CQLParser.FilterGeometryContext) ArrayList(java.util.ArrayList) List(java.util.List) FilterTermContext(org.geotoolkit.cql.CQLParser.FilterTermContext) CQLException(org.apache.sis.cql.CQLException) FilterContext(org.geotoolkit.cql.CQLParser.FilterContext) ValueReference(org.opengis.filter.ValueReference)

Aggregations

ArrayList (java.util.ArrayList)1 List (java.util.List)1 CQLException (org.apache.sis.cql.CQLException)1 ExpressionContext (org.geotoolkit.cql.CQLParser.ExpressionContext)1 ExpressionFctParamContext (org.geotoolkit.cql.CQLParser.ExpressionFctParamContext)1 FilterContext (org.geotoolkit.cql.CQLParser.FilterContext)1 FilterGeometryContext (org.geotoolkit.cql.CQLParser.FilterGeometryContext)1 FilterOrExpressionContext (org.geotoolkit.cql.CQLParser.FilterOrExpressionContext)1 FilterTermContext (org.geotoolkit.cql.CQLParser.FilterTermContext)1 LineString (org.locationtech.jts.geom.LineString)1 Expression (org.opengis.filter.Expression)1 Filter (org.opengis.filter.Filter)1 LogicalOperator (org.opengis.filter.LogicalOperator)1 ValueReference (org.opengis.filter.ValueReference)1