This is an automated email from the ASF dual-hosted git repository. jsorel pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 20e29957c4b01e09c3b177613c0027d5ca5731a5 Author: jsorel <[email protected]> AuthorDate: Tue Nov 5 16:16:50 2019 +0100 Filter : add spatial filter classes, not implemented yet, this allows more CQL tests to be activated --- .../org/apache/sis/cql/FilterToCQLVisitor.java | 4 + .../test/java/org/apache/sis/cql/CQLTestCase.java | 6 +- .../java/org/apache/sis/cql/FilterReadingTest.java | 132 +++---- .../java/org/apache/sis/cql/FilterWritingTest.java | 14 +- .../apache/sis/filter/DefaultFilterFactory.java | 42 ++- .../java/org/apache/sis/filter/DefaultLike.java | 5 + .../org/apache/sis/filter/SpatialFunction.java | 414 +++++++++++++++++++++ 7 files changed, 504 insertions(+), 113 deletions(-) diff --git a/core/sis-cql/src/main/java/org/apache/sis/cql/FilterToCQLVisitor.java b/core/sis-cql/src/main/java/org/apache/sis/cql/FilterToCQLVisitor.java index dd72df6..3ffabcc 100644 --- a/core/sis-cql/src/main/java/org/apache/sis/cql/FilterToCQLVisitor.java +++ b/core/sis-cql/src/main/java/org/apache/sis/cql/FilterToCQLVisitor.java @@ -16,6 +16,7 @@ */ package org.apache.sis.cql; +import java.time.temporal.TemporalAccessor; import java.util.Date; import java.util.List; import java.util.regex.Pattern; @@ -567,6 +568,9 @@ final class FilterToCQLVisitor implements FilterVisitor, ExpressionVisitor { } else if (value instanceof Date) { final Date date = (Date) value; sb.append(StandardDateFormat.FORMAT.format(date.toInstant())); + } else if (value instanceof TemporalAccessor) { + final TemporalAccessor date = (TemporalAccessor) value; + sb.append(StandardDateFormat.FORMAT.format(date)); } else if (value instanceof Geometry) { final Geometry geometry = (Geometry) value; final WKTWriter writer = new WKTWriter(); diff --git a/core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestCase.java b/core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestCase.java index a6c9c26..badb0b4 100644 --- a/core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestCase.java +++ b/core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestCase.java @@ -17,10 +17,10 @@ package org.apache.sis.cql; import java.time.Instant; -import java.util.Date; import org.opengis.filter.FilterFactory2; import org.locationtech.jts.geom.GeometryFactory; import org.apache.sis.filter.DefaultFilterFactory; +import org.apache.sis.internal.util.StandardDateFormat; import org.apache.sis.test.TestCase; @@ -54,7 +54,7 @@ strictfp class CQLTestCase extends TestCase { /** * Returns a date from the given string. */ - static Date parseDate(final String date) { - return Date.from(Instant.parse(date)); + static Instant parseDate(final String date) { + return Instant.from(StandardDateFormat.FORMAT.parse(date)); } } diff --git a/core/sis-cql/src/test/java/org/apache/sis/cql/FilterReadingTest.java b/core/sis-cql/src/test/java/org/apache/sis/cql/FilterReadingTest.java index ab2f673..1fac9de 100644 --- a/core/sis-cql/src/test/java/org/apache/sis/cql/FilterReadingTest.java +++ b/core/sis-cql/src/test/java/org/apache/sis/cql/FilterReadingTest.java @@ -17,6 +17,8 @@ package org.apache.sis.cql; import java.text.ParseException; +import java.time.Instant; +import java.time.temporal.TemporalAccessor; import java.util.Date; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; @@ -62,7 +64,6 @@ import org.opengis.filter.temporal.TContains; import org.opengis.filter.temporal.TEquals; import org.opengis.filter.temporal.TOverlaps; import org.apache.sis.internal.util.UnmodifiableArrayList; -import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; @@ -137,10 +138,9 @@ public final strictfp class FilterReadingTest extends CQLTestCase { filter); } - @Ignore @Test public void testOrAnd1() throws CQLException { - final String cql = "Title = 'VMAI' OR (Title ILIKE 'LO?Li' AND DWITHIN(BoundingBox, POINT(12.1 28.9), 10, meters))"; + final String cql = "Title = 'VMAI' OR (Title ILIKE '!$P_att%ern?' AND DWITHIN(BoundingBox, POINT(12.1 28.9), 10, meters))"; final Object obj = CQL.parseFilter(cql); assertTrue(obj instanceof Filter); final Filter filter = (Filter) obj; @@ -148,14 +148,13 @@ public final strictfp class FilterReadingTest extends CQLTestCase { FF.or( FF.equals(FF.property("Title"), FF.literal("VMAI")), FF.and( - FF.like(FF.property("Title"), "LO?Li","%","_","\\",false), + FF.like(FF.property("Title"), "!$Pa_tt%ern?","%","_","\\",false), FF.dwithin(FF.property("BoundingBox"), FF.literal(baseGeometryPoint), 10, "meters") ) ), filter); } - @Ignore @Test public void testOrAnd2() throws CQLException { final Geometry geom = GF.createPolygon( @@ -197,7 +196,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.not(FF.equals(FF.property("att"), FF.literal(15))), filter); } - @Ignore @Test public void testPropertyIsBetween() throws CQLException { final String cql = "att BETWEEN 15 AND 30"; @@ -257,14 +255,13 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.notEqual(FF.property("att"), FF.literal(15)), filter); } - @Ignore @Test public void testPropertyIsNotEqualTo2() throws CQLException { final String cql = "att <>'15'"; final Object obj = CQL.parseFilter(cql); assertTrue(obj instanceof PropertyIsNotEqualTo); final PropertyIsNotEqualTo filter = (PropertyIsNotEqualTo) obj; - assertEquals(FF.notEqual(FF.property("att"), FF.literal(15)), filter); + assertEquals(FF.notEqual(FF.property("att"), FF.literal("15")), filter); } @Test @@ -303,7 +300,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.lessOrEqual(FF.property("att"), FF.literal(15)), filter); } - @Ignore @Test public void testPropertyIsLike() throws CQLException { final String cql = "att LIKE '%hello_'"; @@ -313,7 +309,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.like(FF.property("att"),"%hello_", "%", "_", "\\",true), filter); } - @Ignore @Test public void testPropertyIsNotLike() throws CQLException { final String cql = "att NOT LIKE '%hello_'"; @@ -323,7 +318,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.not(FF.like(FF.property("att"),"%hello_", "%", "_", "\\",true)), filter); } - @Ignore @Test public void testPropertyIsLikeInsensitive() throws CQLException { final String cql = "att ILIKE '%hello_'"; @@ -352,7 +346,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.isNull(FF.property("att")), filter); } - @Ignore @Test public void testBBOX1() throws CQLException { final String cql = "BBOX(\"att\" ,10, 20, 30, 40)"; @@ -362,7 +355,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.bbox(FF.property("att"), 10,20,30,40, null), filter); } - @Ignore @Test public void testBBOX2() throws CQLException { final String cql = "BBOX(\"att\" ,10, 20, 30, 40, 'CRS:84')"; @@ -372,7 +364,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.bbox(FF.property("att"), 10,20,30,40, "CRS:84"), filter); } - @Ignore @Test public void testBBOX3() throws CQLException { final String cql = "BBOX(att ,10, 20, 30, 40, 'CRS:84')"; @@ -382,7 +373,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.bbox(FF.property("att"), 10,20,30,40, "CRS:84"), filter); } - @Ignore @Test public void testBBOX4() throws CQLException { final String cql = "BBOX(geometry,-10,-20,10,20)"; @@ -392,7 +382,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.bbox(FF.property("geometry"), -10,-20,10,20,null), filter); } - @Ignore @Test public void testBeyond() throws CQLException { final String cql = "BEYOND(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)), 10, meters)"; @@ -407,7 +396,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testContains() throws CQLException { final String cql = "CONTAINS(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -422,7 +410,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testCrosses() throws CQLException { final String cql = "CROSSES(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -437,7 +424,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testDisjoint() throws CQLException { final String cql = "DISJOINT(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -452,7 +438,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testDWithin() throws CQLException { final String cql = "DWITHIN(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)), 10, 'meters')"; @@ -469,7 +454,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testDWithin2() throws CQLException { //there is an error in this syntax, meters is a literal so it should be writen 'meters" @@ -489,7 +473,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { } - @Ignore @Test public void testEquals() throws CQLException { final String cql = "EQUALS(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -504,7 +487,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testIntersects() throws CQLException { final String cql = "INTERSECTS(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -519,7 +501,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testOverlaps() throws CQLException { final String cql = "OVERLAPS(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -534,7 +515,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testTouches() throws CQLException { final String cql = "TOUCHES(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -549,7 +529,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testWithin() throws CQLException { final String cql = "WITHIN(\"att\" ,POLYGON((10 20, 30 40, 50 60, 10 20)))"; @@ -564,7 +543,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertTrue(baseGeometry.equalsExact(filtergeo)); } - @Ignore @Test public void testCombine1() throws CQLException { final String cql = "NOT att = 15 OR att BETWEEN 15 AND 30"; @@ -580,7 +558,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { ); } - @Ignore @Test public void testCombine2() throws CQLException { final String cql = "(NOT att = 15) OR (att BETWEEN 15 AND 30)"; @@ -596,7 +573,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { ); } - @Ignore @Test public void testCombine3() throws CQLException { final String cql = "(NOT att1 = 15) AND (att2 = 15 OR att3 BETWEEN 15 AND 30) AND (att4 BETWEEN 1 AND 2)"; @@ -633,7 +609,6 @@ public final strictfp class FilterReadingTest extends CQLTestCase { ); } - @Ignore @Test public void testAfter() throws CQLException, ParseException { final String cql = "att AFTER 2012-03-21T05:42:36Z"; @@ -643,12 +618,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testAnyInteracts() throws CQLException, ParseException { final String cql = "att ANYINTERACTS 2012-03-21T05:42:36Z"; @@ -658,12 +632,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testBefore() throws CQLException, ParseException { final String cql = "att BEFORE 2012-03-21T05:42:36Z"; @@ -673,12 +646,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testBegins() throws CQLException, ParseException { final String cql = "att BEGINS 2012-03-21T05:42:36Z"; @@ -688,12 +660,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testBegunBy() throws CQLException, ParseException { final String cql = "att BEGUNBY 2012-03-21T05:42:36Z"; @@ -703,12 +674,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testDuring() throws CQLException, ParseException { final String cql = "att DURING 2012-03-21T05:42:36Z"; @@ -718,12 +688,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testEndedBy() throws CQLException, ParseException { final String cql = "att ENDEDBY 2012-03-21T05:42:36Z"; @@ -733,12 +702,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testEnds() throws CQLException, ParseException { final String cql = "att ENDS 2012-03-21T05:42:36Z"; @@ -748,12 +716,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testMeets() throws CQLException, ParseException { final String cql = "att MEETS 2012-03-21T05:42:36Z"; @@ -763,12 +730,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testMetBy() throws CQLException, ParseException { final String cql = "att METBY 2012-03-21T05:42:36Z"; @@ -778,12 +744,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testOverlappedBy() throws CQLException, ParseException { final String cql = "att OVERLAPPEDBY 2012-03-21T05:42:36Z"; @@ -793,12 +758,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testTcontains() throws CQLException, ParseException { final String cql = "att TCONTAINS 2012-03-21T05:42:36Z"; @@ -808,12 +772,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testTequals() throws CQLException, ParseException { final String cql = "att TEQUALS 2012-03-21T05:42:36Z"; @@ -823,12 +786,11 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } - @Ignore @Test public void testToverlaps() throws CQLException, ParseException { final String cql = "att TOVERLAPS 2012-03-21T05:42:36Z"; @@ -838,9 +800,9 @@ public final strictfp class FilterReadingTest extends CQLTestCase { assertEquals(FF.property("att"), filter.getExpression1()); assertTrue(filter.getExpression2() instanceof Literal); - assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof Date); - final Date filterdate = (Date) ((Literal)filter.getExpression2()).getValue(); - assertEquals(parseDate("2012-03-21T05:42:36Z"), filterdate); + assertTrue( ((Literal)filter.getExpression2()).getValue() instanceof TemporalAccessor); + final TemporalAccessor filterdate = (TemporalAccessor) ((Literal)filter.getExpression2()).getValue(); + assertEquals(parseDate("2012-03-21T05:42:36Z"), Instant.from(filterdate)); } } diff --git a/core/sis-cql/src/test/java/org/apache/sis/cql/FilterWritingTest.java b/core/sis-cql/src/test/java/org/apache/sis/cql/FilterWritingTest.java index ff908a8..903258d 100644 --- a/core/sis-cql/src/test/java/org/apache/sis/cql/FilterWritingTest.java +++ b/core/sis-cql/src/test/java/org/apache/sis/cql/FilterWritingTest.java @@ -23,10 +23,10 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LinearRing; import org.opengis.filter.Filter; import org.apache.sis.internal.util.UnmodifiableArrayList; -import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; +import org.junit.Ignore; /** @@ -111,7 +111,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("NOT att = 15", cql); } - @Ignore @Test public void testPropertyIsBetween() throws CQLException { final Filter filter = FF.between(FF.property("att"), FF.literal(15), FF.literal(30)); @@ -185,7 +184,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("att IS NULL", cql); } - @Ignore @Test public void testBBOX() throws CQLException { final Filter filter = FF.bbox(FF.property("att"), 10,20,30,40, null); @@ -194,7 +192,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("BBOX(att,10.0,30.0,20.0,40.0)", cql); } - @Ignore @Test public void testBeyond() throws CQLException { final Filter filter = FF.beyond(FF.property("att"), FF.literal(baseGeometry), 0, ""); @@ -203,7 +200,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("BEYOND(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testContains() throws CQLException { final Filter filter = FF.contains(FF.property("att"), FF.literal(baseGeometry)); @@ -212,7 +208,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("CONTAINS(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testCrosses() throws CQLException { final Filter filter = FF.crosses(FF.property("att"), FF.literal(baseGeometry)); @@ -221,7 +216,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("CROSSES(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testDisjoint() throws CQLException { final Filter filter = FF.disjoint(FF.property("att"), FF.literal(baseGeometry)); @@ -230,7 +224,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("DISJOINT(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testDWithin() throws CQLException { final Filter filter = FF.dwithin(FF.property("att"), FF.literal(baseGeometry), 0, ""); @@ -239,7 +232,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("DWITHIN(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testEquals() throws CQLException { final Filter filter = FF.equal(FF.property("att"), FF.literal(baseGeometry)); @@ -248,7 +240,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("EQUALS(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testIntersects() throws CQLException { final Filter filter = FF.intersects(FF.property("att"), FF.literal(baseGeometry)); @@ -257,7 +248,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("INTERSECTS(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testOverlaps() throws CQLException { final Filter filter = FF.overlaps(FF.property("att"), FF.literal(baseGeometry)); @@ -266,7 +256,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("OVERLAPS(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testTouches() throws CQLException { final Filter filter = FF.touches(FF.property("att"), FF.literal(baseGeometry)); @@ -275,7 +264,6 @@ public final strictfp class FilterWritingTest extends CQLTestCase { assertEquals("TOUCHES(att,POLYGON ((10 20, 30 40, 50 60, 10 20)))", cql); } - @Ignore @Test public void testWithin() throws CQLException { final Filter filter = FF.within(FF.property("att"), FF.literal(baseGeometry)); diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java index 7eeb359..4d5002d 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java +++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java @@ -22,6 +22,9 @@ import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.sis.geometry.GeneralEnvelope; import org.opengis.filter.*; import org.opengis.filter.capability.*; import org.opengis.filter.capability.SpatialOperator; @@ -37,6 +40,9 @@ import org.apache.sis.internal.system.Modules; import org.apache.sis.internal.system.SystemListener; import org.apache.sis.internal.feature.FunctionRegister; import org.apache.sis.internal.feature.Resources; +import org.apache.sis.referencing.CRS; +import org.apache.sis.util.collection.BackingStoreException; +import org.opengis.util.FactoryException; /** @@ -109,7 +115,19 @@ public class DefaultFilterFactory implements FilterFactory2 { public BBOX bbox(final Expression e, final double minx, final double miny, final double maxx, final double maxy, final String srs) { - throw new UnsupportedOperationException("Not supported yet."); + GeneralEnvelope env; + if (srs == null || srs.isEmpty()) { + env = new GeneralEnvelope(2); + } else { + try { + env = new GeneralEnvelope(CRS.forCode(srs)); + } catch (FactoryException ex) { + throw new BackingStoreException(ex.getMessage(), ex); + } + } + env.setRange(0, minx, maxx); + env.setRange(1, miny, maxy); + return bbox(e, env); } /** @@ -117,7 +135,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public BBOX bbox(final Expression e, final Envelope bounds) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.BBOX(e, bounds); } /** @@ -147,7 +165,7 @@ public class DefaultFilterFactory implements FilterFactory2 { public Beyond beyond(final Expression left, final Expression right, final double distance, final String units) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Beyond(left, right, distance, units); } /** @@ -165,7 +183,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Contains contains(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Contains(left, right); } /** @@ -183,7 +201,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Crosses crosses(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Crosses(left, right); } /** @@ -201,7 +219,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Disjoint disjoint(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Disjoint(left, right); } /** @@ -223,7 +241,7 @@ public class DefaultFilterFactory implements FilterFactory2 { public DWithin dwithin(final Expression left, final Expression right, final double distance, final String units) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.DWithin(left, right, distance, units); } /** @@ -241,7 +259,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Equals equal(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Equals(left, right); } /** @@ -259,7 +277,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Intersects intersects(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Intersects(left, right); } /** @@ -277,7 +295,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Overlaps overlaps(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Overlaps(left, right); } /** @@ -295,7 +313,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Touches touches(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Touches(left, right); } /** @@ -313,7 +331,7 @@ public class DefaultFilterFactory implements FilterFactory2 { */ @Override public Within within(final Expression left, final Expression right) { - throw new UnsupportedOperationException("Not supported yet."); + return new SpatialFunction.Within(left, right); } // IDENTIFIERS ///////////////////////////////////////////////////////////// diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLike.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLike.java index 42cec1e..97527c6 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLike.java +++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLike.java @@ -24,6 +24,11 @@ import org.opengis.filter.expression.Expression; /** * The {@value #NAME} filter. + * + * @author Johann Sorel (Geomatys) + * @version 2.0 + * @since 2.0 + * @module */ final class DefaultLike extends Node implements PropertyIsLike { diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java b/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java new file mode 100644 index 0000000..6d40969 --- /dev/null +++ b/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java @@ -0,0 +1,414 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.filter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import org.apache.sis.math.Fraction; +import org.apache.sis.referencing.IdentifiedObjects; +import org.apache.sis.util.collection.BackingStoreException; +import org.opengis.filter.FilterVisitor; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.spatial.BinarySpatialOperator; +import org.opengis.geometry.Envelope; +import org.opengis.util.FactoryException; + +/** + * + * @author Johann Sorel (Geomatys) + * @version 2.0 + * @since 2.0 + * @module + */ +abstract class SpatialFunction extends BinaryFunction implements BinarySpatialOperator { + + protected SpatialFunction(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected Number applyAsLong(long left, long right) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + protected Number applyAsDouble(double left, double right) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + protected Number applyAsFraction(Fraction left, Fraction right) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + protected Number applyAsInteger(BigInteger left, BigInteger right) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + protected Number applyAsDecimal(BigDecimal left, BigDecimal right) { + throw new UnsupportedOperationException("Not supported."); + } + + + /** + * The {@value #NAME} filter. + */ + static final class BBOX extends SpatialFunction implements org.opengis.filter.spatial.BBOX { + + private final Envelope env; + + BBOX(Expression expression, Envelope env) { + super(expression, new LeafExpression.Literal(env)); + this.env = env; + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public String getPropertyName() { + if (expression1 instanceof PropertyName) { + return ((PropertyName) expression1).getPropertyName(); + } + return null; + } + + @Override + public String getSRS() { + try { + return IdentifiedObjects.lookupURN(env.getCoordinateReferenceSystem(), null); + } catch (FactoryException ex) { + throw new BackingStoreException(ex.getMessage(), ex); + } + } + + @Override + public double getMinX() { + return env.getMinimum(0); + } + + @Override + public double getMinY() { + return env.getMinimum(1); + } + + @Override + public double getMaxX() { + return env.getMaximum(0); + } + + @Override + public double getMaxY() { + return env.getMaximum(1); + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Beyond extends SpatialFunction implements org.opengis.filter.spatial.Beyond { + + private final double distance; + private final String units; + + Beyond(Expression expression1, Expression expression2, double distance, String units) { + super(expression1, expression2); + this.distance = distance; + this.units = units; + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public double getDistance() { + return distance; + } + + @Override + public String getDistanceUnits() { + return units; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Contains extends SpatialFunction implements org.opengis.filter.spatial.Contains { + + Contains(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Crosses extends SpatialFunction implements org.opengis.filter.spatial.Crosses { + + Crosses(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Disjoint extends SpatialFunction implements org.opengis.filter.spatial.Disjoint { + + Disjoint(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class DWithin extends SpatialFunction implements org.opengis.filter.spatial.DWithin { + + private final double distance; + private final String units; + + DWithin(Expression expression1, Expression expression2, double distance, String units) { + super(expression1, expression2); + this.distance = distance; + this.units = units; + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public double getDistance() { + return distance; + } + + @Override + public String getDistanceUnits() { + return units; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Equals extends SpatialFunction implements org.opengis.filter.spatial.Equals { + + Equals(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Intersects extends SpatialFunction implements org.opengis.filter.spatial.Intersects { + + Intersects(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Overlaps extends SpatialFunction implements org.opengis.filter.spatial.Overlaps { + + Overlaps(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Touches extends SpatialFunction implements org.opengis.filter.spatial.Touches { + + Touches(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } + + /** + * The {@value #NAME} filter. + */ + static final class Within extends SpatialFunction implements org.opengis.filter.spatial.Within { + + Within(Expression expression1, Expression expression2) { + super(expression1, expression2); + } + + @Override + protected String getName() { + return NAME; + } + + @Override + public boolean evaluate(Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object accept(FilterVisitor visitor, Object extraData) { + return visitor.visit(this, extraData); + } + } +}
