Search in sources :

Example 1 with ExpressionTermContext

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

the class CQL method convertExpression.

/**
 * Convert the given tree in an Expression.
 */
private static Expression convertExpression(ParseTree tree, FilterFactory2 ff) throws CQLException {
    if (tree instanceof ExpressionContext) {
        // | expressionTerm
        if (tree.getChildCount() == 3) {
            final String operand = tree.getChild(1).getText();
            final Expression left = convertExpression((ParseTree) tree.getChild(0), ff);
            final Expression right = convertExpression((ParseTree) tree.getChild(2), ff);
            if ("*".equals(operand)) {
                return ff.multiply(left, right);
            } else if ("/".equals(operand)) {
                return ff.divide(left, right);
            } else if ("+".equals(operand)) {
                return ff.add(left, right);
            } else if ("-".equals(operand)) {
                return ff.subtract(left, right);
            }
        } else {
            return convertExpression(tree.getChild(0), ff);
        }
    } else // }
    if (tree instanceof ExpressionTermContext) {
        // : expressionString
        // | expressionUnary
        // | PROPERTY_NAME
        // | DATE
        // | DURATION_P
        // | DURATION_T
        // | NAME (LPAREN expressionFctParam? RPAREN)?
        // | expressionGeometry
        // | LPAREN expression RPAREN
        // : TEXT
        // | expressionUnary
        // | PROPERTY_NAME
        // | DATE
        // | DURATION_P
        // | DURATION_T
        // | expressionGeometry
        final ExpressionTermContext exp = (ExpressionTermContext) tree;
        if (exp.getChildCount() == 1) {
            return convertExpression(tree.getChild(0), ff);
        }
        // LPAREN expression RPAREN
        if (exp.expression() != null) {
            return convertExpression(exp.expression(), ff);
        }
        // NAME (LPAREN expressionFctParam? RPAREN)?
        if (exp.NAME() != null) {
            final String name = exp.NAME().getText();
            final ExpressionFctParamContext prm = exp.expressionFctParam();
            if (prm == null) {
                // try to find a function with this name
                try {
                    Expression fct = ff.function(name, new Expression[0]);
                    if (fct != null)
                        return fct;
                } catch (IllegalArgumentException ex) {
                // we have try
                }
                // handle as property name
                return ff.property(name);
            }
            // handle as a function
            final List<ExpressionContext> params = prm.expression();
            final List<Expression> exps = new ArrayList<Expression>();
            for (int i = 0, n = params.size(); i < n; i++) {
                exps.add(convertExpression(params.get(i), ff));
            }
            return ff.function(name, exps.toArray(new Expression[exps.size()]));
        }
    } else if (tree instanceof ExpressionUnaryContext) {
        // : UNARY? expressionNum ;
        final ExpressionUnaryContext exp = (ExpressionUnaryContext) tree;
        return ff.literal(unaryAsNumber(exp));
    } else if (tree instanceof ExpressionNumContext) {
        // : INT | FLOAT ;
        return convertExpression(tree.getChild(0), ff);
    } else if (tree instanceof TerminalNode) {
        final TerminalNode exp = (TerminalNode) tree;
        final int type = exp.getSymbol().getType();
        if (PROPERTY_NAME == type) {
            // strip start and end "
            final String text = tree.getText();
            return ff.property(text.substring(1, text.length() - 1));
        } else if (NAME == type) {
            return ff.property(tree.getText());
        } else if (INT == type) {
            return ff.literal(Integer.valueOf(tree.getText()));
        } else if (FLOAT == type) {
            return ff.literal(Double.valueOf(tree.getText()));
        } else if (DATE == type) {
            final ISODateParser parser = new ISODateParser();
            return ff.literal(parser.parseToDate(tree.getText()));
        } else if (DURATION_P == type || DURATION_T == type) {
            return ff.literal(TemporalUtilities.getTimeInMillis(tree.getText()));
        } else if (TEXT == type) {
            // strip start and end '
            String text = tree.getText();
            text = text.replaceAll("\\\\'", "'");
            return ff.literal(text.substring(1, text.length() - 1));
        }
    } else if (tree instanceof ExpressionGeometryContext) {
        // : POINT ( EMPTY | coordinateSerie )
        // | LINESTRING ( EMPTY | coordinateSerie )
        // | POLYGON ( EMPTY | coordinateSeries )
        // | MPOINT ( EMPTY | coordinateSerie )
        // | MLINESTRING  ( EMPTY | coordinateSeries )
        // | MPOLYGON ( EMPTY | LPAREN coordinateSeries (COMMA coordinateSeries)* RPAREN )
        // | GEOMETRYCOLLECTION ( EMPTY | (LPAREN expressionGeometry (COMMA expressionGeometry)* RPAREN) )
        // | ENVELOPE ( EMPTY | (LPAREN expressionUnary COMMA expressionUnary COMMA expressionUnary COMMA expressionUnary RPAREN) )
        final ExpressionGeometryContext exp = (ExpressionGeometryContext) tree;
        final int type = ((TerminalNode) exp.getChild(0)).getSymbol().getType();
        if (POINT == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final CoordinateSequence cs;
            if (isEmptyToken(st)) {
                cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
            } else {
                cs = parseSequence(st);
            }
            final Geometry geom = GF.createPoint(cs);
            return ff.literal(geom);
        } else if (LINESTRING == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final CoordinateSequence cs;
            if (isEmptyToken(st)) {
                cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
            } else {
                cs = parseSequence(st);
            }
            final Geometry geom = GF.createLineString(cs);
            return ff.literal(geom);
        } else if (POLYGON == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final Geometry geom;
            if (isEmptyToken(st)) {
                geom = GF.createPolygon(GF.createLinearRing(new Coordinate[0]), new LinearRing[0]);
            } else {
                final CoordinateSeriesContext series = (CoordinateSeriesContext) st;
                final List<CoordinateSerieContext> subs = series.coordinateSerie();
                final LinearRing contour = GF.createLinearRing(parseSequence(subs.get(0)));
                final int n = subs.size();
                final LinearRing[] holes = new LinearRing[n - 1];
                for (int i = 1; i < n; i++) {
                    holes[i - 1] = GF.createLinearRing(parseSequence(subs.get(i)));
                }
                geom = GF.createPolygon(contour, holes);
            }
            return ff.literal(geom);
        } else if (MPOINT == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final CoordinateSequence cs;
            if (isEmptyToken(st)) {
                cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
            } else {
                cs = parseSequence(st);
            }
            final Geometry geom = GF.createMultiPoint(cs);
            return ff.literal(geom);
        } else if (MLINESTRING == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final Geometry geom;
            if (isEmptyToken(st)) {
                geom = GF.createMultiLineString(new LineString[0]);
            } else {
                final CoordinateSeriesContext series = (CoordinateSeriesContext) st;
                final List<CoordinateSerieContext> subs = series.coordinateSerie();
                final int n = subs.size();
                final LineString[] strings = new LineString[n];
                for (int i = 0; i < n; i++) {
                    strings[i] = GF.createLineString(parseSequence(subs.get(i)));
                }
                geom = GF.createMultiLineString(strings);
            }
            return ff.literal(geom);
        } else if (MPOLYGON == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final Geometry geom;
            if (isEmptyToken(st)) {
                geom = GF.createMultiPolygon(new Polygon[0]);
            } else {
                final List<CoordinateSeriesContext> eles = exp.coordinateSeries();
                final int n = eles.size();
                final Polygon[] polygons = new Polygon[n];
                for (int i = 0; i < n; i++) {
                    final CoordinateSeriesContext polyTree = eles.get(i);
                    final List<CoordinateSerieContext> subs = polyTree.coordinateSerie();
                    final LinearRing contour = GF.createLinearRing(parseSequence(subs.get(0)));
                    final int hn = subs.size();
                    final LinearRing[] holes = new LinearRing[hn - 1];
                    for (int j = 1; j < hn; j++) {
                        holes[j - 1] = GF.createLinearRing(parseSequence(subs.get(j)));
                    }
                    final Polygon poly = GF.createPolygon(contour, holes);
                    polygons[i] = poly;
                }
                geom = GF.createMultiPolygon(polygons);
            }
            return ff.literal(geom);
        } else if (GEOMETRYCOLLECTION == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final Geometry geom;
            if (isEmptyToken(st)) {
                geom = GF.createGeometryCollection(new Geometry[0]);
            } else {
                final List<ExpressionGeometryContext> eles = exp.expressionGeometry();
                final int n = eles.size();
                final Geometry[] subs = new Geometry[n];
                for (int i = 0; i < n; i++) {
                    final ParseTree subTree = eles.get(i);
                    final Geometry sub = (Geometry) convertExpression(subTree, ff).apply(null);
                    subs[i] = sub;
                }
                geom = GF.createGeometryCollection(subs);
            }
            return ff.literal(geom);
        } else if (ENVELOPE == type) {
            final ParseTree st = (ParseTree) tree.getChild(1);
            final Geometry geom;
            if (isEmptyToken(st)) {
                geom = GF.createPolygon(GF.createLinearRing(new Coordinate[0]), new LinearRing[0]);
            } else {
                final List<ExpressionUnaryContext> unaries = exp.expressionUnary();
                final double west = unaryAsNumber(unaries.get(0)).doubleValue();
                final double east = unaryAsNumber(unaries.get(1)).doubleValue();
                final double north = unaryAsNumber(unaries.get(2)).doubleValue();
                final double south = unaryAsNumber(unaries.get(3)).doubleValue();
                final LinearRing contour = GF.createLinearRing(new Coordinate[] { new Coordinate(west, north), new Coordinate(east, north), new Coordinate(east, south), new Coordinate(west, south), new Coordinate(west, north) });
                geom = GF.createPolygon(contour, new LinearRing[0]);
            }
            return ff.literal(geom);
        }
        return convertExpression(tree.getChild(0), ff);
    }
    throw new CQLException("Unreconized expression : type=" + tree.getText());
}
Also used : ExpressionFctParamContext(org.geotoolkit.cql.CQLParser.ExpressionFctParamContext) CoordinateSequence(org.locationtech.jts.geom.CoordinateSequence) LineString(org.locationtech.jts.geom.LineString) CoordinateSeriesContext(org.geotoolkit.cql.CQLParser.CoordinateSeriesContext) ExpressionNumContext(org.geotoolkit.cql.CQLParser.ExpressionNumContext) ISODateParser(org.geotoolkit.temporal.object.ISODateParser) ExpressionTermContext(org.geotoolkit.cql.CQLParser.ExpressionTermContext) ArrayList(java.util.ArrayList) List(java.util.List) Polygon(org.locationtech.jts.geom.Polygon) ExpressionGeometryContext(org.geotoolkit.cql.CQLParser.ExpressionGeometryContext) ExpressionUnaryContext(org.geotoolkit.cql.CQLParser.ExpressionUnaryContext) CoordinateSerieContext(org.geotoolkit.cql.CQLParser.CoordinateSerieContext) Geometry(org.locationtech.jts.geom.Geometry) FilterOrExpressionContext(org.geotoolkit.cql.CQLParser.FilterOrExpressionContext) ExpressionContext(org.geotoolkit.cql.CQLParser.ExpressionContext) Expression(org.opengis.filter.Expression) Coordinate(org.locationtech.jts.geom.Coordinate) CQLException(org.apache.sis.cql.CQLException) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) LinearRing(org.locationtech.jts.geom.LinearRing) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Aggregations

ArrayList (java.util.ArrayList)1 List (java.util.List)1 ParseTree (org.antlr.v4.runtime.tree.ParseTree)1 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)1 CQLException (org.apache.sis.cql.CQLException)1 CoordinateSerieContext (org.geotoolkit.cql.CQLParser.CoordinateSerieContext)1 CoordinateSeriesContext (org.geotoolkit.cql.CQLParser.CoordinateSeriesContext)1 ExpressionContext (org.geotoolkit.cql.CQLParser.ExpressionContext)1 ExpressionFctParamContext (org.geotoolkit.cql.CQLParser.ExpressionFctParamContext)1 ExpressionGeometryContext (org.geotoolkit.cql.CQLParser.ExpressionGeometryContext)1 ExpressionNumContext (org.geotoolkit.cql.CQLParser.ExpressionNumContext)1 ExpressionTermContext (org.geotoolkit.cql.CQLParser.ExpressionTermContext)1 ExpressionUnaryContext (org.geotoolkit.cql.CQLParser.ExpressionUnaryContext)1 FilterOrExpressionContext (org.geotoolkit.cql.CQLParser.FilterOrExpressionContext)1 ISODateParser (org.geotoolkit.temporal.object.ISODateParser)1 Coordinate (org.locationtech.jts.geom.Coordinate)1 CoordinateSequence (org.locationtech.jts.geom.CoordinateSequence)1 Geometry (org.locationtech.jts.geom.Geometry)1 LineString (org.locationtech.jts.geom.LineString)1 LinearRing (org.locationtech.jts.geom.LinearRing)1