You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2016/03/15 13:15:22 UTC

svn commit: r1735066 - in /sis/branches/JDK8: core/sis-referencing/src/main/java/org/apache/sis/referencing/ core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/ core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/ co...

Author: desruisseaux
Date: Tue Mar 15 12:15:22 2016
New Revision: 1735066

URL: http://svn.apache.org/viewvc?rev=1735066&view=rev
Log:
Replace NonStandardCRS class by CommonCRS.spherical() method and add tests.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java   (with props)
Removed:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NonStandardCRS.java
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.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/CoordinateSystemTransform.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/CommonCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.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/operation/transform/CartesianToSphericalTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/src/main/config/logging.properties

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -149,10 +149,6 @@ public final class CRS extends Static {
             throws NoSuchAuthorityCodeException, FactoryException
     {
         ArgumentChecks.ensureNonNull("code", code);
-        if (code.startsWith(NonStandardCRS.PREFIX)) {       // Internal to SIS.
-            final CoordinateReferenceSystem crs = NonStandardCRS.forCode(code);
-            if (crs != null) return crs;
-        }
         try {
             return AuthorityFactories.ALL.createCoordinateReferenceSystem(code);
         } catch (UnavailableFactoryException e) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -38,8 +38,10 @@ import org.opengis.referencing.crs.CRSAu
 import org.opengis.referencing.cs.TimeCS;
 import org.opengis.referencing.cs.VerticalCS;
 import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.SphericalCS;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CSAuthorityFactory;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.PrimeMeridian;
@@ -276,6 +278,11 @@ public enum CommonCRS {
     static final CommonCRS DEFAULT = WGS84;
 
     /**
+     * Properties to exclude when using an other object as a template.
+     */
+    private static final String[] EXCLUDE = new String[] {IdentifiedObject.IDENTIFIERS_KEY};
+
+    /**
      * The EPSG code of the two-dimensional geographic CRS.
      */
     final short geographic;
@@ -334,13 +341,20 @@ public enum CommonCRS {
     private transient volatile GeographicCRS cachedGeo3D;
 
     /**
-     * The geocentric CRS, created when first needed.
+     * The geocentric CRS using Cartesian coordinate system, created when first needed.
      *
      * @see #geocentric()
      */
     private transient volatile GeocentricCRS cachedGeocentric;
 
     /**
+     * The geocentric CRS using spherical coordinate system, created when first needed.
+     *
+     * @see #spherical()
+     */
+    private transient volatile GeocentricCRS cachedSpherical;
+
+    /**
      * The Universal Transverse Mercator projections, created when first needed.
      * All accesses to this map shall be synchronized on {@code cachedUTM}.
      *
@@ -641,6 +655,56 @@ public enum CommonCRS {
     }
 
     /**
+     * Returns the geocentric CRS using a spherical coordinate system. Axes are:
+     *
+     * <ol>
+     *   <li>Spherical latitude in degrees oriented toward {@linkplain AxisDirection#NORTH north}.</li>
+     *   <li>Spherical longitude in degrees oriented toward {@linkplain AxisDirection#EAST east}.</li>
+     *   <li>Geocentric radius in metres oriented toward {@linkplain AxisDirection#UP up}.</li>
+     * </ol>
+     *
+     * @return The geocentric CRS associated to this enum.
+     *
+     * @see DefaultGeocentricCRS
+     *
+     * @since 0.7
+     */
+    public GeocentricCRS spherical() {
+        GeocentricCRS object = cachedSpherical;
+        if (object == null) {
+            synchronized (this) {
+                object = cachedSpherical;
+                if (object == null) {
+                    /*
+                     * All constants defined in this enumeration use the same coordinate system, EPSG:6404.
+                     * We will arbitrarily create this CS only for the most frequently created CRS,
+                     * and share that CS instance for all other constants.
+                     */
+                    SphericalCS cs = null;
+                    if (this == DEFAULT) {
+                        final CSAuthorityFactory factory = csFactory();
+                        if (factory != null) try {
+                            cs = factory.createSphericalCS("6404");
+                        } catch (FactoryException e) {
+                            failure(this, "spherical", e);
+                        }
+                        if (cs == null) {
+                            cs = (SphericalCS) StandardDefinitions.createCoordinateSystem((short) 6404);
+                        }
+                    } else {
+                        cs = (SphericalCS) DEFAULT.spherical().getCoordinateSystem();
+                    }
+                    // Use same name and datum than the geographic CRS.
+                    final GeographicCRS base = geographic();
+                    object = new DefaultGeocentricCRS(IdentifiedObjects.getProperties(base, EXCLUDE), base.getDatum(), cs);
+                    cachedSpherical = object;
+                }
+            }
+        }
+        return object;
+    }
+
+    /**
      * Returns the geodetic datum associated to this geodetic object.
      * The following table summarizes the datums known to this class,
      * together with an enumeration value that can be used for fetching that datum:
@@ -1133,7 +1197,7 @@ public enum CommonCRS {
                             object = StandardDefinitions.createVerticalCRS(crs, datum());
                         } else {
                             final VerticalCS cs = cs();
-                            object = new DefaultVerticalCRS(IdentifiedObjects.getProperties(cs), datum(), cs);
+                            object = new DefaultVerticalCRS(IdentifiedObjects.getProperties(cs, EXCLUDE), datum(), cs);
                         }
                         cached = object;
                     }
@@ -1371,7 +1435,7 @@ public enum CommonCRS {
                     object = crs(cached);
                     if (object == null) {
                         final TemporalDatum datum = datum();
-                        object = new DefaultTemporalCRS(IdentifiedObjects.getProperties(datum), datum, cs());
+                        object = new DefaultTemporalCRS(IdentifiedObjects.getProperties(datum, EXCLUDE), datum, cs());
                         cached = object;
                     }
                 }
@@ -1399,8 +1463,8 @@ public enum CommonCRS {
                 case UNIX: {
                     // Share the NamedIdentifier created for Java time.
                     final TimeCS share = JAVA.crs().getCoordinateSystem();
-                    cs   = IdentifiedObjects.getProperties(share);
-                    axis = IdentifiedObjects.getProperties(share.getAxis(0));
+                    cs   = IdentifiedObjects.getProperties(share, EXCLUDE);
+                    axis = IdentifiedObjects.getProperties(share.getAxis(0), EXCLUDE);
                     break;
                 }
                 case JAVA: {
@@ -1500,7 +1564,7 @@ public enum CommonCRS {
      * Returns the same properties than the given object, except for the identifier which is set to the given code.
      */
     private static Map<String,?> properties(final IdentifiedObject template, final short code) {
-        final Map<String,Object> properties = new HashMap<>(IdentifiedObjects.getProperties(template));
+        final Map<String,Object> properties = new HashMap<>(IdentifiedObjects.getProperties(template, EXCLUDE));
         properties.put(GeographicCRS.IDENTIFIERS_KEY, new NamedIdentifier(Citations.EPSG, String.valueOf(code)));
         return properties;
     }
@@ -1517,6 +1581,20 @@ public enum CommonCRS {
             }
         }
         return null;
+    }
+
+    /**
+     * Returns the EPSG factory to use for creating coordinate systems, or {@code null} if none.
+     * If this method returns {@code null}, then the caller will silently fallback on hard-coded values.
+     */
+    static CSAuthorityFactory csFactory() {
+        if (!EPSGFactoryFallback.FORCE_HARDCODED) {
+            final AuthorityFactory factory = AuthorityFactories.EPSG();
+            if (!(factory instanceof EPSGFactoryFallback)) {
+                return (CSAuthorityFactory) factory;
+            }
+        }
+        return null;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -319,7 +319,7 @@ final class StandardDefinitions {
         switch (code) {
             case 6422: name = "Ellipsoidal 2D"; dim = 2; axisCode = 108; break;
             case 6423: name = "Ellipsoidal 3D"; dim = 3; axisCode = 111; break;
-            case 6404: name = "Spherical 3D";   dim = 3; axisCode =  63; isSpherical = true; break;
+            case 6404: name = "Spherical";      dim = 3; axisCode =  63; isSpherical = true; break;
             case 6500: name = "Earth centred";  dim = 3; axisCode = 118; isCartesian = true; break;
             case 4400: name = "Cartesian 2D";   dim = 2; axisCode =   3; isCartesian = true; break;
             default:   throw new AssertionError(code);
@@ -375,7 +375,7 @@ final class StandardDefinitions {
                        dir  = AxisDirection.NORTH;
                        break;
             case 60:   name = "Spherical latitude";
-                       abrv = "φ′";
+                       abrv = "φ′";                         // See HardCodedAxes.SPHERICAL_LATITUDE in tests.
                        unit = NonSI.DEGREE_ANGLE;
                        dir  = AxisDirection.NORTH;
                        min  = Latitude.MIN_VALUE;
@@ -383,7 +383,7 @@ final class StandardDefinitions {
                        rm   = RangeMeaning.EXACT;
                        break;
             case 61:   name = "Spherical longitude";
-                       abrv = "θ";
+                       abrv = "θ";                          // See HardCodedAxes.SPHERICAL_LONGITUDE in tests.
                        unit = NonSI.DEGREE_ANGLE;
                        dir  = AxisDirection.EAST;
                        min  = Longitude.MIN_VALUE;
@@ -391,7 +391,7 @@ final class StandardDefinitions {
                        rm   = RangeMeaning.WRAPAROUND;
                        break;
             case 62:   name = "Geocentric radius";
-                       abrv = "r";
+                       abrv = "r";                          // See HardCodedAxes.GEOCENTRIC_RADIUS in tests.
                        unit = SI.METRE;
                        dir  = AxisDirection.UP;
                        min  = 0;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -323,7 +323,7 @@ public class DefaultCoordinateSystemAxis
                 } else if (dir.equals(AxisDirection.EAST)) {
                     min = fromDegrees.convert(Longitude.MIN_VALUE);
                     max = fromDegrees.convert(Longitude.MAX_VALUE);
-                    rm  = RangeMeaning.WRAPAROUND; // 180°E wraps to 180°W
+                    rm  = RangeMeaning.WRAPAROUND;                                  // 180°E wraps to 180°W
                 }
                 if (min > max) {
                     final double t = min;
@@ -697,10 +697,10 @@ public class DefaultCoordinateSystemAxis
      */
     private static CoordinateSystem getEnclosingCS(final Formatter formatter) {
         final FormattableObject e = formatter.getEnclosingElement(1);
-        if (e instanceof CoordinateReferenceSystem) {   // This is what we expect in standard WKT.
+        if (e instanceof CoordinateReferenceSystem) {           // This is what we expect in standard WKT.
             return ((CoordinateReferenceSystem) e).getCoordinateSystem();
         }
-        if (e instanceof CoordinateSystem) {    // Not standard WKT, but conceptually the right thing.
+        if (e instanceof CoordinateSystem) {                    // Not standard WKT, but conceptually the right thing.
             return (CoordinateSystem) e;
         }
         return null;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -2259,7 +2259,8 @@ addURIs:    for (int i=0; ; i++) {
                     throw new FactoryDataException(exception.getLocalizedMessage(), exception);
                 }
                 final AxisName an = getAxisName(nameCode);
-                final CoordinateSystemAxis axis = owner.csFactory.createCoordinateSystemAxis(createProperties("Coordinate Axis", an.name, epsg, an.description, false),
+                final CoordinateSystemAxis axis = owner.csFactory.createCoordinateSystemAxis(
+                        createProperties("Coordinate Axis", an.name, epsg, an.description, false),
                         abbreviation, direction, owner.createUnit(unit));
                 returnValue = ensureSingleton(axis, returnValue, code);
             }
@@ -2736,7 +2737,7 @@ next:               while (r.next()) {
                         sourceDimensions = sourceCRS.getCoordinateSystem().getDimension();
                     } else {
                         sourceCRS = null;
-                        sourceDimensions = 2;       // Acceptable default for projections only.
+                        sourceDimensions = 2;           // Acceptable default for projections only.
                         isDimensionKnown = false;
                     }
                     if (targetCode != null) {
@@ -2744,7 +2745,7 @@ next:               while (r.next()) {
                         targetDimensions = targetCRS.getCoordinateSystem().getDimension();
                     } else {
                         targetCRS = null;
-                        targetDimensions = 2;       // Acceptable default for projections only.
+                        targetDimensions = 2;           // Acceptable default for projections only.
                         isDimensionKnown = false;
                     }
                     /*
@@ -2796,7 +2797,7 @@ next:               while (r.next()) {
                          * we are going to invoke this method recursively in the following lines.
                          */
                         result.close();
-                        opProperties = new HashMap<>(opProperties);     // Because this class uses a shared map.
+                        opProperties = new HashMap<>(opProperties);         // Because this class uses a shared map.
                         final List<String> codes = new ArrayList<>();
                         try (ResultSet cr = executeQuery("Coordinate_Operation Path",
                                 "SELECT SINGLE_OPERATION_CODE" +

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -18,13 +18,12 @@ package org.apache.sis.referencing.opera
 
 import java.util.Arrays;
 import java.io.Serializable;
+import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
-import org.opengis.util.FactoryException;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.CRS;
 
 import static java.lang.Math.*;
 
@@ -47,6 +46,11 @@ final class CartesianToSpherical extends
     private static final long serialVersionUID = 7174557821232512348L;
 
     /**
+     * The source coordinate system.
+     */
+    static final CartesianCS SOURCE = (CartesianCS) CommonCRS.WGS84.geocentric().getCoordinateSystem();
+
+    /**
      * The singleton instance computing output coordinates are in radians.
      * For the instance computing output coordinates in degrees, use {@link #completeTransform()} instead.
      */
@@ -82,7 +86,7 @@ final class CartesianToSpherical extends
      */
     @Override
     final CoordinateSystem getSourceCS() {
-        return CommonCRS.WGS84.geocentric().getCoordinateSystem();
+        return SOURCE;
     }
 
     /**
@@ -90,8 +94,8 @@ final class CartesianToSpherical extends
      * Angular units shall be degrees.
      */
     @Override
-    final CoordinateSystem getTargetCS() throws FactoryException {
-        return CRS.forCode("SIS:6404").getCoordinateSystem();
+    final CoordinateSystem getTargetCS() {
+        return SphericalToCartesian.SOURCE;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -26,7 +26,6 @@ import org.opengis.referencing.cs.Coordi
 import org.opengis.referencing.cs.SphericalCS;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.OperationNotFoundException;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.system.DefaultFactories;
@@ -50,11 +49,6 @@ import org.apache.sis.util.resources.Err
  */
 abstract class CoordinateSystemTransform extends AbstractMathTransform {
     /**
-     * Number of input and output dimensions.
-     */
-    private final int dimension;
-
-    /**
      * An empty contextual parameter, used only for representing conversion from degrees to radians.
      */
     final transient ContextualParameters context;
@@ -70,7 +64,6 @@ abstract class CoordinateSystemTransform
      * or {@link ContextualParameters#denormalizeGeographicOutputs(double)} after this constructor.
      */
     CoordinateSystemTransform(final String method, final int dimension) {
-        this.dimension = dimension;
         final Map<String,?> properties = Collections.singletonMap(DefaultOperationMethod.NAME_KEY,
                 new ImmutableIdentifier(Citations.SIS, Constants.SIS, method));
         context = new ContextualParameters(new DefaultOperationMethod(properties, dimension, dimension,
@@ -93,13 +86,13 @@ abstract class CoordinateSystemTransform
      * Returns the source coordinate system of the complete math transform.
      * Angular units shall be degrees.
      */
-    abstract CoordinateSystem getSourceCS() throws FactoryException;
+    abstract CoordinateSystem getSourceCS();
 
     /**
      * Returns the target coordinate system of the complete math transform.
      * Angular units shall be degrees.
      */
-    abstract CoordinateSystem getTargetCS() throws FactoryException;
+    abstract CoordinateSystem getTargetCS();
 
     /**
      * Returns the number of dimensions in the source coordinate points.
@@ -107,7 +100,7 @@ abstract class CoordinateSystemTransform
      */
     @Override
     public final int getSourceDimensions() {
-        return dimension;
+        return getSourceCS().getDimension();
     }
 
     /**
@@ -116,7 +109,7 @@ abstract class CoordinateSystemTransform
      */
     @Override
     public final int getTargetDimensions() {
-        return dimension;
+        return getTargetCS().getDimension();
     }
 
     /**
@@ -156,17 +149,19 @@ abstract class CoordinateSystemTransform
             }
         }
         Exception cause = null;
-        if (tr != null && tr.getSourceDimensions() == source.getDimension()
-                       && tr.getTargetDimensions() == target.getDimension())
-        {
-            try {
-                final Matrix before = CoordinateSystems.swapAndScaleAxes(source, tr.getSourceCS());
-                final Matrix after = CoordinateSystems.swapAndScaleAxes(tr.getTargetCS(), target);
-                return MathTransforms.concatenate(
-                        MathTransforms.linear(before), tr.completeTransform(), MathTransforms.linear(after));
-            } catch (IllegalArgumentException | ConversionException e) {
-                cause = e;
+        try {
+            if (tr == null) {
+                return factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(source, target));
+            } else if (tr.getSourceDimensions() == source.getDimension() &&
+                       tr.getTargetDimensions() == target.getDimension())
+            {
+                final MathTransform before = factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(source, tr.getSourceCS()));
+                final MathTransform after  = factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(tr.getTargetCS(), target));
+                return factory.createConcatenatedTransform(before,
+                       factory.createConcatenatedTransform(tr.completeTransform(), after));
             }
+        } catch (IllegalArgumentException | ConversionException e) {
+            cause = e;
         }
         throw new OperationNotFoundException(Errors.format(Errors.Keys.CoordinateOperationNotFound_2,
                 WKTUtilities.toType(CoordinateSystem.class, source.getClass()),

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -18,13 +18,14 @@ package org.apache.sis.referencing.opera
 
 import java.util.Arrays;
 import java.io.Serializable;
+import org.opengis.referencing.cs.SphericalCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
-import org.opengis.util.FactoryException;
-import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.CRS;
+import org.apache.sis.referencing.cs.AxesConvention;
+import org.apache.sis.referencing.crs.DefaultGeocentricCRS;
+import org.apache.sis.referencing.operation.matrix.Matrix3;
 
 import static java.lang.Math.*;
 
@@ -65,6 +66,12 @@ final class SphericalToCartesian extends
     private static final long serialVersionUID = 8001536207920751506L;
 
     /**
+     * The source coordinate system.
+     */
+    static final SphericalCS SOURCE = (SphericalCS) DefaultGeocentricCRS.castOrCopy(CommonCRS.WGS84.spherical())
+            .forConvention(AxesConvention.RIGHT_HANDED).getCoordinateSystem();
+
+    /**
      * The singleton instance expecting input coordinates in radians.
      * For the instance expecting input coordinates in degrees, use {@link #completeTransform()} instead.
      */
@@ -99,8 +106,8 @@ final class SphericalToCartesian extends
      * Angular units shall be degrees.
      */
     @Override
-    final CoordinateSystem getSourceCS() throws FactoryException {
-        return CRS.forCode("SIS:6404").getCoordinateSystem();
+    final CoordinateSystem getSourceCS() {
+        return SOURCE;
     }
 
     /**
@@ -109,7 +116,7 @@ final class SphericalToCartesian extends
      */
     @Override
     final CoordinateSystem getTargetCS() {
-        return CommonCRS.WGS84.geocentric().getCoordinateSystem();
+        return CartesianToSpherical.SOURCE;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -40,7 +40,7 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.opengis.test.Assert.*;
 import static org.apache.sis.test.TestUtilities.*;
 
 
@@ -100,7 +100,7 @@ public final strictfp class CommonCRSTes
     public void testGeographic3D() {
         final GeographicCRS crs = CommonCRS.WGS72.geographic3D();
         Validators.validate(crs);
-        assertEquals("WGS 72", crs.getName().getCode());
+        assertEquals ("WGS 72", crs.getName().getCode());
         assertSame   (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum());
         assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum());
 
@@ -108,9 +108,7 @@ public final strictfp class CommonCRSTes
         final String name = cs.getName().getCode();
         assertTrue(name, name.startsWith("Ellipsoidal 3D"));
         assertEquals("dimension", 3, cs.getDimension());
-        assertEquals(AxisDirection.NORTH, cs.getAxis(0).getDirection());
-        assertEquals(AxisDirection.EAST,  cs.getAxis(1).getDirection());
-        assertEquals(AxisDirection.UP,    cs.getAxis(2).getDirection());
+        assertAxisDirectionsEqual(name, cs, AxisDirection.NORTH, AxisDirection.EAST, AxisDirection.UP);
         assertSame("Cached value", crs, CommonCRS.WGS72.geographic3D());
     }
 
@@ -122,7 +120,7 @@ public final strictfp class CommonCRSTes
     public void testGeocentric() {
         final GeocentricCRS crs = CommonCRS.WGS72.geocentric();
         Validators.validate(crs);
-        assertEquals("WGS 72", crs.getName().getCode());
+        assertEquals ("WGS 72", crs.getName().getCode());
         assertSame   (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum());
         assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum());
 
@@ -130,13 +128,32 @@ public final strictfp class CommonCRSTes
         final String name = cs.getName().getCode();
         assertTrue(name, name.startsWith("Earth centred"));
         assertEquals("dimension", 3, cs.getDimension());
-        assertEquals(AxisDirection.GEOCENTRIC_X, cs.getAxis(0).getDirection());
-        assertEquals(AxisDirection.GEOCENTRIC_Y, cs.getAxis(1).getDirection());
-        assertEquals(AxisDirection.GEOCENTRIC_Z, cs.getAxis(2).getDirection());
+        assertAxisDirectionsEqual(name, cs, AxisDirection.GEOCENTRIC_X,
+                AxisDirection.GEOCENTRIC_Y, AxisDirection.GEOCENTRIC_Z);
         assertSame("Cached value", crs, CommonCRS.WGS72.geocentric());
     }
 
     /**
+     * Tests the {@link CommonCRS#spherical()} method.
+     */
+    @Test
+    @DependsOnMethod("testGeographic3D")
+    public void testSpherical() {
+        final GeocentricCRS crs = CommonCRS.ETRS89.spherical();
+        Validators.validate(crs);
+        assertEquals ("ETRS89", crs.getName().getCode());
+        assertSame   (CommonCRS.ETRS89.geographic().getDatum(), crs.getDatum());
+        assertNotSame(CommonCRS.WGS84 .geographic().getDatum(), crs.getDatum());
+
+        final CoordinateSystem cs = crs.getCoordinateSystem();
+        final String name = cs.getName().getCode();
+        assertTrue(name, name.startsWith("Spherical"));
+        assertEquals("dimension", 3, cs.getDimension());
+        assertAxisDirectionsEqual(name, cs, AxisDirection.NORTH, AxisDirection.EAST, AxisDirection.UP);
+        assertSame("Cached value", crs, CommonCRS.ETRS89.spherical());
+    }
+
+    /**
      * Verifies the vertical datum enumeration.
      */
     @Test

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -156,6 +156,9 @@ public final strictfp class StandardDefi
             switch (code) {
                 case   1: compare(HardCodedAxes.EASTING,                actual); break;
                 case   2: compare(HardCodedAxes.NORTHING,               actual); break;
+                case  60: compare(HardCodedAxes.SPHERICAL_LATITUDE,     actual); break;
+                case  61: compare(HardCodedAxes.SPHERICAL_LONGITUDE,    actual); break;
+                case  62: compare(HardCodedAxes.GEOCENTRIC_RADIUS,      actual); break;
                 case 106: compare(HardCodedAxes.GEODETIC_LATITUDE,      actual); break;
                 case 107: compare(HardCodedAxes.GEODETIC_LONGITUDE,     actual); break;
                 case 110: compare(HardCodedAxes.ELLIPSOIDAL_HEIGHT,     actual); break;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -18,12 +18,16 @@ package org.apache.sis.referencing.crs;
 
 import javax.measure.unit.SI;
 import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.internal.referencing.Legacy;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
+import org.opengis.test.Validators;
 import org.junit.Test;
 
 import static org.apache.sis.test.MetadataAssert.*;
@@ -34,7 +38,7 @@ import static org.apache.sis.test.Metada
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -42,6 +46,48 @@ import static org.apache.sis.test.Metada
 })
 public final strictfp class DefaultGeocentricCRSTest extends TestCase {
     /**
+     * Tests the {@link DefaultGeocentricCRS#forConvention(AxesConvention)} method
+     * for {@link AxesConvention#RIGHT_HANDED}.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testRightHanded() {
+        final DefaultGeocentricCRS crs = DefaultGeocentricCRS.castOrCopy(HardCodedCRS.SPHERICAL);
+        final DefaultGeocentricCRS normalized = crs.forConvention(AxesConvention.RIGHT_HANDED);
+        assertNotSame(crs, normalized);
+        final CoordinateSystem cs = normalized.getCoordinateSystem();
+        final CoordinateSystem ref = crs.getCoordinateSystem();
+        assertSame("longitude", ref.getAxis(1), cs.getAxis(0));
+        assertSame("latitude",  ref.getAxis(0), cs.getAxis(1));
+        assertSame("height",    ref.getAxis(2), cs.getAxis(2));
+    }
+
+    /**
+     * Tests the {@link DefaultGeocentricCRS#forConvention(AxesConvention)} method
+     * for {@link AxesConvention#POSITIVE_RANGE}.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testShiftLongitudeRange() {
+        final DefaultGeocentricCRS crs = HardCodedCRS.SPHERICAL;
+        CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(1);
+        assertEquals("longitude.minimumValue", -180.0, axis.getMinimumValue(), STRICT);
+        assertEquals("longitude.maximumValue", +180.0, axis.getMaximumValue(), STRICT);
+
+        final DefaultGeocentricCRS shifted =  crs.forConvention(AxesConvention.POSITIVE_RANGE);
+        assertNotSame("Expected a new CRS.", crs, shifted);
+        Validators.validate(shifted);
+
+        axis = shifted.getCoordinateSystem().getAxis(1);
+        assertEquals("longitude.minimumValue",      0.0, axis.getMinimumValue(), STRICT);
+        assertEquals("longitude.maximumValue",    360.0, axis.getMaximumValue(), STRICT);
+        assertSame("Expected a no-op.",         shifted, shifted.forConvention(AxesConvention.POSITIVE_RANGE));
+        assertSame("Expected cached instance.", shifted, crs    .forConvention(AxesConvention.POSITIVE_RANGE));
+    }
+
+    /**
      * Tests WKT 1 formatting.
      * Axis directions Geocentric X, Y and Z shall be replaced be Other, East and North respectively,
      * for conformance with legacy WKT 1 practice.

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -166,6 +166,9 @@ public final strictfp class HardCodedAxe
      * Increasing ordinates values go {@linkplain AxisDirection#UP up} and units are {@linkplain SI#METRE metres}.
      * The ISO 19111 name is <cite>"geocentric radius"</cite> and the abbreviation is lower case <cite>"r"</cite>.
      *
+     * <div class="note"><b>Note:</b> EPSG dataset 8.9 uses upper-case <cite>"R"</cite>.
+     * In this class, we use the ISO 19111 abbreviation instead.</div>
+     *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
      *
@@ -185,7 +188,8 @@ public final strictfp class HardCodedAxe
      * The ISO 19111 name is <cite>"spherical longitude"</cite> and the abbreviation is "θ" (theta).
      *
      * <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.</p>
+     * 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>
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
@@ -208,7 +212,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".</p>
+     * interchanged or in which this axis is named "elevation" and is oriented toward "Up".
+     * Other conventions use symbol Ψ or Ω.</p>
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -87,8 +87,7 @@ public final strictfp class HardCodedCS
      * A three-dimensional spherical CS with
      * <var>{@linkplain HardCodedAxes#SPHERICAL_LATITUDE latitude}</var>,
      * <var>{@linkplain HardCodedAxes#SPHERICAL_LONGITUDE longitude}</var>,
-     * <var>{@linkplain HardCodedAxes#GEOCENTRIC_RADIUS radius}</var>
-     * axes.
+     * <var>{@linkplain HardCodedAxes#GEOCENTRIC_RADIUS radius}</var> axes.
      * This axis order is the one of EPSG:6404.
      * Note that this is not a right-handed system.
      */

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -18,6 +18,8 @@ package org.apache.sis.referencing.opera
 
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.operation.TransformException;
+
+// Test dependencies
 import org.opengis.test.referencing.TransformTestCase;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
@@ -74,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 = 1E-7;
+        tolerance = 2E-7;
         verifyInDomain(new double[] {-100, -100, -100},      // Minimal coordinates
                        new double[] {+100, +100, +100},      // Maximal coordinates
                        new int[]    {  10,   10,   10},

Added: 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=1735066&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+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.operation.MathTransformFactory;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.cs.CoordinateSystems;
+import org.apache.sis.referencing.cs.AxisFilter;
+
+// Test dependencies
+import org.opengis.test.referencing.TransformTestCase;
+import org.apache.sis.referencing.cs.HardCodedCS;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.util.ArraysExt;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+
+
+/**
+ * Tests the {@link CoordinateSystemTransform} static factory method.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn({
+    SphericalToCartesianTest.class,
+    CartesianToSphericalTest.class
+})
+public final strictfp class CoordinateSystemTransformTest extends TransformTestCase {
+    /**
+     * The factory to use for creating the affine transforms and concatenated transforms.
+     */
+    private static MathTransformFactory factory;
+
+    /**
+     * Creates the {@link MathTransformFactory} to be used for the tests.
+     * We do not use the system-wide factory in order to have better tests isolation.
+     */
+    @BeforeClass
+    public static void createFactory() {
+        factory = new DefaultMathTransformFactory();
+    }
+
+    /**
+     * Disposes the {@link MathTransformFactory} used for the tests.
+     */
+    @AfterClass
+    public static void disposeFactory() {
+        factory = null;
+    }
+
+    /**
+     * Returns {@link HardCodedCS#GEOCENTRIC} but with axes in centimetres instead of metres.
+     */
+    private static CoordinateSystem geocentricInCentimetres() {
+        return CoordinateSystems.replaceAxes(HardCodedCS.GEOCENTRIC, new AxisFilter() {
+            @Override public Unit<?> getUnitReplacement(Unit<?> ignored) {
+                return SI.CENTIMETRE;
+            }
+        });
+    }
+
+    /**
+     * Returns {@link SphericalToCartesianTest#testData()} modified for the source and target
+     * coordinate systems used in this class.
+     */
+    private static double[][] sphericalTestData() {
+        final double[][] data = SphericalToCartesianTest.testData();
+        final double[] source = data[0];
+        for (int i=0; i<source.length; i += 3) {
+            ArraysExt.swap(source, i, i+1);
+        }
+        final double[] target = data[1];
+        for (int i=0; i<target.length; i++) {
+            target[i] *= 100;
+        }
+        return data;
+    }
+
+    /**
+     * Tests {@link CoordinateSystemTransform#create(MathTransformFactory, CoordinateSystem, CoordinateSystem)}.
+     * for a conversion between two spherical coordinate systems.
+     *
+     * @throws FactoryException if an error occurred while creating the transform.
+     * @throws TransformException if an error occurred while transforming the test point.
+     */
+    @Test
+    public void testSphericalToSpherical() throws FactoryException, TransformException {
+        transform = CoordinateSystemTransform.create(factory, HardCodedCS.SPHERICAL, SphericalToCartesian.SOURCE);
+        tolerance = 0;
+        final double[][] data = SphericalToCartesianTest.testData();
+        final double[] source = data[0];
+        final double[] target = data[1];
+        System.arraycopy(source, 0, target, 0, source.length);
+        for (int i=0; i<source.length; i += 3) {
+            ArraysExt.swap(source, i, i+1);
+        }
+        verifyTransform(source, target);
+    }
+
+    /**
+     * Tests {@link CoordinateSystemTransform#create(MathTransformFactory, CoordinateSystem, CoordinateSystem)}.
+     * for a conversion from spherical to Cartesian coordinates.
+     *
+     * @throws FactoryException if an error occurred while creating the transform.
+     * @throws TransformException if an error occurred while transforming the test point.
+     */
+    @Test
+    public void testSphericalToCartesian() throws FactoryException, TransformException {
+        transform = CoordinateSystemTransform.create(factory, HardCodedCS.SPHERICAL, geocentricInCentimetres());
+        tolerance = 1E-9;
+        final double[][] data = sphericalTestData();
+        verifyTransform(data[0], data[1]);
+    }
+
+    /**
+     * Tests {@link CoordinateSystemTransform#create(MathTransformFactory, CoordinateSystem, CoordinateSystem)}.
+     * for a conversion from Cartesian to spherical coordinates.
+     *
+     * @throws FactoryException if an error occurred while creating the transform.
+     * @throws TransformException if an error occurred while transforming the test point.
+     */
+    @Test
+    public void testCartesianToSpherical() throws FactoryException, TransformException {
+        transform = CoordinateSystemTransform.create(factory, geocentricInCentimetres(), HardCodedCS.SPHERICAL);
+        tolerance = 1E-9;
+        final double[][] data = sphericalTestData();
+        verifyTransform(data[1], data[0]);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java [UTF-8] Tue Mar 15 12:15:22 2016
@@ -18,6 +18,8 @@ package org.apache.sis.referencing.opera
 
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.operation.TransformException;
+
+// Test dependencies
 import org.opengis.test.referencing.TransformTestCase;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestUtilities;

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=1735066&r1=1735065&r2=1735066&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] Tue Mar 15 12:15:22 2016
@@ -123,6 +123,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.transform.MolodenskyTransformTest.class,
     org.apache.sis.referencing.operation.transform.SphericalToCartesianTest.class,
     org.apache.sis.referencing.operation.transform.CartesianToSphericalTest.class,
+    org.apache.sis.referencing.operation.transform.CoordinateSystemTransformTest.class,
     org.apache.sis.referencing.operation.DefaultFormulaTest.class,
     org.apache.sis.referencing.operation.DefaultOperationMethodTest.class,
     org.apache.sis.referencing.operation.AbstractSingleOperationTest.class,

Modified: sis/branches/JDK8/src/main/config/logging.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/src/main/config/logging.properties?rev=1735066&r1=1735065&r2=1735066&view=diff
==============================================================================
--- sis/branches/JDK8/src/main/config/logging.properties [UTF-8] (original)
+++ sis/branches/JDK8/src/main/config/logging.properties [UTF-8] Tue Mar 15 12:15:22 2016
@@ -17,7 +17,8 @@
 handlers= java.util.logging.ConsoleHandler
 
 # Default global logging level.
-.level= CONFIG
+.level= FINE
 
-# Set the message that are printed on the console to INFO and above.
-java.util.logging.ConsoleHandler.level = CONFIG
+# Set the message that are printed on the console to FINE and above.
+# FINE provides debugging information normally hidden in production.
+java.util.logging.ConsoleHandler.level = FINE