sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/03: More complete detection of wraparound cases when adding a note in `toString()` representation.
Date Sat, 26 Sep 2020 22:05:19 GMT
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> &gt; <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> &gt; <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));
+    }
 }


Mime
View raw message