This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sis.git

commit f9759678243294344be5460f8c52bd48907099c2
Merge: f3170bc4ec bb738fc51c
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Sep 2 17:37:07 2025 +0200

    Merge branch 'geoapi-3.1'.

 .../apache/sis/console/MetadataCommandTest.java    |   3 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  18 ++--
 .../pending/geoapi/referencing/MissingMethods.java |  69 +++++++++++++
 .../main/org/apache/sis/referencing/CommonCRS.java | 107 +++++++++++++++------
 .../sis/referencing/EPSGFactoryFallback.java       |  32 ++++--
 .../sis/referencing/StandardDefinitions.java       |  18 ++--
 .../sis/referencing/datum/DatumOrEnsemble.java     |  60 ++++++++++++
 .../referencing/datum/DefaultDatumEnsemble.java    |   4 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |   4 +-
 .../factory/GeodeticAuthorityFactory.java          |   2 +-
 .../referencing/factory/GeodeticObjectFactory.java |  81 +++++++++-------
 .../referencing/factory/sql/EPSGDataAccess.java    |  36 ++-----
 .../referencing/internal/ServicesForMetadata.java  |  75 ---------------
 .../operation/CoordinateOperationFinder.java       |   6 +-
 .../org/apache/sis/referencing/Assertions.java     |  20 +++-
 .../test/org/apache/sis/referencing/CRSTest.java   |   2 +
 .../org/apache/sis/referencing/CommonCRSTest.java  |   8 +-
 .../sis/referencing/EPSGFactoryFallbackTest.java   |  25 +++--
 .../sis/referencing/GeodeticObjectVerifier.java    |   7 +-
 .../sis/referencing/StandardDefinitionsTest.java   |   2 +-
 .../sis/referencing/datum/HardCodedDatum.java      |   1 +
 .../sis/storage/geotiff/reader/CRSBuilder.java     |   2 +-
 .../apache/sis/storage/netcdf/base/CRSBuilder.java |   3 +-
 .../apache/sis/storage/netcdf/base/Convention.java |   2 +-
 .../sis/storage/netcdf/base/GridMapping.java       |   2 +-
 .../org/apache/sis/storage/CoverageSubsetTest.java |   4 +-
 26 files changed, 365 insertions(+), 228 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
index 8631f90798,2f364380b5..1291af32e8
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@@ -87,11 -87,8 +87,13 @@@ import org.apache.sis.util.iso.Types
  // Specific to the main and geoapi-3.1 branches:
  import org.opengis.referencing.ReferenceIdentifier;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.referencing.ObjectDomain;
 +// Specific to the main branch:
 +import org.opengis.referencing.ReferenceSystem;
- import org.apache.sis.referencing.internal.ServicesForMetadata;
++import org.apache.sis.pending.geoapi.referencing.MissingMethods;
++import org.apache.sis.referencing.cs.DefaultParametricCS;
++import org.apache.sis.referencing.datum.DefaultParametricDatum;
 +import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 +import org.apache.sis.temporal.TemporalDate;
  
  
  /**
@@@ -983,7 -969,7 +985,7 @@@ class GeodeticObjectParser extends Math
              }
              case WKTKeywords.parametric: {
                  if (axes.length != (dimension = 1)) break;
-                 return ServicesForMetadata.createParametricCS(csProperties, 
axes[0], csFactory);
 -                return csFactory.createParametricCS(csProperties, axes[0]);
++                return MissingMethods.createParametricCS(csProperties, 
axes[0], csFactory);
              }
              default: {
                  warning(parent, WKTKeywords.CS, 
Errors.formatInternational(Errors.Keys.UnknownType_1, type), null);
@@@ -1513,10 -1498,10 +1515,10 @@@
       *
       * @param  mode    {@link #FIRST}, {@link #OPTIONAL} or {@link 
#MANDATORY}.
       * @param  parent  the parent element.
 -     * @return the {@code "ParametricDatum"} element as a {@link 
ParametricDatum} object.
 +     * @return the {@code "ParametricDatum"} element as a {@code 
ParametricDatum} object.
       * @throws ParseException if the {@code "ParametricDatum"} element cannot 
be parsed.
       */
-     private Datum parseParametricDatum(final int mode, final Element parent) 
throws ParseException {
 -    private ParametricDatum parseParametricDatum(final int mode, final 
Element parent) throws ParseException {
++    private DefaultParametricDatum parseParametricDatum(final int mode, final 
Element parent) throws ParseException {
          final Element element = parent.pullElement(mode, 
WKTKeywords.ParametricDatum, WKTKeywords.PDatum);
          if (element == null) {
              return null;
@@@ -1524,7 -1509,7 +1526,7 @@@
          final String name = element.pullString("name");
          final DatumFactory datumFactory = factories.getDatumFactory();
          try {
-             return 
ServicesForMetadata.createParametricDatum(parseAnchorAndClose(element, name), 
datumFactory);
 -            return 
datumFactory.createParametricDatum(parseAnchorAndClose(element, name));
++            return 
MissingMethods.createParametricDatum(parseAnchorAndClose(element, name), 
datumFactory);
          } catch (FactoryException exception) {
              throw element.parseFailed(exception);
          }
@@@ -2058,7 -2046,7 +2060,7 @@@
           * A ParametricCRS can be either a "normal" one (with a non-null 
datum), or a DerivedCRS of kind ParametricCRS.
           * In the latter case, the datum is null and we have instead 
DerivingConversion element from a BaseParametricCRS.
           */
-         Datum datum = null;
 -        ParametricDatum datum = null;
++        DefaultParametricDatum datum = null;
          SingleCRS baseCRS = null;
          Conversion fromBase = null;
          if (!isBaseCRS) {
@@@ -2084,12 -2072,12 +2086,12 @@@
          try {
              cs = parseCoordinateSystem(element, WKTKeywords.parametric, 1, 
false, unit, false, null);
              final Map<String,?> properties = parseMetadataAndClose(element, 
name, datum);
-             if (cs != null) {
 -            if (cs instanceof ParametricCS) {
++            if (cs instanceof DefaultParametricCS) {
                  final CRSFactory crsFactory = factories.getCRSFactory();
                  if (baseCRS != null) {
                      return crsFactory.createDerivedCRS(properties, baseCRS, 
fromBase, cs);
                  }
-                 return ServicesForMetadata.createParametricCRS(properties, 
datum, cs, crsFactory);
 -                return crsFactory.createParametricCRS(properties, datum, 
(ParametricCS) cs);
++                return MissingMethods.createParametricCRS(properties, datum, 
(DefaultParametricCS) cs, crsFactory);
              }
          } catch (FactoryException exception) {
              throw element.parseFailed(exception);
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java
index a84e462276,0000000000..091edd126e
mode 100644,000000..100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java
@@@ -1,96 -1,0 +1,165 @@@
 +/*
 + * 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.pending.geoapi.referencing;
 +
++import java.util.Map;
 +import java.util.function.Function;
++import org.opengis.util.FactoryException;
 +import org.opengis.referencing.crs.*;
 +import org.opengis.referencing.datum.*;
++import org.opengis.referencing.cs.CSFactory;
++import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.apache.sis.referencing.crs.DefaultVerticalCRS;
 +import org.apache.sis.referencing.crs.DefaultTemporalCRS;
 +import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
++import org.apache.sis.referencing.cs.DefaultParametricCS;
 +import org.apache.sis.referencing.datum.DefaultDatumEnsemble;
++import org.apache.sis.referencing.datum.DefaultParametricDatum;
++import org.apache.sis.referencing.factory.GeodeticObjectFactory;
++import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 +
 +
 +/**
 + * Placeholder for methods missing in the GeoAPI 3.0 interface.
 + */
 +public final class MissingMethods {
 +    /**
 +     * To be set by static {@code AbstractCRS} initializer.
 +     */
 +    public static volatile Function<CoordinateReferenceSystem, 
DefaultDatumEnsemble<?>> datumEnsemble;
 +
 +    /**
 +     * To be set by static {@code DefaultGeodeticCRS} initializer.
 +     */
 +    public static volatile Function<GeodeticCRS, 
DefaultDatumEnsemble<GeodeticDatum>> geodeticDatumEnsemble;
 +
 +    private MissingMethods() {
 +    }
 +
 +    /**
 +     * Returns the datum ensemble of an arbitrary CRS.
 +     *
 +     * @param  datum  the CRS from which to get a datum ensemble, or {@code 
null} if none.
 +     * @return the datum ensemble, or {@code null} if none.
 +     */
 +    public static DefaultDatumEnsemble<?> getDatumEnsemble(final 
CoordinateReferenceSystem crs) {
 +        final var m = datumEnsemble;
 +        return (m != null) ? m.apply(crs) : null;
 +    }
 +
 +    /**
 +     * Returns the datum ensemble of an arbitrary geodetic CRS.
 +     *
 +     * @param  datum  the CRS from which to get a datum ensemble, or {@code 
null} if none.
 +     * @return the datum ensemble, or {@code null} if none.
 +     */
 +    public static DefaultDatumEnsemble<GeodeticDatum> getDatumEnsemble(final 
GeodeticCRS crs) {
 +        final var m = geodeticDatumEnsemble;
 +        return (m != null) ? m.apply(crs) : null;
 +    }
 +
 +    /**
 +     * Returns the datum ensemble of an arbitrary vertical CRS.
 +     *
 +     * @param  datum  the CRS from which to get a datum ensemble, or {@code 
null} if none.
 +     * @return the datum ensemble, or {@code null} if none.
 +     */
 +    public static DefaultDatumEnsemble<VerticalDatum> getDatumEnsemble(final 
VerticalCRS crs) {
 +        return (crs instanceof DefaultVerticalCRS) ? ((DefaultVerticalCRS) 
crs).getDatumEnsemble() : null;
 +    }
 +
 +    /**
 +     * Returns the datum ensemble of an arbitrary temporal CRS.
 +     *
 +     * @param  datum  the CRS from which to get a datum ensemble, or {@code 
null} if none.
 +     * @return the datum ensemble, or {@code null} if none.
 +     */
 +    public static DefaultDatumEnsemble<TemporalDatum> getDatumEnsemble(final 
TemporalCRS crs) {
 +        return (crs instanceof DefaultTemporalCRS) ? ((DefaultTemporalCRS) 
crs).getDatumEnsemble() : null;
 +    }
 +
 +    /**
 +     * Returns the datum ensemble of an arbitrary engineering CRS.
 +     *
 +     * @param  datum  the CRS from which to get a datum ensemble, or {@code 
null} if none.
 +     * @return the datum ensemble, or {@code null} if none.
 +     */
 +    public static DefaultDatumEnsemble<EngineeringDatum> 
getDatumEnsemble(final EngineeringCRS crs) {
 +        return (crs instanceof DefaultEngineeringCRS) ? 
((DefaultEngineeringCRS) crs).getDatumEnsemble() : null;
 +    }
++
++    /**
++     * Creates a parametric CS. This method requires the <abbr>SIS</abbr> 
factory
++     * since parametric CRS were not available in GeoAPI 3.0.
++     *
++     * @param  properties  the coordinate system name, and optionally other 
properties.
++     * @param  axis        the axis of the parametric coordinate system.
++     * @param  factory     the factory to use for creating the coordinate 
system.
++     * @return a parametric coordinate system using the given axes.
++     * @throws FactoryException if the parametric object creation failed.
++     */
++    public static DefaultParametricCS createParametricCS(final Map<String,?> 
properties, final CoordinateSystemAxis axis,
++            CSFactory factory) throws FactoryException
++    {
++        if (!(factory instanceof GeodeticObjectFactory)) {
++            factory = GeodeticObjectFactory.provider();
++        }
++        return ((GeodeticObjectFactory) 
factory).createParametricCS(properties, axis);
++    }
++
++    /**
++     * Creates a parametric datum. This method requires the <abbr>SIS</abbr> 
factory
++     * since parametric <abbr>CRS</abbr> were not available in GeoAPI 3.0.
++     *
++     * @param  properties  the datum name, and optionally other properties.
++     * @param  factory     the factory to use for creating the datum.
++     * @return a parametric datum using the given name.
++     * @throws FactoryException if the parametric object creation failed.
++     */
++    public static DefaultParametricDatum createParametricDatum(final 
Map<String,?> properties, DatumFactory factory)
++            throws FactoryException
++    {
++        if (!(factory instanceof GeodeticObjectFactory)) {
++            factory = GeodeticObjectFactory.provider();
++        }
++        return ((GeodeticObjectFactory) 
factory).createParametricDatum(properties);
++    }
++
++    /**
++     * Creates a parametric <abbr>CRS</abbr>. This method requires the 
<abbr>SIS</abbr> factory
++     * since parametric <abbr>CRS</abbr> were not available in GeoAPI 3.0.
++     *
++     * @param  properties  the coordinate reference system name, and 
optionally other properties.
++     * @param  datum       the parametric datum.
++     * @param  cs          the parametric coordinate system.
++     * @param  factory     the factory to use for creating the coordinate 
reference system.
++     * @return a parametric coordinate system using the given axes.
++     * @throws FactoryException if the parametric object creation failed.
++     */
++    public static SingleCRS createParametricCRS(final Map<String,?> 
properties, final DefaultParametricDatum datum,
++            final DefaultParametricCS cs, CRSFactory factory) throws 
FactoryException
++    {
++        if (!(factory instanceof GeodeticObjectFactory)) {
++            factory = GeodeticObjectFactory.provider();
++        }
++        try {
++            return ((GeodeticObjectFactory) 
factory).createParametricCRS(properties, datum, cs);
++        } catch (ClassCastException e) {
++            throw new InvalidGeodeticParameterException(e.toString(), e);
++        }
++    }
 +}
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 0248507b48,12a11b590e..b2eec3b12e
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@@ -503,8 -502,8 +504,8 @@@ public enum CommonCRS 
              }
          }
          final Datum datum = single.getDatum();
-         if (datum instanceof GeodeticDatum) {
+         if (datum == null || datum instanceof GeodeticDatum) {
 -            final CommonCRS c = forDatum((GeodeticDatum) datum, 
single.getDatumEnsemble());
 +            final CommonCRS c = forDatum((GeodeticDatum) datum, 
getDatumEnsemble(single));
              if (c != null) return c;
          }
          throw new IllegalArgumentException(Errors.format(
@@@ -881,8 -910,8 +920,8 @@@
       *
       * @since 1.5
       */
 -    public DatumEnsemble<GeodeticDatum> datumEnsemble() {
 +    public DefaultDatumEnsemble<GeodeticDatum> datumEnsemble() {
-         return getDatumEnsemble(geographic());
+         return DatumOrEnsemble.asEnsemble(datum(true)).orElse(null);
      }
  
      /**
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EPSGFactoryFallback.java
index 2a7f97c27c,4ab57382bd..d75d81c095
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EPSGFactoryFallback.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EPSGFactoryFallback.java
@@@ -52,6 -52,6 +52,9 @@@ import org.apache.sis.setup.Installatio
  import org.apache.sis.measure.Latitude;
  import org.apache.sis.measure.Units;
  
++// Specific to the main branch:
++import org.apache.sis.referencing.datum.DefaultDatumEnsemble;
++
  // Specific to the main and geoapi-3.1 branches:
  import org.opengis.referencing.crs.GeocentricCRS;
  
@@@ -218,7 -224,15 +223,15 @@@ final class EPSGFactoryFallback extend
       */
      @Override
      public Datum createDatum(final String code) throws 
NoSuchAuthorityCodeException {
-         return (Datum) predefined(code, DATUM);
+         return (Datum) predefined(code, DATUM | ENSEMBLE);
+     }
+ 
+     /**
+      * Returns a datum ensemble for the given EPSG code.
+      */
+     @Override
 -    public DatumEnsemble<?> createDatumEnsemble(final String code) throws 
NoSuchAuthorityCodeException {
 -        return (DatumEnsemble<?>) predefined(code, ENSEMBLE);
++    public DefaultDatumEnsemble<?> createDatumEnsemble(final String code) 
throws NoSuchAuthorityCodeException {
++        return (DefaultDatumEnsemble<?>) predefined(code, ENSEMBLE);
      }
  
      /**
@@@ -418,6 -435,7 +433,7 @@@
          switch (kind) {
              case CRS:            return CoordinateReferenceSystem.class;
              case DATUM:          return Datum.class;
 -            case ENSEMBLE:       return DatumEnsemble.class;
++            case ENSEMBLE:       return DefaultDatumEnsemble.class;
              case ELLIPSOID:      return Ellipsoid.class;
              case PRIME_MERIDIAN: return PrimeMeridian.class;
              case UNIT:           return Unit.class;
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java
index 19e6daa6b7,c1691e4fe1..fc062eace9
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java
@@@ -76,9 -76,12 +76,10 @@@ import org.apache.sis.measure.Latitude
  import org.apache.sis.measure.Units;
  import static 
org.apache.sis.metadata.privy.ReferencingServices.AUTHALIC_RADIUS;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.referencing.datum.DatumEnsemble;
 -import static org.opengis.referencing.ObjectDomain.DOMAIN_OF_VALIDITY_KEY;
 -
 -// Specific to the geoapi-3.1 branch:
 -import org.opengis.referencing.datum.RealizationMethod;
 +// Specific to the main branch:
 +import org.opengis.referencing.datum.VerticalDatumType;
 +import static org.opengis.referencing.datum.Datum.DOMAIN_OF_VALIDITY_KEY;
++import org.apache.sis.referencing.datum.DefaultDatumEnsemble;
  
  
  /**
@@@ -233,14 -236,17 +234,17 @@@ final class StandardDefinitions 
      }
  
      /**
-      * Creates a geodetic CRS from hard-coded values for the given code.
+      * Creates a geodetic <abbr>CRS</abbr> from hard-coded values for the 
given code.
       *
-      * @param  code   the EPSG code.
-      * @param  datum  the geodetic reference frame.
-      * @param  cs     the coordinate system.
-      * @return the geographic CRS for the given code.
+      * @param  code      the EPSG code.
+      * @param  datum     the geodetic reference frame, or {@code null} if a 
datum ensemble is used instead.
+      * @param  ensemble  the datum ensemble, or {@code null} if none.
+      * @param  cs        the coordinate system.
+      * @return the geographic <abbr>CRS</abbr> for the given code.
       */
-     static GeographicCRS createGeographicCRS(final short code, final 
GeodeticDatum datum, final EllipsoidalCS cs) {
+     static GeographicCRS createGeographicCRS(final short code, final 
GeodeticDatum datum,
 -            final DatumEnsemble<GeodeticDatum> ensemble, final EllipsoidalCS 
cs)
++            final DefaultDatumEnsemble<GeodeticDatum> ensemble, final 
EllipsoidalCS cs)
+     {
          final String name;
          boolean world = false;
          switch (code) {
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java
index ce78a4c244,820ce1cfcc..5243d12f90
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java
@@@ -372,6 -382,81 +372,66 @@@ public final class DatumOrEnsemble exte
          return false;
      }
  
+     /**
+      * If the given object is a pseudo-datum for a geodetic ensemble, returns 
that ensemble.
+      * This method is the converse of {@link #asDatum(GeodeticCRS)} and 
recognizes only the
+      * pseudo-datum created by this class of by {@link DefaultDatumEnsemble} 
static methods.
+      *
+      * @param  datum  the object which may be a pseudo-datum for an ensemble, 
or {@code null}.
+      * @return the given object cast to a datum ensemble if the cast is valid.
+      */
 -    public static Optional<DatumEnsemble<GeodeticDatum>> asEnsemble(final 
GeodeticDatum datum) {
++    public static Optional<DefaultDatumEnsemble<GeodeticDatum>> 
asEnsemble(final GeodeticDatum datum) {
+         if (datum instanceof DefaultDatumEnsemble.Geodetic) {
+             return Optional.of((DefaultDatumEnsemble.Geodetic) datum);
+         }
+         return Optional.empty();
+     }
+ 
+     /**
+      * If the given object is a pseudo-datum for a vertical ensemble, returns 
that ensemble.
+      * This method is the converse of {@link #asDatum(VerticalCRS)} and 
recognizes only the
+      * pseudo-datum created by this class of by {@link DefaultDatumEnsemble} 
static methods.
+      *
+      * @param  datum  the object which may be a pseudo-datum for an ensemble, 
or {@code null}.
+      * @return the given object cast to a datum ensemble if the cast is valid.
+      */
 -    public static Optional<DatumEnsemble<VerticalDatum>> asEnsemble(final 
VerticalDatum datum) {
++    public static Optional<DefaultDatumEnsemble<VerticalDatum>> 
asEnsemble(final VerticalDatum datum) {
+         if (datum instanceof DefaultDatumEnsemble.Vertical) {
+             return Optional.of((DefaultDatumEnsemble.Vertical) datum);
+         }
+         return Optional.empty();
+     }
+ 
+     /**
+      * If the given object is a pseudo-datum for a temporal ensemble, returns 
that ensemble.
+      * This method is the converse of {@link #asDatum(TemporalCRS)} and 
recognizes only the
+      * pseudo-datum created by this class of by {@link DefaultDatumEnsemble} 
static methods.
+      *
+      * @param  datum  the object which may be a pseudo-datum for an ensemble, 
or {@code null}.
+      * @return the given object cast to a datum ensemble if the cast is valid.
+      */
 -    public static Optional<DatumEnsemble<TemporalDatum>> asEnsemble(final 
TemporalDatum datum) {
++    public static Optional<DefaultDatumEnsemble<TemporalDatum>> 
asEnsemble(final TemporalDatum datum) {
+         if (datum instanceof DefaultDatumEnsemble.Time) {
+             return Optional.of((DefaultDatumEnsemble.Time) datum);
+         }
+         return Optional.empty();
+     }
+ 
 -    /**
 -     * If the given object is a pseudo-datum for a parametric ensemble, 
returns that ensemble.
 -     * This method is the converse of {@link #asDatum(ParametricCRS)} and 
recognizes only the
 -     * pseudo-datum created by this class of by {@link DefaultDatumEnsemble} 
static methods.
 -     *
 -     * @param  datum  the object which may be a pseudo-datum for an ensemble, 
or {@code null}.
 -     * @return the given object cast to a datum ensemble if the cast is valid.
 -     */
 -    public static Optional<DatumEnsemble<ParametricDatum>> asEnsemble(final 
ParametricDatum datum) {
 -        if (datum instanceof DefaultDatumEnsemble.Parametric) {
 -            return Optional.of((DefaultDatumEnsemble.Parametric) datum);
 -        }
 -        return Optional.empty();
 -    }
 -
+     /**
+      * If the given object is a pseudo-datum for a engineering ensemble, 
returns that ensemble.
+      * This method is the converse of {@link #asDatum(EngineeringCRS)} and 
recognizes only the
+      * pseudo-datum created by this class of by {@link DefaultDatumEnsemble} 
static methods.
+      *
+      * @param  datum  the object which may be a pseudo-datum for an ensemble, 
or {@code null}.
+      * @return the given object cast to a datum ensemble if the cast is valid.
+      */
 -    public static Optional<DatumEnsemble<EngineeringDatum>> asEnsemble(final 
EngineeringDatum datum) {
++    public static Optional<DefaultDatumEnsemble<EngineeringDatum>> 
asEnsemble(final EngineeringDatum datum) {
+         if (datum instanceof DefaultDatumEnsemble.Engineering) {
+             return Optional.of((DefaultDatumEnsemble.Engineering) datum);
+         }
+         return Optional.empty();
+     }
+ 
      /**
       * Returns whether a legacy definition of a datum may be considered as 
equivalent to the given datum ensemble.
       * This is {@code true} if all reference frames (both the specified datum 
and the ensemble members) have the
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
index 0797fabecc,01e51591b7..c647333610
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
@@@ -612,10 -605,10 +612,10 @@@ public class GeodeticObjectFactory exte
       * @param  datum       geodetic reference frame, or {@code null} if the 
CRS is associated only to a datum ensemble.
       * @param  ensemble    collection of reference frames which for low 
accuracy requirements may be considered to be
       *                     insignificantly different from each other, or 
{@code null} if there is no such ensemble.
-      * @param  cs          the two- or three-dimensional ellipsoidal 
coordinate system for the created CRS.
+      * @param  cs          the two- or three-dimensional ellipsoidal 
coordinate system for the created <abbr>CRS</abbr>.
       * @throws FactoryException if the object creation failed.
       *
 -     * @see DefaultGeographicCRS#DefaultGeographicCRS(Map, GeodeticDatum, 
DatumEnsemble, EllipsoidalCS)
 +     * @see DefaultGeographicCRS#DefaultGeographicCRS(Map, GeodeticDatum, 
DefaultDatumEnsemble, EllipsoidalCS)
       * @see GeodeticAuthorityFactory#createGeographicCRS(String)
       *
       * @since 1.5
@@@ -636,22 -630,23 +636,24 @@@
      }
  
      /**
-      * Creates a geographic <abbr>CRS</abbr> from a reference frame.
-      * This is a shortcut for the {@linkplain #createGeographicCRS(Map, 
GeodeticDatum, DefaultDatumEnsemble, EllipsoidalCS)
-      * more generic method} without datum ensemble.
+      * Creates a geographic <abbr>CRS</abbr> with a datum that may be a datum 
ensemble.
+      * If the given {@code datum} argument is a {@linkplain 
DefaultDatumEnsemble datum ensemble
+      * viewed as a pseudo-datum}, then it is used as the {@code ensemble} 
argument of the above
+      * constructor.
       *
       * @param  properties  name and other properties to give to the new 
object.
-      *                     Available properties are {@linkplain ObjectFactory 
listed there}.
-      * @param  datum       geodetic reference frame to use in created CRS.
-      * @param  cs          the ellipsoidal coordinate system for the created 
CRS.
+      * @param  datum       the geodetic reference frame or datum ensemble 
viewed as a pseudo-datum.
+      * @param  cs          the two- or three-dimensional ellipsoidal 
coordinate system for the created <abbr>CRS</abbr>.
 +     * @return the coordinate reference system for the given properties.
       * @throws FactoryException if the object creation failed.
       */
      @Override
-     public GeographicCRS createGeographicCRS(Map<String, ?> properties, 
GeodeticDatum datum, EllipsoidalCS cs)
+     public GeographicCRS createGeographicCRS(Map<String,?> properties, 
GeodeticDatum datum, EllipsoidalCS cs)
              throws FactoryException
      {
-         return createGeographicCRS(properties, datum, null, cs);
 -        DatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
++        DefaultDatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
+         if (ensemble != null) datum = null;
+         return createGeographicCRS(properties, datum, ensemble, cs);
      }
  
      /**
@@@ -1078,10 -1072,10 +1080,10 @@@
       * @param  datum       vertical reference frame, or {@code null} if the 
CRS is associated only to a datum ensemble.
       * @param  ensemble    collection of reference frames which for low 
accuracy requirements may be considered to be
       *                     insignificantly different from each other, or 
{@code null} if there is no such ensemble.
-      * @param  cs          the vertical coordinate system for the created CRS.
+      * @param  cs          the vertical coordinate system for the created 
<abbr>CRS</abbr>.
       * @throws FactoryException if the object creation failed.
       *
 -     * @see DefaultVerticalCRS#DefaultVerticalCRS(Map, VerticalDatum, 
DatumEnsemble, VerticalCS)
 +     * @see DefaultVerticalCRS#DefaultVerticalCRS(Map, VerticalDatum, 
DefaultDatumEnsemble, VerticalCS)
       * @see GeodeticAuthorityFactory#createVerticalCRS(String)
       *
       * @since 1.5
@@@ -1102,23 -1097,52 +1104,26 @@@
      }
  
      /**
-      * Creates a static vertical datum from a realization method.
-      * The default implementation creates a {@link DefaultVerticalDatum} 
instance.
+      * Creates a vertical <abbr>CRS</abbr> with a datum that may be a datum 
ensemble.
+      * If the given {@code datum} argument is a {@linkplain 
DefaultDatumEnsemble datum ensemble
+      * viewed as a pseudo-datum}, then it is used as the {@code ensemble} 
argument of the above
+      * constructor.
       *
       * @param  properties  name and other properties to give to the new 
object.
-      *                     Available properties are {@linkplain ObjectFactory 
listed there}.
-      * @param  datum       vertical datum to use in created CRS.
-      * @param  cs          the vertical coordinate system for the created CRS.
+      * @param  datum       the vertical reference frame or datum ensemble 
viewed as a pseudo-datum.
+      * @param  cs          the vertical coordinate system for the created 
<abbr>CRS</abbr>.
 +     * @return the coordinate reference system for the given properties.
       * @throws FactoryException if the object creation failed.
       */
      @Override
-     public VerticalCRS createVerticalCRS(Map<String, ?> properties, 
VerticalDatum datum, VerticalCS cs)
+     public VerticalCRS createVerticalCRS(Map<String,?> properties, 
VerticalDatum datum, VerticalCS cs)
              throws FactoryException
      {
-         return createVerticalCRS(properties, datum, null, cs);
 -        DatumEnsemble<VerticalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
++        DefaultDatumEnsemble<VerticalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
+         if (ensemble != null) datum = null;
+         return createVerticalCRS(properties, datum, ensemble, cs);
      }
  
 -    /**
 -     * Creates a static vertical datum from a realization method.
 -     * The default implementation creates a {@link DefaultVerticalDatum} 
instance.
 -     *
 -     * @param  properties  name and other properties to give to the new 
object.
 -     * @param  method      the realization method of the vertical datum, or 
{@code null} if none.
 -     * @throws FactoryException if the object creation failed.
 -     *
 -     * @see DefaultVerticalDatum#DefaultVerticalDatum(Map, RealizationMethod)
 -     * @see GeodeticAuthorityFactory#createVerticalDatum(String)
 -     *
 -     * @since 2.0 (temporary version number until this branch is released)
 -     */
 -    @Override
 -    public VerticalDatum createVerticalDatum(final Map<String,?> properties,
 -                                             final RealizationMethod method)
 -            throws FactoryException
 -    {
 -        final DefaultVerticalDatum datum;
 -        try {
 -            datum = new DefaultVerticalDatum(complete(properties), method);
 -        } catch (IllegalArgumentException exception) {
 -            throw new InvalidGeodeticParameterException(exception);
 -        }
 -        return unique("createVerticalDatum", datum);
 -    }
 -
      /**
       * Creates a vertical datum from an enumerated type value.
       * The default implementation creates a {@link DefaultVerticalDatum} 
instance.
@@@ -1224,10 -1285,10 +1229,10 @@@
       * @param  datum       temporal datum, or {@code null} if the CRS is 
associated only to a datum ensemble.
       * @param  ensemble    collection of datum which for low accuracy 
requirements may be considered to be
       *                     insignificantly different from each other, or 
{@code null} if there is no such ensemble.
-      * @param  cs          the temporal coordinate system for the created CRS.
+      * @param  cs          the temporal coordinate system for the created 
<abbr>CRS</abbr>.
       * @throws FactoryException if the object creation failed.
       *
 -     * @see DefaultTemporalCRS#DefaultTemporalCRS(Map, TemporalDatum, 
DatumEnsemble, TimeCS)
 +     * @see DefaultTemporalCRS#DefaultTemporalCRS(Map, TemporalDatum, 
DefaultDatumEnsemble, TimeCS)
       * @see GeodeticAuthorityFactory#createTemporalCRS(String)
       *
       * @since 1.5
@@@ -1247,22 -1309,23 +1252,24 @@@
      }
  
      /**
-      * Creates a temporal <abbr>CRS</abbr> from a datum.
-      * This is a shortcut for the {@linkplain #createTemporalCRS(Map, 
TemporalDatum, DefaultDatumEnsemble, TimeCS)
-      * more generic method} without datum ensemble.
+      * Creates a temporal <abbr>CRS</abbr> with a datum that may be a datum 
ensemble.
+      * If the given {@code datum} argument is a {@linkplain 
DefaultDatumEnsemble datum ensemble
+      * viewed as a pseudo-datum}, then it is used as the {@code ensemble} 
argument of the above
+      * constructor.
       *
       * @param  properties  name and other properties to give to the new 
object.
-      *         Available properties are {@linkplain ObjectFactory listed 
there}.
-      * @param  datum  temporal datum to use in created CRS.
-      * @param  cs  the temporal coordinate system for the created CRS.
+      * @param  datum       the temporal datum or datum ensemble viewed as a 
pseudo-datum.
+      * @param  cs          the temporal coordinate system for the created 
<abbr>CRS</abbr>.
 +     * @return the coordinate reference system for the given properties.
       * @throws FactoryException if the object creation failed.
       */
      @Override
-     public TemporalCRS createTemporalCRS(Map<String, ?> properties, 
TemporalDatum datum, TimeCS cs)
+     public TemporalCRS createTemporalCRS(Map<String,?> properties, 
TemporalDatum datum, TimeCS cs)
              throws FactoryException
      {
-         return createTemporalCRS(properties, datum, null, cs);
 -        DatumEnsemble<TemporalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
++        DefaultDatumEnsemble<TemporalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
+         if (ensemble != null) datum = null;
+         return createTemporalCRS(properties, datum, ensemble, cs);
      }
  
      /**
@@@ -1349,10 -1407,10 +1356,10 @@@
       * @param  datum       parametric datum, or {@code null} if the CRS is 
associated only to a datum ensemble.
       * @param  ensemble    collection of datum which for low accuracy 
requirements may be considered to be
       *                     insignificantly different from each other, or 
{@code null} if there is no such ensemble.
-      * @param  cs          the parametric coordinate system for the created 
CRS.
+      * @param  cs          the parametric coordinate system for the created 
<abbr>CRS</abbr>.
       * @throws FactoryException if the object creation failed.
       *
 -     * @see DefaultParametricCRS#DefaultParametricCRS(Map, ParametricDatum, 
DatumEnsemble, ParametricCS)
 +     * @see DefaultParametricCRS#DefaultParametricCRS(Map, 
DefaultParametricDatum, DefaultDatumEnsemble, ParametricCS)
       * @see GeodeticAuthorityFactory#createParametricCRS(String)
       *
       * @since 1.5
@@@ -1627,22 -1683,23 +1634,24 @@@
      }
  
      /**
-      * Creates a engineering <abbr>CRS</abbr> from a datum.
-      * This is a shortcut for the {@linkplain #createEngineeringCRS(Map, 
EngineeringDatum, DefaultDatumEnsemble, CoordinateSystem)
-      * more generic method} without datum ensemble.
+      * Creates a engineering <abbr>CRS</abbr> with a datum that may be a 
datum ensemble.
+      * If the given {@code datum} argument is a {@linkplain 
DefaultDatumEnsemble datum ensemble
+      * viewed as a pseudo-datum}, then it is used as the {@code ensemble} 
argument of the above
+      * constructor.
       *
       * @param  properties  name and other properties to give to the new 
object.
-      *                     Available properties are {@linkplain ObjectFactory 
listed there}.
-      * @param  datum       engineering datum to use in created CRS.
-      * @param  cs          the coordinate system for the created CRS.
+      * @param  datum       the engineering datum or datum ensemble viewed as 
a pseudo-datum.
+      * @param  cs          the coordinate system for the created 
<abbr>CRS</abbr>.
 +     * @return the coordinate reference system for the given properties.
       * @throws FactoryException if the object creation failed.
       */
      @Override
-     public EngineeringCRS createEngineeringCRS(Map<String, ?> properties, 
EngineeringDatum datum, CoordinateSystem cs)
+     public EngineeringCRS createEngineeringCRS(Map<String,?> properties, 
EngineeringDatum datum, CoordinateSystem cs)
              throws FactoryException
      {
-         return createEngineeringCRS(properties, datum, null, cs);
 -        DatumEnsemble<EngineeringDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
++        DefaultDatumEnsemble<EngineeringDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datum).orElse(null);
+         if (ensemble != null) datum = null;
+         return createEngineeringCRS(properties, datum, ensemble, cs);
      }
  
      /**
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index 3f8fab53f4,c3b772b488..8bccebf8da
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@@ -1635,7 -1623,7 +1636,7 @@@ search: try (ResultSet result = execute
                          final String datumCode = getString(code, result, 9);
                          final CoordinateSystem cs = 
owner.createCoordinateSystem(csCode);  // Do not inline the `getString(…)` 
calls.
                          final GeodeticDatum datumOrEnsemble = 
owner.createGeodeticDatum(datumCode);
-                         final DefaultDatumEnsemble<GeodeticDatum> ensemble = 
wasDatumEnsemble(datumOrEnsemble, GeodeticDatum.class);
 -                        final DatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
++                        final DefaultDatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
                          final GeodeticDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
                          if (cs instanceof CartesianCS) {
                              final var c = (CartesianCS) cs;
@@@ -1671,11 -1655,9 +1672,11 @@@
                              csCode = replaceDeprecatedCS(csCode);
                          }
                          final EllipsoidalCS cs = 
owner.createEllipsoidalCS(csCode.toString());
-                         final DefaultDatumEnsemble<GeodeticDatum> ensemble = 
wasDatumEnsemble(datumOrEnsemble, GeodeticDatum.class);
 -                        final DatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
++                        final DefaultDatumEnsemble<GeodeticDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
                          final GeodeticDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
 -                        constructor = (factory, metadata) -> 
factory.createGeographicCRS(metadata, datum, ensemble, cs);
 +                        constructor = (factory, metadata) ->
 +                                (ensemble != null) ? 
extended(factory).createGeographicCRS(metadata, datum, ensemble, cs)
 +                                                   : 
factory.createGeographicCRS(metadata, datum, cs);
                          break;
                      }
                      /* 
──────────────────────────────────────────────────────────────────────
@@@ -1763,11 -1745,9 +1764,11 @@@
                          final String datumCode = getString(code, result, 9);
                          final VerticalCS cs = owner.createVerticalCS(csCode); 
  // Do not inline the `getString(…)` calls.
                          final VerticalDatum datumOrEnsemble = 
owner.createVerticalDatum(datumCode);
-                         final DefaultDatumEnsemble<VerticalDatum> ensemble = 
wasDatumEnsemble(datumOrEnsemble, VerticalDatum.class);
 -                        final DatumEnsemble<VerticalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
++                        final DefaultDatumEnsemble<VerticalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
                          final VerticalDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
 -                        constructor = (factory, metadata) -> 
factory.createVerticalCRS(metadata, datum, ensemble, cs);
 +                        constructor = (factory, metadata) ->
 +                                (ensemble != null) ? 
extended(factory).createVerticalCRS(metadata, datum, ensemble, cs)
 +                                                   : 
factory.createVerticalCRS(metadata, datum, cs);
                          break;
                      }
                      /* 
──────────────────────────────────────────────────────────────────────
@@@ -1782,11 -1762,9 +1783,11 @@@
                          final String datumCode = getString(code, result, 9);
                          final TimeCS cs = owner.createTimeCS(csCode);    // 
Do not inline the `getString(…)` calls.
                          final TemporalDatum datumOrEnsemble = 
owner.createTemporalDatum(datumCode);
-                         final DefaultDatumEnsemble<TemporalDatum> ensemble = 
wasDatumEnsemble(datumOrEnsemble, TemporalDatum.class);
 -                        final DatumEnsemble<TemporalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
++                        final DefaultDatumEnsemble<TemporalDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
                          final TemporalDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
 -                        constructor = (factory, metadata) -> 
factory.createTemporalCRS(metadata, datum, ensemble, cs);
 +                        constructor = (factory, metadata) ->
 +                                (ensemble != null) ? 
extended(factory).createTemporalCRS(metadata, datum, ensemble, cs)
 +                                                   : 
factory.createTemporalCRS(metadata, datum, cs);
                          break;
                      }
                      /* 
──────────────────────────────────────────────────────────────────────
@@@ -1797,11 -1775,9 +1798,11 @@@
                          final String datumCode = getString(code, result, 9);
                          final CoordinateSystem cs = 
owner.createCoordinateSystem(csCode);    // Do not inline the `getString(…)` 
calls.
                          final EngineeringDatum datumOrEnsemble = 
owner.createEngineeringDatum(datumCode);
-                         final DefaultDatumEnsemble<EngineeringDatum> ensemble 
= wasDatumEnsemble(datumOrEnsemble, EngineeringDatum.class);
 -                        final DatumEnsemble<EngineeringDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
++                        final DefaultDatumEnsemble<EngineeringDatum> ensemble 
= DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
                          final EngineeringDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
 -                        constructor = (factory, metadata) -> 
factory.createEngineeringCRS(metadata, datum, ensemble, cs);
 +                        constructor = (factory, metadata) ->
 +                                (ensemble != null) ? 
extended(factory).createEngineeringCRS(metadata, datum, ensemble, cs)
 +                                                   : 
factory.createEngineeringCRS(metadata, datum, cs);
                          break;
                      }
                      /* 
──────────────────────────────────────────────────────────────────────
@@@ -1810,11 -1786,11 +1811,11 @@@
                      case "parametric": {
                          final String csCode    = getString(code, result, 8);
                          final String datumCode = getString(code, result, 9);
 -                        final ParametricCS cs = 
owner.createParametricCS(csCode);    // Do not inline the `getString(…)` calls.
 -                        final ParametricDatum datumOrEnsemble = 
owner.createParametricDatum(datumCode);
 -                        final DatumEnsemble<ParametricDatum> ensemble = 
DatumOrEnsemble.asEnsemble(datumOrEnsemble).orElse(null);
 -                        final ParametricDatum datum = (ensemble == null) ? 
datumOrEnsemble : null;
 -                        constructor = (factory, metadata) -> 
factory.createParametricCRS(metadata, datum, ensemble, cs);
 +                        final DefaultParametricCS cs = 
owner.createParametricCS(csCode);    // Do not inline the `getString(…)` calls.
 +                        final DefaultParametricDatum datumOrEnsemble = 
owner.createParametricDatum(datumCode);
-                         final DefaultDatumEnsemble<DefaultParametricDatum> 
ensemble = wasDatumEnsemble(datumOrEnsemble, DefaultParametricDatum.class);
++                        final DefaultDatumEnsemble<DefaultParametricDatum> 
ensemble = null; // TODO: not yet implemented.
 +                        final DefaultParametricDatum datum = (ensemble == 
null) ? datumOrEnsemble : null;
 +                        constructor = (factory, metadata) -> 
extended(factory).createParametricCRS(metadata, datum, ensemble, cs);
                          break;
                      }
                      /* 
──────────────────────────────────────────────────────────────────────
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
index 15366f34aa,8c6fc20090..9c7e99fead
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
@@@ -568,7 -473,7 +494,6 @@@ public final class ServicesForMetadata 
          return new CoordinateFormat(locale, timezone);
      }
  
--
      /**
       * Returns transform between a pair of vertical CRS.
       *
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index f06bb790fb,2fc63352b1..611d3b2e35
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@@ -630,8 -634,11 +630,10 @@@ public class CoordinateOperationFinder 
          if (!(interpolationCS instanceof EllipsoidalCS)) {
              final EllipsoidalCS cs = 
CommonCRS.WGS84.geographic3D().getCoordinateSystem();
              if (!Utilities.equalsIgnoreMetadata(interpolationCS, cs)) {
-                 final GeographicCRS stepCRS = factorySIS.crsFactory
-                         .createGeographicCRS(derivedFrom(sourceCRS), 
DatumOrEnsemble.asDatum(sourceCRS), cs);
+                 final GeographicCRS stepCRS = 
factorySIS.crsFactory.createGeographicCRS(
+                         derivedFrom(sourceCRS),
 -                        sourceCRS.getDatum(),
 -                        sourceCRS.getDatumEnsemble(),
++                        DatumOrEnsemble.asDatum(sourceCRS),
+                         cs);
                  step1 = createOperation(sourceCRS, 
toAuthorityDefinition(GeographicCRS.class, stepCRS));
                  interpolationCRS = step1.getTargetCRS();
                  interpolationCS  = interpolationCRS.getCoordinateSystem();
diff --cc 
endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
index bfcaeb984f,a9c3ebde88..ee0dae34e9
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
@@@ -1000,10 -1007,9 +1000,9 @@@ previous:   for (int i = components.siz
          @Override void createCRS(CRSFactory factory, Map<String,?> 
properties) throws FactoryException {
              properties = 
properties(getFirstAxis().coordinates.getUnitsString());
              if (datum != null) {
 -                referenceSystem = factory.createTemporalCRS(properties, 
datum, datumEnsemble, coordinateSystem);
 +                referenceSystem =  factory.createTemporalCRS(properties, 
datum, coordinateSystem);
              } else {
-                 referenceSystem =  factory.createEngineeringCRS(properties,
-                         CommonCRS.Engineering.TIME.datum(), coordinateSystem);
+                 referenceSystem = factory.createEngineeringCRS(properties, 
CommonCRS.Engineering.TIME.datum(), coordinateSystem);
              }
          }
      }

Reply via email to