sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1683283 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/io/wkt/ main/java/org/apache/sis/referencing/cs/ main/java/org/apache/sis/referencing/operation/transform/ test/java/org/apache/sis/referencing/cs/
Date Wed, 03 Jun 2015 11:06:41 GMT
Author: desruisseaux
Date: Wed Jun  3 11:06:40 2015
New Revision: 1683283

URL: http://svn.apache.org/r1683283
Log:
Referencing: allow AxisFilter to filter out some axes (which is what many peoples would probably expects from its name)
and retrofit CoordinateSystems.normalize(CoordinateSystem) into CoordinateSystems.replaceAxes(CoordinateSystem, AxisFilter).

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.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/DefaultAffineCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.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/DefaultEllipsoidalCS.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/DefaultPolarCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultTimeCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.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/cs/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -712,7 +712,7 @@ final class GeodeticObjectParser extends
             } else {
                 cs = (CartesianCS) CommonCRS.WGS84.geocentric().getCoordinateSystem();
                 if (!SI.METRE.equals(linearUnit)) {
-                    cs = (CartesianCS) CoordinateSystems.modifyAxes(cs, new AxisFilter() {
+                    cs = (CartesianCS) CoordinateSystems.replaceAxes(cs, new AxisFilter() {
                         @Override public Unit<?> getUnitReplacement(final Unit<?> unit) {
                             return linearUnit;
                         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -340,13 +340,7 @@ public class AbstractCS extends Abstract
         }
         AbstractCS cs = derived.get(convention);
         if (cs == null) {
-            switch (convention) {
-                case NORMALIZED:              // Fall through
-                case CONVENTIONALLY_ORIENTED: cs = Normalizer.normalize(this, convention, true); break;
-                case RIGHT_HANDED:            cs = Normalizer.normalize(this, null, true); break;
-                case POSITIVE_RANGE:          cs = Normalizer.shiftAxisRange(this); break;
-                default: throw new AssertionError(convention);
-            }
+            cs = Normalizer.forConvention(this, convention);
             if (cs == null) {
                 cs = this;  // This coordinate system is already normalized.
             }
@@ -362,17 +356,36 @@ public class AbstractCS extends Abstract
     }
 
     /**
-     * Returns a coordinate system of the same type than this CS but with different axes.
+     * Returns a coordinate system usually of the same type than this CS but with different axes.
      * This method shall be overridden by all {@code AbstractCS} subclasses in this package.
      *
+     * <p>This method returns a coordinate system of the same type if the number of axes is unchanged.
+     * But if the given {@code axes} array has less elements than this coordinate system dimension, then
+     * this method may return an other kind of coordinate system. See {@link AxisFilter} for an example.</p>
+     *
      * @param  axes The set of axes to give to the new coordinate system.
      * @return A new coordinate system of the same type than {@code this}, but using the given axes.
      */
-    AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+    AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
         return new AbstractCS(properties, axes);
     }
 
     /**
+     * Convenience method for implementations of {@link #createForAxes(Map, CoordinateSystemAxis[])}
+     * when the resulting coordinate system would have an unexpected number of dimensions.
+     *
+     * @param properties The properties which was supposed to be given to the constructor.
+     * @param axes       The axes which was supposed to be given to the constructor.
+     * @param expected   The minimal expected number of dimensions (may be less than {@link #getDimension()}).
+     */
+    static IllegalArgumentException unexpectedDimension(final Map<String,?> properties,
+            final CoordinateSystemAxis[] axes, final int expected)
+    {
+        return new IllegalArgumentException(Errors.getResources(properties).getString(
+                Errors.Keys.MismatchedDimension_3, "filter(cs)", expected, axes.length));
+    }
+
+    /**
      * Compares the specified object with this coordinate system for equality.
      *
      * @param  object The object to compare to {@code this}.

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -17,21 +17,70 @@
 package org.apache.sis.referencing.cs;
 
 import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import javax.measure.unit.Unit;
 
 
 /**
  * Modifications to apply on the axes of a coordinate system in order to produce a new coordinate system.
- * Possible modifications include changes of axis unit direction.
+ * {@code AxisFilter} can specify the axes to exclude in the new coordinate system, or specify different
+ * units and directions associated to the axes.
+ *
+ * <div class="note"><b>Terminology note</b>
+ * the word <cite>“filter”</cite> is understood here as <cite>“a computer program or subroutine to process a stream,
+ * producing another stream”</cite> (<a href="http://en.wikipedia.org/wiki/Filter_%28software%29">Wikipedia</a>).
+ * </div>
+ *
+ * <p>Note that filtering one or more axes may result in a change of coordinate system type.
+ * For example excluding the <var>z</var> axis of a {@linkplain DefaultCylindricalCS cylindrical} coordinate system
+ * results in a {@linkplain DefaultPolarCS polar} coordinate system.</p>
+ *
+ * <div class="section">Default implementation</div>
+ * All methods in this interface have a default implementation equivalent to <i>no-operation</i>.
+ * Implementors need to override only the methods for the aspects to change.
+ *
+ * <div class="section">Limitations</div>
+ * This interface is not for changing axis order.
+ * For changing axis order in addition to axis directions or units, see {@link AxesConvention}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
  * @version 0.6
  * @module
+ *
+ * @see CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)
  */
 public interface AxisFilter {
     /**
+     * Returns {@code true} if the given axis shall be included in the new coordinate system.
+     * The default implementation unconditionally returns {@code true}.
+     *
+     * @param  axis The axis to test.
+     * @return {@code true} if the given axis shall be included in the new coordinate system.
+     */
+    default boolean accept(CoordinateSystemAxis axis) {
+        return true;
+    }
+
+    /**
      * Returns a replacement for the given axis direction.
+     * The default implementation unconditionally returns the given {@code direction} unchanged.
+     *
+     * <div class="note"><b>Example:</b>
+     * for forcing the direction of the <var>z</var> axis toward up while leaving other axes unchanged,
+     * one can write:
+     *
+     * {@preformat java
+     *     &#64;Override
+     *     public getDirectionReplacement(AxisDirection direction) {
+     *         if (direction == AxisDirection.DOWN) {
+     *             direction = AxisDirection.UP;
+     *         }
+     *         return direction;
+     *     }
+     * }
+     * </div>
      *
      * @param  direction The original axis direction.
      * @return The new axis direction, or {@code direction} if there is no change.
@@ -42,6 +91,22 @@ public interface AxisFilter {
 
     /**
      * Returns a replacement for the given axis unit.
+     * The default implementation unconditionally returns the given {@code unit} unchanged.
+     *
+     * <div class="note"><b>Example:</b>
+     * for replacing all angular units of a coordinate system to degrees (regardless what the original
+     * angular units were) while leaving other kinds of units unchanged, one can write:
+     *
+     * {@preformat java
+     *     &#64;Override
+     *     public Unit<?> getUnitReplacement(Unit<?> unit) {
+     *         if (Units.isAngular(unit)) {
+     *             unit = NonSI.DEGREE_ANGLE;
+     *         }
+     *         return unit;
+     *     }
+     * }
+     * </div>
      *
      * @param  unit The original axis unit.
      * @return The new axis unit, or {@code unit} if there is no change.

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -43,6 +43,9 @@ import java.util.Objects;
 
 /**
  * Utility methods working on {@link CoordinateSystem} objects and their axes.
+ * Those methods allow for example to {@linkplain #angle estimate an angle between two axes}
+ * or {@linkplain #swapAndScaleAxes determining the change of axis directions and units}
+ * between two coordinate systems.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
@@ -300,60 +303,69 @@ public final class CoordinateSystems ext
     }
 
     /**
-     * Returns a coordinate system with axes modified according the given filter.
+     * Returns a coordinate system derived from the given one but with a modified list of axes.
+     * The axes may be filtered (excluding some axes), reordered or have their unit and direction modified.
      *
-     * @param  cs     The coordinate system.
-     * @param  filter The modifications to apply on coordinate system axes.
-     * @return The modified coordinate system, or {@code cs} if no change was needed.
+     * <div class="note"><b>Example:</b>
+     * for replacing all angular units of a coordinate system to degrees (regardless what the original
+     * angular units were) while leaving other kinds of units unchanged, one can write:
      *
-     * @since 0.6
-     */
-    public static CoordinateSystem modifyAxes(final CoordinateSystem cs, final AxisFilter filter) {
-        ensureNonNull("filter", filter);
-        if (cs != null) {
-            final CoordinateSystem newCS = Normalizer.normalize(cs, filter, false);
-            if (newCS != null) {
-                return newCS;
-            }
-        }
-        return cs;
-    }
-
-    /**
-     * Returns a coordinate system with {@linkplain AxesConvention#NORMALIZED normalized} axis order and units.
-     * This method is typically used together with {@link #swapAndScaleAxes swapAndScaleAxes} for the creation
-     * of a transformation step before some
-     * {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform math transform}.
-     * Example:
+     * {@preformat java
+     *     CoordinateSystem cs = ...;
+     *     cs = CoordinateSystems.replaceAxes(cs, new AxisFilter() {
+     *         &#64;Override
+     *         public Unit<?> getUnitReplacement(Unit<?> unit) {
+     *             if (Units.isAngular(unit)) {
+     *                 unit = NonSI.DEGREE_ANGLE;
+     *             }
+     *             return unit;
+     *         }
+     *     });
+     * }</div>
+     *
+     * <div class="section">Coordinate system normalization</div>
+     * This method is often used together with {@link #swapAndScaleAxes swapAndScaleAxes(…)} for normalizing the
+     * coordinate values given to a {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform
+     * math transform}.
      *
+     * <div class="note"><b>Example:</b>
      * {@preformat java
-     *     Matrix step1 = swapAndScaleAxes(sourceCS, normalize(sourceCS));
-     *     Matrix step2 = ... some transform operating on standard axis ...
-     *     Matrix step3 = swapAndScaleAxes(normalize(targetCS), targetCS);
-     * }
+     *     CoordinateSystem sourceCS = ...;
+     *     CoordinateSystem targetCS = ...;
+     *     Matrix step1 = swapAndScaleAxes(sourceCS, replaceAxes(sourceCS, AxisConvention.NORMALIZED));
+     *     Matrix step2 = ...; // some transform working on coordinates with standard axis order and unit.
+     *     Matrix step3 = swapAndScaleAxes(replaceAxes(targetCS, AxisConvention.NORMALIZED), targetCS);
+     * }</div>
      *
-     * A rational for normalized axis order and units is explained in the <cite>Axis units and
-     * direction</cite> section in the {@linkplain org.apache.sis.referencing.operation.projection
-     * description of map projection package}.
+     * A rational for normalized axis order and units is explained in the <cite>Axis units and direction</cite> section
+     * in the description of the {@linkplain org.apache.sis.referencing.operation.projection map projection package}.
      *
-     * @param  cs The coordinate system.
-     * @return A coordinate system similar to the specified {@code cs} with normalized axes.
+     * @param  cs     The coordinate system, or {@code null}.
+     * @param  filter The modifications to apply on coordinate system axes.
+     * @return The modified coordinate system as a new instance,
+     *         or {@code cs} if the given coordinate system was null or does not need any change.
      * @throws IllegalArgumentException if the specified coordinate system can not be normalized.
      *
      * @see AxesConvention#NORMALIZED
      *
      * @since 0.6
      */
-    public static CoordinateSystem normalize(final CoordinateSystem cs) throws IllegalArgumentException {
+    public static CoordinateSystem replaceAxes(final CoordinateSystem cs, final AxisFilter filter) {
+        ensureNonNull("filter", filter);
         if (cs != null) {
-            if (cs instanceof AbstractCS) {
-                // User may have overridden the 'forConvention' method.
-                return ((AbstractCS) cs).forConvention(AxesConvention.NORMALIZED);
-            } else {
-                final CoordinateSystem newCS = Normalizer.normalize(cs, AxesConvention.NORMALIZED, true);
-                if (newCS != null) {
-                    return newCS;
+            final CoordinateSystem newCS;
+            if (filter instanceof AxesConvention) {
+                if (cs instanceof AbstractCS) {
+                    // User may have overridden the 'forConvention' method.
+                    return ((AbstractCS) cs).forConvention((AxesConvention) filter);
+                } else {
+                    newCS = Normalizer.forConvention(cs, (AxesConvention) filter);
                 }
+            } else {
+                newCS = Normalizer.normalize(cs, filter, false);
+            }
+            if (newCS != null) {
+                return newCS;
             }
         }
         return cs;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -223,11 +223,15 @@ public class DefaultAffineCS extends Abs
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      * This method shall be overridden by all {@code AffineCS} subclasses in this package.
      */
     @Override
-    AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultAffineCS(properties, axes);
+    AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: // Fall through
+            case 3: return new DefaultAffineCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -78,7 +78,7 @@ public class DefaultCartesianCS extends
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultCartesianCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -232,10 +232,14 @@ public class DefaultCartesianCS extends
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultCartesianCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: // Fall through
+            case 3: return new DefaultCartesianCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -200,7 +200,7 @@ public class DefaultCompoundCS extends A
     }
 
     /*
-     * Do not override createSameType(…) and forConvention(…) because we can not create a new DefaultCompoundCS
+     * Do not override createForAxes(…) and forConvention(…) because we can not create a new DefaultCompoundCS
      * without knownledge of the CoordinateSystem components to give to it. It would be possible to recursively
      * invoke components[i].forConvention(…), but it would be useless to perform such decomposition here because
      * DefaultCompoundCRS will need to perform its own decomposition anyway.

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -72,7 +72,7 @@ public class DefaultCylindricalCS extend
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultCylindricalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -203,10 +203,14 @@ public class DefaultCylindricalCS extend
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultCylindricalCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: return new DefaultPolarCS(properties, axes);
+            case 3: return new DefaultCylindricalCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -70,7 +70,7 @@ public class DefaultEllipsoidalCS extend
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultEllipsoidalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -241,10 +241,15 @@ public class DefaultEllipsoidalCS extend
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultEllipsoidalCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 1: return new DefaultVerticalCS(properties, axes);
+            case 2: // Fall through
+            case 3: return new DefaultEllipsoidalCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 1);
+        }
     }
 }

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -71,7 +71,7 @@ public class DefaultLinearCS extends Abs
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultLinearCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -196,10 +196,13 @@ public class DefaultLinearCS extends Abs
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultLinearCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 1: return new DefaultLinearCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 1);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -70,10 +70,10 @@ public class DefaultPolarCS extends Abst
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
-    private DefaultPolarCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+    DefaultPolarCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
         super(properties, axes);
     }
 
@@ -199,10 +199,13 @@ public class DefaultPolarCS extends Abst
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultPolarCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: return new DefaultPolarCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -74,7 +74,7 @@ public class DefaultSphericalCS extends
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultSphericalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -203,10 +203,14 @@ public class DefaultSphericalCS extends
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultSphericalCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: return new DefaultPolarCS(properties, axes);
+            case 3: return new DefaultSphericalCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultTimeCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultTimeCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultTimeCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultTimeCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -73,7 +73,7 @@ public class DefaultTimeCS extends Abstr
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultTimeCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -196,10 +196,13 @@ public class DefaultTimeCS extends Abstr
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultTimeCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 1: return new DefaultTimeCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 1);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -65,7 +65,7 @@ public class DefaultUserDefinedCS extend
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
     private DefaultUserDefinedCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
@@ -193,10 +193,14 @@ public class DefaultUserDefinedCS extend
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultUserDefinedCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 2: // Fall through
+            case 3: return new DefaultUserDefinedCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 2);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -83,10 +83,10 @@ public class DefaultVerticalCS extends A
 
     /**
      * Creates a new coordinate system from an arbitrary number of axes. This constructor is for
-     * implementations of the {@link #createSameType(Map, CoordinateSystemAxis[])} method only,
+     * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only,
      * because it does not verify the number of axes.
      */
-    private DefaultVerticalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+    DefaultVerticalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
         super(properties, axes);
     }
 
@@ -211,10 +211,13 @@ public class DefaultVerticalCS extends A
     }
 
     /**
-     * Returns a coordinate system of the same class than this CS but with different axes.
+     * Returns a coordinate system with different axes.
      */
     @Override
-    final AbstractCS createSameType(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        return new DefaultVerticalCS(properties, axes);
+    final AbstractCS createForAxes(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
+        switch (axes.length) {
+            case 1: return new DefaultVerticalCS(properties, axes);
+            default: throw unexpectedDimension(properties, axes, 1);
+        }
     }
 }

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -30,6 +30,7 @@ import org.apache.sis.internal.referenci
 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 static java.util.Collections.singletonMap;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
@@ -194,14 +195,19 @@ final class Normalizer implements Compar
     static AbstractCS normalize(final CoordinateSystem cs, final AxisFilter changes, final boolean reorder) {
         boolean changed = false;
         final int dimension = cs.getDimension();
-        final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[dimension];
+        CoordinateSystemAxis[] axes = new CoordinateSystemAxis[dimension];
+        int n = 0;
         for (int i=0; i<dimension; i++) {
             CoordinateSystemAxis axis = cs.getAxis(i);
             if (changes != null) {
+                if (!changes.accept(axis)) {
+                    continue;
+                }
                 changed |= (axis != (axis = normalize(axis, changes)));
             }
-            axes[i] = axis;
+            axes[n++] = axis;
         }
+        axes = ArraysExt.resize(axes, n);
         /*
          * Sort the axes in an attempt to create a right-handed system.
          * If nothing changed, return the given Coordinate System as-is.
@@ -209,16 +215,16 @@ final class Normalizer implements Compar
         if (reorder) {
             changed |= sort(axes);
         }
-        if (!changed) {
+        if (!changed && n == dimension) {
             return null;
         }
         /*
          * Create a new coordinate system of the same type than the given one, but with the given axes.
          * We need to change the Coordinate System name, since it is likely to not be valid anymore.
          */
-        final AbstractCS impl = (cs instanceof AbstractCS) ? (AbstractCS) cs : AbstractCS.castOrCopy(cs);
+        final AbstractCS impl = castOrCopy(cs);
         final StringBuilder buffer = (StringBuilder) CharSequences.camelCaseToSentence(impl.getInterface().getSimpleName());
-        return impl.createSameType(singletonMap(AbstractCS.NAME_KEY, DefaultCompoundCS.createName(buffer, axes)), axes);
+        return impl.createForAxes(singletonMap(AbstractCS.NAME_KEY, DefaultCompoundCS.createName(buffer, axes)), axes);
     }
 
     /**
@@ -232,9 +238,9 @@ final class Normalizer implements Compar
      * of -60° still locate the same point in the old and the new coordinate system. But the preferred way
      * to locate that point become the 300° value if the longitude range has been shifted to positive values.</p>
      *
-     * @return A coordinate system using the given kind of longitude range (may be {@code axis}).
+     * @return A coordinate system using the given kind of longitude range, or {@code null} if no change is needed.
      */
-    static AbstractCS shiftAxisRange(final AbstractCS cs) {
+    private static AbstractCS shiftAxisRange(final CoordinateSystem cs) {
         boolean changed = false;
         final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
         for (int i=0; i<axes.length; i++) {
@@ -263,8 +269,37 @@ final class Normalizer implements Compar
             axes[i] = axis;
         }
         if (!changed) {
-            return cs;
+            return null;
+        }
+        return castOrCopy(cs).createForAxes(IdentifiedObjects.getProperties(cs, EXCLUDES), axes);
+    }
+
+    /**
+     * Returns the given coordinate system as an {@code AbstractCS} instance. This method performs an
+     * {@code instanceof} check before to delegate to {@link AbstractCS#castOrCopy(CoordinateSystem)}
+     * because there is no need to check for all interfaces before the implementation class here.
+     * Checking the implementation class first is usually more efficient in this particular case.
+     */
+    private static AbstractCS castOrCopy(final CoordinateSystem cs) {
+        return (cs instanceof AbstractCS) ? (AbstractCS) cs : AbstractCS.castOrCopy(cs);
+    }
+
+    /**
+     * Returns a coordinate system equivalent to the given one but with axes rearranged according the given convention.
+     * If the given coordinate system is already compatible with the given convention, then returns {@code null}.
+     *
+     * @param  convention The axes convention for which a coordinate system is desired.
+     * @return A coordinate system compatible with the given convention, or {@code null} if no change is needed.
+     *
+     * @see AbstractCS#forConvention(AxesConvention)
+     */
+    static AbstractCS forConvention(final CoordinateSystem cs, final AxesConvention convention) {
+        switch (convention) {
+            case NORMALIZED:              // Fall through
+            case CONVENTIONALLY_ORIENTED: return normalize(cs, convention, true);
+            case RIGHT_HANDED:            return normalize(cs, null, true);
+            case POSITIVE_RANGE:          return shiftAxisRange(cs);
+            default: throw new AssertionError(convention);
         }
-        return cs.createSameType(IdentifiedObjects.getProperties(cs, EXCLUDES), axes);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -28,6 +28,10 @@
  *   <li>{@link org.apache.sis.referencing.cs.AbstractCS#forConvention AbstractCS.forConvention(AxesConvention)}</li>
  * </ul>
  *
+ * This package provides also a {@link org.apache.sis.referencing.cs.CoordinateSystems} utility class
+ * with static methods for estimating an angle between two axes, determining the change of axis directions
+ * and units between two coordinate systems, or filtering axes.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
  * @version 0.6

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1683283&r1=1683282&r2=1683283&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Wed Jun  3 11:06:40 2015
@@ -54,6 +54,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.j2d.ParameterizedAffine;
 import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.operation.DefaultOperationMethod;
 import org.apache.sis.referencing.operation.matrix.Matrices;
@@ -588,8 +589,8 @@ public class DefaultMathTransformFactory
          */
         final Matrix swap1, swap3;
         try {
-            swap1 = CoordinateSystems.swapAndScaleAxes(baseCS, CoordinateSystems.normalize(baseCS));
-            swap3 = CoordinateSystems.swapAndScaleAxes(CoordinateSystems.normalize(derivedCS), derivedCS);
+            swap1 = CoordinateSystems.swapAndScaleAxes(baseCS, CoordinateSystems.replaceAxes(baseCS, AxesConvention.NORMALIZED));
+            swap3 = CoordinateSystems.swapAndScaleAxes(CoordinateSystems.replaceAxes(derivedCS, AxesConvention.NORMALIZED), derivedCS);
         } catch (IllegalArgumentException | ConversionException cause) {
             throw new FactoryException(cause);
         }

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=1683283&r1=1683282&r2=1683283&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 Jun  3 11:06:40 2015
@@ -17,11 +17,17 @@
 package org.apache.sis.referencing.cs;
 
 import javax.measure.unit.SI;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.Unit;
 import javax.measure.converter.ConversionException;
 import org.opengis.referencing.operation.Matrix;
 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.VerticalCS;
 import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.measure.Units;
 import org.apache.sis.measure.Angle;
 import org.apache.sis.measure.ElevationAngle;
 import org.apache.sis.test.DependsOnMethod;
@@ -42,12 +48,13 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (IRD)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @DependsOn({
     org.apache.sis.internal.referencing.AxisDirectionsTest.class,
-    DirectionAlongMeridianTest.class
+    DirectionAlongMeridianTest.class,
+    NormalizerTest.class
 })
 public final strictfp class CoordinateSystemsTest extends TestCase {
     /**
@@ -264,4 +271,47 @@ public final strictfp class CoordinateSy
                 0,     0,   0,   1
         }), matrix, STRICT);
     }
+
+    /**
+     * Tests {@link CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)}
+     * without change of coordinate system type.
+     */
+    @Test
+    public void testReplaceAxes() {
+        final EllipsoidalCS    sourceCS = HardCodedCS.GEODETIC_3D;
+        final EllipsoidalCS    targetCS = HardCodedCS.ELLIPSOIDAL_gon;  // What we want to get.
+        final CoordinateSystem actualCS = CoordinateSystems.replaceAxes(sourceCS, new AxisFilter() {
+            @Override
+            public boolean accept(final CoordinateSystemAxis axis) {
+                return Units.isAngular(axis.getUnit());
+            }
+
+            @Override
+            public Unit<?> getUnitReplacement(Unit<?> unit) {
+                if (Units.isAngular(unit)) {
+                    unit = NonSI.GRADE;
+                }
+                return unit;
+            }
+        });
+        assertEqualsIgnoreMetadata(targetCS, actualCS);
+    }
+
+    /**
+     * Tests {@link CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)}
+     * with a change of coordinate system type.
+     */
+    @Test
+    @DependsOnMethod("testReplaceAxes")
+    public void testReplaceAxesWithTypeChange() {
+        final EllipsoidalCS    sourceCS = HardCodedCS.GEODETIC_3D;
+        final VerticalCS       targetCS = HardCodedCS.ELLIPSOIDAL_HEIGHT;   // What we want to get.
+        final CoordinateSystem actualCS = CoordinateSystems.replaceAxes(sourceCS, new AxisFilter() {
+            @Override
+            public boolean accept(final CoordinateSystemAxis axis) {
+                return Units.isLinear(axis.getUnit());
+            }
+        });
+        assertEqualsIgnoreMetadata(targetCS, actualCS);
+    }
 }



Mime
View raw message