sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Adjust the computation of "gridToCRS" in pixel center when derivating from another grid geometry.
Date Wed, 24 Apr 2019 11:26:55 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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 8158557  Adjust the computation of "gridToCRS" in pixel center when derivating from
another grid geometry.
8158557 is described below

commit 81585574a5cadc56476c845dc2b78af9fa164dd0
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Apr 24 13:26:09 2019 +0200

    Adjust the computation of "gridToCRS" in pixel center when derivating from another grid
geometry.
---
 .../org/apache/sis/coverage/grid/GridGeometry.java |  9 ++++---
 .../apache/sis/coverage/grid/PixelTranslation.java | 24 +++--------------
 .../apache/sis/coverage/grid/GridGeometryTest.java | 30 +++++++++++++++++++--
 .../operation/transform/MathTransforms.java        | 31 ++++++++++++++++++++++
 4 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
index 2b86fce..73c0942 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
@@ -243,9 +243,9 @@ public class GridGeometry implements Serializable {
      * <p>If {@code toOther} is non-null, it should be a transform from the given {@code
extent} coordinates to the
      * {@code other} grid coordinates. That transform should be merely a {@linkplain MathTransforms#scale(double...)
      * scale} and {@linkplain MathTransforms#translation(double...) translation} even if
more complex transforms are
-     * accepted. The {@link #gridToCRS} transform of the new grid geometry will be set to
the following concatenation:</p>
+     * accepted. The {@link #cornerToCRS} transform of the new grid geometry will be set
to the following concatenation:</p>
      *
-     * <blockquote>{@code this.gridToCRS} = {@code toOther} → {@code other.gridToCRS}</blockquote>
+     * <blockquote>{@code this.cornerToCRS} = {@code toOther} → {@code other.cornerToCRS}</blockquote>
      *
      * The new {@linkplain #getEnvelope() grid geometry envelope} will be {@linkplain GeneralEnvelope#intersect(Envelope)
      * clipped} to the envelope of the other grid geometry. This is for preventing the envelope
to become larger under the
@@ -269,8 +269,11 @@ public class GridGeometry implements Serializable {
             resolution  = other.resolution;
             nonLinears  = other.nonLinears;
         } else {
-            gridToCRS   = MathTransforms.concatenate(toOther, other.gridToCRS);
+            final MathTransform centerShift = MathTransforms.concatenate(
+                    MathTransforms.uniformTranslation(dimension, +0.5), toOther,
+                    MathTransforms.uniformTranslation(dimension, -0.5));
             cornerToCRS = MathTransforms.concatenate(toOther, other.cornerToCRS);
+            gridToCRS   = MathTransforms.concatenate(centerShift, other.gridToCRS);
             resolution  = resolution(gridToCRS, extent);
             nonLinears  = findNonLinearTargets(gridToCRS);
         }
diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
index a6f69f5..f82a3ab 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
@@ -18,7 +18,6 @@ package org.apache.sis.coverage.grid;
 
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Arrays;
 import java.io.Serializable;
 
 import org.opengis.referencing.operation.Matrix;
@@ -258,11 +257,11 @@ public final class PixelTranslation extends Static implements Serializable
{
         }
         MathTransform mt;
         if (ci < 0 || ci >= translations.length) {
-            mt = translate(dimension, offset);
+            mt = MathTransforms.uniformTranslation(dimension, offset);
         } else synchronized (translations) {
             mt = translations[ci];
             if (mt == null) {
-                mt = translate(dimension, offset);
+                mt = MathTransforms.uniformTranslation(dimension, offset);
                 translations[ci] = mt;
             }
         }
@@ -318,7 +317,7 @@ public final class PixelTranslation extends Static implements Serializable
{
             synchronized (translations) {
                 mt = translations[ci];
                 if (mt == null) {
-                    mt = translate(dimension, dx);
+                    mt = MathTransforms.uniformTranslation(dimension, dx);
                     translations[ci] = mt;
                 }
             }
@@ -339,23 +338,6 @@ public final class PixelTranslation extends Static implements Serializable
{
     }
 
     /**
-     * Creates an affine transform that apply the same translation for all dimensions.
-     * For each dimension, input values <var>x</var> are converted into output
values <var>y</var>
-     * using the following equation:
-     *
-     * <blockquote><var>y</var> = <var>x</var> + {@code offset}</blockquote>
-     *
-     * @param  dimension  the input and output dimensions.
-     * @param  offset     the {@code offset} term in the linear equation.
-     * @return the linear transform for the given offset.
-     */
-    private static MathTransform translate(final int dimension, final double offset) {
-        final double[] vector = new double[dimension];
-        Arrays.fill(vector, offset);
-        return MathTransforms.translation(vector);
-    }
-
-    /**
      * Returns a string representation of this pixel translation.
      */
     @Override
diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java
b/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java
index 3a3ed67..d0ac7e1 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java
@@ -149,7 +149,7 @@ public final strictfp class GridGeometryTest extends TestCase {
         long[]        high      = new long[] {101, 203, 4};
         GridExtent    extent    = new GridExtent(null, low, high, false);
         MathTransform gridToCRS = MathTransforms.translation(5, 7, 8);
-        GridGeometry  grid      = new GridGeometry(extent, PixelInCell.CELL_CENTER, gridToCRS,
null);
+        GridGeometry  grid      = new GridGeometry(extent, PixelInCell.CELL_CORNER, gridToCRS,
null);
 
         low    = new long[] { 11,  35, 20};
         high   = new long[] {120, 250, 39};
@@ -160,7 +160,33 @@ public final strictfp class GridGeometryTest extends TestCase {
                 2, 0, 0, 5,
                 0, 1, 0, 7,     // Combination of above scales (diagonal) and translation
(last column).
                 0, 0, 3, 8,
-                0, 0, 0, 1), MathTransforms.getMatrix(grid.getGridToCRS(PixelInCell.CELL_CENTER)),
STRICT);
+                0, 0, 0, 1), MathTransforms.getMatrix(grid.getGridToCRS(PixelInCell.CELL_CORNER)),
STRICT);
+    }
+
+    /**
+     * Tests the adjustment done for pixel center in {@link GridGeometry#GridGeometry(GridGeometry,
GridExtent, MathTransform)}
+     * constructor. This test depends on {@link GridGeometry#derive()}, which will (indirectly)
invoke the constructor to test.
+     * We check envelopes as a more intuitive way to verify consistency than inspecting the
math transforms.
+     */
+    @Test
+    public void testFromOtherConsistency() {
+        GridExtent extent = new GridExtent(126, 197);
+        GridGeometry grid = new GridGeometry(extent, PixelInCell.CELL_CENTER, MathTransforms.identity(2),
HardCodedCRS.WGS84);
+        GeneralEnvelope expected = new GeneralEnvelope(new double[] {-0.5, -0.5}, new double[]
{125.5, 196.5});
+        assertEnvelopeEquals(expected, grid.getEnvelope(), STRICT);
+        /*
+         * Derive a new grid geometry with 10×10 times more cells. The geographic area should
be unchanged.
+         */
+        extent = extent.resize(1260, 1970);
+        grid = grid.derive().resize(extent, 0.1, 0.1).build();
+        assertEnvelopeEquals(expected, grid.getEnvelope(), STRICT);
+        /*
+         * If we try to create a grid geometry with identical properties, the envelope computed
by that grid geometry would
+         * be different than the envelope computed above if the "grid to CRS" transforms
are not correctly adjusted.
+         */
+        final GridGeometry alternative = new GridGeometry(grid.getExtent(), PixelInCell.CELL_CENTER,
+                 grid.getGridToCRS(PixelInCell.CELL_CENTER), grid.getCoordinateReferenceSystem());
+        assertEnvelopeEquals(expected, alternative.getEnvelope(), STRICT);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
index 7544a93..3ef0fca 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.operation.transform;
 
 import java.util.Map;
 import java.util.List;
+import java.util.Arrays;
 import java.util.Collections;
 import java.awt.geom.AffineTransform;
 import org.opengis.util.FactoryException;
@@ -88,6 +89,36 @@ public final class MathTransforms extends Static {
     }
 
     /**
+     * Creates an affine transform which applies the same translation for all dimensions.
+     * For each dimension, input values <var>x</var> are converted into output
values <var>y</var>
+     * using the following equation:
+     *
+     * <blockquote><var>y</var> = <var>x</var> + {@code offset}</blockquote>
+     *
+     * @param  dimension  the input and output dimensions.
+     * @param  offset     the {@code offset} term in the linear equation.
+     * @return the linear transform for the given offset.
+     *
+     * @since 1.0
+     */
+    public static LinearTransform uniformTranslation(final int dimension, final double offset)
{
+        ArgumentChecks.ensurePositive("dimension", dimension);
+        if (offset == 0) {
+            return IdentityTransform.create(dimension);
+        }
+        switch (dimension) {
+            case 0:  return IdentityTransform.create(0);
+            case 1:  return LinearTransform1D.create(1, offset);
+            case 2:  return new AffineTransform2D(1, 0, 0, 1, offset, offset);
+            default: {
+                final double[] vector = new double[dimension];
+                Arrays.fill(vector, offset);
+                return new TranslationTransform(vector);
+            }
+        }
+    }
+
+    /**
      * Creates a transform which applies the given translation.
      * The source and target dimensions of the transform are the length of the given vector.
      *


Mime
View raw message