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 d58bf3769ea80723c2b24802da01a4933bea847d
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Nov 29 23:01:23 2021 +0100

    Subsampling computed by `GridDerivation.subgrid(GridGeometry)` must be 
integer
    (it was not when the given grid geometry has only a "grid to CRS" 
transform).
    Better determination of which grid between source and target must have a 
CRS.
---
 .../coverage/grid/CoordinateOperationFinder.java   | 65 ++++++++++------------
 .../apache/sis/coverage/grid/GridDerivation.java   | 22 ++++----
 .../org/apache/sis/coverage/grid/GridGeometry.java |  1 +
 .../sis/coverage/grid/ResampledGridCoverage.java   |  1 +
 4 files changed, 43 insertions(+), 46 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
index 1608b6c..df88dbb 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
@@ -17,6 +17,7 @@
 package org.apache.sis.coverage.grid;
 
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.function.Supplier;
 import javax.measure.Quantity;
 import javax.measure.quantity.Length;
@@ -74,7 +75,7 @@ import org.apache.sis.internal.util.Numerics;
  *
  * @author  Alexis Manin (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   1.1
  * @module
  */
@@ -234,6 +235,18 @@ final class CoordinateOperationFinder implements 
Supplier<double[]> {
     }
 
     /**
+     * Verifies whether the presence of a CRS considered mandatory, unless the 
CRS of opposite grid
+     * is also missing.
+     *
+     * @param  rs  {@code true} is source CRS is mandatory, {@code false} if 
target CRS is mandatory.
+     */
+    final void verifyPresenceOfCRS(final boolean rs) {
+        if ((rs ? target : source).isDefined(GridGeometry.CRS)) {
+            Objects.requireNonNull((rs ? source : 
target).getCoordinateReferenceSystem());
+        }
+    }
+
+    /**
      * Sets whether operations will be between cell centers or cell corners.
      * This method must be invoked before any other method in this class.
      * The {@link PixelInCell#CELL_CORNER} value should be used first
@@ -277,28 +290,12 @@ final class CoordinateOperationFinder implements 
Supplier<double[]> {
     }
 
     /**
-     * Returns the CRS of the source grid geometry. If neither the source and 
target grid geometry
-     * define a CRS, then this method returns {@code null}.
-     *
-     * @throws IncompleteGridGeometryException if the target grid geometry has 
a CRS but the source
-     *         grid geometry has none. Note that the converse is allowed, in 
which case the target
-     *         CRS is assumed the same than the source.
-     */
-    private CoordinateReferenceSystem getSourceCRS() {
-        return source.isDefined(GridGeometry.CRS) ||
-               target.isDefined(GridGeometry.CRS) ? 
source.getCoordinateReferenceSystem() : null;
-    }
-
-    /**
      * Returns the target of the "corner to CRS" transform.
      * May be {@code null} if the neither the source and target grid geometry 
define a CRS.
-     *
-     * @throws IncompleteGridGeometryException if the target grid geometry has 
a CRS but the source
-     *         grid geometry has none. Note that the converse is allowed, in 
which case the target
-     *         CRS is assumed the same than the source.
      */
     final CoordinateReferenceSystem getTargetCRS() {
-        return (changeOfCRS != null) ? changeOfCRS.getTargetCRS() : 
getSourceCRS();
+        return (changeOfCRS != null) ? changeOfCRS.getTargetCRS() :
+                source.isDefined(GridGeometry.CRS) ? 
source.getCoordinateReferenceSystem() : null;
     }
 
     /**
@@ -322,23 +319,21 @@ final class CoordinateOperationFinder implements 
Supplier<double[]> {
                 if (sourceEnvelope != null && targetEnvelope != null) {
                     changeOfCRS = Envelopes.findOperation(sourceEnvelope, 
targetEnvelope);
                 }
-                if (changeOfCRS == null && target.isDefined(GridGeometry.CRS)) 
{
-                    final CoordinateReferenceSystem sourceCRS = getSourceCRS();
-                    if (sourceCRS != null) {
-                        /*
-                         * Unconditionally create operation even if CRS are 
the same. A non-null operation trig
-                         * the check for wraparound axes, which is necessary 
even if the transform is identity.
-                         */
-                        DefaultGeographicBoundingBox areaOfInterest = null;
-                        if (sourceEnvelope != null || targetEnvelope != null) 
try {
-                            areaOfInterest = new 
DefaultGeographicBoundingBox();
-                            areaOfInterest.setBounds(targetEnvelope != null ? 
targetEnvelope : sourceEnvelope);
-                        } catch (TransformException e) {
-                            areaOfInterest = null;
-                            recoverableException("changeOfCRS", e);
-                        }
-                        changeOfCRS = CRS.findOperation(sourceCRS, 
target.getCoordinateReferenceSystem(), areaOfInterest);
+                if (changeOfCRS == null && source.isDefined(GridGeometry.CRS) 
&& target.isDefined(GridGeometry.CRS)) {
+                    final CoordinateReferenceSystem sourceCRS = 
source.getCoordinateReferenceSystem();
+                    /*
+                     * Unconditionally create operation even if CRS are the 
same. A non-null operation trig
+                     * the check for wraparound axes, which is necessary even 
if the transform is identity.
+                     */
+                    DefaultGeographicBoundingBox areaOfInterest = null;
+                    if (sourceEnvelope != null || targetEnvelope != null) try {
+                        areaOfInterest = new DefaultGeographicBoundingBox();
+                        areaOfInterest.setBounds(targetEnvelope != null ? 
targetEnvelope : sourceEnvelope);
+                    } catch (TransformException e) {
+                        areaOfInterest = null;
+                        recoverableException("changeOfCRS", e);
                     }
+                    changeOfCRS = CRS.findOperation(sourceCRS, 
target.getCoordinateReferenceSystem(), areaOfInterest);
                 }
             } catch (BackingStoreException e) {                         // May 
be thrown by getConstantCoordinates().
                 throw e.unwrapOrRethrow(TransformException.class);
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
index 9041ca6..0822d14 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridDerivation.java
@@ -500,25 +500,25 @@ public class GridDerivation {
             if (base.equals(areaOfInterest)) {
                 return this;
             }
-            if (areaOfInterest.extent == null && areaOfInterest.resolution != 
null) {
-                return subgrid(areaOfInterest.envelope, 
areaOfInterest.resolution);
-            }
             final MathTransform mapCenters;
-            final GridExtent domain = areaOfInterest.getExtent();       // May 
throw IncompleteGridGeometryException.
+            final GridExtent domain = areaOfInterest.extent;
+            final CoordinateOperationFinder finder = new 
CoordinateOperationFinder(areaOfInterest, base);
+            finder.verifyPresenceOfCRS(false);
             try {
-                final CoordinateOperationFinder finder = new 
CoordinateOperationFinder(areaOfInterest, base);
-                final MathTransform mapCorners = finder.gridToGrid();
+                final MathTransform mapCorners = (domain != null) ? 
finder.gridToGrid() : null;
                 finder.setAnchor(PixelInCell.CELL_CENTER);
                 finder.nowraparound();
                 mapCenters = finder.gridToGrid();                              
 // We will use only the scale factors.
-                setBaseExtentClipped(domain.toCRS(mapCorners, mapCenters, 
null));
+                if (domain != null) {
+                    setBaseExtentClipped(domain.toCRS(mapCorners, mapCenters, 
null));
+                    if (baseExtent != base.extent && 
baseExtent.equals(domain)) {
+                        baseExtent = domain;                                   
 // Share common instance.
+                    }
+                }
                 subGridSetter = "subgrid";
             } catch (FactoryException | TransformException e) {
                 throw new IllegalGridGeometryException(e, "areaOfInterest");
             }
-            if (baseExtent != base.extent && 
baseExtent.equals(areaOfInterest.extent)) {
-                baseExtent = areaOfInterest.extent;                            
             // Share common instance.
-            }
             // The `domain` extent must be the source of the `mapCenters` 
transform.
             scales = GridGeometry.resolution(mapCenters, domain);
         }
@@ -540,7 +540,7 @@ public class GridDerivation {
     }
 
     /**
-     * Requests a grid geometry over a sub-envelope and optionally with a 
different a coarser resolution.
+     * Requests a grid geometry over a sub-envelope and optionally with a 
coarser resolution.
      * The given envelope does not need to be expressed in the same coordinate 
reference system (CRS)
      * than {@linkplain GridGeometry#getCoordinateReferenceSystem() the CRS of 
the base grid geometry};
      * coordinate conversions or transformations will be applied as needed.
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
index 720fd8d..25eddfd 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
@@ -1365,6 +1365,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
          * effort for using `WraparoundTransform` only if needed (contrarily 
to `gridToCRS(…)`).
          */
         final CoordinateOperationFinder finder = new 
CoordinateOperationFinder(target, this);
+        finder.verifyPresenceOfCRS(false);
         finder.setAnchor(anchor);
         final MathTransform tr;
         try {
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
index dc01606..758678b 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
@@ -282,6 +282,7 @@ final class ResampledGridCoverage extends GridCoverage {
     {
         final GridGeometry sourceGG = source.getGridGeometry();
         final CoordinateOperationFinder changeOfCRS = new 
CoordinateOperationFinder(sourceGG, target);
+        changeOfCRS.verifyPresenceOfCRS(true);
         /*
          * Compute the transform from source pixels to target CRS (to be 
completed to target pixels later).
          * The following lines may throw IncompleteGridGeometryException, 
which is desired because if that

Reply via email to