sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1811543 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/internal/metadata/ sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/mai...
Date Mon, 09 Oct 2017 09:31:41 GMT
Author: desruisseaux
Date: Mon Oct  9 09:31:41 2017
New Revision: 1811543

URL: http://svn.apache.org/viewvc?rev=1811543&view=rev
Log:
Complete support of three-dimensional projected CRS.

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java
      - copied, changed from r1811538, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java   (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java
      - copied, changed from r1811538, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java

Copied: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java (from r1811538, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java?p2=sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java&p1=sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java&r1=1811538&r2=1811543&rev=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -17,443 +17,99 @@
 package org.apache.sis.internal.metadata;
 
 import java.util.Map;
-import java.util.Collections;
-import java.util.Locale;
-import java.util.TimeZone;
-import java.text.Format;
-import javax.measure.Unit;
-import javax.measure.quantity.Length;
-import org.opengis.geometry.Envelope;
-import org.opengis.geometry.DirectPosition;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CRSFactory;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.crs.SingleCRS;
-import org.opengis.referencing.crs.DerivedCRS;
 import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.ProjectedCRS;
-import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.EllipsoidalCS;
-import org.opengis.referencing.datum.DatumFactory;
-import org.opengis.referencing.datum.PrimeMeridian;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.Conversion;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
-import org.opengis.referencing.operation.OperationMethod;
-import org.opengis.referencing.operation.SingleOperation;
-import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
-import org.apache.sis.metadata.iso.extent.DefaultExtent;
-import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
-import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;
-import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
-import org.apache.sis.metadata.iso.extent.DefaultSpatialTemporalExtent;
-import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.system.OptionalDependency;
-import org.apache.sis.internal.system.Modules;
-import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.Deprecable;
 
 
 /**
- * Provides access to services defined in the {@code "sis-referencing"} module.
- * This class searches for the {@link org.apache.sis.internal.referencing.ServicesForMetadata}
- * implementation using Java reflection.
- *
- * <p>This class also opportunistically defines some methods and constants related to
- * <cite>"referencing by coordinates"</cite> but needed by metadata.</p>
+ * A class in charges of combining two-dimensional geographic or projected CRS with an ellipsoidal height
+ * into a three-dimensional CRS.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
- * @since   0.3
+ * @since   0.8
  * @module
  */
-public class ReferencingServices extends OptionalDependency {
-    /**
-     * The length of one nautical mile, which is {@value} metres.
-     */
-    public static final double NAUTICAL_MILE = 1852;
-
-    /**
-     * The GRS80 {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#getAuthalicRadius() authalic radius},
-     * which is {@value} metres.
-     */
-    public static final double AUTHALIC_RADIUS = 6371007;
-
-    /**
-     * The {@link org.apache.sis.referencing.datum.DefaultGeodeticDatum#BURSA_WOLF_KEY} value.
-     */
-    public static final String BURSA_WOLF_KEY = "bursaWolf";
-
-    /**
-     * The key for specifying explicitely the value to be returned by
-     * {@link org.apache.sis.referencing.operation.DefaultConversion#getParameterValues()}.
-     * It is usually not necessary to specify those parameters because they are inferred either from
-     * the {@link MathTransform}, or specified explicitely in a {@code DefiningConversion}. However
-     * there is a few cases, for example the Molodenski transform, where none of the above can apply,
-     * because SIS implements those operations as a concatenation of math transforms, and such
-     * concatenations do not have {@link org.opengis.parameter.ParameterValueGroup}.
-     */
-    public static final String PARAMETERS_KEY = "parameters";
-
-    /**
-     * The key for specifying the base type of the coordinate operation to create. This optional entry
-     * is used by {@code DefaultCoordinateOperationFactory.createSingleOperation(…)}. Apache SIS tries
-     * to infer this value automatically, but this entry may help SIS to perform a better choice in
-     * some cases. For example an "Affine" operation can be both a conversion or a transformation
-     * (the later is used in datum shift in geocentric coordinates).
-     */
-    public static final String OPERATION_TYPE_KEY = "operationType";
-
-    /**
-     * The key for specifying a {@link MathTransformFactory} instance to use for geodetic object constructions.
-     * This is usually not needed for CRS construction, except in the special case of a derived CRS created
-     * from a defining conversion.
-     */
-    public static final String MT_FACTORY = "mtFactory";
-
-    /**
-     * The key for specifying a {@link CRSFactory} instance to use for geodetic object constructions.
-     */
-    public static final String CRS_FACTORY = "crsFactory";
-
-    /**
-     * The key for specifying a {@link CSFactory} instance to use for geodetic object constructions.
-     */
-    public static final String CS_FACTORY = "csFactory";
-
-    /**
-     * The key for specifying a {@link DatumFactory} instance to use for geodetic object constructions.
-     */
-    public static final String DATUM_FACTORY = "datumFactory";
-
-    /**
-     * The services, fetched when first needed.
-     */
-    private static volatile ReferencingServices instance;
-
-    /**
-     * For subclass only. This constructor registers this instance as a
-     * {@link org.apache.sis.internal.system.SystemListener} in order to
-     * force a new {@code ReferencingServices} lookup if the classpath changes.
-     */
-    protected ReferencingServices() {
-        super(Modules.METADATA, "sis-referencing");
-    }
-
-    /**
-     * Invoked when the classpath changed. Resets the {@link #instance} to {@code null}
-     * in order to force the next call to {@link #getInstance()} to fetch a new one,
-     * which may be different.
-     */
-    @Override
-    protected final void classpathChanged() {
-        synchronized (ReferencingServices.class) {
-            super.classpathChanged();
-            instance = null;
-        }
-    }
-
-    /**
-     * Returns the singleton instance.
-     *
-     * @return the singleton instance.
-     */
-    @SuppressWarnings("DoubleCheckedLocking")
-    public static ReferencingServices getInstance() {
-        ReferencingServices c = instance;
-        if (c == null) {
-            synchronized (ReferencingServices.class) {
-                c = instance;
-                if (c == null) {
-                    /*
-                     * Double-checked locking: okay since Java 5 provided that the 'instance' field is volatile.
-                     * In the particular case of this class, the intend is to ensure that SystemListener.add(…)
-                     * is invoked only once.
-                     */
-                    c = getInstance(ReferencingServices.class, Modules.METADATA, "sis-referencing",
-                            "org.apache.sis.internal.referencing.ServicesForMetadata");
-                    if (c == null) {
-                        c = new ReferencingServices();
-                    }
-                    instance = c;
-                }
-            }
-        }
-        return c;
-    }
-
-
-
-
-    ///////////////////////////////////////////////////////////////////////////////////////
-    ////                                                                               ////
-    ////                        SERVICES FOR ISO 19115 METADATA                        ////
-    ////                                                                               ////
-    ///////////////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Sets a geographic bounding box from the specified envelope.
-     * If the envelope contains a CRS which is not geographic, then the bounding box will be transformed
-     * to a geographic CRS (without datum shift if possible). Otherwise, the envelope is assumed already
-     * in a geographic CRS using (<var>longitude</var>, <var>latitude</var>) axis order.
-     *
-     * @param  envelope  the source envelope.
-     * @param  target    the target bounding box.
-     * @throws TransformException if the given envelope can't be transformed.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     */
-    public void setBounds(Envelope envelope, DefaultGeographicBoundingBox target) throws TransformException {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Sets a vertical extent with the value inferred from the given envelope.
-     * Only the vertical ordinates are extracted; all other ordinates are ignored.
-     *
-     * @param  envelope  the source envelope.
-     * @param  target    the target vertical extent.
-     * @throws TransformException if no vertical component can be extracted from the given envelope.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     */
-    public void setBounds(Envelope envelope, DefaultVerticalExtent target) throws TransformException {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Sets a temporal extent with the value inferred from the given envelope.
-     * Only the temporal ordinates are extracted; all other ordinates are ignored.
-     *
-     * @param  envelope  the source envelope.
-     * @param  target    the target temporal extent.
-     * @throws TransformException if no temporal component can be extracted from the given envelope.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     */
-    public void setBounds(Envelope envelope, DefaultTemporalExtent target) throws TransformException {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Sets the geographic, vertical and temporal extents with the values inferred from the given envelope.
-     * If the given {@code target} has more geographic or vertical extents than needed (0 or 1), then the
-     * extraneous extents are removed.
-     *
-     * <p>Behavior regarding missing dimensions:</p>
-     * <ul>
-     *   <li>If the given envelope has no horizontal component, then all geographic extents are removed
-     *       from the given {@code target}. Non-geographic extents (e.g. descriptions and polygons) are
-     *       left unchanged.</li>
-     *   <li>If the given envelope has no vertical component, then the vertical extent is set to {@code null}.</li>
-     *   <li>If the given envelope has no temporal component, then the temporal extent is set to {@code null}.</li>
-     * </ul>
-     *
-     * @param  envelope  the source envelope.
-     * @param  target    the target spatio-temporal extent.
-     * @throws TransformException if no temporal component can be extracted from the given envelope.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     */
-    public void setBounds(Envelope envelope, DefaultSpatialTemporalExtent target) throws TransformException {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Initializes a horizontal, vertical and temporal extent with the values inferred from the given envelope.
-     *
-     * @param  envelope  the source envelope.
-     * @param  target    the target extent.
-     * @throws TransformException if a coordinate transformation was required and failed.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     */
-    public void addElements(Envelope envelope, DefaultExtent target) throws TransformException {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Creates a two-dimensional geographic position associated to the default geographic CRS.
-     * Axis order is (longitude, latitude).
-     *
-     * @param  λ  the longitude value.
-     * @param  φ  the latitude value.
-     * @return the direct position for the given geographic coordinate.
-     *
-     * @since 0.8
-     */
-    public DirectPosition geographic(final double λ, final double φ) {
-        throw moduleNotFound();
-    }
-
-
-
-
-    ///////////////////////////////////////////////////////////////////////////////////////
-    ////                                                                               ////
-    ////                          SERVICES FOR WKT FORMATTING                          ////
-    ////                                                                               ////
-    ///////////////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Returns a fully implemented parameter descriptor.
-     *
-     * @param  parameter  a partially implemented parameter descriptor, or {@code null}.
-     * @return a fully implemented parameter descriptor, or {@code null} if the given argument was null.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     *
-     * @since 0.5
-     */
-    public ParameterDescriptor<?> toImplementation(ParameterDescriptor<?> parameter) {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Converts the given object in a {@code FormattableObject} instance.
-     *
-     * @param  object  the object to wrap.
-     * @return the given object converted to a {@code FormattableObject} instance.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     *
-     * @see org.apache.sis.referencing.AbstractIdentifiedObject#castOrCopy(IdentifiedObject)
-     *
-     * @since 0.4
-     */
-    public FormattableObject toFormattableObject(IdentifiedObject object) {
-        throw moduleNotFound();
-    }
-
+public class EllipsoidalHeightCombiner {
     /**
-     * Converts the given object in a {@code FormattableObject} instance. Callers should verify that the given
-     * object is not already an instance of {@code FormattableObject} before to invoke this method. This method
-     * returns {@code null} if it can not convert the object.
-     *
-     * @param  object  the object to wrap.
-     * @param  internal {@code true} if the formatting convention is {@code Convention.INTERNAL}.
-     * @return the given object converted to a {@code FormattableObject} instance, or {@code null}.
-     * @throws UnsupportedOperationException if the {@code "sis-referencing"} module has not been found on the classpath.
-     *
-     * @since 0.6
+     * The kind of factory initialized by {@link #initialize(int)}.
      */
-    public FormattableObject toFormattableObject(MathTransform object, boolean internal) {
-        throw moduleNotFound();
-    }
-
-
-
-
-    ///////////////////////////////////////////////////////////////////////////////////////
-    ////                                                                               ////
-    ////                           SERVICES FOR WKT PARSING                            ////
-    ////                                                                               ////
-    ///////////////////////////////////////////////////////////////////////////////////////
+    protected static final int CRS=1, CS=2, OPERATION=4;
 
     /**
-     * Returns a coordinate reference system for heights above the mean seal level.
-     *
-     * @return the "Mean Seal Level (MSL) height" coordinate reference system, or {@code null}.
-     *
-     * @since 0.6
+     * The factory to use for creating compound or three-dimensional geographic CRS.
      */
-    public VerticalCRS getMSLH() {
-        throw moduleNotFound();
-    }
+    protected CRSFactory crsFactory;
 
     /**
-     * Returns the Greenwich prime meridian.
-     *
-     * @return the Greenwich prime meridian.
-     *
-     * @since 0.6
+     * The factory to use for creating three-dimensional ellipsoidal CS, if needed.
      */
-    public PrimeMeridian getGreenwich() {
-        throw moduleNotFound();
-    }
+    protected CSFactory csFactory;
 
     /**
-     * Returns the coordinate system of a geocentric CRS using axes in the given unit of measurement.
-     *
-     * @param  unit  the unit of measurement for the geocentric CRS axes.
-     * @return the coordinate system for a geocentric CRS with axes using the given unit of measurement.
-     *
-     * @since 0.6
+     * The factory to use for creating defining conversions, if needed.
      */
-    public CartesianCS getGeocentricCS(final Unit<Length> unit) {
-        throw moduleNotFound();
-    }
+    protected CoordinateOperationFactory opFactory;
 
     /**
-     * Converts a geocentric coordinate system from the legacy WKT 1 to the current ISO 19111 standard.
-     * This method replaces the (Other, East, North) directions by (Geocentric X, Geocentric Y, Geocentric Z).
-     *
-     * @param  cs  the geocentric coordinate system to upgrade.
-     * @return the upgraded coordinate system, or {@code cs} if this method can not upgrade the given CS.
-     *
-     * @since 0.6
+     * Creates a new combiner with no initial factory.
+     * Subclasses must override the {@link #initialize(int)} method.
      */
-    public CartesianCS upgradeGeocentricCS(final CartesianCS cs) {
-        return cs;
+    protected EllipsoidalHeightCombiner() {
     }
 
     /**
-     * Creates a coordinate system of unknown type. This method is used during parsing of WKT version 1,
-     * since that legacy format did not specified any information about the coordinate system in use.
-     * This method should not need to be invoked for parsing WKT version 2.
-     *
-     * @param  properties  the coordinate system name, and optionally other properties.
-     * @param  axes        the axes of the unknown coordinate system.
-     * @return an "abstract" coordinate system using the given axes.
+     * Creates a new combiner which will use the given factories.
+     * Any factory given in argument may be {@code null} if lazy instantiation is desired.
      *
-     * @since 0.6
+     * @param  crsFactory  the factory to use for creating compound or three-dimensional geographic CRS.
+     * @param  csFactory   the factory to use for creating three-dimensional ellipsoidal CS, if needed.
+     * @param  opFactory   the factory to use for creating defining conversions, if needed.
      */
-    public CoordinateSystem createAbstractCS(final Map<String,?> properties, final CoordinateSystemAxis[] axes) {
-        throw moduleNotFound();
+    public EllipsoidalHeightCombiner(final CRSFactory crsFactory, final CSFactory csFactory,
+                                     final CoordinateOperationFactory opFactory)
+    {
+        this.crsFactory = crsFactory;
+        this.csFactory  = csFactory;
+        this.opFactory  = opFactory;
     }
 
     /**
-     * Creates a derived CRS from the information found in a WKT 1 {@code FITTED_CS} element.
-     * This coordinate system can not be easily constructed from the information provided by the WKT 1 format.
-     * Note that this method is needed only for WKT 1 parsing, since WKT provides enough information for using
-     * the standard factories.
-     *
-     * @param  properties     the properties to be given to the {@code DerivedCRS} and {@code Conversion} objects.
-     * @param  baseCRS        coordinate reference system to base the derived CRS on.
-     * @param  method         the coordinate operation method (mandatory in all cases).
-     * @param  baseToDerived  transform from positions in the base CRS to positions in this target CRS.
-     * @param  derivedCS      the coordinate system for the derived CRS.
-     * @return the newly created derived CRS, potentially implementing an additional CRS interface.
+     * Initializes the factory identified by the given code. This is used for lazy initialization if any factory given
+     * to the constructor was null. In such case, subclass must override. If the same {@code EllipsoidalHeightCombiner}
+     * instance is used more than once, than it is subclass responsibility to verify that the {@link #crsFactory},
+     * {@link #csFactory} or {@link #opFactory} field has not already been set.
      *
-     * @since 0.6
+     * @param  factoryTypes  a bitwise combination of {@link #CRS}, {@link #CS} and {@link #OPERATION}.
      */
-    public DerivedCRS createDerivedCRS(final Map<String,?>    properties,
-                                       final SingleCRS        baseCRS,
-                                       final OperationMethod  method,
-                                       final MathTransform    baseToDerived,
-                                       final CoordinateSystem derivedCS)
-    {
-        throw moduleNotFound();
+    protected void initialize(final int factoryTypes) {
     }
 
     /**
      * Creates a compound CRS, but we special processing for (two-dimensional Geographic + ellipsoidal heights) tupples.
      * If any such tupple is found, a three-dimensional geographic CRS is created instead than the compound CRS.
      *
-     * @param  crsFactory  the factory to use for creating compound or three-dimensional geographic CRS.
-     * @param  csFactory   the factory to use for creating three-dimensional ellipsoidal CS, if needed.
      * @param  properties  name and other properties to give to the new object.
      * @param  components  ordered array of {@code CoordinateReferenceSystem} objects.
      * @return the coordinate reference system for the given properties.
      * @throws FactoryException if the object creation failed.
-     *
-     * @since 0.7
      */
-    public final CoordinateReferenceSystem createCompoundCRS(final CRSFactory crsFactory, final CSFactory csFactory,
-            final Map<String,?> properties, CoordinateReferenceSystem... components) throws FactoryException
+    public final CoordinateReferenceSystem createCompoundCRS(final Map<String,?> properties,
+            CoordinateReferenceSystem... components) throws FactoryException
     {
         for (int i=0; i<components.length; i++) {
             final CoordinateReferenceSystem vertical = components[i];
@@ -484,19 +140,30 @@ public class ReferencingServices extends
                     axes[axisPosition++   ] = cs.getAxis(0);
                     axes[axisPosition++   ] = cs.getAxis(1);
                     axes[axisPosition %= 3] = vertical.getCoordinateSystem().getAxis(0);
-                    final Map<String,?> csProps = getProperties(cs, false);
-                    final Map<String,?> crsProps = (components.length == 2) ? properties : getProperties(crs, false);
+                    final ReferencingServices referencing = ReferencingServices.getInstance();
+                    final Map<String,?> csProps = referencing.getProperties(cs, false);
+                    final Map<String,?> crsProps = (components.length == 2) ? properties : referencing.getProperties(crs, false);
                     if (crs instanceof GeodeticCRS) {
+                        initialize(CS | CRS);
                         cs = csFactory.createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
                         crs = crsFactory.createGeographicCRS(crsProps, ((GeodeticCRS) crs).getDatum(), (EllipsoidalCS) cs);
                     } else {
+                        initialize(CS | CRS | OPERATION);
                         final ProjectedCRS proj = (ProjectedCRS) crs;
                         GeographicCRS base = proj.getBaseCRS();
                         if (base.getCoordinateSystem().getDimension() == 2) {
-                            base = (GeographicCRS) createCompoundCRS(crsFactory, csFactory, getProperties(base, false), base, vertical);
+                            base = (GeographicCRS) createCompoundCRS(referencing.getProperties(base, false), base, vertical);
                         }
+                        /*
+                         * In Apache SIS implementation, the Conversion contains the source and target CRS together with
+                         * a MathTransform2D. We need to recreate the same conversion, but without CRS and MathTransform
+                         * for letting SIS create or associate new ones, which will be three-dimensional now.
+                         */
+                        Conversion fromBase = proj.getConversionFromBase();
+                        fromBase = opFactory.createDefiningConversion(referencing.getProperties(fromBase, true),
+                                    fromBase.getMethod(), fromBase.getParameterValues());
                         cs = csFactory.createCartesianCS(csProps, axes[0], axes[1], axes[2]);
-                        crs = crsFactory.createProjectedCRS(crsProps, base, proj.getConversionFromBase(), (CartesianCS) cs);
+                        crs = crsFactory.createProjectedCRS(crsProps, base, fromBase, (CartesianCS) cs);
                     }
                     /*
                      * Remove the VerticalCRS and store the three-dimensional GeographicCRS in place of the previous
@@ -512,7 +179,7 @@ public class ReferencingServices extends
         switch (components.length) {
             case 0:  return null;
             case 1:  return components[0];
-            default: return crsFactory.createCompoundCRS(properties, components);
+            default: initialize(CRS); return crsFactory.createCompoundCRS(properties, components);
         }
     }
 
@@ -537,184 +204,4 @@ public class ReferencingServices extends
         }
         return null;
     }
-
-    /**
-     * Creates a format for {@link DirectPosition} instances.
-     *
-     * @param  locale    the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
-     * @param  timezone  the timezone, or {@code null} for UTC.
-     * @return a {@link org.apache.sis.geometry.CoordinateFormat}.
-     *
-     * @since 0.8
-     */
-    public Format createCoordinateFormat(final Locale locale, final TimeZone timezone) {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Returns an axis direction from a pole along a meridian.
-     * The given meridian is usually, but not necessarily, relative to the Greenwich meridian.
-     *
-     * @param  baseDirection  the base direction, which must be {@link AxisDirection#NORTH} or {@link AxisDirection#SOUTH}.
-     * @param  meridian       the meridian in degrees, relative to a unspecified (usually Greenwich) prime meridian.
-     *                        Meridians in the East hemisphere are positive and meridians in the West hemisphere are negative.
-     * @return the axis direction along the given meridian.
-     *
-     * @since 0.6
-     */
-    public AxisDirection directionAlongMeridian(final AxisDirection baseDirection, final double meridian) {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Creates the {@code TOWGS84} element during parsing of a WKT version 1. This is an optional operation:
-     * this method is allowed to return {@code null} if the "sis-referencing" module is not in the classpath.
-     *
-     * @param  values  the 7 Bursa-Wolf parameter values.
-     * @return the {@link org.apache.sis.referencing.datum.BursaWolfParameters}, or {@code null}.
-     *
-     * @since 0.6
-     */
-    public Object createToWGS84(final double[] values) {
-        return null;
-    }
-
-    /**
-     * Creates a single operation from the given properties.
-     * This method is provided here because not yet available in GeoAPI interfaces.
-     *
-     * @param  properties        the properties to be given to the identified object.
-     * @param  sourceCRS         the source CRS.
-     * @param  targetCRS         the target CRS.
-     * @param  interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
-     * @param  method            the coordinate operation method (mandatory in all cases).
-     * @param  factory           the factory to use.
-     * @return the coordinate operation created from the given arguments.
-     * @throws FactoryException if the object creation failed.
-     *
-     * @since 0.6
-     */
-    public SingleOperation createSingleOperation(
-            final Map<String,?>              properties,
-            final CoordinateReferenceSystem  sourceCRS,
-            final CoordinateReferenceSystem  targetCRS,
-            final CoordinateReferenceSystem  interpolationCRS,
-            final OperationMethod            method,
-            final CoordinateOperationFactory factory) throws FactoryException
-    {
-        throw moduleNotFound();
-    }
-
-    /**
-     * Returns the coordinate operation factory to use for the given properties and math transform factory.
-     * If the given properties are empty and the {@code mtFactory} is the system default, then this method
-     * returns the system default {@code CoordinateOperationFactory} instead of creating a new one.
-     *
-     * @param  properties  the default properties.
-     * @param  mtFactory   the math transform factory to use.
-     * @param  crsFactory  the factory to use if the operation factory needs to create CRS for intermediate steps.
-     * @param  csFactory   the factory to use if the operation factory needs to create CS for intermediate steps.
-     * @return the coordinate operation factory to use.
-     *
-     * @since 0.7
-     */
-    public CoordinateOperationFactory getCoordinateOperationFactory(Map<String,?> properties,
-            final MathTransformFactory mtFactory, final CRSFactory crsFactory, final CSFactory csFactory)
-    {
-        /*
-         * The check for 'properties' and 'mtFactory' is performed by the ServicesForMetadata subclass. If this code is
-         * executed, this means that the "sis-referencing" module is not on the classpath, in which case we do not know
-         * how to pass the 'properties' and 'mtFactory' arguments to the foreigner CoordinateOperationFactory anyway.
-         */
-        final CoordinateOperationFactory factory = DefaultFactories.forClass(CoordinateOperationFactory.class);
-        if (factory != null) {
-            return factory;
-        } else {
-            throw moduleNotFound();
-        }
-    }
-
-    /**
-     * Returns the properties of the given object.
-     *
-     * @param  object  the object from which to get the properties.
-     * @param  keepId  {@code true} for preserving the identifiers, {@code false} for discarding them.
-     * @return the properties of the given object.
-     *
-     * @since 0.6
-     */
-    public Map<String,?> getProperties(final IdentifiedObject object, final boolean keepId) {
-        return Collections.singletonMap(IdentifiedObject.NAME_KEY, object.getName());
-    }
-
-    /**
-     * Returns {@code true} if the {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName()
-     * primary name} or an aliases of the given object matches the given name. The comparison ignores case,
-     * some Latin diacritical signs and any characters that are not letters or digits.
-     *
-     * @param  object  the object for which to check the name or alias.
-     * @param  name    the name to compare with the object name or aliases.
-     * @return {@code true} if the primary name of at least one alias matches the specified {@code name}.
-     *
-     * @since 0.6
-     */
-    public boolean isHeuristicMatchForName(final IdentifiedObject object, final String name) {
-        return NameToIdentifier.isHeuristicMatchForName(object.getName(), object.getAlias(), name,
-                NameToIdentifier.Simplifier.DEFAULT);
-    }
-
-    /**
-     * Returns the operation method for the specified name or identifier. The given argument shall be either a
-     * method name (e.g. <cite>"Transverse Mercator"</cite>) or one of its identifiers (e.g. {@code "EPSG:9807"}).
-     *
-     * @param  methods     the method candidates.
-     * @param  identifier  the name or identifier of the operation method to search.
-     * @return the coordinate operation method for the given name or identifier, or {@code null} if none.
-     *
-     * @see org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#getOperationMethod(String)
-     * @see org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory#getOperationMethod(String)
-     *
-     * @since 0.6
-     */
-    public final OperationMethod getOperationMethod(final Iterable<? extends OperationMethod> methods, final String identifier) {
-        OperationMethod fallback = null;
-        for (final OperationMethod method : methods) {
-            if (isHeuristicMatchForName(method, identifier) ||
-                    NameToIdentifier.isHeuristicMatchForIdentifier(method.getIdentifiers(), identifier))
-            {
-                /*
-                 * Stop the iteration at the first non-deprecated method.
-                 * If we find only deprecated methods, take the first one.
-                 */
-                if (!(method instanceof Deprecable) || !((Deprecable) method).isDeprecated()) {
-                    return method;
-                }
-                if (fallback == null) {
-                    fallback = method;
-                }
-            }
-        }
-        return fallback;
-    }
-
-    /**
-     * Returns information about the Apache SIS configuration to be reported in {@link org.apache.sis.setup.About}.
-     * This method is invoked only for aspects that depends on other modules than {@code sis-utility}.
-     *
-     * <p>Current keys are:</p>
-     * <ul>
-     *   <li>{@code "EPSG"}: version of EPSG database.</li>
-     * </ul>
-     *
-     * @param  key     a key identifying the information to return.
-     * @param  locale  language to use if possible.
-     * @return the information, or {@code null} if none.
-     *
-     * @see org.apache.sis.internal.util.MetadataServices#getInformation(String, Locale)
-     *
-     * @since 0.7
-     */
-    public String getInformation(String key, Locale locale) {
-        return null;
-    }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -31,19 +31,14 @@ import org.opengis.referencing.crs.CRSFa
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.DerivedCRS;
-import org.opengis.referencing.crs.GeodeticCRS;
-import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.VerticalCRS;
-import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
-import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.DatumFactory;
 import org.opengis.referencing.datum.PrimeMeridian;
-import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
@@ -60,7 +55,6 @@ import org.apache.sis.internal.system.De
 import org.apache.sis.internal.system.OptionalDependency;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.io.wkt.FormattableObject;
-import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Deprecable;
 
 
@@ -440,105 +434,6 @@ public class ReferencingServices extends
     }
 
     /**
-     * Creates a compound CRS, but we special processing for (two-dimensional Geographic + ellipsoidal heights) tupples.
-     * If any such tupple is found, a three-dimensional geographic CRS is created instead than the compound CRS.
-     *
-     * @param  crsFactory  the factory to use for creating compound or three-dimensional geographic CRS.
-     * @param  csFactory   the factory to use for creating three-dimensional ellipsoidal CS, if needed.
-     * @param  properties  name and other properties to give to the new object.
-     * @param  components  ordered array of {@code CoordinateReferenceSystem} objects.
-     * @return the coordinate reference system for the given properties.
-     * @throws FactoryException if the object creation failed.
-     *
-     * @since 0.7
-     */
-    public final CoordinateReferenceSystem createCompoundCRS(final CRSFactory crsFactory, final CSFactory csFactory,
-            final Map<String,?> properties, CoordinateReferenceSystem... components) throws FactoryException
-    {
-        for (int i=0; i<components.length; i++) {
-            final CoordinateReferenceSystem vertical = components[i];
-            if (vertical instanceof VerticalCRS) {
-                final VerticalDatum datum = ((VerticalCRS) vertical).getDatum();
-                if (datum != null && datum.getVerticalDatumType() == VerticalDatumTypes.ELLIPSOIDAL) {
-                    int axisPosition = 0;
-                    CoordinateSystem cs = null;
-                    CoordinateReferenceSystem crs = null;
-                    if (i == 0 || (cs = getCsIfHorizontal2D(crs = components[i - 1])) == null) {
-                        /*
-                         * GeographicCRS are normally before VerticalCRS. But Apache SIS is tolerant to the
-                         * opposite order (note however that such ordering is illegal according ISO 19162).
-                         */
-                        if (i+1 >= components.length || (cs = getCsIfHorizontal2D(crs = components[i + 1])) == null) {
-                            continue;
-                        }
-                        axisPosition = 1;
-                    }
-                    /*
-                     * At this point we have the horizontal and vertical components. The horizontal component
-                     * begins at 'axisPosition', which is almost always zero. Create the three-dimensional CRS.
-                     * If the result is the CRS to be returned directly by this method (components.length == 2),
-                     * use the properties given in argument. Otherwise we need to use other properties; current
-                     * implementation recycles the properties of the existing two-dimensional CRS.
-                     */
-                    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[3];
-                    axes[axisPosition++   ] = cs.getAxis(0);
-                    axes[axisPosition++   ] = cs.getAxis(1);
-                    axes[axisPosition %= 3] = vertical.getCoordinateSystem().getAxis(0);
-                    final Map<String,?> csProps = getProperties(cs, false);
-                    final Map<String,?> crsProps = (components.length == 2) ? properties : getProperties(crs, false);
-                    if (crs instanceof GeodeticCRS) {
-                        cs = csFactory.createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
-                        crs = crsFactory.createGeographicCRS(crsProps, ((GeodeticCRS) crs).getDatum(), (EllipsoidalCS) cs);
-                    } else {
-                        final ProjectedCRS proj = (ProjectedCRS) crs;
-                        GeographicCRS base = proj.getBaseCRS();
-                        if (base.getCoordinateSystem().getDimension() == 2) {
-                            base = (GeographicCRS) createCompoundCRS(crsFactory, csFactory, getProperties(base, false), base, vertical);
-                        }
-                        cs = csFactory.createCartesianCS(csProps, axes[0], axes[1], axes[2]);
-                        crs = crsFactory.createProjectedCRS(crsProps, base, proj.getConversionFromBase(), (CartesianCS) cs);
-                    }
-                    /*
-                     * Remove the VerticalCRS and store the three-dimensional GeographicCRS in place of the previous
-                     * two-dimensional GeographicCRS. Then let the loop continues in case there is other CRS to merge
-                     * (should never happen, but we are paranoiac).
-                     */
-                    components = ArraysExt.remove(components, i, 1);
-                    if (axisPosition != 0) i--;             // GeographicCRS before VerticalCRS (usual case).
-                    components[i] = crs;
-                }
-            }
-        }
-        switch (components.length) {
-            case 0:  return null;
-            case 1:  return components[0];
-            default: return crsFactory.createCompoundCRS(properties, components);
-        }
-    }
-
-    /**
-     * Returns the coordinate system if the given CRS is a two-dimensional geographic or projected CRS,
-     * or {@code null} otherwise. The returned coordinate system is either ellipsoidal or Cartesian;
-     * no other type is returned.
-     */
-    private static CoordinateSystem getCsIfHorizontal2D(final CoordinateReferenceSystem crs) {
-        final boolean isProjected = (crs instanceof ProjectedCRS);
-        if (isProjected || crs instanceof GeodeticCRS) {
-            final CoordinateSystem cs = crs.getCoordinateSystem();
-            if (cs.getDimension() == 2 && (isProjected || cs instanceof EllipsoidalCS)) {
-                /*
-                 * ProjectedCRS are guaranteed to be associated to CartesianCS, so we do not test that.
-                 * GeodeticCRS may be associated to either CartesianCS or EllipsoidalCS, but this method
-                 * shall accept only EllipsoidalCS. Actually we should accept only GeographicCRS, but we
-                 * relax this condition by accepting GeodeticCRS with EllipsoidalCS.
-                 */
-                return cs;
-            }
-        }
-        return null;
-    }
-
-    /**
      * Creates a format for {@link DirectPosition} instances.
      *
      * @param  locale    the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -70,6 +70,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.metadata.VerticalDatumTypes;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.metadata.TransformationAccuracy;
+import org.apache.sis.internal.metadata.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.CharSequences;
@@ -2179,8 +2180,9 @@ class GeodeticObjectParser extends MathT
             components.add(crs);
         }
         try {
-            return referencing.createCompoundCRS(crsFactory, csFactory, parseMetadataAndClose(element, name, null),
-                    components.toArray(new CoordinateReferenceSystem[components.size()]));
+            return new EllipsoidalHeightCombiner(crsFactory, csFactory, opFactory).createCompoundCRS(
+                            parseMetadataAndClose(element, name, null),
+                            components.toArray(new CoordinateReferenceSystem[components.size()]));
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -40,10 +40,10 @@ import org.opengis.referencing.datum.Tem
 import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.Conversion;
-import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.metadata.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
 import org.apache.sis.internal.referencing.provider.PolarStereographicA;
 import org.apache.sis.measure.Latitude;
@@ -424,7 +424,13 @@ public class GeodeticObjectBuilder exten
      * @throws FactoryException if the object creation failed.
      */
     public CoordinateReferenceSystem createCompoundCRS(final CoordinateReferenceSystem... components) throws FactoryException {
-        return ReferencingServices.getInstance().createCompoundCRS(getCRSFactory(), getCSFactory(), properties, components);
+        return new EllipsoidalHeightCombiner() {
+            @Override public void initialize(final int factoryTypes) {
+                if ((factoryTypes & CRS)       != 0) crsFactory = getCRSFactory();
+                if ((factoryTypes & CS)        != 0)  csFactory = getCSFactory();
+                if ((factoryTypes & OPERATION) != 0)  opFactory = getCoordinateOperationFactory();
+            }
+        }.createCompoundCRS(properties, components);
     }
 
     /**

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java?rev=1811543&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CompoundCRSBuilder.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import org.apache.sis.internal.metadata.EllipsoidalHeightCombiner;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
+
+
+/**
+ * Helper class for combining two-dimensional geographic or projected CRS with an ellipsoidal height
+ * into a three-dimensional CRS.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since   0.8
+ * @module
+ */
+final class CompoundCRSBuilder extends EllipsoidalHeightCombiner {
+    /**
+     * The Apache SIS implementation of {@link CoordinateOperationFactory}.
+     */
+    private final DefaultCoordinateOperationFactory factorySIS;
+
+    /**
+     * Creates a new builder for the given coordinate operation factory.
+     *
+     * @param factory     the factory to use for creating coordinate operations.
+     * @param factorySIS  used only when we need a SIS-specific method.
+     */
+    CompoundCRSBuilder(final CoordinateOperationFactory factory, final DefaultCoordinateOperationFactory factorySIS) {
+        super(null, null, factory);
+        this.factorySIS = factorySIS;
+    }
+
+    /**
+     * Invoked when the builder needs a CRS or CS factory.
+     */
+    @Override
+    public void initialize(final int factoryTypes) {
+        if ((factoryTypes & CRS) != 0) crsFactory = factorySIS.getCRSFactory();
+        if ((factoryTypes & CS)  != 0)  csFactory = factorySIS.getCSFactory();
+    }
+}

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

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

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -33,7 +33,6 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.internal.metadata.AxisDirections;
-import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.provider.Geographic2Dto3D;
 import org.apache.sis.internal.referencing.provider.Geographic3Dto2D;
@@ -839,8 +838,8 @@ public class CoordinateOperationFinder e
             } else if (stepComponents.length == 1) {
                 stepTargetCRS = target;                 // Slight optimization of the next block.
             } else {
-                stepTargetCRS = toAuthorityDefinition(CoordinateReferenceSystem.class, ReferencingServices.getInstance()
-                        .createCompoundCRS(factorySIS.getCRSFactory(), factorySIS.getCSFactory(), derivedFrom(target), stepComponents));
+                stepTargetCRS = toAuthorityDefinition(CoordinateReferenceSystem.class,
+                        new CompoundCRSBuilder(factory, factorySIS).createCompoundCRS(derivedFrom(target), stepComponents));
             }
             int delta = source.getCoordinateSystem().getDimension();
             final int startAtDimension = endAtDimension;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -1044,10 +1044,7 @@ class CoordinateOperationRegistry {
             }
         }
         return toAuthorityDefinition(CoordinateReferenceSystem.class,
-                ReferencingServices.getInstance().createCompoundCRS(
-                        factorySIS.getCRSFactory(),
-                        factorySIS.getCSFactory(),
-                        derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
+                new CompoundCRSBuilder(factory, factorySIS).createCompoundCRS(derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
     }
 
     /**

Copied: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java (from r1811538, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java?p2=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java&p1=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java&r1=1811538&r2=1811543&rev=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -14,13 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.internal.referencing;
+package org.apache.sis.internal.metadata;
 
 import java.util.Map;
 import java.util.Collections;
-import org.opengis.geometry.Envelope;
-import org.opengis.metadata.extent.GeographicBoundingBox;
-import org.opengis.metadata.extent.VerticalExtent;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.SingleCRS;
@@ -28,18 +25,12 @@ import org.opengis.referencing.crs.Geogr
 import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.TemporalCRS;
-import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
-import org.apache.sis.internal.metadata.ReferencingServices;
-import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
-import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
-import org.apache.sis.metadata.iso.extent.DefaultSpatialTemporalExtent;
-import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.referencing.CRS;
-import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.referencing.factory.GeodeticObjectFactory;
+import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
 import org.apache.sis.referencing.operation.HardCodedConversions;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
@@ -47,151 +38,48 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.Assert.*;
-import static org.apache.sis.test.TestUtilities.getSingleton;
 
 
 /**
- * Tests {@link ServicesForMetadata}.
+ * Tests {@link EllipsoidalHeightCombiner}. This class is defined in {@code sis-metadata} module
+ * but tested here because the tests use CRS instances defined in {@code sis-referencing}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
- * @since   0.5
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/SIS-303">SIS-303</a>
+ *
+ * @since 0.8
  * @module
  */
 @DependsOn({
     org.apache.sis.referencing.CRSTest.class,
-    org.apache.sis.referencing.CommonCRSTest.class
+    org.apache.sis.internal.referencing.ServicesForMetadataTest.class
 })
-public final strictfp class ServicesForMetadataTest extends TestCase {
-    /**
-     * Tests {@link org.apache.sis.metadata.iso.extent.Extents#centroid(GeographicBoundingBox)}.
-     *
-     * @since 0.8
-     */
-    @Test
-    public void testGeographicBoundingBoxCentroid() {
-        org.apache.sis.metadata.iso.extent.ExtentsTest.testCentroid();
-    }
-
+public final strictfp class EllipsoidalHeightCombinerTest extends TestCase {
     /**
-     * Creates a test envelope with the given CRS and initialized with
-     * [-10 … 70]° of longitude, [-20 … 30]° of latitude, [-40 … 60] metres of elevation
-     * and [51000 … 52000] modified Julian days.
+     * Creates an instance to be tested.
      */
-    @SuppressWarnings("fallthrough")
-    private static Envelope createEnvelope(final CoordinateReferenceSystem crs) {
-        final GeneralEnvelope envelope = new GeneralEnvelope(crs);
-        switch (crs.getCoordinateSystem().getDimension()) {
-            default: throw new AssertionError();
-            case 4: envelope.setRange(3, 51000, 52000);                 // Fall through
-            case 3: envelope.setRange(2, -10, 70);                      // Fall through
-            case 2: envelope.setRange(1, -20, 30);                      // Fall through
-            case 1: envelope.setRange(0, -40, 60);
-            case 0: break;
-        }
-        return envelope;
-    }
-
-    /**
-     * Verifies the values of the given geographic bounding box.
-     */
-    private static void verifySpatialExtent(final GeographicBoundingBox box) {
-        assertEquals(-40, box.getWestBoundLongitude(), STRICT);
-        assertEquals( 60, box.getEastBoundLongitude(), STRICT);
-        assertEquals(-20, box.getSouthBoundLatitude(), STRICT);
-        assertEquals( 30, box.getNorthBoundLatitude(), STRICT);
-        assertEquals(Boolean.TRUE, box.getInclusion());
-    }
-
-    /**
-     * Verifies the values of the given vertical extent.
-     */
-    private static void verifyVerticalExtent(final CommonCRS.Vertical expectedCRS, final VerticalExtent extent) {
-        assertEquals(-10, extent.getMinimumValue(), STRICT);
-        assertEquals( 70, extent.getMaximumValue(), STRICT);
-        assertEqualsIgnoreMetadata(expectedCRS.crs(), extent.getVerticalCRS());
-    }
-
-    /**
-     * Tests (indirectly) {@link ServicesForMetadata#setBounds(Envelope, DefaultGeographicBoundingBox)}
-     * from a three-dimensional envelope.
-     *
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testSetGeographicBoundsFrom3D() throws TransformException {
-        final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox();
-        box.setBounds(createEnvelope(HardCodedCRS.WGS84_3D));
-        verifySpatialExtent(box);
-    }
-
-    /**
-     * Tests (indirectly) {@link ServicesForMetadata#setBounds(Envelope, DefaultGeographicBoundingBox)}
-     * from a for-dimensional envelope.
-     *
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testSetGeographicBoundsFrom4D() throws TransformException {
-        final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox();
-        box.setBounds(createEnvelope(HardCodedCRS.GEOID_4D));
-        verifySpatialExtent(box);
-    }
-
-    /**
-     * Tests (indirectly) {@link ServicesForMetadata#setBounds(Envelope, DefaultVerticalExtent)}
-     * from an ellipsoidal height
-     *
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testSetVerticalBoundsFromEllipsoid() throws TransformException {
-        final DefaultVerticalExtent extent = new DefaultVerticalExtent();
-        extent.setBounds(createEnvelope(HardCodedCRS.WGS84_3D));
-        verifyVerticalExtent(CommonCRS.Vertical.ELLIPSOIDAL, extent);
-    }
-
-    /**
-     * Tests (indirectly) {@link ServicesForMetadata#setBounds(Envelope, DefaultVerticalExtent)}
-     * from a geoidal height
-     *
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testSetVerticalBoundsFromGeoid() throws TransformException {
-        final DefaultVerticalExtent extent = new DefaultVerticalExtent();
-        extent.setBounds(createEnvelope(HardCodedCRS.GEOID_4D));
-        verifyVerticalExtent(CommonCRS.Vertical.MEAN_SEA_LEVEL, extent);
-    }
-
-    /**
-     * Tests (indirectly) {@link ServicesForMetadata#setBounds(Envelope, DefaultSpatialTemporalExtent)}.
-     *
-     * @throws TransformException should never happen.
-     */
-    @Test
-    @DependsOnMethod({"testSetGeographicBoundsFrom4D", "testSetVerticalBoundsFromGeoid"})
-    public void testSetSpatialTemporalBounds() throws TransformException {
-        final DefaultSpatialTemporalExtent extent = new DefaultSpatialTemporalExtent();
-        extent.setBounds(createEnvelope(HardCodedCRS.GEOID_3D));
-        verifySpatialExtent((GeographicBoundingBox) getSingleton(extent.getSpatialExtent()));
-        verifyVerticalExtent(CommonCRS.Vertical.MEAN_SEA_LEVEL, extent.getVerticalExtent());
+    private static EllipsoidalHeightCombiner create() {
+        final GeodeticObjectFactory factory = new GeodeticObjectFactory();
+        return new EllipsoidalHeightCombiner(factory, factory, null) {
+            @Override protected void initialize(final int factoryTypes) {
+                if ((factoryTypes & OPERATION) != 0) {
+                    opFactory = new DefaultCoordinateOperationFactory();
+                }
+            }
+        };
     }
 
     /**
-     * Tests {@link ServicesForMetadata#createCompoundCRS ReferencingUtilities.createCompoundCRS(…)}
+     * Tests {@link EllipsoidalHeightCombiner#createCompoundCRS EllipsoidalHeightCombiner.createCompoundCRS(…)}
      * with a geographic CRS.
      *
      * @throws FactoryException if a CRS can not be created.
-     *
-     * @see <a href="https://issues.apache.org/jira/browse/SIS-303">SIS-303</a>
-     *
-     * @since 0.7
      */
     @Test
-    public void testCreateCompoundGeographicCRS() throws FactoryException {
-        final ReferencingServices  services = ServicesForMetadata.getInstance();
-        final GeodeticObjectFactory factory = new GeodeticObjectFactory();
+    public void testGeographicCRS() throws FactoryException {
+        final EllipsoidalHeightCombiner services = create();
         final Map<String,String> properties = Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY, "WGS 84 (4D)");
         final GeographicCRS horizontal   = HardCodedCRS.WGS84;
         final GeographicCRS horizontal3D = HardCodedCRS.WGS84_3D;
@@ -201,23 +89,23 @@ public final strictfp class ServicesForM
         /*
          * createCompoundCRS(…) should not combine GeographicCRS with non-ellipsoidal height.
          */
-        CoordinateReferenceSystem compound = services.createCompoundCRS(factory, factory, properties, horizontal, geoidal, temporal);
+        CoordinateReferenceSystem compound = services.createCompoundCRS(properties, horizontal, geoidal, temporal);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal, geoidal, temporal}, CRS.getSingleComponents(compound).toArray());
         /*
          * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height.
          */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical);
+        compound = services.createCompoundCRS(properties, horizontal, vertical);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D}, CRS.getSingleComponents(compound).toArray());
         /*
          * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height and keep time.
          */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical, temporal);
+        compound = services.createCompoundCRS(properties, horizontal, vertical, temporal);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D, temporal}, CRS.getSingleComponents(compound).toArray());
         /*
          * Non-standard feature: accept (VerticalCRS + GeodeticCRS) order.
          * The test below use the reverse order for all axes compared to the previous test.
          */
-        compound = services.createCompoundCRS(factory, factory, properties, temporal, vertical, HardCodedCRS.WGS84_φλ);
+        compound = services.createCompoundCRS(properties, temporal, vertical, HardCodedCRS.WGS84_φλ);
         final Object[] components = CRS.getSingleComponents(compound).toArray();
         assertEquals(2, components.length);
         assertEqualsIgnoreMetadata(temporal, components[0]);
@@ -228,17 +116,15 @@ public final strictfp class ServicesForM
     }
 
     /**
-     * Tests {@link ServicesForMetadata#createCompoundCRS ReferencingUtilities.createCompoundCRS(…)}
+     * Tests {@link EllipsoidalHeightCombiner#createCompoundCRS EllipsoidalHeightCombiner.createCompoundCRS(…)}
      * with a projected CRS.
      *
      * @throws FactoryException if a CRS can not be created.
-     *
-     * @since 0.8
      */
     @Test
-    @DependsOnMethod("testCreateCompoundGeographicCRS")
-    public void testCreateCompoundProjectedCRS() throws FactoryException {
-        final ReferencingServices  services = ServicesForMetadata.getInstance();
+    @DependsOnMethod("testGeographicCRS")
+    public void testProjectedCRS() throws FactoryException {
+        final EllipsoidalHeightCombiner services = create();
         final GeodeticObjectFactory factory = new GeodeticObjectFactory();
         final Map<String,String> properties = Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY, "World Mercator (4D)");
         final ProjectedCRS horizontal   = factory.createProjectedCRS(properties, HardCodedCRS.WGS84,    HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED);
@@ -249,31 +135,28 @@ public final strictfp class ServicesForM
         /*
          * createCompoundCRS(…) should not combine ProjectedCRS with non-ellipsoidal height.
          */
-        CoordinateReferenceSystem compound = services.createCompoundCRS(factory, factory, properties, horizontal, geoidal, temporal);
+        CoordinateReferenceSystem compound = services.createCompoundCRS(properties, horizontal, geoidal, temporal);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal, geoidal, temporal}, CRS.getSingleComponents(compound).toArray());
         /*
          * createCompoundCRS(…) should combine ProjectedCRS with ellipsoidal height.
          */
-        if (true) return;       // TODO - debug after this point.
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical);
+        compound = services.createCompoundCRS(properties, horizontal, vertical);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D}, CRS.getSingleComponents(compound).toArray());
         /*
-         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height and keep time.
+         * createCompoundCRS(…) should combine ProjectedCRS with ellipsoidal height and keep time.
          */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical, temporal);
+        compound = services.createCompoundCRS(properties, horizontal, vertical, temporal);
         assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D, temporal}, CRS.getSingleComponents(compound).toArray());
         /*
-         * Non-standard feature: accept (VerticalCRS + GeodeticCRS) order.
-         * The test below use the reverse order for all axes compared to the previous test.
+         * Non-standard feature: accept (VerticalCRS + ProjectedCRS) order.
          */
-        compound = services.createCompoundCRS(factory, factory, properties,
-                temporal, vertical, HardCodedCRS.WGS84_φλ);
+        compound = services.createCompoundCRS(properties, temporal, vertical, horizontal);
         final Object[] components = CRS.getSingleComponents(compound).toArray();
         assertEquals(2, components.length);
         assertEqualsIgnoreMetadata(temporal, components[0]);
-        assertInstanceOf("Shall be a three-dimensional geographic CRS.", GeographicCRS.class, components[1]);
-        assertAxisDirectionsEqual("Shall be a three-dimensional geographic CRS.",
+        assertInstanceOf("Shall be a three-dimensional projected CRS.", ProjectedCRS.class, components[1]);
+        assertAxisDirectionsEqual("Shall be a three-dimensional projected CRS.",
                 ((CoordinateReferenceSystem) components[1]).getCoordinateSystem(),
-                AxisDirection.UP, AxisDirection.NORTH, AxisDirection.EAST);
+                AxisDirection.UP, AxisDirection.EAST, AxisDirection.NORTH);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java?rev=1811543&r1=1811542&r2=1811543&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java [UTF-8] Mon Oct  9 09:31:41 2017
@@ -16,31 +16,17 @@
  */
 package org.apache.sis.internal.referencing;
 
-import java.util.Map;
-import java.util.Collections;
 import org.opengis.geometry.Envelope;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.metadata.extent.VerticalExtent;
-import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.crs.SingleCRS;
-import org.opengis.referencing.crs.GeographicCRS;
-import org.opengis.referencing.crs.ProjectedCRS;
-import org.opengis.referencing.crs.VerticalCRS;
-import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.operation.TransformException;
-import org.opengis.util.FactoryException;
-import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
 import org.apache.sis.metadata.iso.extent.DefaultSpatialTemporalExtent;
 import org.apache.sis.geometry.GeneralEnvelope;
-import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
-import org.apache.sis.referencing.factory.GeodeticObjectFactory;
-import org.apache.sis.referencing.operation.HardCodedConversions;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -59,7 +45,6 @@ import static org.apache.sis.test.TestUt
  * @module
  */
 @DependsOn({
-    org.apache.sis.referencing.CRSTest.class,
     org.apache.sis.referencing.CommonCRSTest.class
 })
 public final strictfp class ServicesForMetadataTest extends TestCase {
@@ -177,103 +162,4 @@ public final strictfp class ServicesForM
         verifySpatialExtent((GeographicBoundingBox) getSingleton(extent.getSpatialExtent()));
         verifyVerticalExtent(CommonCRS.Vertical.MEAN_SEA_LEVEL, extent.getVerticalExtent());
     }
-
-    /**
-     * Tests {@link ServicesForMetadata#createCompoundCRS ReferencingUtilities.createCompoundCRS(…)}
-     * with a geographic CRS.
-     *
-     * @throws FactoryException if a CRS can not be created.
-     *
-     * @see <a href="https://issues.apache.org/jira/browse/SIS-303">SIS-303</a>
-     *
-     * @since 0.7
-     */
-    @Test
-    public void testCreateCompoundGeographicCRS() throws FactoryException {
-        final ReferencingServices  services = ServicesForMetadata.getInstance();
-        final GeodeticObjectFactory factory = new GeodeticObjectFactory();
-        final Map<String,String> properties = Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY, "WGS 84 (4D)");
-        final GeographicCRS horizontal   = HardCodedCRS.WGS84;
-        final GeographicCRS horizontal3D = HardCodedCRS.WGS84_3D;
-        final VerticalCRS   vertical     = HardCodedCRS.ELLIPSOIDAL_HEIGHT;
-        final TemporalCRS   temporal     = HardCodedCRS.TIME;
-        final VerticalCRS   geoidal      = HardCodedCRS.GRAVITY_RELATED_HEIGHT;
-        /*
-         * createCompoundCRS(…) should not combine GeographicCRS with non-ellipsoidal height.
-         */
-        CoordinateReferenceSystem compound = services.createCompoundCRS(factory, factory, properties, horizontal, geoidal, temporal);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal, geoidal, temporal}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height.
-         */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height and keep time.
-         */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical, temporal);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D, temporal}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * Non-standard feature: accept (VerticalCRS + GeodeticCRS) order.
-         * The test below use the reverse order for all axes compared to the previous test.
-         */
-        compound = services.createCompoundCRS(factory, factory, properties, temporal, vertical, HardCodedCRS.WGS84_φλ);
-        final Object[] components = CRS.getSingleComponents(compound).toArray();
-        assertEquals(2, components.length);
-        assertEqualsIgnoreMetadata(temporal, components[0]);
-        assertInstanceOf("Shall be a three-dimensional geographic CRS.", GeographicCRS.class, components[1]);
-        assertAxisDirectionsEqual("Shall be a three-dimensional geographic CRS.",
-                ((CoordinateReferenceSystem) components[1]).getCoordinateSystem(),
-                AxisDirection.UP, AxisDirection.NORTH, AxisDirection.EAST);
-    }
-
-    /**
-     * Tests {@link ServicesForMetadata#createCompoundCRS ReferencingUtilities.createCompoundCRS(…)}
-     * with a projected CRS.
-     *
-     * @throws FactoryException if a CRS can not be created.
-     *
-     * @since 0.8
-     */
-    @Test
-    @DependsOnMethod("testCreateCompoundGeographicCRS")
-    public void testCreateCompoundProjectedCRS() throws FactoryException {
-        final ReferencingServices  services = ServicesForMetadata.getInstance();
-        final GeodeticObjectFactory factory = new GeodeticObjectFactory();
-        final Map<String,String> properties = Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY, "World Mercator (4D)");
-        final ProjectedCRS horizontal   = factory.createProjectedCRS(properties, HardCodedCRS.WGS84,    HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED);
-        final ProjectedCRS horizontal3D = factory.createProjectedCRS(properties, HardCodedCRS.WGS84_3D, HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED_3D);
-        final VerticalCRS  vertical     = HardCodedCRS.ELLIPSOIDAL_HEIGHT;
-        final TemporalCRS  temporal     = HardCodedCRS.TIME;
-        final VerticalCRS  geoidal      = HardCodedCRS.GRAVITY_RELATED_HEIGHT;
-        /*
-         * createCompoundCRS(…) should not combine ProjectedCRS with non-ellipsoidal height.
-         */
-        CoordinateReferenceSystem compound = services.createCompoundCRS(factory, factory, properties, horizontal, geoidal, temporal);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal, geoidal, temporal}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * createCompoundCRS(…) should combine ProjectedCRS with ellipsoidal height.
-         */
-        if (true) return;       // TODO - debug after this point.
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height and keep time.
-         */
-        compound = services.createCompoundCRS(factory, factory, properties, horizontal, vertical, temporal);
-        assertArrayEqualsIgnoreMetadata(new SingleCRS[] {horizontal3D, temporal}, CRS.getSingleComponents(compound).toArray());
-        /*
-         * Non-standard feature: accept (VerticalCRS + GeodeticCRS) order.
-         * The test below use the reverse order for all axes compared to the previous test.
-         */
-        compound = services.createCompoundCRS(factory, factory, properties,
-                temporal, vertical, HardCodedCRS.WGS84_φλ);
-        final Object[] components = CRS.getSingleComponents(compound).toArray();
-        assertEquals(2, components.length);
-        assertEqualsIgnoreMetadata(temporal, components[0]);
-        assertInstanceOf("Shall be a three-dimensional geographic CRS.", GeographicCRS.class, components[1]);
-        assertAxisDirectionsEqual("Shall be a three-dimensional geographic CRS.",
-                ((CoordinateReferenceSystem) components[1]).getCoordinateSystem(),
-                AxisDirection.UP, AxisDirection.NORTH, AxisDirection.EAST);
-    }
 }

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=1811543&r1=1811542&r2=1811543&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] Mon Oct  9 09:31:41 2017
@@ -229,7 +229,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
     org.apache.sis.referencing.operation.builder.LocalizationGridBuilderTest.class,
 
-    // Geometry
+    // Geometry and miscellaneous
     org.apache.sis.geometry.AbstractDirectPositionTest.class,
     org.apache.sis.geometry.GeneralDirectPositionTest.class,
     org.apache.sis.geometry.DirectPosition1DTest.class,
@@ -244,6 +244,7 @@ import org.junit.BeforeClass;
     org.apache.sis.geometry.Shapes2DTest.class,                 // Simpler than EnvelopesTest.
     org.apache.sis.geometry.EnvelopesTest.class,
     org.apache.sis.internal.referencing.ServicesForMetadataTest.class,
+    org.apache.sis.internal.metadata.EllipsoidalHeightCombinerTest.class,
     org.apache.sis.geometry.CoordinateFormatTest.class,
 
     org.apache.sis.distance.LatLonPointRadiusTest.class,        // Pending refactoring in a geometry package.



Mime
View raw message