This is an automated email from the ASF dual-hosted git repository.
amanin 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 0e887fd feat(Core): add commodity method to translate grid extents.
0e887fd is described below
commit 0e887fd563100a689a0487a324ea9330219655bb
Author: Alexis Manin <[email protected]>
AuthorDate: Tue May 19 12:46:30 2020 +0200
feat(Core): add commodity method to translate grid extents.
---
.../org/apache/sis/coverage/grid/GridExtent.java | 31 ++++++++++++-
.../apache/sis/coverage/grid/GridExtentTest.java | 53 ++++++++++++++++++++++
2 files changed, 82 insertions(+), 2 deletions(-)
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index 61eacf5..b1f1639 100644
---
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.Arrays;
import java.util.Optional;
import java.util.Locale;
+import java.util.stream.LongStream;
import java.io.Serializable;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -67,7 +68,6 @@ import org.opengis.coverage.grid.GridCoordinates;
import org.opengis.coverage.CannotEvaluateException;
import org.opengis.coverage.PointOutsideCoverageException;
-
/**
* A range of grid coverage coordinates, also known as "grid envelope".
* {@code GridExtent} are defined by {@linkplain #getLow() low} coordinates
(often all zeros)
@@ -503,7 +503,7 @@ public class GridExtent implements GridEnvelope,
LenientComparable, Serializable
* @param enclosing the extent from which to copy axes, or {@code null}
if none.
* @param coordinates the coordinates. This array is not cloned.
*/
- GridExtent(final GridExtent enclosing, final long[] coordinates) {
+ GridExtent(final GridExtent enclosing, final long... coordinates) {
this.coordinates = coordinates;
types = (enclosing != null) ? enclosing.types : null;
assert (types == null) || types.length == getDimension();
@@ -1387,4 +1387,31 @@ public class GridExtent implements GridEnvelope,
LenientComparable, Serializable
}
table.flush();
}
+
+ /**
+ * Create a fresh translated extent from the current one. A translated
extent <em>matches this extent size</em>,
+ * meaning that both its low and high coordinates are displaced by the
same amount.
+ *
+ * @param translation Translation to apply to each axis, respectively. If
argument dimension is lower than this
+ * extent, we consider all dimensions non affected as
not translated. Meaning that for an extent
+ * (x: [0..10], y: [2..4], z: [0..1]) and a translation
[-2, 2], the resulting extent would be
+ * (x: [-2..8], y: [4..6], z: [0..1]).
+ * @return A new/independant grid-extent whose coordinates (both low and
high ones) have been translated by a given
+ * amount. However, if given translation is a no-op (no value or only 0
ones), this extent is returned as is.
+ * @throws IllegalArgumentException If given translation dimension is
greater than {@link #getDimension() this extent dimension}.
+ */
+ public GridExtent translate(long... translation) {
+ if (translation == null || translation.length < 1) return this;
+ final int dimension = getDimension();
+ if (translation.length > dimension) throw new
IllegalArgumentException("Given translation dimension is higher than this
extent");
+ // In case of badly sized input, this could become a very costly
check, so we check dimension before.
+ if (LongStream.of(translation).allMatch(v -> v == 0)) return this;
+ final long[] translatedCoords = Arrays.copyOf(coordinates,
coordinates.length);
+ for (int min = 0, max = dimension ; min < translation.length ; min++,
max++) {
+ translatedCoords[min] += translation[min];
+ translatedCoords[max] += translation[min];
+ }
+
+ return new GridExtent(this, translatedCoords);
+ }
}
diff --git
a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridExtentTest.java
b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridExtentTest.java
index b0cb727..f74c902 100644
---
a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridExtentTest.java
+++
b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridExtentTest.java
@@ -314,4 +314,57 @@ public final strictfp class GridExtentTest extends
TestCase {
"Row: [200 … 799] (600 cells)\n" +
"Time: [ 40 … 49] (10 cells)\n", buffer);
}
+
+ @Test
+ public void empty_translation_returns_same_extent_instance() {
+ final GridExtent extent = new GridExtent(10, 10);
+ assertTrue("Same instance returned in case of no-op", extent ==
extent.translate());
+ assertTrue("Same instance returned in case of no-op", extent ==
extent.translate(null));
+ assertTrue("Same instance returned in case of no-op", extent ==
extent.translate(new long[0]));
+ assertTrue("Same instance returned in case of no-op", extent ==
extent.translate(0));
+ assertTrue("Same instance returned in case of no-op", extent ==
extent.translate(0, 0));
+ }
+
+ @Test
+ public void translation_fails_if_given_array_contains_too_many_elements() {
+ try {
+ new GridExtent(2, 1).translate(2, 1, 2);
+ fail("A translation with too many dimensions should fail-fast");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+ }
+
+ @Test
+ public void translating_only_first_dimensions_leave_others_untouched() {
+ final GridExtent base = new GridExtent(null, 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());
+
+ 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());
+
+ 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());
+
+ // paranoid check: ensure 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());
+ }
+
+ @Test
+ public void translating_all_dimensions() {
+ final GridExtent base = new GridExtent(null, -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());
+
+ // paranoid check: ensure 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());
+ }
}