sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ama...@apache.org
Subject [sis] 27/45: wip(Feature): Add unit tests for envelope to geometry operator.
Date Tue, 12 Nov 2019 16:44:54 GMT
This is an automated email from the ASF dual-hosted git repository.

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

commit 82901836cee6586c995d5859d75b799ebd96db2d
Author: Alexis Manin <amanin@apache.org>
AuthorDate: Tue Oct 8 13:05:02 2019 +0200

    wip(Feature): Add unit tests for envelope to geometry operator.
---
 .../apache/sis/internal/feature/Geometries.java    | 20 +++---
 .../sis/internal/feature/GeometriesTestCase.java   | 76 ++++++++++++++++++----
 2 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index 3fd582b..0688024 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@ -22,6 +22,7 @@ import java.util.function.Function;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 
+import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.Geometry;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -346,7 +347,7 @@ public abstract class Geometries<G> {
         return Optional.empty();
     }
 
-    private Object tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
+    Object tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
         // Ensure that we can isolate an horizontal part in the given envelope.
         final int x;
         if (env.getDimension() == 2) {
@@ -361,10 +362,12 @@ public abstract class Geometries<G> {
 
         final int y = x+1;
 
-        double minX = env.getMinimum(x);
-        double minY = env.getMinimum(y);
-        double maxX = env.getMaximum(x);
-        double maxY = env.getMaximum(y);
+        final DirectPosition lc = env.getLowerCorner();
+        final DirectPosition uc = env.getUpperCorner();
+        double minX = lc.getOrdinate(x);
+        double minY = lc.getOrdinate(y);
+        double maxX = uc.getOrdinate(x);
+        double maxY = uc.getOrdinate(y);
         double[] splittedLeft = null;
         // We start by short-circuiting simplest case for minor simplicity/performance reason.
         if (!WrapResolution.NONE.equals(resolution)) {
@@ -373,14 +376,13 @@ public abstract class Geometries<G> {
             fixedEnv.normalize();
             int wrapAxis = -1;
             for (int i = x ; i <= y && wrapAxis < x ; i++) {
-                if (fixedEnv.getMinimum(i) > fixedEnv.getMaximum(i)) wrapAxis = i;
+                if (fixedEnv.getLower(i) > fixedEnv.getUpper(i)) wrapAxis = i;
             }
             if (wrapAxis >= x) {
                 final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
-                if (crs == null) throw new IllegalStateException("Cannot resolve wrap-around
for an envelope without any system defined");
+                if (crs == null) throw new IllegalArgumentException("Cannot resolve wrap-around
for an envelope without any system defined");
                 final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(wrapAxis);
                 final double wrapRange = axis.getMaximumValue() - axis.getMinimumValue();
-                //TODO
                 switch (resolution) {
                     case EXPAND:
                         // simpler and more performant than a call to GeneralEnvelope.simplify()
@@ -422,7 +424,7 @@ public abstract class Geometries<G> {
             maxY = splittedLeft[3];
             Vector[] points2 = clockwiseRing(minX, minY, maxX, maxY);
             final G secondRect = createPolyline(2, points2);
-            return createMultiPolygon(mainRect, secondRect);
+            return createMultiPolygonImpl(mainRect, secondRect);
         }
 
         return mainRect;
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
index 9d02c74..dc67d01 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometriesTestCase.java
@@ -20,6 +20,8 @@ import java.util.Arrays;
 import java.util.EnumMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.stream.Stream;
 
 import org.opengis.geometry.Envelope;
 
@@ -33,9 +35,14 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static java.lang.Double.NaN;
+import static org.apache.sis.internal.feature.WrapResolution.CONTIGUOUS;
+import static org.apache.sis.internal.feature.WrapResolution.EXPAND;
+import static org.apache.sis.internal.feature.WrapResolution.NONE;
+import static org.apache.sis.internal.feature.WrapResolution.SPLIT;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 
 
 /**
@@ -145,30 +152,73 @@ public abstract strictfp class GeometriesTestCase extends TestCase {
 
     @Test
     public void testEnvelopeToLinearRing() {
+        // First, ensure that behavior is constant in case wrap-around is de-activated.
         final GeneralEnvelope noWrapNeeded = new GeneralEnvelope(new DefaultGeographicBoundingBox(-30,
24, -60, -51));
         final double[] expectedResult = {-30, -60, -30, -51, 24, -51, 24, -60, -30, -60};
         for (WrapResolution method : WrapResolution.values()) assertConversion(noWrapNeeded,
method, expectedResult);
 
-        final GeneralEnvelope basicWrap = new GeneralEnvelope(CommonCRS.defaultGeographic());
-        basicWrap.setEnvelope(165, 32, -170, 33);
+        // Check behavior when wrap-around is on first axis.
+        final GeneralEnvelope wrapped = new GeneralEnvelope(CommonCRS.defaultGeographic());
+        wrapped.setEnvelope(165, 32, -170, 33);
         final EnumMap expected = new EnumMap(WrapResolution.class);
-        expected.put(WrapResolution.NONE, new double[]{165, 32, 165, 33, -170, 33, -170,
32, 165, 32});
-        expected.put(WrapResolution.CONTIGUOUS, new double[]{165, 32, 165, 33, 190, 33, 190,
32, 165, 32});
-        expected.put(WrapResolution.EXPAND, new double[]{-180, 32, -180, 33, 180, 33, 180,
32, -180, 32});
-        expected.put(WrapResolution.SPLIT, new double[]{165, 32, 165, 33, 180, 33, 180, 32,
165, 32, -180, 32, -180, 33, -170, 33, -170, 32, -180, 32});
-        assertConversion(basicWrap, expected);
-
+        expected.put(NONE, new double[]{165, 32, 165, 33, -170, 33, -170, 32, 165, 32});
+        expected.put(CONTIGUOUS, new double[]{165, 32, 165, 33, 190, 33, 190, 32, 165, 32});
+        expected.put(EXPAND, new double[]{-180, 32, -180, 33, 180, 33, 180, 32, -180, 32});
+        expected.put(SPLIT, new double[]{165, 32, 165, 33, 180, 33, 180, 32, 165, 32, -180,
32, -180, 33, -170, 33, -170, 32, -180, 32});
+        assertConversion(wrapped, expected);
+
+        wrapped.setEnvelope(177, -42, 190, 2);
+        expected.put(NONE, new double[]{177, -42, 177, 2, 190, 2, 190, -42, 177, -42});
+        expected.put(CONTIGUOUS, new double[]{177, -42, 177, 2, 190, 2, 190, -42, 177, -42});
+        expected.put(EXPAND, new double[]{-180, -42, -180, 2, 180, 2, 180, -42, -180, -42});
+        expected.put(SPLIT, new double[]{177, -42, 177, 2, 180, 2, 180, -42, 177, -42, -180,
-42, -180, 2, -170, 2, -170, -42, -180, -42});
+
+        // Check wrap-around on second axis.
+        wrapped.setCoordinateReferenceSystem(CommonCRS.WGS84.geographic());
+        wrapped.setEnvelope(2, 89, 3, 19);
+        expected.put(NONE, new double[]{2, 89, 2, 19, 3, 19, 3, 89, 2, 89});
+        expected.put(CONTIGUOUS, new double[]{2, 89, 2, 199, 3, 199, 3, 89, 2, 89});
+        expected.put(EXPAND, new double[]{2, -180, 2, 180, 3, 180, 3, -180, 2, -180});
+        expected.put(SPLIT, new double[]{2, 89, 2, 180, 3, 180, 3, 89, 2, 89, 2, -180, 2,
19, 3, 19, 3, -180, 2, -180});
+
+        // Ensure fail fast on dimension ambiguity
+        wrapped.setCoordinateReferenceSystem(null);
+        Stream.of(CONTIGUOUS, EXPAND, SPLIT)
+                .forEach(method
+                        -> expectFailFast(()
+                        -> factory.tryConvertToGeometry(wrapped, method), IllegalArgumentException.class)
+                );
+
+        final GeneralEnvelope wrapped3d = new GeneralEnvelope(3);
+        expectFailFast(() -> factory.tryConvertToGeometry(wrapped3d, NONE), IllegalArgumentException.class);
+    }
 
+    private static void expectFailFast(Callable whichMustFail, Class<? extends Exception>...
expectedErrorTypes) {
+        try {
+            final Object result = whichMustFail.call();
+            fail("Fail fast expected, but successfully returned "+result);
+        } catch (Exception e) {
+            if (expectedErrorTypes == null || expectedErrorTypes.length < 1) return; //
Any error accepted.
+            for (Class errorType : expectedErrorTypes) {
+                if (errorType.isInstance(e)) {
+                    // Expected behavior
+                    return;
+                }
+            }
+            // Unexpected error
+            fail(String.format(
+                    "A fail fast occurred, but thrown error type is unexpected.%nError type:
%s%nStack-trace: %s",
+                    e.getClass().getCanonicalName(), e
+            ));
+        }
     }
 
-    private static void assertConversion(final Envelope source, final Map<WrapResolution,
double[]> expectedResults) {
+    private void assertConversion(final Envelope source, final Map<WrapResolution, double[]>
expectedResults) {
         expectedResults.entrySet().forEach(entry -> assertConversion(source, entry.getKey(),
entry.getValue()));
     }
 
-    private static void assertConversion(final Envelope source, final WrapResolution method,
final double[] expectedOrdinates) {
-        final double[] result = Geometries.toGeometry(source, method)
-                .flatMap(Geometries::getOrdinates)
-                .orElseThrow(() -> new AssertionError("No geometry returned for envelope
conversion"));
+    private void assertConversion(final Envelope source, final WrapResolution method, final
double[] expectedOrdinates) {
+        final double[] result = factory.getPoints(factory.tryConvertToGeometry(source, method));
         assertArrayEquals("Point list for: "+method, expectedOrdinates, result, 1e-9);
     }
 


Mime
View raw message