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 <[email protected]>
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.
+    }
 }

Reply via email to