You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2023/11/24 18:06:19 UTC
(sis) 03/04: Add a `GridGeometry` constructor doing the concatenation of two grid geometries. Opportunistic migration of JUnit 4 to JUnit 5 for the relevant tests.
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 ca8241da59f6885fc6d5446ee9589890c2d3cebb
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Nov 24 16:28:54 2023 +0100
Add a `GridGeometry` constructor doing the concatenation of two grid geometries.
Opportunistic migration of JUnit 4 to JUnit 5 for the relevant tests.
---
.../org/apache/sis/coverage/grid/GridExtent.java | 29 ++++-
.../org/apache/sis/coverage/grid/GridGeometry.java | 63 +++++++++-
.../apache/sis/coverage/grid/GridExtentTest.java | 113 +++++++++--------
.../apache/sis/coverage/grid/GridGeometryTest.java | 140 +++++++++++++--------
.../main/org/apache/sis/util/ArraysExt.java | 20 ++-
5 files changed, 260 insertions(+), 105 deletions(-)
diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
index 352247f403..62d68bb38b 100644
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
@@ -91,7 +91,7 @@ import org.opengis.coverage.grid.GridCoordinates;
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Alexis Manin (Geomatys)
* @author Johann Sorel (Geomatys)
- * @version 1.4
+ * @version 1.5
* @since 1.0
*/
public class GridExtent implements GridEnvelope, LenientComparable, Serializable {
@@ -354,6 +354,33 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
validateCoordinates();
}
+ /**
+ * Creates a new grid extent as the concatenation of the two specified grid extent.
+ * The number of dimensions of the new extent is the sum of the number of dimensions
+ * of the two specified extents. The dimensions of the lower extent are first,
+ * followed by the dimensions of the upper extent.
+ *
+ * @param lower the grid extent providing the lowest dimensions.
+ * @param upper the grid extent providing the highest dimensions.
+ * @throws IllegalArgumentException if the concatenation results in duplicated {@linkplain #getAxisType(int) axis types}.
+ *
+ * @since 1.5
+ */
+ public GridExtent(final GridExtent lower, final GridExtent upper) {
+ final int d1 = lower.getDimension();
+ final int d2 = upper.getDimension();
+ final int dim = d1 + d2;
+ final var axisTypes = new DimensionNameType[dim];
+ if (lower.types != null) System.arraycopy(lower.types, 0, axisTypes, 0, d1);
+ if (upper.types != null) System.arraycopy(upper.types, 0, axisTypes, d1, d2);
+ types = validateAxisTypes(axisTypes);
+ coordinates = allocate(dim);
+ System.arraycopy(lower.coordinates, 0, coordinates, 0, d1);
+ System.arraycopy(upper.coordinates, 0, coordinates, d1, d2);
+ System.arraycopy(lower.coordinates, d1, coordinates, dim, d1);
+ System.arraycopy(upper.coordinates, d2, coordinates, dim+d1, d2);
+ }
+
/**
* Infers the axis types from the given coordinate reference system.
* This method is the converse of {@link GridExtentCRS}.
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 3389b1a534..464b9644bd 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
@@ -747,6 +747,66 @@ public class GridGeometry implements LenientComparable, Serializable {
}
}
+ /**
+ * Creates a new grid geometry as the concatenation of the two specified grid geometries.
+ * The number of dimensions of the new grid geometry is the sum of the number of dimensions
+ * of the two specified grid geometries. The dimensions of the lower grid geometry are first,
+ * followed by the dimensions of the upper grid geometry.
+ *
+ * @param lower the grid geometry providing the lowest dimensions.
+ * @param upper the grid geometry providing the highest dimensions.
+ * @throws IncompleteGridGeometryException if a property presents in one grid geometry is absent in the other.
+ * @throws IllegalArgumentException if the concatenation results in duplicated
+ * {@linkplain GridExtent#getAxisType(int) grid axis types}.
+ * @throws FactoryException if the geodetic factory failed to create the compound CRS.
+ *
+ * @see #selectDimensions(int...)
+ *
+ * @since 1.5
+ */
+ public GridGeometry(final GridGeometry lower, final GridGeometry upper) throws FactoryException {
+ /*
+ * Concatenate the extents first because they perform a check for axis duplication.
+ * We set the extent to null only if both `lower` and `upper` have a null extent.
+ * Otherwise, invoke `getExtent()` for causing an `IncompleteGridGeometryException`
+ * to be thrown if only one grid geometry has an extent.
+ */
+ extent = (lower.extent == null && upper.extent == null) ? null
+ : new GridExtent(lower.getExtent(), upper.getExtent());
+ /*
+ * Concatenate the "grid to CRS" transforms and derived information
+ * (resolutions and non-linearity).
+ */
+ if (lower.gridToCRS == null && upper.gridToCRS == null) {
+ gridToCRS = null;
+ cornerToCRS = null;
+ } else {
+ gridToCRS = compound(lower, upper, PixelInCell.CELL_CENTER);
+ cornerToCRS = compound(lower, upper, PixelInCell.CELL_CORNER);
+ }
+ nonLinears = lower.nonLinears | (upper.nonLinears << lower.getDimension());
+ resolution = (lower.resolution == null && upper.resolution == null) ? null
+ : ArraysExt.concatenate(lower.getResolution(true), upper.getResolution(true));
+ /*
+ * The check for presence/absence of envelope is more complex because an envelope
+ * may be considered missing, but still be non-null in order to store the CRS.
+ */
+ if (lower.envelope == null && upper.envelope == null) {
+ envelope = null;
+ } else {
+ Envelope e1 = lower.envelope; if (e1 == null) e1 = lower.getEnvelope();
+ Envelope e2 = upper.envelope; if (e2 == null) e2 = upper.getEnvelope();
+ envelope = ImmutableEnvelope.castOrCopy(Envelopes.compound(e1, e2));
+ }
+ }
+
+ /**
+ * Aggregates the dimensions of the "grid to CRS" transforms of the given grid geometries.
+ */
+ private static MathTransform compound(final GridGeometry lower, final GridGeometry upper, final PixelInCell anchor) {
+ return MathTransforms.compound(lower.getGridToCRS(anchor), upper.getGridToCRS(anchor));
+ }
+
/**
* Converts a "grid to CRS" transform from "cell corner" convention to "cell center" convention.
* This is a helper method for use of {@link #GridGeometry(GridExtent, MathTransform, MathTransform,
@@ -1542,7 +1602,8 @@ public class GridGeometry implements LenientComparable, Serializable {
* The number of dimensions of the sub grid geometry will be {@code dimensions.length}.
*
* <p>This method performs a <cite>dimensionality reduction</cite>.
- * This method cannot be used for changing dimension order.</p>
+ * This method cannot be used for changing dimension order.
+ * The converse operation is the {@linkplain #GridGeometry(GridGeometry, GridGeometry) concatenation}.</p>
*
* @param indices the grid (not CRS) dimensions to select, in strictly increasing order.
* @return the sub-grid geometry, or {@code this} if the given array contains all dimensions of this grid geometry.
diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
index b9f3646dae..c9afd55f9b 100644
--- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
+++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
@@ -37,7 +37,8 @@ import org.apache.sis.util.internal.Numerics;
// Test dependencies
import org.junit.Test;
-import static org.junit.Assert.*;
+import org.junit.jupiter.api.DisplayName;
+import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.TestCase;
import org.apache.sis.referencing.crs.HardCodedCRS;
import static org.apache.sis.test.Assertions.assertMapEquals;
@@ -77,10 +78,10 @@ public final class GridExtentTest extends TestCase {
* Verifies the low and high values in the specified dimension of the given extent
*/
static void assertExtentEquals(final GridExtent extent, final int dimension, final int low, final int high) {
- assertEquals("low", low, extent.getLow (dimension));
- assertEquals("high", high, extent.getHigh(dimension));
- assertEquals("size", high - low + 1, extent.getSize(dimension));
- assertEquals("median", Numerics.ceilDiv(high + low, 2), extent.getMedian(dimension));
+ assertEquals(low, extent.getLow (dimension), "low");
+ assertEquals(high, extent.getHigh(dimension), "high");
+ assertEquals(high - low + 1, extent.getSize(dimension), "size");
+ assertEquals(Numerics.ceilDiv(high + low, 2), extent.getMedian(dimension), "median");
}
/**
@@ -185,7 +186,7 @@ public final class GridExtentTest extends TestCase {
GridExtent extent = new GridExtent(new DimensionNameType[] {DimensionNameType.COLUMN, DimensionNameType.ROW},
new long[] {100, 200}, new long[] {500, 800}, true);
extent = extent.insertDimension(offset, DimensionNameType.TIME, 40, 50, false);
- assertEquals("dimension", 3, extent.getDimension());
+ assertEquals(3, extent.getDimension(), "dimension");
assertExtentEquals(extent, 0, 100, 500);
assertExtentEquals(extent, rowIndex, 200, 800);
assertExtentEquals(extent, offset, 40, 49);
@@ -201,14 +202,14 @@ public final class GridExtentTest extends TestCase {
public void testSelectDimensions() {
final GridExtent extent = create3D();
GridExtent reduced = extent.selectDimensions(0, 1);
- assertEquals("dimension", 2, reduced.getDimension());
+ assertEquals(2, reduced.getDimension(), "dimension");
assertExtentEquals(reduced, 0, 100, 499);
assertExtentEquals(reduced, 1, 200, 799);
assertEquals(DimensionNameType.COLUMN, reduced.getAxisType(0).get());
assertEquals(DimensionNameType.ROW, reduced.getAxisType(1).get());
reduced = extent.selectDimensions(2);
- assertEquals("dimension", 1, reduced.getDimension());
+ assertEquals(1, reduced.getDimension(), "dimension");
assertExtentEquals(reduced, 0, 40, 49);
assertEquals(DimensionNameType.TIME, reduced.getAxisType(0).get());
}
@@ -294,12 +295,8 @@ public final class GridExtentTest extends TestCase {
assertExtentEquals(extent, 2, 40, 46);
assertSame(extent.intersect(domain), extent);
final GridExtent disjoint = domain.translate(0, 1000);
- try {
- extent.intersect(disjoint);
- fail("Expected DisjointExtentException.");
- } catch (DisjointExtentException e) {
- assertNotNull(e.getMessage());
- }
+ String message = assertThrows(DisjointExtentException.class, () -> extent.intersect(disjoint)).getMessage();
+ assertNotNull(message);
}
/**
@@ -325,12 +322,30 @@ public final class GridExtentTest extends TestCase {
final GridExtent other = new GridExtent(
new DimensionNameType[] {DimensionNameType.COLUMN, DimensionNameType.TRACK, DimensionNameType.TIME},
new long[] {100, 200, 40}, new long[] {500, 800, 50}, false);
- try {
- domain.intersect(other);
- fail("Should not be allowed");
- } catch (IllegalArgumentException e) {
- assertNotNull(e.getMessage());
- }
+
+ String message = assertThrows(IllegalArgumentException.class, () -> domain.intersect(other)).getMessage();
+ assertNotNull(message);
+ }
+
+ /**
+ * Tests {@link GridExtent#GridExtent(GridExtent, GridExtent)}.
+ */
+ @Test
+ public void testConcatenate() {
+ final GridExtent domain = create3D();
+ final GridExtent other = new GridExtent(
+ new DimensionNameType[] {DimensionNameType.VERTICAL},
+ new long[] {-4}, new long[] {17}, true);
+ final GridExtent extent = new GridExtent(domain, other);
+
+ assertArrayEquals(new DimensionNameType[] {
+ DimensionNameType.COLUMN, DimensionNameType.ROW, DimensionNameType.TIME, DimensionNameType.VERTICAL
+ }, extent.getAxisTypes());
+
+ assertArrayEquals(new long[] {
+ 100, 200, 40, -4,
+ 499, 799, 49, 17
+ }, extent.getCoordinates());
}
/**
@@ -341,7 +356,7 @@ public final class GridExtentTest extends TestCase {
final GeneralDirectPosition slicePoint = new GeneralDirectPosition(226.7, 47.2);
final GridExtent extent = create3D();
final GridExtent slice = extent.slice(slicePoint, new int[] {1, 2});
- assertEquals("dimension", 3, slice.getDimension());
+ assertEquals(3, slice.getDimension(), "dimension");
assertExtentEquals(slice, 0, 100, 499);
assertExtentEquals(slice, 1, 227, 227);
assertExtentEquals(slice, 2, 47, 47);
@@ -352,13 +367,8 @@ public final class GridExtentTest extends TestCase {
* change in future SIS version).
*/
slicePoint.setOrdinate(0, 900);
- try {
- extent.slice(slicePoint, new int[] {1, 2});
- fail("Expected PointOutsideCoverageException");
- } catch (PointOutsideCoverageException e) {
- final String message = e.getLocalizedMessage();
- assertTrue(message, message.contains("(900, 47)")); // See above comment.
- }
+ String message = assertThrows(PointOutsideCoverageException.class, () -> extent.slice(slicePoint, new int[] {1, 2})).getLocalizedMessage();
+ assertTrue(message.contains("(900, 47)"), message); // See above comment.
}
/**
@@ -372,12 +382,8 @@ public final class GridExtentTest extends TestCase {
assertSubspaceEquals(extent, 0, 2 );
assertSubspaceEquals(extent, 0,1,2 );
assertSubspaceEquals(extent, 0,1,2,3);
- try {
- extent.getSubspaceDimensions(1);
- fail("Should not reduce to 1 dimension.");
- } catch (SubspaceNotSpecifiedException e) {
- assertNotNull(e.getMessage());
- }
+ String message = assertThrows(SubspaceNotSpecifiedException.class, () -> extent.getSubspaceDimensions(1)).getMessage();
+ assertNotNull(message);
}
/**
@@ -508,11 +514,12 @@ public final class GridExtentTest extends TestCase {
* Verifies that a translation of zero cell results in the same {@link GridExtent} instance.
*/
@Test
- public void empty_translation_returns_same_extent_instance() {
+ @DisplayName("Empty translation returns same extent instance")
+ public void testZeroTranslation() {
final GridExtent extent = new GridExtent(10, 10);
- assertSame("Same instance returned in case of no-op", extent, extent.translate());
- assertSame("Same instance returned in case of no-op", extent, extent.translate(0));
- assertSame("Same instance returned in case of no-op", extent, extent.translate(0, 0));
+ assertSame(extent, extent.translate());
+ assertSame(extent, extent.translate(0));
+ assertSame(extent, extent.translate(0, 0));
}
/**
@@ -520,26 +527,27 @@ public final class GridExtentTest extends TestCase {
* than the extent number of dimensions. No translation shall be applied in missing dimensions.
*/
@Test
- public void translating_only_first_dimensions_leave_others_untouched() {
+ @DisplayName("Translating only first dimensions leave others untouched")
+ public void testTranslateOneDimension() {
final GridExtent base = new GridExtent(null, new long[] {
0, 0, 0,
2, 2, 2
});
final GridExtent translatedByX = base.translate(1);
- assertArrayEquals("Lower corner", new long[] {1, 0, 0}, translatedByX.getLow() .getCoordinateValues());
- assertArrayEquals("Upper corner", new long[] {3, 2, 2}, translatedByX.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {1, 0, 0}, translatedByX.getLow() .getCoordinateValues(), "Lower corner");
+ assertArrayEquals(new long[] {3, 2, 2}, translatedByX.getHigh().getCoordinateValues(), "Upper corner");
final GridExtent translatedByY = base.translate(0, -1);
- assertArrayEquals("Lower corner", new long[] {0, -1, 0}, translatedByY.getLow() .getCoordinateValues());
- assertArrayEquals("Upper corner", new long[] {2, 1, 2}, translatedByY.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {0, -1, 0}, translatedByY.getLow() .getCoordinateValues(), "Lower corner");
+ assertArrayEquals(new long[] {2, 1, 2}, translatedByY.getHigh().getCoordinateValues(), "Upper corner");
final GridExtent translatedByXAndY = base.translate(-1, 4);
- assertArrayEquals("Lower corner", new long[] {-1, 4, 0}, translatedByXAndY.getLow() .getCoordinateValues());
- assertArrayEquals("Upper corner", new long[] { 1, 6, 2}, translatedByXAndY.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {-1, 4, 0}, translatedByXAndY.getLow() .getCoordinateValues(), "Lower corner");
+ assertArrayEquals(new long[] { 1, 6, 2}, translatedByXAndY.getHigh().getCoordinateValues(), "Upper corner");
// Paranoiac check: ensure that base extent has been left untouched.
- assertArrayEquals("Base lower corner", new long[] {0, 0, 0}, base.getLow() .getCoordinateValues());
- assertArrayEquals("Base lower corner", new long[] {2, 2, 2}, base.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {0, 0, 0}, base.getLow() .getCoordinateValues(), "Base lower corner");
+ assertArrayEquals(new long[] {2, 2, 2}, base.getHigh().getCoordinateValues(), "Base lower corner");
}
/**
@@ -547,17 +555,18 @@ public final class GridExtentTest extends TestCase {
* when the given vector is long enough.
*/
@Test
- public void translating_all_dimensions() {
+ @DisplayName("Translating all dimensions")
+ public void testTranslateAllDimensions() {
final GridExtent base = new GridExtent(null, new long[] {
-1, -1, -2, 10,
2, 2, 2, 20
});
final GridExtent translated = base.translate(-2, 1, 1, 100);
- assertArrayEquals("Lower corner", new long[] {-3, 0, -1, 110}, translated.getLow() .getCoordinateValues());
- assertArrayEquals("Upper corner", new long[] { 0, 3, 3, 120}, translated.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {-3, 0, -1, 110}, translated.getLow() .getCoordinateValues(), "Lower corner");
+ assertArrayEquals(new long[] { 0, 3, 3, 120}, translated.getHigh().getCoordinateValues(), "Upper corner");
// Paranoiac check: ensure that base extent has been left untouched.
- assertArrayEquals("Base lower corner", new long[] {-1, -1, -2, 10}, base.getLow() .getCoordinateValues());
- assertArrayEquals("Base lower corner", new long[] { 2, 2, 2, 20}, base.getHigh().getCoordinateValues());
+ assertArrayEquals(new long[] {-1, -1, -2, 10}, base.getLow() .getCoordinateValues(), "Base lower corner");
+ assertArrayEquals(new long[] { 2, 2, 2, 20}, base.getHigh().getCoordinateValues(), "Base lower corner");
}
}
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 e0823cdc82..5c2d342226 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
@@ -16,6 +16,7 @@
*/
package org.apache.sis.coverage.grid;
+import org.opengis.util.FactoryException;
import org.opengis.geometry.Envelope;
import org.opengis.metadata.spatial.DimensionNameType;
import org.opengis.referencing.crs.DerivedCRS;
@@ -32,10 +33,11 @@ import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.referencing.util.ExtendedPrecisionMatrix;
+import org.apache.sis.util.ComparisonMode;
// Test dependencies
import org.junit.Test;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.TestCase;
import org.apache.sis.test.DependsOn;
import org.apache.sis.referencing.crs.HardCodedCRS;
@@ -64,8 +66,8 @@ public final class GridGeometryTest extends TestCase {
* Verifies grid extent coordinates.
*/
static void assertExtentEquals(final long[] low, final long[] high, final GridExtent extent) {
- assertArrayEquals("extent.low", low, extent.getLow() .getCoordinateValues());
- assertArrayEquals("extent.high", high, extent.getHigh().getCoordinateValues());
+ assertArrayEquals(low, extent.getLow() .getCoordinateValues(), "extent.low");
+ assertArrayEquals(high, extent.getHigh().getCoordinateValues(), "extent.high");
}
/**
@@ -123,16 +125,16 @@ public final class GridGeometryTest extends TestCase {
* Verify properties that should be stored "as-is".
*/
final MathTransform trCorner = grid.getGridToCRS(PixelInCell.CELL_CORNER);
- assertSame("gridToCRS", identity, trCorner);
+ assertSame(identity, trCorner, "gridToCRS");
assertExtentEquals(low, high, grid.getExtent());
/*
* Verify computed math transform.
*/
final MathTransform trCenter = grid.getGridToCRS(PixelInCell.CELL_CENTER);
assertNotSame(trCenter, trCorner);
- assertFalse ("gridToCRS.isIdentity", trCenter.isIdentity());
- assertEquals("gridToCRS.sourceDimensions", 4, trCenter.getSourceDimensions());
- assertEquals("gridToCRS.targetDimensions", 4, trCenter.getTargetDimensions());
+ assertFalse (trCenter.isIdentity(), "gridToCRS.isIdentity");
+ assertEquals(4, trCenter.getSourceDimensions(), "gridToCRS.sourceDimensions");
+ assertEquals(4, trCenter.getTargetDimensions(), "gridToCRS.targetDimensions");
assertMatrixEquals("gridToCRS", Matrices.create(5, 5, new double[] {
1, 0, 0, 0, 0.5,
0, 1, 0, 0, 0.5,
@@ -148,8 +150,8 @@ public final class GridGeometryTest extends TestCase {
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {1, 1, 1, 1}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1, 2, 3));
+ assertArrayEquals(new double[] {1, 1, 1, 1}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1, 2, 3), "isConversionLinear");
verifyGridToCRS(grid);
}
@@ -168,16 +170,16 @@ public final class GridGeometryTest extends TestCase {
* Verify properties that should be stored "as-is".
*/
final MathTransform trCenter = grid.getGridToCRS(PixelInCell.CELL_CENTER);
- assertSame("gridToCRS", identity, trCenter);
+ assertSame(identity, trCenter, "gridToCRS");
assertExtentEquals(low, high, grid.getExtent());
/*
* Verify computed math transform.
*/
final MathTransform trCorner = grid.getGridToCRS(PixelInCell.CELL_CORNER);
assertNotSame(trCenter, trCorner);
- assertFalse ("gridToCRS.isIdentity", trCorner.isIdentity());
- assertEquals("gridToCRS.sourceDimensions", 3, trCorner.getSourceDimensions());
- assertEquals("gridToCRS.targetDimensions", 3, trCorner.getTargetDimensions());
+ assertFalse (trCorner.isIdentity(), "gridToCRS.isIdentity");
+ assertEquals(3, trCorner.getSourceDimensions(), "gridToCRS.sourceDimensions");
+ assertEquals(3, trCorner.getTargetDimensions(), "gridToCRS.targetDimensions");
assertMatrixEquals("gridToCRS", new Matrix4(
1, 0, 0, -0.5,
0, 1, 0, -0.5,
@@ -192,8 +194,8 @@ public final class GridGeometryTest extends TestCase {
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {1, 1, 1}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1, 2));
+ assertArrayEquals(new double[] {1, 1, 1}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
verifyGridToCRS(grid);
}
@@ -224,8 +226,8 @@ public final class GridGeometryTest extends TestCase {
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {2, 1, 3}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1, 2));
+ assertArrayEquals(new double[] {2, 1, 3}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
verifyGridToCRS(grid);
}
@@ -275,7 +277,7 @@ public final class GridGeometryTest extends TestCase {
0, 1, 0.5,
0, 0, 1));
final GridGeometry grid = new GridGeometry(extent, PixelInCell.CELL_CENTER, gridToCRS, null);
- assertTrue("gridToCRS.isIdentity", grid.getGridToCRS(PixelInCell.CELL_CORNER).isIdentity());
+ assertTrue(grid.getGridToCRS(PixelInCell.CELL_CORNER).isIdentity(), "gridToCRS.isIdentity");
verifyGridToCRS(grid);
}
@@ -301,10 +303,10 @@ 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("resolution", new double[] {0.5, 0.25, 6.0, 3600}, grid.getResolution(true), STRICT);
- assertArrayEquals("resolution", new double[] {0.5, 0.25, Double.NaN, 3600}, grid.getResolution(false), STRICT);
- assertFalse("isConversionLinear", grid.isConversionLinear(0, 1, 2, 3));
- assertTrue ("isConversionLinear", grid.isConversionLinear(0, 1, 3));
+ 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");
+ assertTrue (grid.isConversionLinear(0, 1, 3), "isConversionLinear");
}
/**
@@ -327,7 +329,7 @@ public final class GridGeometryTest extends TestCase {
assertEnvelopeEquals(new GeneralEnvelope(
new double[] {-70, 5},
new double[] {+80, 15}), grid.getEnvelope(), STRICT);
- assertArrayEquals("resolution", new double[] {0.5, 0.5}, grid.getResolution(false), STRICT);
+ assertArrayEquals(new double[] {0.5, 0.5}, grid.getResolution(false), "resolution");
assertMatrixEquals("gridToCRS", new Matrix3(
0, 0.5, -89.75,
0.5, 0, -179.75,
@@ -335,8 +337,8 @@ public final class GridGeometryTest extends TestCase {
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {0.5, 0.5}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1));
+ assertArrayEquals(new double[] {0.5, 0.5}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
verifyGridToCRS(grid);
}
@@ -366,9 +368,9 @@ public final class GridGeometryTest extends TestCase {
0, 0, 1), matrix, STRICT);
// Verify other computed properties.
- assertArrayEquals("resolution", new double[] {0.5, 2}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1));
- assertSame("extent", extent, grid.getExtent());
+ assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
+ assertSame(extent, grid.getExtent(), "extent");
verifyGridToCRS(grid);
/*
* Same envelope and extent, but flip Y axis.
@@ -382,9 +384,9 @@ public final class GridGeometryTest extends TestCase {
0, 0, 1), matrix, STRICT);
// Verify other computed properties.
- assertArrayEquals("resolution", new double[] {0.5, 2}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1));
- assertSame("extent", extent, grid.getExtent());
+ assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
+ assertSame(extent, grid.getExtent(), "extent");
verifyGridToCRS(grid);
/*
* The use of `DISPLAY` mode in this particular case should be equivalent ro `REFLECTION_Y`.
@@ -423,9 +425,9 @@ public final class GridGeometryTest extends TestCase {
0, 0, 1), matrix, STRICT);
// Verify other computed properties.
- assertArrayEquals("resolution", new double[] {0.5, 2}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1));
- assertSame("extent", extent, grid.getExtent());
+ assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
+ assertSame(extent, grid.getExtent(), "extent");
verifyGridToCRS(grid);
/*
* Same extent and envelope, but reordering extend dimensions
@@ -443,9 +445,9 @@ public final class GridGeometryTest extends TestCase {
new long[] { 9, 14}, grid.getExtent());
// Verify other computed properties.
- assertArrayEquals("resolution", new double[] {0.5, 2}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1));
- assertNotSame("extent", extent, grid.getExtent());
+ assertArrayEquals(new double[] {0.5, 2}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1), "isConversionLinear");
+ assertNotSame(extent, grid.getExtent(), "extent");
verifyGridToCRS(grid);
}
@@ -467,7 +469,7 @@ public final class GridGeometryTest extends TestCase {
final Matrix gridToCRS = MathTransforms.getMatrix(grid.getGridToCRS(PixelInCell.CELL_CORNER));
final Number[] numbers = ((ExtendedPrecisionMatrix) gridToCRS).getElementAsNumbers(false);
final double[] elements = MatrixSIS.castOrCopy(gridToCRS).getElements();
- assertArrayEquals(new double[] {360, 0, 0, -180, 0, 180, 0, -90, 0, 0, 3000, -1000, 0, 0, 0, 1}, elements, STRICT);
+ assertArrayEquals(new double[] {360, 0, 0, -180, 0, 180, 0, -90, 0, 0, 3000, -1000, 0, 0, 0, 1}, elements);
assertEquals(elements.length, numbers.length);
for (int i=0; i<elements.length; i++) {
final double expected = elements[i];
@@ -475,7 +477,7 @@ public final class GridGeometryTest extends TestCase {
if (expected == 0) {
assertNull(actual);
} else {
- assertEquals(expected, actual.doubleValue(), STRICT);
+ assertEquals(expected, actual.doubleValue());
}
}
}
@@ -539,9 +541,9 @@ public final class GridGeometryTest extends TestCase {
final MathTransform gridToCRS = MathTransforms.linear(mat);
expected = new GridGeometry(extent, PixelInCell.CELL_CENTER, gridToCRS, HardCodedCRS.CARTESIAN_2D);
}
- assertSame("envelope", grid.getEnvelope(), upsampled.getEnvelope());
- assertEquals("GridGeometry", expected, upsampled);
- assertArrayEquals("resolution", new double[] {0.25, 0.5}, expected.getResolution(false), STRICT);
+ assertSame(grid.getEnvelope(), upsampled.getEnvelope(), "envelope");
+ assertEquals(expected, upsampled, "GridGeometry");
+ assertArrayEquals(new double[] {0.25, 0.5}, expected.getResolution(false), "resolution");
}
/**
@@ -613,8 +615,8 @@ public final class GridGeometryTest extends TestCase {
GridGeometry reduced = grid.selectDimensions(0, 1);
assertNotSame(grid, reduced);
assertExtentEquals(new long[] {336, 20}, new long[] {401, 419}, reduced.getExtent());
- assertSame("CRS", HardCodedCRS.WGS84, reduced.getCoordinateReferenceSystem());
- assertArrayEquals("resolution", new double[] {0.5, 0.5}, reduced.getResolution(false), STRICT);
+ assertSame(HardCodedCRS.WGS84, reduced.getCoordinateReferenceSystem(), "CRS");
+ assertArrayEquals(new double[] {0.5, 0.5}, reduced.getResolution(false), "resolution");
assertMatrixEquals("gridToCRS", new Matrix3(
0, 0.5, -90,
0.5, 0, -180,
@@ -625,16 +627,16 @@ public final class GridGeometryTest extends TestCase {
reduced = grid.selectDimensions(2);
assertNotSame(grid, reduced);
assertExtentEquals(new long[] {4}, new long[] {10}, reduced.getExtent());
- assertSame("CRS", HardCodedCRS.GRAVITY_RELATED_HEIGHT, reduced.getCoordinateReferenceSystem());
- assertArrayEquals("resolution", new double[] {2}, reduced.getResolution(false), STRICT);
+ assertSame(HardCodedCRS.GRAVITY_RELATED_HEIGHT, reduced.getCoordinateReferenceSystem(), "CRS");
+ assertArrayEquals(new double[] {2}, reduced.getResolution(false), "resolution");
assertMatrixEquals("gridToCRS", new Matrix2(
2, 3,
0, 1), MathTransforms.getMatrix(reduced.getGridToCRS(PixelInCell.CELL_CORNER)), STRICT);
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {0.5, 0.5, 2}, grid.getResolution(false), STRICT);
- assertTrue("isConversionLinear", grid.isConversionLinear(0, 1, 2));
+ assertArrayEquals(new double[] {0.5, 0.5, 2}, grid.getResolution(false), "resolution");
+ assertTrue(grid.isConversionLinear(0, 1, 2), "isConversionLinear");
verifyGridToCRS(grid);
}
@@ -668,8 +670,8 @@ public final class GridGeometryTest extends TestCase {
/*
* Verify other computed properties.
*/
- assertArrayEquals("resolution", new double[] {0.5, 0.5}, reduced.getResolution(false), STRICT);
- assertTrue("isConversionLinear", reduced.isConversionLinear(0, 1));
+ assertArrayEquals(new double[] {0.5, 0.5}, reduced.getResolution(false), "resolution");
+ assertTrue(reduced.isConversionLinear(0, 1), "isConversionLinear");
verifyGridToCRS(reduced);
/*
* Test again by keeping the dimension without scale instead of discarding it.
@@ -680,6 +682,44 @@ public final class GridGeometryTest extends TestCase {
assertMatrixEquals("gridToCRS", new Matrix2(0, 3, 0, 1), MathTransforms.getMatrix(tr), STRICT);
}
+ /**
+ * Tests {@link GridGeometry#GridGeometry(GridGeometry, GridGeometry)}.
+ *
+ * @throws FactoryException if the constructor could not combine the CRS.
+ */
+ @Test
+ public void testConcatenate() throws FactoryException {
+ final GridGeometry lower = new GridGeometry(
+ new GridExtent(null, null, new long[] {17, 10}, true),
+ PixelInCell.CELL_CENTER,
+ MathTransforms.linear(new Matrix3(
+ 1, 0, -7,
+ 0, -1, 50,
+ 0, 0, 1)),
+ HardCodedCRS.WGS84);
+
+ final GridGeometry upper = new GridGeometry(
+ new GridExtent(null, null, new long[] {4}, true),
+ PixelInCell.CELL_CENTER,
+ MathTransforms.linear(new Matrix2(
+ 8, 20,
+ 0, 1)),
+ HardCodedCRS.TIME);
+
+ final GridGeometry expected = new GridGeometry(
+ new GridExtent(null, null, new long[] {17, 10, 4}, true),
+ PixelInCell.CELL_CENTER,
+ MathTransforms.linear(new Matrix4(
+ 1, 0, 0, -7,
+ 0, -1, 0, 50,
+ 0, 0, 8, 20,
+ 0, 0, 0, 1)),
+ HardCodedCRS.WGS84_WITH_TIME);
+
+ final GridGeometry actual = new GridGeometry(lower, upper);
+ assertTrue(actual.equals(expected, ComparisonMode.DEBUG));
+ }
+
/**
* Tests {@link GridGeometry#createImageCRS(String, PixelInCell)}.
*/
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArraysExt.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArraysExt.java
index e6baf24db0..87ccac229d 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArraysExt.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArraysExt.java
@@ -67,7 +67,7 @@ import java.lang.reflect.Array;
* objects.
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 1.4
+ * @version 1.5
*
* @see Arrays
*
@@ -1219,6 +1219,24 @@ public final class ArraysExt extends Static {
return copy;
}
+ /**
+ * Returns the concatenation of the given arrays.
+ * If any of the supplied arrays is null or empty, then the other array is returned directly (not copied).
+ *
+ * @param a1 the first array to concatenate, or {@code null}.
+ * @param a2 the second array to concatenate, or {@code null}.
+ * @return the concatenation of given arrays. May be one of the given arrays returned without copying.
+ *
+ * @since 1.5
+ */
+ public static double[] concatenate(final double[] a1, final double[] a2) {
+ if (a1 == null || a1.length == 0) return a2;
+ if (a2 == null || a2.length == 0) return a1;
+ final double[] copy = Arrays.copyOf(a1, a1.length + a2.length);
+ System.arraycopy(a2, 0, copy, a1.length, a2.length);
+ return copy;
+ }
+
/**
* Removes the duplicated elements in the given array. This method should be invoked only for small arrays,
* typically less than 10 distinct elements. For larger arrays, use {@link java.util.LinkedHashSet} instead.