sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/02: Bug fix: when the 'areaOfInterest' has been converted to geographic coordinates, a conversion needs to be applied on 'domainOfValidity' too.
Date Tue, 19 Mar 2019 19:41:00 GMT
This is an automated email from the ASF dual-hosted git repository.

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

commit f943c9d02e48ded272c2fa2e592b1f6d6eea7305
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Mar 19 20:39:33 2019 +0100

    Bug fix: when the 'areaOfInterest' has been converted to geographic coordinates, a conversion
needs to be applied on 'domainOfValidity' too.
---
 .../apache/sis/coverage/grid/GridDerivation.java   |  2 +-
 .../internal/referencing/WraparoundAdjustment.java | 42 ++++++++++++++--------
 .../referencing/WraparoundAdjustmentTest.java      | 33 +++++++++++++----
 3 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
index 67d5186..3633e3d 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
@@ -503,7 +503,7 @@ public class GridDerivation {
             GeneralEnvelope indices = null;
             if (areaOfInterest != null) {
                 final WraparoundAdjustment adj = new WraparoundAdjustment(areaOfInterest);
-                adj.shiftInto(base.envelope, baseToAOI);
+                adj.shiftInto(base.envelope, (baseToAOI != null) ? baseToAOI.getMathTransform()
: null);
                 indices = adj.result(cornerToCRS.inverse());
                 clipExtent(indices);
             }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
index 2641126..4e0d107 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
@@ -27,7 +27,6 @@ import org.opengis.referencing.cs.RangeMeaning;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.internal.metadata.AxisDirections;
@@ -122,7 +121,7 @@ public final class WraparoundAdjustment {
      *
      * @see GeneralEnvelope#simplify()
      */
-    public void shiftInto(Envelope domainOfValidity, CoordinateOperation validToAOI) throws
TransformException {
+    public void shiftInto(Envelope domainOfValidity, MathTransform validToAOI) throws TransformException
{
         CoordinateReferenceSystem crs = areaOfInterest.getCoordinateReferenceSystem();
         if (crs == null) {
             crs = domainOfValidity.getCoordinateReferenceSystem();      // Assumed to apply
to AOI too.
@@ -135,19 +134,29 @@ public final class WraparoundAdjustment {
          * We need to perform the verification in its base geographic CRS instead, and remember
that we
          * may need to transform the result later.
          */
+        final MathTransform  projection;
+        final DirectPosition lowerCorner;
+        final DirectPosition upperCorner;
         GeneralEnvelope shifted = null;         // To be initialized to a copy of 'areaOfInterest'
when first needed.
         if (crs instanceof ProjectedCRS) {
             final ProjectedCRS p = (ProjectedCRS) crs;
             crs = p.getBaseCRS();
-            geographicToAOI = p.getConversionFromBase().getMathTransform();
-            areaOfInterest = shifted = Envelopes.transform(geographicToAOI.inverse(), areaOfInterest);
+            projection  = p.getConversionFromBase().getMathTransform();
+            shifted     = Envelopes.transform(projection.inverse(), areaOfInterest);
+            lowerCorner = shifted.getLowerCorner();
+            upperCorner = shifted.getUpperCorner();
+            if (validToAOI == null) {
+                validToAOI = MathTransforms.identity(projection.getTargetDimensions());
+            }
+        } else {
+            projection  = null;
+            lowerCorner = areaOfInterest.getLowerCorner();
+            upperCorner = areaOfInterest.getUpperCorner();
         }
         /*
-         * We will not reference 'areaOfInterest' anymore after we got its two corner points.
+         * We will not read 'areaOfInterest' anymore after we got its two corner points.
          * The following loop search for "wraparound" axis.
          */
-        final DirectPosition lowerCorner = areaOfInterest.getLowerCorner();
-        final DirectPosition upperCorner = areaOfInterest.getUpperCorner();
         final CoordinateSystem cs = crs.getCoordinateSystem();
         for (int i=cs.getDimension(); --i >= 0;) {
             final double period = range(cs, i);
@@ -158,14 +167,13 @@ public final class WraparoundAdjustment {
                  * Transform that envelope when first needed.
                  */
                 if (validToAOI != null) {
-                    MathTransform mt = validToAOI.getMathTransform();
-                    if (geographicToAOI != null) {
-                        mt = MathTransforms.concatenate(mt, geographicToAOI.inverse());
+                    if (projection != null) {
+                        validToAOI = MathTransforms.concatenate(validToAOI, projection.inverse());
                     }
-                    validToAOI = null;
-                    if (!mt.isIdentity()) {
-                        domainOfValidity = Envelopes.transform(mt, domainOfValidity);
+                    if (!validToAOI.isIdentity()) {
+                        domainOfValidity = Envelopes.transform(validToAOI, domainOfValidity);
                     }
+                    validToAOI = null;
                 }
                 /*
                  * "Unroll" the range. For example if we have [+160 … -170]° of longitude,
we can replace by [160 … 190]°.
@@ -268,12 +276,16 @@ public final class WraparoundAdjustment {
                     }
                 }
                 /*
-                 * If there is change to apply, copy the envelope when first needed.
+                 * If there is change to apply, copy the envelope when first needed and set
the fields.
+                 * If we never enter in this block, then 'areaOfInterest' will stay the envelope
given
+                 * at construction time.
                  */
                 if (lowerCycles != 0 || upperCycles != 0) {
                     if (shifted == null) {
-                        areaOfInterest = shifted = new GeneralEnvelope(areaOfInterest);
+                        shifted = new GeneralEnvelope(areaOfInterest);
                     }
+                    areaOfInterest  = shifted;                          // 'shifted' may
have been set before the loop.
+                    geographicToAOI = projection;
                     shifted.setRange(i, lower + lowerCycles * period,       // TODO: use
Math.fma in JDK9.
                                         upper + upperCycles * period);
                 }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
index e6634ed..6feaf28 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
@@ -16,14 +16,16 @@
  */
 package org.apache.sis.internal.referencing;
 
-import org.apache.sis.geometry.GeneralEnvelope;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.cs.*;
-import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.crs.DefaultProjectedCRS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.referencing.cs.HardCodedCS;
+import org.apache.sis.referencing.operation.HardCodedConversions;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -53,7 +55,7 @@ public final strictfp class WraparoundAdjustmentTest extends TestCase {
     /**
      * Convenience method for the tests.
      */
-    private static Envelope adjustWraparoundAxes(Envelope areaOfInterest, Envelope domainOfValidity,
CoordinateOperation validToAOI)
+    private static Envelope adjustWraparoundAxes(Envelope areaOfInterest, Envelope domainOfValidity,
MathTransform validToAOI)
             throws TransformException
     {
         WraparoundAdjustment adj = new WraparoundAdjustment(areaOfInterest);
@@ -62,7 +64,7 @@ public final strictfp class WraparoundAdjustmentTest extends TestCase {
     }
 
     /**
-     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, CoordinateOperation)}
+     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)}
      * with an envelope crossing the anti-meridian.
      *
      * @throws TransformException should never happen since this test does not transform
coordinates.
@@ -86,7 +88,7 @@ public final strictfp class WraparoundAdjustmentTest extends TestCase {
     }
 
     /**
-     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, CoordinateOperation)}
+     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)}
      * with an envelope shifted by 360° before or after the grid valid area.
      *
      * @throws TransformException should never happen since this test does not transform
coordinates.
@@ -117,7 +119,7 @@ public final strictfp class WraparoundAdjustmentTest extends TestCase
{
     }
 
     /**
-     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, CoordinateOperation)}
+     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)}
      * with an envelope that cause the method to expand the area of interest. Illustration:
      *
      * {@preformat text
@@ -149,4 +151,23 @@ public final strictfp class WraparoundAdjustmentTest extends TestCase
{
         final Envelope actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
         assertEnvelopeEquals(expected, actual);
     }
+
+    /**
+     * Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)} with a projected
envelope.
+     *
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    public void testWithProjection() throws TransformException {
+        final GeneralEnvelope domainOfValidity = new GeneralEnvelope(HardCodedCRS.WGS84);
+        domainOfValidity.setRange(0,  80, 100);
+        domainOfValidity.setRange(1, -70, +70);
+
+        final DefaultProjectedCRS mercator = HardCodedConversions.mercator();
+        final GeneralEnvelope areaOfInterest = new GeneralEnvelope(mercator);
+        areaOfInterest.setRange(0,   5000000,  7000000);                        // About
45°E to 63°E
+        areaOfInterest.setRange(1, -10000000, 10000000);                        // About
66.6°S to 66.6°N
+
+        // TODO: complete test.
+    }
 }


Mime
View raw message