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 f5a77be Complete the tests and fix an erroneous shift when the AOI is
outside the domain of validity.
f5a77be is described below
commit f5a77bec6e664cf9670cd4122878d82375cc6079
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Mar 20 11:15:34 2019 +0100
Complete the tests and fix an erroneous shift when the AOI is outside the
domain of validity.
---
.../internal/referencing/WraparoundAdjustment.java | 16 +++++--
.../referencing/WraparoundAdjustmentTest.java | 51 +++++++++++++++++++---
2 files changed, 57 insertions(+), 10 deletions(-)
diff --git
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
index 4e0d107..96568f2 100644
---
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
+++
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
@@ -224,6 +224,8 @@ public final class WraparoundAdjustment {
final double lowerToValidEnd = ((validEnd - lower) /
period) - lowerCycles;
if (lowerIsBefore) {
/*
+ * Notation: ⎣x⎦=floor(x) and ⎡x⎤=ceil(x).
+ *
* We need to add an integer amount of 'period' to
both sides in order to move the range
* inside the valid area. We need ⎣lowerToValidStart⎦
for reaching the point where:
*
@@ -233,9 +235,15 @@ public final class WraparoundAdjustment {
*
* (new upper) ≧ validStart
*
- * That second condition is met by
⎡upperToValidStart⎤. Note: ⎣x⎦=floor(x) and ⎡x⎤=ceil(x).
+ * That second condition is met by
⎡upperToValidStart⎤. However adding more may cause the
+ * range to move the AOI completely on the right side
of the domain of validity. We prevent
+ * that with a third condition:
+ *
+ * (new lower) < validEnd
*/
- final double cycles =
Math.max(Math.floor(lowerToValidStart), Math.ceil(upperToValidStart));
+ final double cycles =
Math.min(Math.floor(lowerToValidEnd),
+
Math.max(Math.floor(lowerToValidStart),
+ Math.ceil
(upperToValidStart)));
/*
* If after the shift we see that the following
condition hold:
*
@@ -266,7 +274,9 @@ public final class WraparoundAdjustment {
* In this block, 'upperToValidEnd' and
'lowerToValidEnd' are negative, contrarily to
* above block where they were positive.
*/
- final double cycles =
Math.min(Math.ceil(upperToValidEnd), Math.floor(lowerToValidEnd));
+ final double cycles = Math.max(Math.ceil
(upperToValidStart),
+ Math.min(Math.ceil
(upperToValidEnd),
+
Math.floor(lowerToValidEnd)));
if (cycles - 1 > upperToValidStart) {
lowerCycles += Math.floor(lowerToValidStart);
} else {
diff --git
a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
index 6feaf28..ba454f5 100644
---
a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
+++
b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/WraparoundAdjustmentTest.java
@@ -89,6 +89,26 @@ public final strictfp class WraparoundAdjustmentTest extends
TestCase {
/**
* Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)}
+ * with an envelope which is outside the grid valid area.
+ *
+ * @throws TransformException should never happen since this test does not
transform coordinates.
+ */
+ @Test
+ public void testDisjointAOI() throws TransformException {
+ final GeneralEnvelope domainOfValidity = new
GeneralEnvelope(HardCodedCRS.WGS84);
+ domainOfValidity.setRange(0, 80, 100);
+ domainOfValidity.setRange(1, -70, +70);
+
+ final GeneralEnvelope areaOfInterest = new
GeneralEnvelope(HardCodedCRS.WGS84);
+ areaOfInterest.setRange(0, 50, 70);
+ areaOfInterest.setRange(1, -80, 60);
+
+ Envelope actual = adjustWraparoundAxes(areaOfInterest,
domainOfValidity, null);
+ assertEnvelopeEquals(areaOfInterest, actual); // Expect
no change.
+ }
+
+ /**
+ * Tests {@link WraparoundAdjustment#shiftInto(Envelope, MathTransform)}
* with an envelope shifted by 360° before or after the grid valid area.
*
* @throws TransformException should never happen since this test does not
transform coordinates.
@@ -103,16 +123,21 @@ public final strictfp class WraparoundAdjustmentTest
extends TestCase {
final GeneralEnvelope areaOfInterest = new
GeneralEnvelope(HardCodedCRS.WGS84);
areaOfInterest.setRange(0, 70, 90);
areaOfInterest.setRange(1, -80, 60);
-
+ /*
+ * AOI intersects the domain of validity: expected result is identical
to given AOI.
+ */
final GeneralEnvelope expected = new GeneralEnvelope(areaOfInterest);
-
Envelope actual = adjustWraparoundAxes(areaOfInterest,
domainOfValidity, null);
assertEnvelopeEquals(expected, actual);
-
+ /*
+ * AOI is on the left side of domain of validity. Expect a 360° shift
to the right.
+ */
areaOfInterest.setRange(0, -290, -270); // [70 …
90] - 360
actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
assertEnvelopeEquals(expected, actual);
-
+ /*
+ * AOI is on the right side of domain of validity. Expect a 360° shift
to the left.
+ */
areaOfInterest.setRange(0, 430, 450); // [70 …
90] + 360
actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
assertEnvelopeEquals(expected, actual);
@@ -160,14 +185,26 @@ public final strictfp class WraparoundAdjustmentTest
extends TestCase {
@Test
public void testWithProjection() throws TransformException {
final GeneralEnvelope domainOfValidity = new
GeneralEnvelope(HardCodedCRS.WGS84);
- domainOfValidity.setRange(0, 80, 100);
+ domainOfValidity.setRange(0, 50, 60);
domainOfValidity.setRange(1, -70, +70);
final DefaultProjectedCRS mercator = HardCodedConversions.mercator();
final GeneralEnvelope areaOfInterest = new GeneralEnvelope(mercator);
areaOfInterest.setRange(0, 5000000, 7000000);
// About 45°E to 63°E
areaOfInterest.setRange(1, -10000000, 10000000);
// About 66.6°S to 66.6°N
-
- // TODO: complete test.
+ /*
+ * AOI intersects the domain of validity: expected result is identical
to given AOI.
+ */
+ final GeneralEnvelope expected = new GeneralEnvelope(areaOfInterest);
+ final MathTransform validToAOI =
mercator.getConversionFromBase().getMathTransform();
+ Envelope actual = adjustWraparoundAxes(areaOfInterest,
domainOfValidity, validToAOI);
+ assertEnvelopeEquals(expected, actual);
+ /*
+ * AOI is on the right side of domain of validity. Expect a 360° shift
to the left.
+ * We add 40000 km to AOI, which is approximately the Earth
circumference.
+ */
+ areaOfInterest.setRange(0, 45000000, 47000000);
+ actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity,
validToAOI);
+ assertEnvelopeEquals(expected, actual, 1E+5,
Formulas.LINEAR_TOLERANCE);
}
}