sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1557738 - in /sis/branches/JDK7/core: sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/referencing/cs/ sis-referencing/src/test/java/org/apache/sis/referencing/cs/ sis-utility/...
Date Mon, 13 Jan 2014 14:50:42 GMT
Author: desruisseaux
Date: Mon Jan 13 14:50:41 2014
New Revision: 1557738

URL: http://svn.apache.org/r1557738
Log:
Modify CoordinateSystems.angle(...) API in order to let user know when the angle sign give
no indication
about whether the coordinate system is right-handed or left-handed, and clarify javadoc.

Added:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
  (with props)
Modified:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -195,6 +195,18 @@ public final class AxisDirections extend
     }
 
     /**
+     * Returns {@code true} if the given direction is {@code OTHER} or a user-defined direction.
+     *
+     * @param  dir The direction to test, or {@code null}.
+     * @return {@code true} if the given direction is {@code OTHER} or a user-defined direction.
+     */
+    public static boolean isCustom(final AxisDirection dir) {
+        if (dir == null) return false;
+        final int ordinal = dir.ordinal();
+        return ordinal <= OTHER.ordinal() || ordinal > DISPLAY_DOWN.ordinal();
+    }
+
+    /**
      * Returns {@code true} if the given direction is a spatial axis direction (including
vertical and geocentric axes).
      * The current implementation conservatively returns {@code true} for every non-null
directions except a hard-coded
      * set of directions which are known to be non-spatial. We conservatively accept unknown
axis directions because

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -72,8 +72,9 @@ public enum AxesConvention {
     /**
      * Axes are reordered for a <cite>right-handed</cite> coordinate system.
Axis orientations and ranges are unchanged.
      * This enum is often used for deriving a coordinate system with the (<var>longitude</var>,
<var>latitude</var>) or
-     * (<var>x</var>,<var>y</var>) axis order. However a right-handed
coordinate system does not guarantee
-     * that longitude or <var>x</var> axis will be first (see for example the
(North, West) case below).
+     * (<var>x</var>,<var>y</var>) axis order. While it works in
many cases, note that a right-handed coordinate system
+     * does not guarantee that longitude or <var>x</var> axis will be first in
every cases. The most notable exception
+     * is the (North, West) case.
      *
      * {@note We do not provide a "<cite>longitude or <var>x</var> axis
first</cite>" enumeration value because
      *        such criterion is hard to apply to inter-cardinal directions and has no meaning
for map projections

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -24,6 +24,8 @@ import javax.measure.converter.Conversio
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.measure.Angle;
+import org.apache.sis.measure.ElevationAngle;
 import org.apache.sis.measure.Units;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.Classes;
@@ -96,12 +98,12 @@ public final class CoordinateSystems ext
     }
 
     /**
-     * Returns the arithmetic (counterclockwise) angle from the first axis direction to the
second direction,
-     * in decimal <strong>degrees</strong>. This method returns a value between
-180° and +180°,
-     * or {@link Double#NaN NaN} if no angle can be computed.
+     * Returns the arithmetic (counterclockwise) angle from the first axis direction to the
second direction.
+     * This method returns a value between -180° and +180°, or {@code null} if no angle
can be computed.
      *
-     * <p>A positive angle between two compass directions denotes a right-handed system,
-     * while a negative angle denotes a left-handed system. Examples:</p>
+     * {@section Horizontal directions}
+     * For any pair of compass directions which are not opposite directions, a positive angle
denotes
+     * a right-handed system while a negative angle denotes a left-handed system. Examples:
      *
      * <ul>
      *   <li>The angle from {@link AxisDirection#EAST EAST} to {@link AxisDirection#NORTH
NORTH} is 90°</li>
@@ -109,16 +111,22 @@ public final class CoordinateSystems ext
      *   <li>The angle from "<cite>North along 90° East</cite>" to "<cite>North
along 0°</cite>" is 90°.</li>
      * </ul>
      *
-     * {@section Vertical directions}
-     * By convention, this method defines the angle from any compass direction to the {@link
AxisDirection#UP UP}
-     * vertical direction (the <cite>altitude</cite> or <cite>elevation</cite>)
as 90°, and the angle of any compass
-     * direction to the {@link AxisDirection#DOWN DOWN} vertical direction as -90°. The
angle between two opposite
-     * vertical directions is ±180°. Those directions are approximative since this method
does not take the Earth
-     * ellipsoidal or geoidal shape in account.
+     * {@section Horizontal and vertical directions}
+     * By convention this method defines the angle from any compass direction to the {@link
AxisDirection#UP UP}
+     * vertical direction as 90°, and the angle of any compass direction to the {@link AxisDirection#DOWN
DOWN}
+     * vertical direction as -90°. The sign of those angles gives no indication about whether
the coordinate system
+     * is right-handed or left-handed. Those angles are returned as instances of {@link ElevationAngle}.
+     *
+     * <p>All angles are approximative since this method does not take the Earth ellipsoidal
or geoidal shape in
+     * account.</p>
      *
      * {@section Invariants}
-     * {@code angle(A, B) == -angle(B, A)} for any return value different than {@code NaN}.
-     * This invariant holds also for angles of ±180°, even if an angle of -180° is equivalent
to +180°.
+     * For any non-null return value:
+     * <ul>
+     *   <li>{@code angle(A, A) == 0°}</li>
+     *   <li>{@code angle(A, opposite(A)) == ±180°}</li>
+     *   <li>{@code angle(A, B) == -angle(B, A)}</li>
+     * </ul>
      *
      * @param  source The source axis direction.
      * @param  target The target axis direction.
@@ -126,7 +134,7 @@ public final class CoordinateSystems ext
      *         the source direction in order to make it point toward the target direction,
or
      *         {@link Double#NaN} if this value can not be computed.
      */
-    public static double angle(final AxisDirection source, final AxisDirection target) {
+    public static Angle angle(final AxisDirection source, final AxisDirection target) {
         ensureNonNull("source", source);
         ensureNonNull("target", target);
         /*
@@ -135,47 +143,48 @@ public final class CoordinateSystems ext
          */
         int c = AxisDirections.angleForCompass(source, target);
         if (c != Integer.MIN_VALUE) {
-            return c * (360.0 / AxisDirections.COMPASS_COUNT);
-        }
-        /*
-         * Check for UP and DOWN, with special case if one of the direction is a compass
one.
-         */
-        final boolean v1 = AxisDirections.isVertical(source);
-        final boolean v2 = AxisDirections.isVertical(target);
-        if (v1 | v2) {
-            if (v1 & v2) {
-                return (source == target) ? 0 : (target == AxisDirection.UP) ? 180 : -180;
-            }
-            if (AxisDirections.isCompass(v1 ? target : source)) {
-                return (v1 ? source : target) == AxisDirection.UP ? 90 : -90;
-            }
+            return new Angle(c * (360.0 / AxisDirections.COMPASS_COUNT));
         }
         /*
          * Check for GEOCENTRIC_X, GEOCENTRIC_Y, GEOCENTRIC_Z.
          */
         c = AxisDirections.angleForGeocentric(source, target);
         if (c != Integer.MIN_VALUE) {
-            return c * 90.0;
+            return new Angle(c * 90);
         }
         /*
          * Check for DISPLAY_UP, DISPLAY_DOWN, etc.
          */
         c = AxisDirections.angleForDisplay(source, target);
         if (c != Integer.MIN_VALUE) {
-            return c * (360.0 / AxisDirections.DISPLAY_COUNT);
+            return new Angle(c * (360 / AxisDirections.DISPLAY_COUNT));
         }
         /*
          * Check for "South along 90° East", etc. directions. We do this test last
          * because it performs a relatively costly parsing of axis direction name.
          */
-        final DirectionAlongMeridian src = DirectionAlongMeridian.parse(source);
-        if (src != null) {
-            final DirectionAlongMeridian tgt = DirectionAlongMeridian.parse(target);
-            if (tgt != null) {
-                return src.getAngle(tgt);
+        final DirectionAlongMeridian srcMeridian = DirectionAlongMeridian.parse(source);
+        final DirectionAlongMeridian tgtMeridian = DirectionAlongMeridian.parse(target);
+        if (srcMeridian != null && tgtMeridian != null) {
+            return new Angle(srcMeridian.angle(tgtMeridian));
+        }
+        /*
+         * Check for UP and DOWN, with special case if one of the direction is a compass
one.
+         */
+        final boolean srcVrt = AxisDirections.isVertical(source);
+        final boolean tgtVrt = AxisDirections.isVertical(target);
+        if (tgtVrt) {
+            if (srcVrt) {
+                return new Angle(source.equals(target) ? 0 : target.equals(AxisDirection.UP)
? 180 : -180);
+            } else if (AxisDirections.isCompass(source) || srcMeridian != null) {
+                return target.equals(AxisDirection.UP) ? ElevationAngle.ZENITH : ElevationAngle.NADIR;
+            }
+        } else if (srcVrt) {
+            if (AxisDirections.isCompass(target) || tgtMeridian != null) {
+                return source.equals(AxisDirection.UP) ? ElevationAngle.NADIR : ElevationAngle.ZENITH;
             }
         }
-        return Double.NaN;
+        return null;
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -22,8 +22,9 @@ import javax.xml.bind.annotation.XmlRoot
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
-import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.measure.Angle;
 
 
 /**
@@ -194,11 +195,16 @@ public class DefaultCartesianCS extends 
             final AxisDirection axis0 = getAxis(i).getDirection();
             for (int j=i; ++j<dimension;) {
                 final AxisDirection axis1 = getAxis(j).getDirection();
-                final double angle = CoordinateSystems.angle(axis0, axis1); // May be NaN,
which we accept.
-                if (Math.abs(Math.abs(angle) - 90) > Formulas.ANGULAR_TOLERANCE) {
-                    throw new IllegalArgumentException(Errors.format(
-                            Errors.Keys.NonPerpendicularDirections_2, axis0, axis1));
+                final Angle angle = CoordinateSystems.angle(axis0, axis1);
+                if (angle != null) {
+                    if (Math.abs(angle.degrees()) == 90) {
+                        continue; // Axes are perpendicular.
+                    }
+                } else if (AxisDirections.isCustom(axis0) || AxisDirections.isCustom(axis1))
{
+                    continue; // If we do not recognize an axis, assume that the user know
what he is doing.
                 }
+                throw new IllegalArgumentException(Errors.format(
+                        Errors.Keys.NonPerpendicularDirections_2, axis0, axis1));
             }
         }
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -21,6 +21,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.measure.Longitude;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.referencing.AxisDirections;
 
@@ -127,7 +128,7 @@ final class DirectionAlongMeridian imple
             // since we are supposed to return 'null' in this situation.
             return null;
         }
-        if (!(meridian >= -180 && meridian <= 180)) {
+        if (!(meridian >= Longitude.MIN_VALUE && meridian <= Longitude.MAX_VALUE))
{
             // Meridian is NaN or is not in the valid range.
             return null;
         }
@@ -172,24 +173,14 @@ final class DirectionAlongMeridian imple
      *
      * {@example The angle from "<cite>North along 90 deg East</cite>" to "<cite>North
along 0 deg</cite> is 90°.}
      */
-    public double getAngle(final DirectionAlongMeridian other) {
+    public double angle(final DirectionAlongMeridian other) {
         if (!baseDirection.equals(other.baseDirection)) {
             return Double.NaN;
         }
         /*
-         * We want the following pair of axis:
-         * (NORTH along 90°E, NORTH along 0°)
-         * to give a positive angle of 90°
+         * Example: angle between (NORTH along 90°E, NORTH along 0°) shall be +90°
          */
-        double angle = meridian - other.meridian;
-        /*
-         * Forces to the [-180° .. +180°] range.
-         */
-        if (angle < -180) {
-            angle += 360;
-        } else if (angle > 180) {
-            angle -= 360;
-        }
+        double angle = Longitude.normalize(meridian - other.meridian);
         /*
          * Reverses the sign for axis oriented toward SOUTH,
          * so a positive angle is a right-handed system.
@@ -220,7 +211,7 @@ final class DirectionAlongMeridian imple
         if (c != 0) {
             return c;
         }
-        final double angle = getAngle(that);
+        final double angle = angle(that);
         if (angle < 0) return +1;  // Really the opposite sign.
         if (angle > 0) return -1;  // Really the opposite sign.
         return 0;
@@ -275,7 +266,7 @@ final class DirectionAlongMeridian imple
             buffer.append(md);
         }
         buffer.append('°');
-        if (md != 0 && md != 180) {
+        if (md != 0 && md != Longitude.MAX_VALUE) {
             buffer.append(meridian < 0 ? 'W' : 'E');
         }
         name = buffer.toString();

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -21,6 +21,8 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.measure.Angle;
+import org.apache.sis.measure.ElevationAngle;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -49,7 +51,7 @@ public final strictfp class CoordinateSy
     /**
      * Tolerance threshold for strict floating point comparisons.
      */
-    static final double STRICT = 0;
+    private static final double STRICT = 0;
 
     /**
      * Tests {@link CoordinateSystems#parseAxisDirection(String)}.
@@ -78,27 +80,29 @@ public final strictfp class CoordinateSy
      */
     @Test
     public void testAngle() {
-        assertAngleEquals(  0,   AxisDirection.EAST,             AxisDirection.EAST);
-        assertAngleEquals( 90,   AxisDirection.EAST,             AxisDirection.NORTH);
-        assertAngleEquals( 90,   AxisDirection.WEST,             AxisDirection.SOUTH);
-        assertAngleEquals(180,   AxisDirection.SOUTH,            AxisDirection.NORTH);
-        assertAngleEquals(180,   AxisDirection.WEST,             AxisDirection.EAST);
-        assertAngleEquals( 45,   AxisDirection.NORTH_EAST,       AxisDirection.NORTH);
-        assertAngleEquals( 22.5, AxisDirection.NORTH_NORTH_EAST, AxisDirection.NORTH);
-        assertAngleEquals( 45,   AxisDirection.SOUTH,            AxisDirection.SOUTH_EAST);
-        assertAngleEquals(NaN,   AxisDirection.NORTH,            AxisDirection.FUTURE);
-        assertAngleEquals(  0,   AxisDirection.UP,               AxisDirection.UP);
-        assertAngleEquals(  0,   AxisDirection.DOWN,             AxisDirection.DOWN);
-        assertAngleEquals(180,   AxisDirection.DOWN,             AxisDirection.UP);
-        assertAngleEquals(NaN,   AxisDirection.DOWN,             AxisDirection.FUTURE);
-        assertAngleEquals(180,   AxisDirection.DISPLAY_DOWN,     AxisDirection.DISPLAY_UP);
-        assertAngleEquals(-90,   AxisDirection.DISPLAY_RIGHT,    AxisDirection.DISPLAY_DOWN);
-        assertAngleEquals(NaN,   AxisDirection.DISPLAY_UP,       AxisDirection.DOWN);
-        assertAngleEquals(NaN,   AxisDirection.PAST,             AxisDirection.FUTURE); //
Not spatial directions.
-        assertAngleEquals( 90,   AxisDirection.GEOCENTRIC_X,     AxisDirection.GEOCENTRIC_Y);
-        assertAngleEquals( 90,   AxisDirection.GEOCENTRIC_Y,     AxisDirection.GEOCENTRIC_Z);
-        assertAngleEquals(  0,   AxisDirection.GEOCENTRIC_Y,     AxisDirection.GEOCENTRIC_Y);
-        assertAngleEquals(NaN,   AxisDirection.GEOCENTRIC_Z,     AxisDirection.UP);
+        assertAngleEquals(false,   0,   AxisDirection.EAST,             AxisDirection.EAST);
+        assertAngleEquals(false,  90,   AxisDirection.EAST,             AxisDirection.NORTH);
+        assertAngleEquals(false,  90,   AxisDirection.WEST,             AxisDirection.SOUTH);
+        assertAngleEquals(false, 180,   AxisDirection.SOUTH,            AxisDirection.NORTH);
+        assertAngleEquals(false, 180,   AxisDirection.WEST,             AxisDirection.EAST);
+        assertAngleEquals(false,  45,   AxisDirection.NORTH_EAST,       AxisDirection.NORTH);
+        assertAngleEquals(false,  22.5, AxisDirection.NORTH_NORTH_EAST, AxisDirection.NORTH);
+        assertAngleEquals(false,  45,   AxisDirection.SOUTH,            AxisDirection.SOUTH_EAST);
+        assertAngleEquals(false, NaN,   AxisDirection.NORTH,            AxisDirection.FUTURE);
+        assertAngleEquals(true,   90,   AxisDirection.SOUTH,            AxisDirection.UP);
+        assertAngleEquals(true,  -90,   AxisDirection.SOUTH,            AxisDirection.DOWN);
+        assertAngleEquals(false,   0,   AxisDirection.UP,               AxisDirection.UP);
+        assertAngleEquals(false,   0,   AxisDirection.DOWN,             AxisDirection.DOWN);
+        assertAngleEquals(false, 180,   AxisDirection.DOWN,             AxisDirection.UP);
+        assertAngleEquals(false, NaN,   AxisDirection.DOWN,             AxisDirection.FUTURE);
+        assertAngleEquals(false, 180,   AxisDirection.DISPLAY_DOWN,     AxisDirection.DISPLAY_UP);
+        assertAngleEquals(false, -90,   AxisDirection.DISPLAY_RIGHT,    AxisDirection.DISPLAY_DOWN);
+        assertAngleEquals(false, NaN,   AxisDirection.DISPLAY_UP,       AxisDirection.DOWN);
+        assertAngleEquals(false, NaN,   AxisDirection.PAST,             AxisDirection.FUTURE);
// Not spatial directions.
+        assertAngleEquals(false,  90,   AxisDirection.GEOCENTRIC_X,     AxisDirection.GEOCENTRIC_Y);
+        assertAngleEquals(false,  90,   AxisDirection.GEOCENTRIC_Y,     AxisDirection.GEOCENTRIC_Z);
+        assertAngleEquals(false,   0,   AxisDirection.GEOCENTRIC_Y,     AxisDirection.GEOCENTRIC_Y);
+        assertAngleEquals(false, NaN,   AxisDirection.GEOCENTRIC_Z,     AxisDirection.UP);
     }
 
     /**
@@ -107,38 +111,50 @@ public final strictfp class CoordinateSy
     @Test
     @DependsOnMethod({"testParseAxisDirection", "testAngle"})
     public void testAngleAlongMeridians() {
-        assertAngleEquals( 90.0, "West",                    "South");
-        assertAngleEquals(-90.0, "South",                   "West");
-        assertAngleEquals( 45.0, "South",                   "South-East");
-        assertAngleEquals(-22.5, "North-North-West",        "North");
-        assertAngleEquals(-22.5, "North_North_West",        "North");
-        assertAngleEquals(-22.5, "North North West",        "North");
-        assertAngleEquals( 90.0, "North along 90 deg East", "North along 0 deg");
-        assertAngleEquals( 90.0, "South along 180 deg",     "South along 90 deg West");
-        assertAngleEquals(   90, "North along 90°E",        "North along 0°");
-        assertAngleEquals(  135, "North along 90°E",        "North along 45°W");
-        assertAngleEquals( -135, "North along 45°W",        "North along 90°E");
+        assertAngleEquals(false,   90.0, "West",                    "South");
+        assertAngleEquals(false,  -90.0, "South",                   "West");
+        assertAngleEquals(false,   45.0, "South",                   "South-East");
+        assertAngleEquals(true,    90.0, "West",                    "Up");
+        assertAngleEquals(true,   -90.0, "West",                    "Down");
+        assertAngleEquals(false,  -22.5, "North-North-West",        "North");
+        assertAngleEquals(false,  -22.5, "North_North_West",        "North");
+        assertAngleEquals(false,  -22.5, "North North West",        "North");
+        assertAngleEquals(false,   90.0, "North along 90 deg East", "North along 0 deg");
+        assertAngleEquals(false,   90.0, "South along 180 deg",     "South along 90 deg West");
+        assertAngleEquals(false,   90.0, "North along 90°E",        "North along 0°");
+        assertAngleEquals(false,  135.0, "North along 90°E",        "North along 45°W");
+        assertAngleEquals(false, -135.0, "North along 45°W",        "North along 90°E");
+        assertAngleEquals(true,    90.0, "North along 45°W",        "Up");
+        assertAngleEquals(true,   -90.0, "North along 45°W",        "Down");
     }
 
     /**
      * Asserts that the angle between the parsed directions is equals to the given value.
      * This method tests also the angle by interchanging the axis directions.
      */
-    private static void assertAngleEquals(final double expected, final String source, final
String target) {
+    private static void assertAngleEquals(final boolean isElevation, final double expected,
+            final String source, final String target)
+    {
         final AxisDirection dir1 = parseAxisDirection(source);
         final AxisDirection dir2 = parseAxisDirection(target);
         assertNotNull(source, dir1);
         assertNotNull(target, dir2);
-        assertAngleEquals(expected, dir1, dir2);
+        assertAngleEquals(isElevation, expected, dir1, dir2);
     }
 
     /**
      * Asserts that the angle between the given directions is equals to the given value.
      * This method tests also the angle by interchanging the given directions.
      */
-    private static void assertAngleEquals(final double expected, final AxisDirection source,
final AxisDirection target) {
-        assertEquals(+expected, angle(source, target), STRICT);
-        assertEquals(-expected, angle(target, source), STRICT);
+    private static void assertAngleEquals(final boolean isElevation, final double expected,
+            final AxisDirection source, final AxisDirection target)
+    {
+        final Angle forward = angle(source, target);
+        final Angle inverse = angle(target, source);
+        assertEquals(isElevation, forward instanceof ElevationAngle);
+        assertEquals(isElevation, inverse instanceof ElevationAngle);
+        assertEquals(+expected, (forward != null) ? forward.degrees() : Double.NaN, STRICT);
+        assertEquals(-expected, (inverse != null) ? inverse.degrees() : Double.NaN, STRICT);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -35,9 +35,9 @@ import static org.junit.Assert.*;
 @DependsOn(org.apache.sis.internal.referencing.AxisDirectionsTest.class)
 public final strictfp class DirectionAlongMeridianTest extends TestCase {
     /**
-     * For floating point comparisons.
+     * Tolerance threshold for strict floating point comparisons.
      */
-    private static final double EPS = 1E-10;
+    private static final double STRICT = 0;
 
     /**
      * Tests the {@link DirectionAlongMeridian#parse(AxisDirection)} method.
@@ -99,8 +99,8 @@ public final strictfp class DirectionAlo
     private static void assertOrdered(final String dir1, final String dir2) {
         final DirectionAlongMeridian m1 = DirectionAlongMeridian.parse(dir1);
         final DirectionAlongMeridian m2 = DirectionAlongMeridian.parse(dir2);
-        assertEquals(+90, m1.getAngle(m2), EPS);
-        assertEquals(-90, m2.getAngle(m1), EPS);
+        assertEquals(+90, m1.angle(m2), STRICT);
+        assertEquals(-90, m2.angle(m1), STRICT);
         assertEquals( -1, m1.compareTo(m2));
         assertEquals( +1, m2.compareTo(m1));
         assertFalse (m1.equals(m2));

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java [UTF-8]
(original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java [UTF-8]
Mon Jan 13 14:50:41 2014
@@ -31,18 +31,18 @@ import static org.apache.sis.math.MathFu
 
 /**
  * An angle in decimal degrees. An angle is the amount of rotation needed to bring one line
or plane
- * into coincidence with another, generally measured in degrees, sexagesimal degrees or grads.
- * Various kind of angles are used in geographic information systems,
+ * into coincidence with another. Various kind of angles are used in geographic information
systems,
  * some of them having a specialized class in Apache SIS:
  *
  * <ul>
- *   <li>{@linkplain Latitude} is an angle which ranges from 0° at the equator to
90° at the poles.</li>
- *   <li>{@linkplain Longitude} is an angle measured east-west from a prime meridian
- *       (usually Greenwich, but not necessarily).</li>
+ *   <li>{@linkplain Latitude} is an angle ranging from 0° at the equator to 90°
at the poles.</li>
+ *   <li>{@linkplain Longitude} is an angle measured east-west from a prime meridian
(usually Greenwich, but not necessarily).</li>
  *   <li><cite>Azimuth</cite> is a direction given by an angle between
0° and 360° measured clockwise from North.</li>
- *   <li><cite>Bearing</cite> is a direction given by an angle between
0° and 90° in a quadrant defined by a cardinal
- *       direction. Bearing is also sometime used for an angle relative to a vessel forward
direction.</li>
+ *   <li><cite>Bearing</cite> is a direction given by an angle between
0° and 90° in a quadrant defined by a cardinal direction.</li>
+ *   <li><cite>Bearing</cite> is also sometime used in navigation for an
angle relative to the vessel forward direction.</li>
+ *   <li><cite>Deflection angle</cite> is the angle between a line and
the prolongation of a preceding line.</li>
  *   <li><cite>Interior angle</cite> is an angle measured between two lines
of sight.</li>
+ *   <li><cite>Elevation angle</cite> is the angular height from the horizontal
plane to an object above the horizon.</li>
  * </ul>
  *
  * {@section Formatting angles}

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -195,7 +195,7 @@ public class AngleFormat extends Format 
     private static final int[] SYMBOLS = {'D', 'M', 'S', '#', '?'};
 
     /**
-     * Defines constants that are used as attribute keys in the iterator returned from
+     * Constants that are used as attribute keys in the iterator returned from
      * {@link AngleFormat#formatToCharacterIterator(Object)}.
      *
      * @author  Martin Desruisseaux (Geomatys)

Added: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java?rev=1557738&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
(added)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.measure;
+
+
+/**
+ * The angular height of an object measured from the horizontal.
+ * For visible objects it is an angle between 0 and 90 degrees.
+ *
+ * {@note <cite>Elevation angle</cite> and <cite>altitude angle</cite>
may be used interchangeably.
+ *        Both <cite>altitude</cite> and <cite>elevation</cite> words
are also used to describe the
+ *        height in meters above sea level.}
+ *
+ * {@section Immutability and thread safety}
+ * This final class is immutable and thus inherently thread-safe.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.4
+ * @version 0.4
+ * @module
+ */
+public final class ElevationAngle extends Angle {
+    /**
+     * Serial number for inter-operability with different versions.
+     */
+    private static final long serialVersionUID = 442355803542468396L;
+
+    /**
+     * An elevation angle of 90° for an imaginary point directly above a location.
+     * This is the opposite of {@link #NADIR} direction.
+     */
+    public static final ElevationAngle ZENITH = new ElevationAngle(90);
+
+    /**
+     * An elevation angle of -90° for an imaginary point directly below a location.
+     * This is the opposite of {@link #ZENITH} direction.
+     */
+    public static final ElevationAngle NADIR = new ElevationAngle(-90);
+
+    /**
+     * Constructs a new elevation angle with the specified angular value.
+     *
+     * @param θ Elevation angle value in decimal degrees.
+     */
+    public ElevationAngle(final double θ) {
+        super(θ);
+    }
+
+    /**
+     * Constructs a newly allocated {@code ElevationAngle} object that contain the angular
value
+     * represented by the string. The string should represent an angle in either fractional
degrees
+     * (e.g. 45.5°) or degrees with minutes and seconds (e.g. 45°30').
+     *
+     * @param  string A string to be converted to an {@code ElevationAngle}.
+     * @throws NumberFormatException if the string does not contain a parsable angle,
+     *         or represents an elevation angle.
+     */
+    public ElevationAngle(final String string) throws NumberFormatException {
+        super(string);
+    }
+}

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ElevationAngle.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -40,7 +40,7 @@ package org.apache.sis.measure;
  * {@linkplain org.apache.sis.referencing.crs.DefaultGeographicCRS geographic},
  * or <cite>geocentric</cite> if the coordinate reference system is
  * {@linkplain org.apache.sis.referencing.crs.DefaultGeocentricCRS geocentric}.
- * If the context is unknown, geodetic latitude can usually be assumed.
+ * If the context is unknown, then geodetic latitude can usually be assumed.
  *
  * {@section Immutability and thread safety}
  * This final class is immutable and thus inherently thread-safe.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java?rev=1557738&r1=1557737&r2=1557738&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java
[UTF-8] Mon Jan 13 14:50:41 2014
@@ -123,7 +123,7 @@ public class RangeFormat extends Format 
     private static final int UNIT_FIELD = 2;
 
     /**
-     * Defines constants that are used as attribute keys in the iterator returned from
+     * Constants that are used as attribute keys in the iterator returned from
      * {@link RangeFormat#formatToCharacterIterator(Object)}.
      *
      * @author  Martin Desruisseaux (Geomatys)



Mime
View raw message