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 8b4885e8521785eccd058a0a93e3aacd9b316532
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Sep 26 16:29:21 2020 +0200
More complete detection of wraparound cases when adding a note in `toString()` representation.
---
.../org/apache/sis/coverage/grid/GridGeometry.java | 2 +-
.../java/org/apache/sis/metadata/SpecialCases.java | 2 +-
.../java/org/apache/sis/measure/Longitude.java | 20 ++++++++-
.../java/org/apache/sis/measure/AngleTest.java | 51 ++++++++++++++--------
4 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
index f9d79b9..28b2b8b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
@@ -1583,7 +1583,7 @@ public class GridGeometry implements LenientComparable, Serializable
{
table.append(times[1].toString());
}
table.flush();
- if (eastBoundLongitude < westBoundLongitude) {
+ if (Longitude.isWraparound(westBoundLongitude, eastBoundLongitude)) {
vocabulary.appendLabel(Vocabulary.Keys.Note, buffer);
buffer.append(' ')
.append(org.apache.sis.internal.metadata.Resources.forLocale(locale).getString(
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java
index 81704e6..a608830 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java
@@ -98,7 +98,7 @@ final class SpecialCases extends PropertyAccessor {
Object east = super.get(index, metadata);
if (east != null) {
Object west = super.get(westBoundLongitude, metadata);
- if (west != null && (Double) east < (Double) west) {
+ if (west != null && Longitude.isWraparound((Double) west, (Double)
east)) {
return Resources.formatInternational(Resources.Keys.BoxCrossesAntiMeridian);
}
}
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
index 3f6be3f..96a0d35 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
@@ -16,7 +16,6 @@
*/
package org.apache.sis.measure;
-import static org.apache.sis.measure.Angle.valueOf;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.cs.AxisDirection;
@@ -35,7 +34,7 @@ import org.opengis.referencing.cs.AxisDirection;
* This final class is immutable and thus inherently thread-safe.
*
* @author Martin Desruisseaux (MPO, IRD, Geomatys)
- * @version 0.8
+ * @version 1.1
*
* @see Latitude
* @see AngleFormat
@@ -163,4 +162,21 @@ public final class Longitude extends Angle {
return λ - Math.floor((λ - MIN_VALUE) / (MAX_VALUE - MIN_VALUE)) * (MAX_VALUE
- MIN_VALUE);
}
}
+
+ /**
+ * Returns {@code true} if the given longitude range crosses the anti-meridian in a way
expressed by
+ * <var>west</var> > <var>east</var>. For the purpose
of this method, +0 is considered "greater" than −0.
+ * See {@link org.apache.sis.geometry.GeneralEnvelope} for a wraparound illustration.
+ *
+ * @param west the west bound longitude. This is the minimum value when there is no
wraparound.
+ * @param east the east bound longitude. This is the maximum value when there is no
wraparound.
+ * @return {@code true} if <var>west</var> > <var>east</var>
or if the arguments are (+0, −0),
+ * {@code false} otherwise (including when at least one argument is NaN).
+ *
+ * @since 1.1
+ */
+ public static boolean isWraparound(final double west, final double east) {
+ return (west > east) || (Double.doubleToRawLongBits(west) == 0 &&
+ Double.doubleToRawLongBits(east) == Long.MIN_VALUE);
+ }
}
diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
index d1ca979..db9ad04 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/AngleTest.java
@@ -30,7 +30,7 @@ import static org.junit.Assert.*;
* Tests the {@link Angle}, {@link Longitude} and {@link Latitude} classes.
*
* @author Martin Desruisseaux (MPO, IRD, Geomatys)
- * @version 0.4
+ * @version 1.1
* @since 0.3
* @module
*/
@@ -96,13 +96,13 @@ public final strictfp class AngleTest extends TestCase {
*/
@Test
public void testClamp() {
- assertEquals( 45, Latitude.clamp( 45), 0);
- assertEquals(-45, Latitude.clamp(-45), 0);
- assertEquals( 90, Latitude.clamp( 95), 0);
- assertEquals(-90, Latitude.clamp(-95), 0);
- assertEquals(NaN, Latitude.clamp(NaN), 0);
- assertEquals( 90, Latitude.clamp(Double.POSITIVE_INFINITY), 0);
- assertEquals(-90, Latitude.clamp(Double.NEGATIVE_INFINITY), 0);
+ assertEquals( 45, Latitude.clamp( 45), STRICT);
+ assertEquals(-45, Latitude.clamp(-45), STRICT);
+ assertEquals( 90, Latitude.clamp( 95), STRICT);
+ assertEquals(-90, Latitude.clamp(-95), STRICT);
+ assertEquals(NaN, Latitude.clamp(NaN), STRICT);
+ assertEquals( 90, Latitude.clamp(Double.POSITIVE_INFINITY), STRICT);
+ assertEquals(-90, Latitude.clamp(Double.NEGATIVE_INFINITY), STRICT);
assertEquals(doubleToLongBits(+0.0), doubleToLongBits(Latitude.clamp(+0.0)));
assertEquals(doubleToLongBits(-0.0), doubleToLongBits(Latitude.clamp(-0.0)));
// Sign shall be preserved.
}
@@ -112,16 +112,33 @@ public final strictfp class AngleTest extends TestCase {
*/
@Test
public void testNormalize() {
- assertEquals( 120, Longitude.normalize( 120), 0);
- assertEquals(-120, Longitude.normalize(-120), 0);
- assertEquals(-160, Longitude.normalize( 200), 0);
- assertEquals( 160, Longitude.normalize(-200), 0);
- assertEquals(-180, Longitude.normalize(-180), 0);
- assertEquals(-180, Longitude.normalize( 180), 0); // Upper
value shall be exclusive.
- assertEquals(NaN, Longitude.normalize( NaN), 0);
- assertEquals(NaN, Longitude.normalize(Double.POSITIVE_INFINITY), 0);
- assertEquals(NaN, Longitude.normalize(Double.NEGATIVE_INFINITY), 0);
+ assertEquals( 20, Longitude.normalize( 20), STRICT);
+ assertEquals( -20, Longitude.normalize( -20), STRICT);
+ assertEquals( 20, Longitude.normalize( 380), STRICT);
+ assertEquals( -20, Longitude.normalize( 340), STRICT);
+ assertEquals( 120, Longitude.normalize( 120), STRICT);
+ assertEquals(-120, Longitude.normalize(-120), STRICT);
+ assertEquals(-160, Longitude.normalize( 200), STRICT);
+ assertEquals( 160, Longitude.normalize(-200), STRICT);
+ assertEquals(-180, Longitude.normalize(-180), STRICT);
+ assertEquals(-180, Longitude.normalize( 180), STRICT); // Upper
value shall be exclusive.
+ assertEquals(NaN, Longitude.normalize( NaN), STRICT);
+ assertEquals(NaN, Longitude.normalize(Double.POSITIVE_INFINITY), STRICT);
+ assertEquals(NaN, Longitude.normalize(Double.NEGATIVE_INFINITY), STRICT);
assertEquals(doubleToLongBits(+0.0), doubleToLongBits(Longitude.normalize(+0.0)));
assertEquals(doubleToLongBits(-0.0), doubleToLongBits(Longitude.normalize(-0.0)));
// Sign shall be preserved.
}
+
+ /**
+ * Tests {@link Longitude#isWraparound(double, double)}.
+ */
+ @Test
+ public void testIsWraparound() {
+ assertFalse(Longitude.isWraparound( 20, 40));
+ assertTrue (Longitude.isWraparound( 40, 20));
+ assertFalse(Longitude.isWraparound( 0d, 0d));
+ assertFalse(Longitude.isWraparound(-0d, 0d));
+ assertFalse(Longitude.isWraparound(-0d, -0d));
+ assertTrue (Longitude.isWraparound(+0d, -0d));
+ }
}
|