/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012, 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; * version 2.1 of the License. * * 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.cql; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import java.text.ParseException; import org.geotoolkit.filter.DefaultFilterFactory2; import org.geotoolkit.temporal.object.TemporalUtilities; import static org.junit.Assert.*; import org.junit.Test; import org.opengis.filter.FilterFactory2; import org.opengis.filter.expression.Add; import org.opengis.filter.expression.Divide; 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; /** * Test reading CQL expressions. * * @author Johann Sorel (Geomatys) */ public class ExpressionReadingTest extends org.geotoolkit.test.TestBase { private final FilterFactory2 FF = new DefaultFilterFactory2(); private final GeometryFactory GF = new GeometryFactory(); @Test public void testPropertyName1() throws CQLException{ final String cql = "geom"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof PropertyName); final PropertyName expression = (PropertyName) obj; assertEquals("geom", expression.getPropertyName()); } @Test public void testPropertyName2() throws CQLException{ final String cql = "\"geom\""; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof PropertyName); final PropertyName expression = (PropertyName) obj; assertEquals("geom", expression.getPropertyName()); } @Test public void testPropertyName3() throws CQLException{ final String cql = "ùth{e_$uglY^_pr@perté"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof PropertyName); final PropertyName expression = (PropertyName) obj; assertEquals("ùth{e_$uglY^_pr@perté", expression.getPropertyName()); } @Test public void testInteger() throws CQLException{ final String cql = "15"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(Integer.valueOf(15), expression.getValue()); } @Test public void testNegativeInteger() throws CQLException{ final String cql = "-15"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(Integer.valueOf(-15), expression.getValue()); } @Test public void testDecimal1() throws CQLException{ final String cql = "3.14"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(Double.valueOf(3.14), expression.getValue()); } @Test public void testDecimal2() throws CQLException{ final String cql = "9e-1"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(Double.valueOf(9e-1), expression.getValue()); } @Test public void testNegativeDecimal() throws CQLException{ final String cql = "-3.14"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(Double.valueOf(-3.14), expression.getValue()); } @Test public void testText() throws CQLException{ final String cql = "'hello world'"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals("hello world", expression.getValue()); } @Test public void testText2() throws CQLException{ final String cql = "'Valle d\\'Aosta'"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals("Valle d'Aosta", expression.getValue()); } @Test public void testText3() throws CQLException{ final String cql = "'Valle d\\'Aosta/Vallée d\\'Aoste'"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals("Valle d'Aosta/Vallée d'Aoste", expression.getValue()); } @Test public void testDate() throws CQLException, ParseException{ //dates are expected to be formated in ISO 8601 : yyyy-MM-dd'T'HH:mm:ss'Z' final String cql = "2012-03-21T05:42:36Z"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; assertEquals(TemporalUtilities.parseDate("2012-03-21T05:42:36Z"), expression.getValue()); } @Test public void testDuration() throws CQLException, ParseException{ final String cql = "P7Y6M5D4H3M2S"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final long duration = (Long) expression.getValue(); assertEquals(236966582000l, duration); } @Test public void testDuration2() throws CQLException, ParseException{ final String cql = "T4H3M2S"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final long duration = (Long) expression.getValue(); assertEquals(14582000,duration); } @Test public void testAddition() throws CQLException{ final String cql = "3 + 2"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Add); final Add expression = (Add) obj; assertEquals(FF.add(FF.literal(3), FF.literal(2)), expression); } @Test public void testAddition2() throws CQLException{ final String cql = "'test' + '23'"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Add); final Add expression = (Add) obj; Object res = expression.evaluate(null); assertEquals("test23", res); } @Test public void testSubstract() throws CQLException{ final String cql = "3 - 2"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Subtract); final Subtract expression = (Subtract) obj; assertEquals(FF.subtract(FF.literal(3), FF.literal(2)), expression); } @Test public void testMultiply() throws CQLException{ final String cql = "3 * 2"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Multiply); final Multiply expression = (Multiply) obj; assertEquals(FF.multiply(FF.literal(3), FF.literal(2)), expression); } @Test public void testDivide() throws CQLException{ final String cql = "3 / 2"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Divide); final Divide expression = (Divide) obj; assertEquals(FF.divide(FF.literal(3), FF.literal(2)), expression); } @Test public void testFunction1() throws CQLException{ final String cql = "max(\"att\",15)"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Function); final Function expression = (Function) obj; assertEquals(FF.function("max",FF.property("att"), FF.literal(15)), expression); } @Test public void testFunction2() throws CQLException{ final String cql = "min(\"att\",cos(3.14))"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Function); final Function expression = (Function) obj; assertEquals(FF.function("min",FF.property("att"), FF.function("cos",FF.literal(3.14d))), expression); } @Test public void testGeometryPoint() throws CQLException{ final String cql = "POINT(15 30)"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createPoint(new Coordinate(15, 30)); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryPointEmpty() throws CQLException{ final String cql = "POINT EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof Point); assertTrue(geom.isEmpty()); } @Test public void testGeometryMPoint() throws CQLException{ final String cql = "MULTIPOINT(15 30, 45 60)"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createMultiPoint( new Coordinate[]{ new Coordinate(15, 30), new Coordinate(45, 60) }); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryMPointEmpty() throws CQLException{ final String cql = "MULTIPOINT EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof MultiPoint); assertTrue(geom.isEmpty()); } @Test public void testGeometryLineString() throws CQLException{ final String cql = "LINESTRING(10 20, 30 40, 50 60)"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createLineString( new Coordinate[]{ new Coordinate(10, 20), new Coordinate(30, 40), new Coordinate(50, 60) }); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryLineStringEmpty() throws CQLException{ final String cql = "LINESTRING EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof LineString); assertTrue(geom.isEmpty()); } @Test public void testGeometryMLineString() throws CQLException{ final String cql = "MULTILINESTRING((10 20, 30 40, 50 60),(70 80, 90 100, 110 120))"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createMultiLineString( new LineString[]{ GF.createLineString( new Coordinate[]{ new Coordinate(10, 20), new Coordinate(30, 40), new Coordinate(50, 60) }), GF.createLineString( new Coordinate[]{ new Coordinate(70, 80), new Coordinate(90, 100), new Coordinate(110, 120) }) } ); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryMLineStringEmpty() throws CQLException{ final String cql = "MULTILINESTRING EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof MultiLineString); assertTrue(geom.isEmpty()); } @Test public void testGeometryPolygon() throws CQLException{ final String cql = "POLYGON((10 20, 30 40, 50 60, 10 20), (70 80, 90 100, 110 120, 70 80))"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createPolygon( GF.createLinearRing( new Coordinate[]{ new Coordinate(10, 20), new Coordinate(30, 40), new Coordinate(50, 60), new Coordinate(10, 20) }), new LinearRing[]{ GF.createLinearRing( new Coordinate[]{ new Coordinate(70, 80), new Coordinate(90, 100), new Coordinate(110, 120), new Coordinate(70, 80) }) } ); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryPolygonEmpty() throws CQLException{ final String cql = "POLYGON EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof Polygon); assertTrue(geom.isEmpty()); } @Test public void testGeometryMPolygon() throws CQLException{ final String cql = "MULTIPOLYGON(" + "((10 20, 30 40, 50 60, 10 20), (70 80, 90 100, 110 120, 70 80))," + "((11 21, 31 41, 51 61, 11 21), (71 81, 91 101, 111 121, 71 81))" + ")"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Polygon geom1 = GF.createPolygon( GF.createLinearRing( new Coordinate[]{ new Coordinate(10, 20), new Coordinate(30, 40), new Coordinate(50, 60), new Coordinate(10, 20) }), new LinearRing[]{ GF.createLinearRing( new Coordinate[]{ new Coordinate(70, 80), new Coordinate(90, 100), new Coordinate(110, 120), new Coordinate(70, 80) }) } ); final Polygon geom2 = GF.createPolygon( GF.createLinearRing( new Coordinate[]{ new Coordinate(11, 21), new Coordinate(31, 41), new Coordinate(51, 61), new Coordinate(11, 21) }), new LinearRing[]{ GF.createLinearRing( new Coordinate[]{ new Coordinate(71, 81), new Coordinate(91, 101), new Coordinate(111, 121), new Coordinate(71, 81) }) } ); final Geometry geom = GF.createMultiPolygon(new Polygon[]{geom1,geom2}); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryMPolygonEmpty() throws CQLException{ final String cql = "MULTIPOLYGON EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof MultiPolygon); assertTrue(geom.isEmpty()); } @Test public void testGeometryCollection() throws CQLException{ final String cql = "GEOMETRYCOLLECTION( POINT(15 30), LINESTRING(10 20, 30 40, 50 60) )"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom1 = GF.createPoint(new Coordinate(15, 30)); final Geometry geom2 = GF.createLineString( new Coordinate[]{ new Coordinate(10, 20), new Coordinate(30, 40), new Coordinate(50, 60) }); final GeometryCollection geom = GF.createGeometryCollection(new Geometry[]{geom1,geom2}); final GeometryCollection returned = (GeometryCollection)expression.getValue(); assertEquals(geom.getNumGeometries(), returned.getNumGeometries()); assertEquals(geom.getGeometryN(0), returned.getGeometryN(0)); assertEquals(geom.getGeometryN(1), returned.getGeometryN(1)); } @Test public void testGeometryCollectionEmpty() throws CQLException{ final String cql = "GEOMETRYCOLLECTION EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof GeometryCollection); assertTrue(geom.isEmpty()); } @Test public void testGeometryEnvelope() throws CQLException{ final String cql = "ENVELOPE(10, 20, 40, 30)"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = GF.createPolygon( GF.createLinearRing( new Coordinate[]{ new Coordinate(10, 40), new Coordinate(20, 40), new Coordinate(20, 30), new Coordinate(10, 30), new Coordinate(10, 40) }), new LinearRing[0] ); assertTrue(geom.equals((Geometry)expression.getValue())); } @Test public void testGeometryEnvelopeEmpty() throws CQLException{ final String cql = "ENVELOPE EMPTY"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Literal); final Literal expression = (Literal) obj; final Geometry geom = (Geometry)expression.getValue(); assertTrue(geom instanceof Polygon); assertTrue(geom.isEmpty()); } @Test public void testCombine1() throws CQLException{ final String cql = "((3*1)+(2-6))/4"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Divide); final Divide expression = (Divide) obj; assertEquals( FF.divide( FF.add( FF.multiply(FF.literal(3), FF.literal(1)), FF.subtract(FF.literal(2), FF.literal(6)) ), FF.literal(4)) , expression); } @Test public void testCombine2() throws CQLException{ final String cql = "3*1+2/4"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Add); final Add rootAdd = (Add) obj; assertEquals( FF.add( FF.multiply(FF.literal(3), FF.literal(1)), FF.divide(FF.literal(2), FF.literal(4)) ) , rootAdd); } @Test public void testCombine3() throws CQLException{ final String cql = "3*max(val,15)+2/4"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Add); final Add rootAdd = (Add) obj; assertEquals( FF.add( FF.multiply( FF.literal(3), FF.function("max", FF.property("val"),FF.literal(15)) ), FF.divide(FF.literal(2), FF.literal(4)) ) , rootAdd); } @Test public void testCombine4() throws CQLException{ final String cql = "3 * max ( val , 15 ) + 2 / 4"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Add); final Add rootAdd = (Add) obj; assertEquals( FF.add( FF.multiply( FF.literal(3), FF.function("max", FF.property("val"),FF.literal(15)) ), FF.divide(FF.literal(2), FF.literal(4)) ) , rootAdd); } @Test public void testCombine5() throws CQLException{ final String cql = "(\"NB-Curistes\"*50)/12000"; final Object obj = CQL.parseExpression(cql); assertTrue(obj instanceof Divide); final Divide result = (Divide) obj; assertEquals( FF.divide( FF.multiply( FF.property("NB-Curistes"), FF.literal(50) ), FF.literal(12000) ) , result); } }