You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2021/07/30 16:49:40 UTC

[sis] 04/07: chore(Storage): Add a test-case to verify that geometry CRS are properly synchronized (when possible) in comparison functions.

This is an automated email from the ASF dual-hosted git repository.

amanin pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit ee9a44d3fa7e2794c32205b95d68a09f9eef79fc
Author: Alexis Manin <al...@geomatys.com>
AuthorDate: Wed Jul 28 16:29:19 2021 +0200

    chore(Storage): Add a test-case to verify that geometry CRS are properly synchronized (when possible) in comparison functions.
---
 .../sql/feature/FilterInterpreterTest.java         | 77 ++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/FilterInterpreterTest.java b/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/FilterInterpreterTest.java
index 07e3046..4b39e05 100644
--- a/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/FilterInterpreterTest.java
+++ b/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/FilterInterpreterTest.java
@@ -16,9 +16,13 @@
  */
 package org.apache.sis.internal.sql.feature;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import org.apache.sis.filter.DefaultFilterFactory;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
+import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -26,9 +30,16 @@ import static org.apache.sis.test.Assert.*;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
+import org.opengis.filter.Expression;
 import org.opengis.filter.Filter;
 import org.opengis.filter.FilterFactory;
+import org.opengis.filter.InvalidFilterValueException;
 import org.opengis.filter.SpatialOperator;
+import org.opengis.filter.SpatialOperatorName;
+import org.opengis.util.CodeList;
+
+import static org.opengis.filter.SpatialOperatorName.BBOX;
+import static org.opengis.filter.SpatialOperatorName.INTERSECTS;
 
 
 /**
@@ -71,6 +82,40 @@ public final strictfp class FilterInterpreterTest extends TestCase {
     }
 
     /**
+     * Expects that a spatial operator transforms literal value before-hand if possible.
+     */
+    @Test
+    public void testGeometricFilterWithTransform() {
+        final PostGISInterpreter interpreter = new PostGISInterpreter();
+        final GeneralEnvelope bbox = new GeneralEnvelope(CommonCRS.WGS84.geographic());
+        bbox.setEnvelope(-10, 20, -5, 25);
+        String expectedQueryString = "ST_Intersects(\"Toto\"," +
+                " ST_GeomFromText('POLYGON ((20 -10, 20 -5, 25 -5, 25 -10, 20 -10))'))";
+
+        StringBuilder query = new StringBuilder();
+        Filter intersectionFilter = new Mock(INTERSECTS, FF.property("Toto"), FF.literal(bbox));
+        interpreter.visit(intersectionFilter, query);
+        assertEquals(expectedQueryString, query.toString());
+
+        // same attempt but with an SIS filter: expect same behavior
+        query = new StringBuilder();
+        intersectionFilter = FF.intersects(FF.property("Toto"), FF.literal(bbox));
+        interpreter.visit(intersectionFilter, query);
+        assertEquals(expectedQueryString, query.toString());
+
+        query = new StringBuilder();
+        final Mock bboxFilter = new Mock(BBOX, FF.property("Toto"), FF.literal(bbox));
+        interpreter.visit(bboxFilter, query);
+        assertEquals(
+                "(\"Toto\" && " +
+                        "ST_GeomFromText(" +
+                            "'POLYGON ((20 -10, 20 -5, 25 -5, 25 -10, 20 -10))'" +
+                        "))",
+                query.toString()
+        );
+    }
+
+    /**
      * Creates a filter without geometry and verifies that it is translated to the expected SQL fragment.
      */
     @Test
@@ -94,4 +139,36 @@ public final strictfp class FilterInterpreterTest extends TestCase {
         new ANSIInterpreter().visit(source, sb);
         assertEquals(expected, sb.toString());
     }
+
+    /**
+     * Mock spatial operator to ensure PostGIS interpreter will make necessary CRS conversion by itself.
+     * Using directly SIS filter make the test obsolete, because it makes CRS conversion before-hand. However, it is an
+     * implementation detail. We should be prepared to receive third-party implementations that does <em>not</em>
+     * perform implicit conversion.
+     */
+    private static class Mock implements SpatialOperator {
+
+        final SpatialOperatorName name;
+        final List<Expression> operands;
+
+        private Mock(SpatialOperatorName name, Expression<?, ?> left, Expression<?, ?> right) {
+            this.name = name;
+            operands = Collections.unmodifiableList(Arrays.asList(left, right));
+        }
+
+        @Override
+        public CodeList<?> getOperatorType() {
+            return name;
+        }
+
+        @Override
+        public List<Expression> getExpressions() {
+            return operands;
+        }
+
+        @Override
+        public boolean test(Object o) throws InvalidFilterValueException {
+            throw new UnsupportedOperationException("Should not be used");
+        }
+    }
 }