sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1735272 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/internal/metadata/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/referencing/cs/ sis-referenc...
Date Wed, 16 Mar 2016 17:58:44 GMT
Author: desruisseaux
Date: Wed Mar 16 17:58:44 2016
New Revision: 1735272

URL: http://svn.apache.org/viewvc?rev=1735272&view=rev
Log:
More robust normalization of axis order and orientation in the context of PolarCS and CylindricalCS.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCylindricalCSTest.java
      - copied, changed from r1735209, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxisFilter.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToCylindrical.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CylindricalToCartesian.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.HashMap;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Angle;
+import org.opengis.annotation.UML;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
@@ -30,6 +31,8 @@ import org.apache.sis.util.iso.Types;
 import org.apache.sis.measure.Units;
 
 import static org.opengis.referencing.cs.AxisDirection.*;
+import static org.opengis.annotation.Obligation.CONDITIONAL;
+import static org.opengis.annotation.Specification.ISO_19162;
 import static org.apache.sis.util.CharSequences.*;
 
 
@@ -66,6 +69,7 @@ public final class AxisDirections extend
      *
      * @since 0.7
      */
+    @UML(identifier="clockwise", obligation=CONDITIONAL, specification=ISO_19162)
     public static final AxisDirection CLOCKWISE = AxisDirection.valueOf("CLOCKWISE");
 
     /**
@@ -74,6 +78,7 @@ public final class AxisDirections extend
      *
      * @since 0.7
      */
+    @UML(identifier="counterclockwise", obligation=CONDITIONAL, specification=ISO_19162)
     public static final AxisDirection COUNTERCLOCKWISE = AxisDirection.valueOf("COUNTERCLOCKWISE");
 
     /**
@@ -160,11 +165,16 @@ public final class AxisDirections extend
      * @param  dir The direction for which to return the absolute direction, or {@code null}.
      * @return The direction from the above table, or {@code null} if the given direction was null.
      */
-    public static AxisDirection absolute(final AxisDirection dir) {
+    public static AxisDirection absolute(AxisDirection dir) {
         final AxisDirection opposite = opposite(dir);
         if (opposite != null) {
             if (opposite.ordinal() < dir.ordinal()) {
-                return opposite;
+                dir = opposite;
+            }
+            // Below is a temporary patch pending integration of code list values into GeoAPI.
+            // We need this patch because we can not rely on ordinal() value for custom codes.
+            if (dir == CLOCKWISE) {
+                dir = COUNTERCLOCKWISE;
             }
         }
         return dir;
@@ -564,10 +574,14 @@ public final class AxisDirections extend
     }
 
     /**
-     * Returns {@code true} if the given name starts with the given keyword, ignoring case.
+     * Returns {@code true} if the given name starts or ends with the given keyword, ignoring case.
+     *
+     * @param start {@code false} if the given keyword is expected at the beggining of the name,
+     *        or {@code end} if expected at the end.
      */
-    private static boolean startsWith(final String name, final String keyword) {
-        return name.regionMatches(true, 0, keyword, 0, keyword.length());
+    private static boolean contains(final String name, final String keyword, final boolean end) {
+        final int length = keyword.length();
+        return name.regionMatches(true, end ? name.length() - length : 0, keyword, 0, length);
     }
 
     /**
@@ -588,12 +602,18 @@ public final class AxisDirections extend
         }
         if (isCompass(direction)) {
             /*
+             * Radius at θ = 0° may be oriented toward North, but we do not want the "N" abbreviation.
+             */
+            if (contains(name, "radius", true)) {
+                return "r";
+            }
+            /*
              * NORTH, EAST, SOUTH, WEST and all intercardinal directions (SOUTH_SOUTH_WEST, etc.):
              * we will use the acronym (e.g. "SE" for SOUTH_EAST), unless the axis is likely to be
              * a longitude or latitude axis. We detect those later cases by the unit of measurement.
              */
             if (!isIntercardinal(direction) && Units.isAngular(unit)) {
-                if (startsWith(name, "Spherical")) {
+                if (contains(name, "Spherical", false)) {
                     return NORTH.equals(absolute(direction)) ? "φ′" : "θ";
                 } else {
                     return NORTH.equals(absolute(direction)) ? "φ" : "λ";
@@ -607,7 +627,7 @@ public final class AxisDirections extend
              * use "h" as the fallback for unknown vertical axis.
              */
             if (UP.equals(direction)) {
-                return startsWith(name, "Gravity") ? "H" : startsWith(name, "Geocentric") ? "r": "h";
+                return contains(name, "Gravity", false) ? "H" : contains(name, "Geocentric", false) ? "r": "h";
             } else if (DOWN.equals(direction)) {
                 return "D"; // "Depth"
             } else if (isGeocentric(direction)) {
@@ -628,6 +648,8 @@ public final class AxisDirections extend
                 return "y";
             } else if (OTHER.equals(a)) {
                 return "z";                     // Arbitrary abbreviation, may change in any future SIS version.
+            } else if (COUNTERCLOCKWISE.equals(a)) {
+                return "θ";
             }
         }
         final String id = direction.identifier();   // UML identifier, or null if none.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -20,6 +20,7 @@ import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.cs.AxisFilter;
 import org.apache.sis.referencing.cs.CoordinateSystems;
@@ -120,7 +121,7 @@ public final class Legacy implements Axi
     // -----------------------------------------------------------------
 
     /**
-     * The value to be returned by {@link #getUnitReplacement(Unit)},
+     * The value to be returned by {@link #getUnitReplacement(CoordinateSystemAxis, Unit)},
      * or {@code null} if no replacement should be done.
      */
     private final Unit<?> replacement;
@@ -135,11 +136,12 @@ public final class Legacy implements Axi
     /**
      * For internal usage by {@link #replaceUnit(CartesianCS, Unit)} only.
      *
+     * @param  axis ignored.
      * @param  unit ignored.
      * @return The unit of the new coordinate system.
      */
     @Override
-    public Unit<?> getUnitReplacement(final Unit<?> unit) {
+    public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, final Unit<?> unit) {
         return replacement;
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -21,6 +21,7 @@ import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;                 // For javadoc
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.internal.metadata.AxisDirections;
 import org.apache.sis.measure.Units;
 
@@ -107,7 +108,7 @@ import org.apache.sis.measure.Units;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see AbstractCS#forConvention(AxesConvention)
@@ -147,7 +148,7 @@ public enum AxesConvention implements Ax
      */
     NORMALIZED {
         @Override
-        public Unit<?> getUnitReplacement(Unit<?> unit) {
+        public Unit<?> getUnitReplacement(final CoordinateSystemAxis axis, Unit<?> unit) {
             if (Units.isLinear(unit)) {
                 unit = SI.METRE;
             } else if (Units.isAngular(unit)) {
@@ -158,18 +159,29 @@ public enum AxesConvention implements Ax
             return unit;
         }
 
-        /*
-         * Same policy than AxesConvention.CONVENTIONALLY_ORIENTATED.
-         */
         @Override
-        public AxisDirection getDirectionReplacement(final AxisDirection direction) {
-            return AxisDirections.isIntercardinal(direction) ? direction : AxisDirections.absolute(direction);
+        public AxisDirection getDirectionReplacement(final CoordinateSystemAxis axis, final AxisDirection direction) {
+            /*
+             * For now we do not touch to inter-cardinal directions (e.g. "North-East")
+             * because it is not clear which normalization policy would match common usage.
+             */
+            if (!AxisDirections.isIntercardinal(direction)) {
+                /*
+                 * Change the direction only if the axis allows negative values.
+                 * If the axis accepts only positive values, then the direction
+                 * is considered non-invertible.
+                 */
+                if (axis == null || axis.getMinimumValue() < 0) {
+                    return AxisDirections.absolute(direction);
+                }
+            }
+            return direction;
         }
     },
 
     /**
      * Axes are oriented toward conventional directions and ordered for a {@linkplain #RIGHT_HANDED right-handed}
-     * coordinate system. Ranges of ordinate values and units of measurement are unchanged.
+     * coordinate system. Units of measurement are unchanged.
      *
      * <p>More specifically, directions opposites to the following ones are replaced by their "forward" counterpart
      * (e.g. {@code SOUTH} → {@code NORTH}):</p>
@@ -215,13 +227,8 @@ public enum AxesConvention implements Ax
      * @since 0.5
      */
     CONVENTIONALLY_ORIENTED {
-        /*
-         * For now we do not touch to inter-cardinal directions (e.g. "North-East")
-         * because it is not clear which normalization policy would match common usage.
-         */
-        @Override
-        public AxisDirection getDirectionReplacement(final AxisDirection direction) {
-            return AxisDirections.isIntercardinal(direction) ? direction : AxisDirections.absolute(direction);
+        @Override public AxisDirection getDirectionReplacement(CoordinateSystemAxis axis, AxisDirection direction) {
+            return NORMALIZED.getDirectionReplacement(axis, direction);
         }
     },
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxisFilter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxisFilter.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxisFilter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxisFilter.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -46,7 +46,7 @@ import javax.measure.unit.Unit;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)
@@ -73,7 +73,7 @@ public interface AxisFilter {
      *
      * {@preformat java
      *     &#64;Override
-     *     public getDirectionReplacement(AxisDirection direction) {
+     *     public getDirectionReplacement(CoordinateSystemAxis axis, AxisDirection direction) {
      *         if (direction == AxisDirection.DOWN) {
      *             direction = AxisDirection.UP;
      *         }
@@ -82,14 +82,25 @@ public interface AxisFilter {
      * }
      * </div>
      *
+     * @param  axis The axis for which to change axis direction, if desired.
      * @param  direction The original axis direction.
      * @return The new axis direction, or {@code direction} if there is no change.
+     *
+     * @since 0.7
      */
-    default AxisDirection getDirectionReplacement(AxisDirection direction) {
+    default AxisDirection getDirectionReplacement(CoordinateSystemAxis axis, AxisDirection direction) {
         return direction;
     }
 
     /**
+     * @deprecated Use {@link #getDirectionReplacement(CoordinateSystemAxis, AxisDirection)} instead.
+     */
+    @Deprecated
+    default AxisDirection getDirectionReplacement(AxisDirection direction) {
+        return getDirectionReplacement(null, direction);
+    }
+
+    /**
      * Returns a replacement for the given axis unit.
      * The default implementation unconditionally returns the given {@code unit} unchanged.
      *
@@ -99,7 +110,7 @@ public interface AxisFilter {
      *
      * {@preformat java
      *     &#64;Override
-     *     public Unit<?> getUnitReplacement(Unit<?> unit) {
+     *     public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> unit) {
      *         if (Units.isAngular(unit)) {
      *             unit = NonSI.DEGREE_ANGLE;
      *         }
@@ -108,10 +119,21 @@ public interface AxisFilter {
      * }
      * </div>
      *
+     * @param  axis The axis for which to change unit, if desired.
      * @param  unit The original axis unit.
      * @return The new axis unit, or {@code unit} if there is no change.
+     *
+     * @since 0.7
      */
-    default Unit<?> getUnitReplacement(Unit<?> unit) {
+    default Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> unit) {
         return unit;
     }
+
+    /**
+     * @deprecated Use {@link #getUnitReplacement(CoordinateSystemAxis, Unit)} instead.
+     */
+    @Deprecated
+    default Unit<?> getUnitReplacement(Unit<?> unit) {
+        return getUnitReplacement(null, unit);
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -349,7 +349,7 @@ public final class CoordinateSystems ext
      *     CoordinateSystem cs = ...;
      *     cs = CoordinateSystems.replaceAxes(cs, new AxisFilter() {
      *         &#64;Override
-     *         public Unit<?> getUnitReplacement(Unit<?> unit) {
+     *         public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> unit) {
      *             if (Units.isAngular(unit)) {
      *                 unit = NonSI.DEGREE_ANGLE;
      *             }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -165,7 +165,7 @@ public class DefaultCylindricalCS extend
         if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
-        if (!Units.isLinear(unit)) {
+        if (!Units.isAngular(unit) && !Units.isLinear(unit)) {
             return INVALID_UNIT;
         }
         return VALID;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -157,7 +157,7 @@ public class DefaultLinearCS extends Abs
         if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
-        if (!Units.isLinear(unit)) {
+        if (!Units.isLinear(unit) && !Unit.ONE.equals(unit)) {
             return INVALID_UNIT;
         }
         return VALID;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -26,11 +26,16 @@ import org.opengis.referencing.cs.RangeM
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.CylindricalCS;
+import org.opengis.referencing.cs.PolarCS;
 import org.apache.sis.internal.metadata.AxisDirections;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArraysExt;
+import org.apache.sis.measure.Units;
 
 import static java.util.Collections.singletonMap;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
@@ -50,12 +55,39 @@ import static org.apache.sis.internal.re
  * The main usage for this class is to reorder the axes in some fixed order like
  * (<var>x</var>, <var>y</var>, <var>z</var>) or (<var>longitude</var>, <var>latitude</var>).
  *
+ * <p>The normalization performed by this class shall be compatible with axis order expected by various
+ * {@code MathTransform} implementations in the {@link org.apache.sis.referencing.operation.transform} package.
+ * In particular:</p>
+ *
+ * <ul>
+ *   <li>{@code EllipsoidToCentricTransform} input:<ol>
+ *     <li>Geodetic longitude (λ) in degrees</li>
+ *     <li>Geodetic latitude (φ) in degrees</li>
+ *     <li>Height in units of semi-axes</li>
+ *   </ol></li>
+ *   <li>{@code SphericalToCartesian} input:<ol>
+ *     <li>Spherical longitude in degrees</li>
+ *     <li>Spherical latitude in degrees</li>
+ *     <li>Spherical radius (r) in any units</li>
+ *   </ol></li>
+ *   <li>{@code CartesianToSpherical} input:<ol>
+ *     <li>X in units of the above radius</li>
+ *     <li>Y in units of the above radius</li>
+ *     <li>Z in units of the above radius</li>
+ *   </ol></li>
+ *   <li>{@code CylindricalToCartesian} input:<ol>
+ *     <li>Radius (r) in any units</li>
+ *     <li>Angle (θ) in degrees</li>
+ *     <li>Height (z) in any units</li>
+ *   </ol></li>
+ * </ul>
+ *
  * <p>This class implements {@link Comparable} for opportunist reasons.
  * This should be considered as an implementation details.</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 final class Normalizer implements Comparable<Normalizer> {
@@ -78,10 +110,19 @@ final class Normalizer implements Compar
     private final DirectionAlongMeridian meridian;
 
     /**
+     * Angular units order relative to other units.
+     * A value of -1 means that angular units should be first.
+     * A value of +1 means than angular units should be last.
+     * A value of 0 means to not use this criterion.
+     */
+    private final int unitOrder;
+
+    /**
      * For internal usage by {@link #sort(CoordinateSystemAxis[])} only.
      */
-    private Normalizer(final CoordinateSystemAxis axis) {
+    private Normalizer(final CoordinateSystemAxis axis, final int angularUnitOrder) {
         this.axis = axis;
+        unitOrder = Units.isAngular(axis.getUnit()) ? angularUnitOrder : 0;
         final AxisDirection dir = axis.getDirection();
         meridian = AxisDirections.isUserDefined(dir) ? DirectionAlongMeridian.parse(dir) : null;
     }
@@ -92,6 +133,10 @@ final class Normalizer implements Compar
      */
     @Override
     public int compareTo(final Normalizer that) {
+        final int d = unitOrder - that.unitOrder;
+        if (d != 0) {
+            return d;
+        }
         final AxisDirection d1 = this.axis.getDirection();
         final AxisDirection d2 = that.axis.getDirection();
         final int compass = AxisDirections.angleForCompass(d2, d1);
@@ -113,18 +158,21 @@ final class Normalizer implements Compar
      * Sorts the specified axis in an attempt to create a right-handed system.
      * The sorting is performed in place. This method returns {@code true} if
      * at least one axis moved as result of this method call.
+     *
+     * @param axes The axes to sort.
+     * @param angularUnitOrder -1 for sorting angular units first, +1 for sorting them last, or 0 if neutral.
      */
-    static boolean sort(final CoordinateSystemAxis[] axis) {
-        final Normalizer[] wrappers = new Normalizer[axis.length];
-        for (int i=0; i<axis.length; i++) {
-            wrappers[i] = new Normalizer(axis[i]);
+    static boolean sort(final CoordinateSystemAxis[] axes, final int angularUnitOrder) {
+        final Normalizer[] wrappers = new Normalizer[axes.length];
+        for (int i=0; i<axes.length; i++) {
+            wrappers[i] = new Normalizer(axes[i], angularUnitOrder);
         }
         Arrays.sort(wrappers);
         boolean changed = false;
-        for (int i=0; i<axis.length; i++) {
+        for (int i=0; i<axes.length; i++) {
             final CoordinateSystemAxis a = wrappers[i].axis;
-            changed |= (axis[i] != a);
-            axis[i] = a;
+            changed |= (axes[i] != a);
+            axes[i] = a;
         }
         return changed;
     }
@@ -140,8 +188,8 @@ final class Normalizer implements Compar
     static CoordinateSystemAxis normalize(final CoordinateSystemAxis axis, final AxisFilter changes) {
         final Unit<?>       unit      = axis.getUnit();
         final AxisDirection direction = axis.getDirection();
-        final Unit<?>       newUnit   = changes.getUnitReplacement(unit);
-        final AxisDirection newDir    = changes.getDirectionReplacement(direction);
+        final Unit<?>       newUnit   = changes.getUnitReplacement(axis, unit);
+        final AxisDirection newDir    = changes.getDirectionReplacement(axis, direction);
         /*
          * Reuse some properties (name, remarks, etc.) from the existing axis. If the direction changed,
          * then the axis name may need change too (e.g. "Westing" → "Easting"). The new axis name may be
@@ -176,18 +224,30 @@ final class Normalizer implements Compar
             properties.put(NAME_KEY, UNNAMED);
         }
         /*
-         * Converts the axis range and build the new axis.
+         * Convert the axis range and build the new axis. The axis range will be converted only if
+         * the axis direction is the same or the opposite, otherwise we do not know what should be
+         * the new values. In the particular case of opposite axis direction, we need to reverse the
+         * sign of minimum and maximum values.
          */
-        final UnitConverter c;
-        try {
-            c = unit.getConverterToAny(newUnit);
-        } catch (ConversionException e) {
-            // Use IllegalStateException because the public API is an AbstractCS member method.
-            throw new IllegalStateException(Errors.format(Errors.Keys.IllegalUnitFor_2, "axis", unit), e);
-        }
-        properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, c.convert(axis.getMinimumValue()));
-        properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, c.convert(axis.getMaximumValue()));
-        properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, axis.getRangeMeaning());
+        if (sameDirection || newDir.equals(AxisDirections.opposite(direction))) {
+            final UnitConverter c;
+            try {
+                c = unit.getConverterToAny(newUnit);
+            } catch (ConversionException e) {
+                // Use IllegalStateException because the public API is an AbstractCS member method.
+                throw new IllegalStateException(Errors.format(Errors.Keys.IllegalUnitFor_2, "axis", unit), e);
+            }
+            double minimum = c.convert(axis.getMinimumValue());
+            double maximum = c.convert(axis.getMaximumValue());
+            if (!sameDirection) {
+                final double tmp = minimum;
+                minimum = -maximum;
+                maximum = -tmp;
+            }
+            properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, minimum);
+            properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, maximum);
+            properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, axis.getRangeMeaning());
+        }
         return new DefaultCoordinateSystemAxis(properties, newAbbr, newDir, newUnit);
     }
 
@@ -221,7 +281,26 @@ final class Normalizer implements Compar
          * If nothing changed, return the given Coordinate System as-is.
          */
         if (reorder) {
-            changed |= sort(axes);
+            int angularUnitOrder = 0;
+            if  (cs instanceof EllipsoidalCS || cs instanceof SphericalCS) angularUnitOrder = -1;      // (λ,φ,h) order
+            else if (cs instanceof CylindricalCS || cs instanceof PolarCS) angularUnitOrder = +1;      // (r,θ) order
+            changed |= sort(axes, angularUnitOrder);
+            if (angularUnitOrder == 1) {                            // Cylindrical or polar
+                /*
+                 * Change (r,z,θ) to (r,θ,z) order in CylindricalCS. The check on unit of
+                 * measurements should be always true, but we verify as a paranoiac check.
+                 */
+                if (axes.length == 3 && isLengthAndAngle(axes, 1)) {
+                    ArraysExt.swap(axes, 1, 2);
+                }
+                /*
+                 * If we were not allowed to normalize the axis direction, we may have a
+                 * left-handed coordinate system here. Is so, make it right-handed.
+                 */
+                if (AxisDirections.CLOCKWISE.equals(axes[1].getDirection()) && isLengthAndAngle(axes, 0)) {
+                    ArraysExt.swap(axes, 0, 1);
+                }
+            }
         }
         if (!changed && n == dimension) {
             return null;
@@ -236,6 +315,14 @@ final class Normalizer implements Compar
     }
 
     /**
+     * Returns {@code true} if the units of measurement at the given position is a linear unit,
+     * followed by an angular unit on the next axis.
+     */
+    private static boolean isLengthAndAngle(final CoordinateSystemAxis[] axes, final int p) {
+        return Units.isLinear(axes[p].getUnit()) && Units.isAngular(axes[p+1].getUnit());
+    }
+
+    /**
      * Returns a coordinate system with the same axes than the given CS, except that the wrapround axes
      * are shifted to a range of positive values. This method can be used in order to shift between the
      * [-180 … +180]° and [0 … 360]° ranges of longitude values.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -42,6 +42,7 @@ import org.opengis.referencing.crs.Singl
 import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.datum.DatumFactory;
 import org.opengis.referencing.datum.EngineeringDatum;
 import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
@@ -634,7 +635,7 @@ public class CommonAuthorityFactory exte
             }
             if (!SI.METRE.equals(unit)) {
                 cs = (CartesianCS) CoordinateSystems.replaceAxes(cs, new AxisFilter() {
-                    @Override public Unit<?> getUnitReplacement(Unit<?> ignored) {
+                    @Override public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> ignored) {
                         assert SI.METRE.equals(ignored) : ignored;
                         return unit;
                     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -251,6 +251,8 @@ public abstract class AbstractMathTransf
      *   <li>Delegates to the {@link #transform(double[], int, double[], int, boolean)} method.</li>
      * </ul>
      *
+     * This method does not update the associated {@link org.opengis.referencing.crs.CoordinateReferenceSystem} value.
+     *
      * @param  ptSrc the coordinate point to be transformed.
      * @param  ptDst the coordinate point that stores the result of transforming {@code ptSrc}, or {@code null}.
      * @return the coordinate point after transforming {@code ptSrc} and storing the result in {@code ptDst},

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToCylindrical.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToCylindrical.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToCylindrical.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToCylindrical.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -31,7 +31,8 @@ import static java.lang.Math.*;
  * This class is also used for polar conversions by just dropping the <var>z</var> ordinate.
  * This conversion assumes that there is no datum change.
  *
- * <p>See {@link CylindricalToCartesian} for explanation on axes convention.</p>
+ * <p>See {@link CylindricalToCartesian} for explanation on axes convention.
+ * Axis order shall match the order defined by {@code Normalizer} in {@link org.apache.sis.referencing.cs} package.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -29,7 +29,8 @@ import static java.lang.Math.*;
  * Conversions from three-dimensional Cartesian coordinates to spherical coordinates.
  * This conversion assumes that there is no datum change.
  *
- * <p>See {@link SphericalToCartesian} for explanation on axes convention.</p>
+ * <p>See {@link SphericalToCartesian} for explanation on axes convention.
+ * Axis order shall match the order defined by {@code Normalizer} in {@link org.apache.sis.referencing.cs} package.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CylindricalToCartesian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CylindricalToCartesian.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CylindricalToCartesian.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CylindricalToCartesian.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -45,6 +45,8 @@ import static java.lang.Math.*;
  *   <li><var>z</var> in the some direction than the source</li>
  * </ul>
  *
+ * Axis order shall match the order defined by {@code Normalizer} in {@link org.apache.sis.referencing.cs} package.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -38,6 +38,7 @@ import static java.lang.Math.*;
  * the spherical latitude is related to geodetic latitude φ by {@literal Ω(φ) = atan((1-ℯ²)⋅tan(φ))}.</div>
  *
  * This order matches the {@link EllipsoidToCentricTransform} axis order.
+ * It shall also match the order defined by {@code Normalizer} in {@link org.apache.sis.referencing.cs} package.
  * Note that this is <strong>not</strong> the convention used neither in physics (ISO 80000-2:2009) or in mathematics.
  *
  * <div class="note"><b>Relationship with the convention used in physics</b>

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -286,7 +286,7 @@ public final strictfp class CoordinateSy
             }
 
             @Override
-            public Unit<?> getUnitReplacement(Unit<?> unit) {
+            public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> unit) {
                 if (Units.isAngular(unit)) {
                     unit = NonSI.GRADE;
                 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -170,8 +170,8 @@ public final strictfp class DefaultCarte
      * Then ensures that swapping the axes and applying conventional orientation gives back the original CS.
      */
     private static void testConventionalOrientation(final String x, final String y) {
-        assertConventionallyOrientedEquals(x, y, x, y); // Expect no-op.
-        assertConventionallyOrientedEquals(x, y, y, x); // Expect normalization.
+        assertConventionallyOrientedEquals(x, y, x, y);         // Expect no-op.
+        assertConventionallyOrientedEquals(x, y, y, x);         // Expect normalization.
     }
 
     /**

Copied: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCylindricalCSTest.java (from r1735209, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCylindricalCSTest.java?p2=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCylindricalCSTest.java&p1=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java&r1=1735209&r2=1735272&rev=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCylindricalCSTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -17,36 +17,56 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Collections;
+import org.opengis.referencing.cs.AxisDirection;
+import org.apache.sis.internal.metadata.AxisDirections;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static org.apache.sis.test.Assert.*;
-import static org.apache.sis.referencing.cs.HardCodedCS.*;
+import static org.opengis.test.Assert.*;
 
 
 /**
- * Tests {@link DefaultSphericalCS}.
+ * Tests {@link DefaultCylindricalCS}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.4
- * @version 0.5
+ * @since   0.7
+ * @version 0.7
  * @module
  */
 @DependsOn(AbstractCSTest.class)
-public final strictfp class DefaultSphericalCSTest extends TestCase {
+public final strictfp class DefaultCylindricalCSTest extends TestCase {
     /**
-     * Tests the conventional orientation of a coordinate system.
+     * Tests {@link DefaultCylindricalCS#forConvention(AxesConvention)}
+     * with a change from clockwise to counterclockwise axis orientation.
      */
     @Test
-    public void testConventionalOrientation() {
-        final AbstractCS normalized = SPHERICAL.forConvention(AxesConvention.CONVENTIONALLY_ORIENTED);
-        assertNotSame(SPHERICAL, normalized);
-        assertEquals(new DefaultSphericalCS(
-            Collections.singletonMap(AbstractCS.NAME_KEY, "Spherical CS: East (°), North (°), Up (m)."),
-            HardCodedAxes.SPHERICAL_LONGITUDE,
-            HardCodedAxes.SPHERICAL_LATITUDE,
-            HardCodedAxes.GEOCENTRIC_RADIUS
-        ), normalized);
+    public void testChangeClockwiseOrientation() {
+        final DefaultCylindricalCS cs = HardCodedCS.CYLINDRICAL;
+        final DefaultCylindricalCS normalized = cs.forConvention(AxesConvention.CONVENTIONALLY_ORIENTED);
+        assertNotSame("Should create a new CoordinateSystem.", cs, normalized);
+        assertAxisDirectionsEqual("Normalized", normalized,
+                AxisDirection.SOUTH,                        // Not modified to North because radius can not be negative.
+                AxisDirections.COUNTERCLOCKWISE,
+                AxisDirection.UP);
+    }
+
+    /**
+     * Tests {@link DefaultCylindricalCS#forConvention(AxesConvention)} with a change of axis order.
+     */
+    @Test
+    public void testChangeAxisOrder() {
+        final DefaultCylindricalCS cs = new DefaultCylindricalCS(
+                Collections.singletonMap(DefaultCylindricalCS.NAME_KEY, "Cylindrical"),
+                HardCodedAxes.AZIMUTH,
+                HardCodedAxes.Z,
+                HardCodedAxes.RADIUS);
+
+        final DefaultCylindricalCS normalized = cs.forConvention(AxesConvention.RIGHT_HANDED);
+        assertNotSame("Should create a new CoordinateSystem.", cs, normalized);
+        assertAxisDirectionsEqual("Normalized", normalized,
+                AxisDirections.CLOCKWISE,                       // Interchanged (r,θ) order for making right handed.
+                AxisDirection.SOUTH,
+                AxisDirection.UP);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -17,12 +17,12 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Collections;
+import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static org.apache.sis.test.Assert.*;
-import static org.apache.sis.referencing.cs.HardCodedCS.*;
+import static org.opengis.test.Assert.*;
 
 
 /**
@@ -30,23 +30,29 @@ import static org.apache.sis.referencing
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @DependsOn(AbstractCSTest.class)
 public final strictfp class DefaultSphericalCSTest extends TestCase {
     /**
-     * Tests the conventional orientation of a coordinate system.
+     * Tests {@link DefaultSphericalCS#forConvention(AxesConvention)} with a change of axis order.
      */
     @Test
-    public void testConventionalOrientation() {
-        final AbstractCS normalized = SPHERICAL.forConvention(AxesConvention.CONVENTIONALLY_ORIENTED);
-        assertNotSame(SPHERICAL, normalized);
+    public void testChangeAxisOrder() {
+        final DefaultSphericalCS cs = HardCodedCS.SPHERICAL;
+        final DefaultSphericalCS normalized = cs.forConvention(AxesConvention.CONVENTIONALLY_ORIENTED);
+        assertNotSame("Should create a new CoordinateSystem.", cs, normalized);
+        assertAxisDirectionsEqual("Normalized", normalized,
+                AxisDirection.EAST,
+                AxisDirection.NORTH,
+                AxisDirection.UP);
+
         assertEquals(new DefaultSphericalCS(
-            Collections.singletonMap(AbstractCS.NAME_KEY, "Spherical CS: East (°), North (°), Up (m)."),
-            HardCodedAxes.SPHERICAL_LONGITUDE,
-            HardCodedAxes.SPHERICAL_LATITUDE,
-            HardCodedAxes.GEOCENTRIC_RADIUS
+                Collections.singletonMap(AbstractCS.NAME_KEY, "Spherical CS: East (°), North (°), Up (m)."),
+                HardCodedAxes.SPHERICAL_LONGITUDE,
+                HardCodedAxes.SPHERICAL_LATITUDE,
+                HardCodedAxes.GEOCENTRIC_RADIUS
         ), normalized);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -24,6 +24,7 @@ import javax.measure.unit.NonSI;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.RangeMeaning;
 import org.apache.sis.internal.metadata.AxisNames;
+import org.apache.sis.internal.metadata.AxisDirections;
 
 
 /**
@@ -31,7 +32,7 @@ import org.apache.sis.internal.metadata.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public final strictfp class HardCodedAxes {
@@ -189,7 +190,8 @@ public final strictfp class HardCodedAxe
      *
      * <p>This axis is close to the definition found in the EPSG database, except for the "long" abbreviation which
      * is replaced by "θ". Note that other conventions exist, in which the meaning of φ and θ are interchanged.
-     * ISO mentions also the symbol Ω, but it is not clear if it applies to longitude or latitude.</p>
+     * ISO mentions also the symbol Ω, but it is not clear if it applies to longitude or latitude.
+     * See {@link AxisNames#SPHERICAL_LONGITUDE} for other information.</p>
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
@@ -213,7 +215,8 @@ public final strictfp class HardCodedAxe
      * <p>This axis is close to the definition found in the EPSG database, except for the "lat" abbreviation
      * which is replaced by "φ′". Note that other conventions exist, in which the meaning of φ and θ are
      * interchanged or in which this axis is named "elevation" and is oriented toward "Up".
-     * Other conventions use symbol Ψ or Ω.</p>
+     * Other conventions use symbol Ψ or Ω.
+     * See {@link AxisNames#SPHERICAL_LATITUDE} for other information.</p>
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
@@ -366,16 +369,28 @@ public final strictfp class HardCodedAxe
     /**
      * An axis with North-East orientation.
      */
-    static final DefaultCoordinateSystemAxis NORTH_EAST = create("NORTH_EAST", "NE",
+    public static final DefaultCoordinateSystemAxis NORTH_EAST = create("North-East", "NE",
             AxisDirection.NORTH_EAST, SI.METRE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, null);
 
     /**
      * An axis with South-East orientation.
      */
-    static final DefaultCoordinateSystemAxis SOUTH_EAST = create("SOUTH_EAST", "SE",
+    public static final DefaultCoordinateSystemAxis SOUTH_EAST = create("South-East", "SE",
             AxisDirection.SOUTH_EAST, SI.METRE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, null);
 
     /**
+     * An axis for a radius oriented toward South.
+     */
+    public static final DefaultCoordinateSystemAxis RADIUS = create("Radius", "r",
+            AxisDirection.SOUTH, SI.METRE, 0, Double.POSITIVE_INFINITY, RangeMeaning.EXACT);
+
+    /**
+     * An axis with clockwise orientation.
+     */
+    public static final DefaultCoordinateSystemAxis AZIMUTH = create("Azimuth", "θ",
+            AxisDirections.CLOCKWISE, NonSI.DEGREE_ANGLE, -180, +180, RangeMeaning.WRAPAROUND);
+
+    /**
      * Axis for time values in a {@linkplain org.apache.sis.referencing.cs.DefaultTimeCS time CS}.
      * Increasing time go toward {@linkplain AxisDirection#FUTURE future} and units are {@linkplain NonSI#DAY days}.
      * The abbreviation is lower case <cite>"t"</cite>.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -31,7 +31,7 @@ import static org.apache.sis.referencing
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 public final strictfp class HardCodedCS {
@@ -111,6 +111,21 @@ public final strictfp class HardCodedCS
             HardCodedAxes.GEOCENTRIC_Z);
 
     /**
+     * A three-dimensional cylindrical CS with
+     * <var>{@linkplain HardCodedAxes#RADIUS radius} (oriented toward south)</var>,
+     * <var>{@linkplain HardCodedAxes#AZIMUTH azimuth}</var>,
+     * <var>{@linkplain HardCodedAxes#Z z}</var> axes.
+     * Note that this is not a right-handed system.
+     *
+     * @since 0.7
+     */
+    public static final DefaultCylindricalCS CYLINDRICAL = new DefaultCylindricalCS(
+            singletonMap(NAME_KEY, "Cylindrical"),
+            HardCodedAxes.RADIUS,
+            HardCodedAxes.AZIMUTH,
+            HardCodedAxes.Z);
+
+    /**
      * A two-dimensional Cartesian CS with
      * <var>{@linkplain HardCodedAxes#EASTING Easting}</var>,
      * <var>{@linkplain HardCodedAxes#NORTHING Northing}</var>

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -36,7 +36,7 @@ import static org.apache.sis.test.Refere
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -70,8 +70,8 @@ public final strictfp class NormalizerTe
 
         // A plausible CS.
         assertOrdered(new AxisDirection[] {
-            AxisDirection.EAST,    // Right handed-rule
-            AxisDirection.NORTH,   // Right handed-rule
+            AxisDirection.EAST,                 // Right handed-rule
+            AxisDirection.NORTH,                // Right handed-rule
             AxisDirection.UP
         }, new AxisDirection[] {
             AxisDirection.NORTH,
@@ -82,8 +82,8 @@ public final strictfp class NormalizerTe
         // A very dummy CS just for testing. The order of
         // any non-compass direction should be unchanged.
         assertOrdered(new AxisDirection[] {
-            AxisDirection.NORTH_EAST,        // Right handed-rule
-            AxisDirection.NORTH_NORTH_WEST,  // Right handed-rule
+            AxisDirection.NORTH_EAST,           // Right handed-rule
+            AxisDirection.NORTH_NORTH_WEST,     // Right handed-rule
             AxisDirection.GEOCENTRIC_X,
             AxisDirection.GEOCENTRIC_Y,
             AxisDirection.PAST
@@ -97,8 +97,8 @@ public final strictfp class NormalizerTe
 
         // An other plausible CS.
         assertOrdered(new AxisDirection[] {
-            AxisDirection.WEST,   // Right handed-rule
-            AxisDirection.SOUTH,  // Right handed-rule
+            AxisDirection.WEST,                 // Right handed-rule
+            AxisDirection.SOUTH,                // Right handed-rule
             AxisDirection.DOWN
         }, new AxisDirection[] {
             AxisDirection.SOUTH,
@@ -108,8 +108,8 @@ public final strictfp class NormalizerTe
 
         // An other plausible CS.
         assertOrdered(new AxisDirection[] {
-            AxisDirection.SOUTH,  // Right handed-rule
-            AxisDirection.EAST,   // Right handed-rule
+            AxisDirection.SOUTH,                // Right handed-rule
+            AxisDirection.EAST,                 // Right handed-rule
             AxisDirection.DOWN
         }, new AxisDirection[] {
             AxisDirection.SOUTH,
@@ -136,7 +136,7 @@ public final strictfp class NormalizerTe
                                       final CoordinateSystemAxis[] actual)
     {
         final boolean changeExpected = !Arrays.equals(actual, expected);
-        assertEquals(changeExpected, Normalizer.sort(actual));
+        assertEquals(changeExpected, Normalizer.sort(actual, 0));
         assertArrayEquals(expected, actual);
     }
 
@@ -171,10 +171,12 @@ public final strictfp class NormalizerTe
         assertSame(HardCodedAxes.NORTHING,           Normalizer.normalize(HardCodedAxes.NORTHING, changes));
         assertSame(HardCodedAxes.ALTITUDE,           Normalizer.normalize(HardCodedAxes.ALTITUDE, changes));
         assertSame(HardCodedAxes.TIME,               Normalizer.normalize(HardCodedAxes.TIME, changes));
+        assertSame("Radius orientation should not be changed from South to North because it does not allow negative values.",
+                HardCodedAxes.RADIUS, Normalizer.normalize(HardCodedAxes.RADIUS, changes));
     }
 
     /**
-     * Tests {@link Normalizer#normalize(CoordinateSystemAxis)}.
+     * Tests {@link Normalizer#normalize(CoordinateSystemAxis, AxisFilter)}.
      */
     @Test
     public void testNormalizeAxis() {
@@ -185,15 +187,15 @@ public final strictfp class NormalizerTe
          * Test a change of unit from centimetre to metre.
          */
         assertSame(HardCodedAxes.HEIGHT_cm, Normalizer.normalize(HardCodedAxes.HEIGHT_cm,
-                AxesConvention.CONVENTIONALLY_ORIENTED));   // Do not change unit.
+                AxesConvention.CONVENTIONALLY_ORIENTED));                                   // Do not change unit.
         assertAxisEquals("Height", "h", AxisDirection.UP,
-            Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, null,
-            Normalizer.normalize(HardCodedAxes.HEIGHT_cm, AxesConvention.NORMALIZED));
+                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, null,
+                Normalizer.normalize(HardCodedAxes.HEIGHT_cm, AxesConvention.NORMALIZED));
         /*
          * Test a change of direction from West to East.
          */
         assertAxisEquals(Vocabulary.format(Vocabulary.Keys.Unnamed), "E",
-            AxisDirection.EAST, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, null,
-            Normalizer.normalize(HardCodedAxes.WESTING, AxesConvention.NORMALIZED));
+                AxisDirection.EAST, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, null,
+                Normalizer.normalize(HardCodedAxes.WESTING, AxesConvention.NORMALIZED));
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -76,7 +76,7 @@ public final strictfp class CartesianToS
     public void testConsistency() throws FactoryException, TransformException {
         transform = CartesianToSpherical.INSTANCE.completeTransform();
         derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
-        tolerance = 2E-7;
+        tolerance = 1E-6;
         verifyInDomain(new double[] {-100, -100, -100},      // Minimal coordinates
                        new double[] {+100, +100, +100},      // Maximal coordinates
                        new int[]    {  10,   10,   10},

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -20,6 +20,7 @@ import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.SphericalCS;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.TransformException;
@@ -88,7 +89,7 @@ public final strictfp class CoordinateSy
      */
     private static CoordinateSystem geocentricInCentimetres() {
         return CoordinateSystems.replaceAxes(HardCodedCS.GEOCENTRIC, new AxisFilter() {
-            @Override public Unit<?> getUnitReplacement(Unit<?> ignored) {
+            @Override public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> ignored) {
                 return SI.CENTIMETRE;
             }
         });

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1735272&r1=1735271&r2=1735272&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Wed Mar 16 17:58:44 2016
@@ -91,6 +91,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.cs.DefaultCartesianCSTest.class,
     org.apache.sis.referencing.cs.DefaultEllipsoidalCSTest.class,
     org.apache.sis.referencing.cs.DefaultSphericalCSTest.class,
+    org.apache.sis.referencing.cs.DefaultCylindricalCSTest.class,
     org.apache.sis.referencing.cs.DefaultCompoundCSTest.class,
     org.apache.sis.referencing.cs.CoordinateSystemsTest.class,
     org.apache.sis.referencing.cs.HardCodedCSTest.class,



Mime
View raw message