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 56de57f5b7 Add a `GridGeometry.getOrigin()` method.
56de57f5b7 is described below

commit 56de57f5b7045b2f5e34c63d798dc9b3d7edde28
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Dec 6 17:20:50 2024 +0100

    Add a `GridGeometry.getOrigin()` method.
---
 .../org/apache/sis/coverage/grid/GridGeometry.java | 211 ++++++++++++++++-----
 .../apache/sis/coverage/grid/GridGeometryTest.java |  15 +-
 2 files changed, 179 insertions(+), 47 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
index 7007c688a7..54810c7869 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
@@ -174,6 +174,14 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      */
     public static final int GRID_TO_CRS = 8;
 
+    /**
+     * A bitmask to specify the validity of the "real world" coordinates of 
cell at indices (0, 0, …, 0).
+     *
+     * @see #getOrigin()
+     * @since 1.5
+     */
+    public static final int ORIGIN = 128;
+
     /**
      * A bitmask to specify the validity of the grid resolution.
      *
@@ -999,12 +1007,19 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      *         i.e. <code>{@linkplain #isDefined(int) isDefined}({@linkplain 
#ENVELOPE})</code> returned {@code false}.
      */
     public Envelope getEnvelope() {
-        if (envelope != null && !envelope.isAllNaN()) {
+        if (!isEnvelopeUndefined()) {
             return envelope;
         }
         throw incomplete(ENVELOPE, (extent == null) ? 
Resources.Keys.UnspecifiedGridExtent : Resources.Keys.UnspecifiedTransform);
     }
 
+    /**
+     * Returns {@code true} if the envelope is null or undefined (all 
coordinates set to NaN).
+     */
+    private boolean isEnvelopeUndefined() {
+        return (envelope == null) || envelope.isAllNaN();
+    }
+
     /**
      * Returns the "real world" bounding box of this grid geometry transformed 
to the given CRS.
      * This envelope is computed from the {@linkplain #getExtent() grid 
extent} if available,
@@ -1143,6 +1158,46 @@ public class GridGeometry implements LenientComparable, 
Serializable {
         return times;
     }
 
+    /**
+     * Returns the "real world" coordinates of the cell at indices (0, 0, … 0).
+     * The returned coordinates map the {@linkplain PixelInCell#CELL_CORNER 
cell corner}.
+     * This method computes the origin from the "grid to CRS" transform if 
available.
+     * If that transform is not available, then the minimal coordinate values 
of the
+     * {@linkplain #getEnvelope() envelope} are returned.
+     *
+     * @return the "real world" coordinates of the cell at indices (0, 0, … 0).
+     * @throws IncompleteGridGeometryException if this grid geometry has no 
origin —
+     *         i.e. <code>{@linkplain #isDefined(int) isDefined}({@linkplain 
#ORIGIN})</code> returned {@code false}.
+     *
+     * @since 1.5
+     */
+    public double[] getOrigin() {
+        if (cornerToCRS == null) {
+            if (isEnvelopeUndefined()) {
+                throw incomplete(ORIGIN, Resources.Keys.UnspecifiedTransform);
+            }
+            return getEnvelope().getLowerCorner().getCoordinates();
+        }
+        final double[] origin = new double[cornerToCRS.getTargetDimensions()];
+        final Matrix matrix = MathTransforms.getMatrix(cornerToCRS);
+        if (matrix != null) {
+            final int lastColumn = matrix.getNumCol() - 1;
+            for (int j=0; j < origin.length; j++) {
+                if (Double.isNaN(origin[j] = matrix.getElement(j, 
lastColumn))) {
+                    final Matrix other = MathTransforms.getMatrix(gridToCRS);
+                    if (other != null) {
+                        origin[j] = other.getElement(j, lastColumn);
+                    }
+                }
+            }
+        } else try {
+            cornerToCRS.transform(new 
double[cornerToCRS.getSourceDimensions()], 0, origin, 0, 1);
+        } catch (TransformException e) {
+            throw new IllegalGridGeometryException(e, "gridToCRS");
+        }
+        return origin;
+    }
+
     /**
      * Returns an <em>estimation</em> of the grid resolution, in units of the 
coordinate reference system axes.
      * The length of the returned array is the number of CRS dimensions, with 
{@code resolution[0]}
@@ -1266,8 +1321,8 @@ public class GridGeometry implements LenientComparable, 
Serializable {
     private static long findNonLinearTargets(final MathTransform gridToCRS) {
         long nonLinearDimensions = 0;
         for (final MathTransform step : MathTransforms.getSteps(gridToCRS)) {
-            final Matrix mat = MathTransforms.getMatrix(step);
-            if (mat != null) {
+            final Matrix matrix = MathTransforms.getMatrix(step);
+            if (matrix != null) {
                 /*
                  * For linear transforms there are no bits to set. However if 
some bits were set by a previous
                  * iteration, we may need to move them (for example the 
transform may swap axes). We take the
@@ -1277,8 +1332,8 @@ public class GridGeometry implements LenientComparable, 
Serializable {
                 nonLinearDimensions = 0;
                 while (mask != 0) {
                     final int i = Long.numberOfTrailingZeros(mask);         // 
Source dimension of non-linear part
-                    for (int j = mat.getNumRow() - 1; --j >= 0;) {          // 
Possible target dimensions
-                        if (mat.getElement(j, i) != 0) {
+                    for (int j = matrix.getNumRow() - 1; --j >= 0;) {       // 
Possible target dimensions
+                        if (matrix.getElement(j, i) != 0) {
                             if (j >= Long.SIZE) {
                                 throw excessiveDimension(gridToCRS);
                             }
@@ -1393,7 +1448,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      * methods will not throw {@link IncompleteGridGeometryException}.
      *
      * @param  bitmask  any combination of {@link #CRS}, {@link #ENVELOPE}, 
{@link #EXTENT},
-     *         {@link #GRID_TO_CRS} and {@link #RESOLUTION}.
+     *         {@link #GRID_TO_CRS} and derived bit masks.
      * @return {@code true} if all specified properties are defined (i.e. 
invoking the
      *         corresponding getter methods will not throw {@link 
IncompleteGridGeometryException}).
      * @throws IllegalArgumentException if the specified bitmask is not a 
combination of known masks.
@@ -1405,13 +1460,14 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      * @see #getGridToCRS(PixelInCell)
      */
     public boolean isDefined(final int bitmask) {
-        if ((bitmask & ~(CRS | ENVELOPE | EXTENT | GRID_TO_CRS | RESOLUTION | 
GEOGRAPHIC_EXTENT | TEMPORAL_EXTENT)) != 0) {
+        if ((bitmask & ~(CRS | ENVELOPE | EXTENT | GRID_TO_CRS | ORIGIN | 
RESOLUTION | GEOGRAPHIC_EXTENT | TEMPORAL_EXTENT)) != 0) {
             throw new 
IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, 
"bitmask", bitmask));
         }
         return ((bitmask & CRS)               == 0 || (null != 
getCoordinateReferenceSystem(envelope)))
-            && ((bitmask & ENVELOPE)          == 0 || (null != envelope && 
!envelope.isAllNaN()))
+            && ((bitmask & ENVELOPE)          == 0 || !isEnvelopeUndefined())
             && ((bitmask & EXTENT)            == 0 || (null != extent))
             && ((bitmask & GRID_TO_CRS)       == 0 || (null != gridToCRS))
+            && ((bitmask & ORIGIN)            == 0 || (null != gridToCRS || 
!isEnvelopeUndefined()))
             && ((bitmask & RESOLUTION)        == 0 || (null != resolution))
             && ((bitmask & GEOGRAPHIC_EXTENT) == 0 || (null != 
geographicBBox()))
             && ((bitmask & TEMPORAL_EXTENT)   == 0 || (timeRange().length != 
0));
@@ -1809,14 +1865,36 @@ public class GridGeometry implements LenientComparable, 
Serializable {
     /**
      * Returns the default set of flags to use for {@link #toString()} 
implementations.
      * Current implementation returns all core properties, augmented with only 
derived
-     * properties that are defined.
+     * properties that are defined and that are not redundant with other 
properties.
      */
     final int defaultFlags() {
         int flags = EXTENT | GRID_TO_CRS | CRS;
-        if (null != envelope)         flags |= ENVELOPE;
-        if (null != resolution)       flags |= RESOLUTION;
-        if (null != geographicBBox()) flags |= GEOGRAPHIC_EXTENT;
-        if (timeRange().length != 0)  flags |= TEMPORAL_EXTENT;
+        if (envelope != null) flags |= ENVELOPE;
+        final Matrix matrix = MathTransforms.getMatrix(gridToCRS);
+        if (matrix != null) {
+            final int lastColumn = matrix.getNumCol() - 1;
+            for (int j = matrix.getNumRow() - 1; --j >= 0;) {
+                if (Double.isNaN(matrix.getElement(j, lastColumn))) {
+                    final Matrix other = MathTransforms.getMatrix(cornerToCRS);
+                    if (other != null && !Double.isNaN(other.getElement(j, 
lastColumn))) {
+                        // Found an information which will not be visible in 
the "Conversion" section.
+                        flags |= ORIGIN;
+                        break;
+                    }
+                }
+            }
+        } else if (gridToCRS != null) {
+            flags |= ORIGIN;
+        }
+        if (resolution != null && isEnvelopeUndefined()) {
+            flags |= RESOLUTION;
+        }
+        if (geographicBBox() != null) {
+            flags |= GEOGRAPHIC_EXTENT;
+        }
+        if (timeRange().length != 0) {
+            flags |= TEMPORAL_EXTENT;
+        }
         return flags;
     }
 
@@ -1839,7 +1917,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      *
      * @param  locale   the locale to use for textual labels.
      * @param  bitmask  combination of {@link #EXTENT}, {@link #ENVELOPE}, 
{@link #CRS}, {@link #GRID_TO_CRS},
-     *                  {@link #RESOLUTION}, {@link #GEOGRAPHIC_EXTENT} and 
{@link #TEMPORAL_EXTENT}.
+     *                  {@link #ORIGIN}, {@link #RESOLUTION}, {@link 
#GEOGRAPHIC_EXTENT} and {@link #TEMPORAL_EXTENT}.
      * @return a tree representation of the specified elements.
      */
     @Debug
@@ -1856,7 +1934,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      * Formats a string representation of this grid geometry in the specified 
tree.
      */
     final void formatTo(final Locale locale, final Vocabulary vocabulary, 
final int bitmask, final TreeTable.Node root) {
-        if ((bitmask & ~(EXTENT | ENVELOPE | CRS | GRID_TO_CRS | RESOLUTION | 
GEOGRAPHIC_EXTENT | TEMPORAL_EXTENT)) != 0) {
+        if ((bitmask & ~(EXTENT | ENVELOPE | CRS | GRID_TO_CRS | ORIGIN | 
RESOLUTION | GEOGRAPHIC_EXTENT | TEMPORAL_EXTENT)) != 0) {
             throw new IllegalArgumentException(Errors.format(
                     Errors.Keys.IllegalArgumentValue_2, "bitmask", bitmask));
         }
@@ -1872,8 +1950,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      */
     private final class Formatter {
         /**
-         * Combination of {@link #EXTENT}, {@link #ENVELOPE}, {@link #CRS}, 
{@link #GRID_TO_CRS},
-         * {@link #RESOLUTION}, {@link #GEOGRAPHIC_EXTENT} and {@link 
#TEMPORAL_EXTENT}.
+         * Combination of {@link #EXTENT}, {@link #ENVELOPE}, {@link #CRS}, 
{@link #GRID_TO_CRS} and derived bit masks.
          */
         private final int bitmask;
 
@@ -1913,18 +1990,33 @@ public class GridGeometry implements LenientComparable, 
Serializable {
          */
         private final CoordinateSystem cs;
 
+        /**
+         * The format to use for formatting numbers. Created when first needed.
+         */
+        private NumberFormat numberFormat;
+
         /**
          * Creates a new formatter for the given combination of {@link 
#EXTENT}, {@link #ENVELOPE},
-         * {@link #CRS}, {@link #GRID_TO_CRS} and {@link #RESOLUTION}.
+         * {@link #CRS}, {@link #GRID_TO_CRS} and derived bit masks.
          */
         Formatter(final Locale locale, final Vocabulary vocabulary, final int 
bitmask, final TreeTable.Node out) {
-            this.root          = out;
-            this.bitmask       = bitmask;
-            this.buffer        = new StringBuilder(256);
-            this.locale        = locale;
-            this.vocabulary    = vocabulary;
-            this.crs           = getCoordinateReferenceSystem(envelope);
-            this.cs            = (crs != null) ? crs.getCoordinateSystem() : 
null;
+            this.root       = out;
+            this.bitmask    = bitmask;
+            this.buffer     = new StringBuilder(256);
+            this.locale     = locale;
+            this.vocabulary = vocabulary;
+            this.crs        = getCoordinateReferenceSystem(envelope);
+            this.cs         = (crs != null) ? crs.getCoordinateSystem() : null;
+        }
+
+        /**
+         * Returns the object to use for formatting numbers.
+         */
+        private NumberFormat numberFormat() {
+            if (numberFormat == null) {
+                numberFormat = NumberFormat.getNumberInstance(locale);
+            }
+            return numberFormat;
         }
 
         /**
@@ -2005,10 +2097,10 @@ public class GridGeometry implements LenientComparable, 
Serializable {
              * Those numbers vary for each line depending on the envelope 
values and the resolution at that line.
              */
             if (section(ENVELOPE, Vocabulary.Keys.Envelope, true, false)) {
-                final boolean appendResolution = (bitmask & RESOLUTION) != 0 
&& resolution != null;
+                final boolean appendResolution = (bitmask & RESOLUTION) != 0 
&& (resolution != null);
                 final TableAppender table = new TableAppender(buffer, "");
                 final int dimension = envelope.getDimension();
-                final NumberFormat nf = NumberFormat.getNumberInstance(locale);
+                final NumberFormat nf = numberFormat();
                 for (int i=0; i<dimension; i++) {
                     final double lower = envelope.getLower(i);
                     final double upper = envelope.getUpper(i);
@@ -2031,26 +2123,33 @@ public class GridGeometry implements LenientComparable, 
Serializable {
                         }
                         table.nextColumn();
                         table.append(' ').append(isLinear ? '=' : 
'≈').append(' ');
-                        appendResolution(table, nf, delta, i);
+                        append(table, delta, Double.NaN, i);
                     }
                     table.nextLine();
                 }
                 table.flush();
                 writeNodes();
-            } else if (section(RESOLUTION, Vocabulary.Keys.Resolution, true, 
false)) {
+                nf.setMinimumFractionDigits(0);
+            }
+            if (section(ORIGIN, Vocabulary.Keys.Origin, true, false)) {
+                /*
+                 * Example: Origin
+                 * └─ 20° 30°
+                 */
+                buffer.append('(');
+                append(getOrigin(), resolution, "  ");
+                buffer.append(')');
+                writeNode();
+            }
+            if (section(RESOLUTION, Vocabulary.Keys.Resolution, true, false)) {
                 /*
                  * Example: Resolution
                  * └─ 0.5° × 0.5°
                  *
-                 * Formatted only as a fallback if the envelope was not 
formatted.
+                 * By default, this is formatted only as a fallback if the 
envelope was not formatted.
                  * Otherwise, this information is already part of above 
envelope.
                  */
-                String separator = "";
-                final NumberFormat nf = NumberFormat.getNumberInstance(locale);
-                for (int i=0; i < resolution.length; i++) {
-                    appendResolution(buffer.append(separator), nf, 
resolution[i], i);
-                    separator = " × ";
-                }
+                append(resolution, null, " × ");
                 writeNode();
             }
             /*
@@ -2094,7 +2193,7 @@ public class GridGeometry implements LenientComparable, 
Serializable {
         /**
          * Starts a new section for the given property.
          *
-         * @param  property    one of {@link #EXTENT}, {@link #ENVELOPE}, 
{@link #CRS}, {@link #GRID_TO_CRS} and {@link #RESOLUTION}.
+         * @param  property    one of {@link #EXTENT}, {@link #ENVELOPE}, 
{@link #CRS}, {@link #GRID_TO_CRS} and derived bit masks.
          * @param  title       the {@link Vocabulary} key for the title to 
show for this section, if formatted.
          * @param  mandatory   whether to write "undefined" if the property is 
undefined.
          * @param  cellCenter  whether to add a "origin in cell center" text 
in the title. This is relevant only for conversion.
@@ -2150,19 +2249,39 @@ public class GridGeometry implements LenientComparable, 
Serializable {
         }
 
         /**
-         * Appends a single value on the resolution line, together with its 
unit of measurement.
+         * Appends the given values with their units of measurement.
+         *
+         * @param  values      the values to write.
+         * @param  resolution  the resolution of the values, or {@link 
Double#NaN} is unknown.
+         * @param  separator   the separator to insert between values.
+         */
+        private void append(final double[] values, final double[] resolution, 
final String separator) throws IOException {
+            for (int i=0; i < values.length; i++) {
+                if (i != 0) buffer.append(separator);
+                double delta = (resolution != null) ? resolution[i] : 
Double.NaN;
+                append(buffer, values[i], delta, i);
+            }
+        }
+
+        /**
+         * Appends a single value with a number of digits determined by the 
resolution.
+         * Appends also the unit of measurement.
          *
-         * @param  out  where to write the resolution.
-         * @param  nf   number format to use for writing the number.
-         * @param  res  the resolution to write, or {@link Double#NaN}.
-         * @param  dim  index of the coordinate system axis of the resolution.
+         * @param  out    where to write the value.
+         * @param  value  the value to write (may be {@link Double#NaN}).
+         * @param  delta  the resolution of the value, or {@link Double#NaN} 
is unknown.
+         * @param  dim    index of the coordinate system axis of the value.
          */
-        private void appendResolution(final Appendable out, final NumberFormat 
nf, final double res, final int dim) throws IOException {
-            if (Double.isNaN(res)) {
+        private void append(final Appendable out, final double value, final 
double delta, final int dim) throws IOException {
+            if (Double.isNaN(value)) {
                 out.append('?');
             } else {
-                
nf.setMaximumFractionDigits(Numerics.suggestFractionDigits(res) / 2);
-                out.append(nf.format(res));
+                final NumberFormat nf = numberFormat();
+                final int n = Double.isNaN(delta)
+                        ? Numerics.suggestFractionDigits(value) / 2
+                        : Numerics.fractionDigitsForDelta(delta);
+                nf.setMaximumFractionDigits(n + 1);
+                out.append(nf.format(value));
             }
             if (cs != null) {
                 final String unit = String.valueOf(cs.getAxis(dim).getUnit());
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridGeometryTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridGeometryTest.java
index 3b1d182cbc..810f98b75f 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridGeometryTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridGeometryTest.java
@@ -148,6 +148,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[4], grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {1, 1, 1, 1}, 
grid.getResolution(false), "resolution");
         assertTrue(grid.isConversionLinear(0, 1, 2, 3), "isConversionLinear");
         verifyGridToCRS(grid);
@@ -192,6 +193,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[] {-0.5, -0.5, -0.5}, grid.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {1, 1, 1}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
         verifyGridToCRS(grid);
@@ -224,6 +226,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[] {5, 7, 8}, grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {2, 1, 3}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
         verifyGridToCRS(grid);
@@ -301,6 +304,7 @@ public final class GridGeometryTest extends TestCase {
         final MathTransform temporal  = MathTransforms.linear(3600, 60);
         final MathTransform gridToCRS = MathTransforms.compound(horizontal, 
vertical, temporal);
         final GridGeometry  grid      = new GridGeometry(extent, 
PixelInCell.CELL_CENTER, gridToCRS, null);
+        assertArrayEquals(new double[] {11.75, -2.125, 0.5, -1740}, 
grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {0.5, 0.25,        6.0, 3600}, 
grid.getResolution(true),  "resolution");
         assertArrayEquals(new double[] {0.5, 0.25, Double.NaN, 3600}, 
grid.getResolution(false), "resolution");
         assertFalse(grid.isConversionLinear(0, 1, 2, 3), "isConversionLinear");
@@ -327,7 +331,6 @@ public final class GridGeometryTest extends TestCase {
         assertEnvelopeEquals(new GeneralEnvelope(
                 new double[] {-70,  5},
                 new double[] {+80, 15}), grid.getEnvelope(), STRICT);
-        assertArrayEquals(new double[] {0.5, 0.5}, grid.getResolution(false), 
"resolution");
         assertMatrixEquals(new Matrix3(0,   0.5, -89.75,
                                        0.5, 0,  -179.75,
                                        0,   0,     1),
@@ -335,6 +338,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[] {-90, -180}, grid.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {0.5, 0.5}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
         verifyGridToCRS(grid);
@@ -366,6 +370,7 @@ public final class GridGeometryTest extends TestCase {
                 matrix, STRICT, "cornerToCRS");
 
         // Verify other computed properties.
+        assertArrayEquals(new double[] {50, 40}, grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
         assertSame(extent, grid.getExtent(), "extent");
@@ -382,6 +387,7 @@ public final class GridGeometryTest extends TestCase {
                 matrix, STRICT, "cornerToCRS");
 
         // Verify other computed properties.
+        assertArrayEquals(new double[] {50, 20}, grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
         assertSame(extent, grid.getExtent(), "extent");
@@ -423,6 +429,7 @@ public final class GridGeometryTest extends TestCase {
                 matrix, STRICT, "cornerToCRS");
 
         // Verify other computed properties.
+        assertArrayEquals(new double[] {50, 20}, grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
         assertSame(extent, grid.getExtent(), "extent");
@@ -443,6 +450,7 @@ public final class GridGeometryTest extends TestCase {
                 new long[] {  9,  14}, grid.getExtent());
 
         // Verify other computed properties.
+        assertArrayEquals(new double[] {50, 20}, grid.getOrigin(), "origin");
         assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), 
"resolution");
         assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
         assertNotSame(extent, grid.getExtent(), "extent");
@@ -541,6 +549,7 @@ public final class GridGeometryTest extends TestCase {
         }
         assertSame(grid.getEnvelope(), upsampled.getEnvelope(), "envelope");
         assertEquals(expected, upsampled, "GridGeometry");
+        assertArrayEquals(new double[] {9.5, 51}, expected.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {0.25, 0.5}, 
expected.getResolution(false), "resolution");
     }
 
@@ -614,6 +623,7 @@ public final class GridGeometryTest extends TestCase {
         assertNotSame(grid, reduced);
         assertExtentEquals(new long[] {336, 20}, new long[] {401, 419}, 
reduced.getExtent());
         assertSame(HardCodedCRS.WGS84, reduced.getCoordinateReferenceSystem(), 
"CRS");
+        assertArrayEquals(new double[] {-90, -180}, reduced.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {0.5, 0.5}, 
reduced.getResolution(false), "resolution");
         assertMatrixEquals(new Matrix3(0, 0.5,  -90,
                                        0.5, 0, -180,
@@ -626,6 +636,7 @@ public final class GridGeometryTest extends TestCase {
         assertNotSame(grid, reduced);
         assertExtentEquals(new long[] {4}, new long[] {10}, 
reduced.getExtent());
         assertSame(HardCodedCRS.GRAVITY_RELATED_HEIGHT, 
reduced.getCoordinateReferenceSystem(), "CRS");
+        assertArrayEquals(new double[] {3}, reduced.getOrigin(), "origin");
         assertArrayEquals(new double[] {2}, reduced.getResolution(false), 
"resolution");
         assertMatrixEquals(new Matrix2(2, 3, 0, 1),
                 
MathTransforms.getMatrix(reduced.getGridToCRS(PixelInCell.CELL_CORNER)),
@@ -633,6 +644,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[] {-90, -180, 3}, grid.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {0.5, 0.5, 2}, 
grid.getResolution(false), "resolution");
         assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
         verifyGridToCRS(grid);
@@ -668,6 +680,7 @@ public final class GridGeometryTest extends TestCase {
         /*
          * Verify other computed properties.
          */
+        assertArrayEquals(new double[] {-90, -180}, reduced.getOrigin(), 
"origin");
         assertArrayEquals(new double[] {0.5, 0.5}, 
reduced.getResolution(false), "resolution");
         assertTrue(reduced.isConversionLinear(0, 1), "isConversionLinear");
         verifyGridToCRS(reduced);

Reply via email to