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

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

commit 90b66dd6adaf489e8feb543f89bbdb1e1e688a7f
Merge: 56fa4c52ad 7997e9f006
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Oct 4 12:45:44 2025 +0200

    Merge branch 'geoapi-4.0' into geoapi-3.1.
    This merge is all about removal of deprecated methods.

 .../main/org/apache/sis/console/SIS.java           |   3 +-
 .../org/apache/sis/console/TransformCommand.java   |   4 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |  34 --
 .../org/apache/sis/coverage/grid/GridExtent.java   |  34 --
 .../org/apache/sis/coverage/grid/GridGeometry.java |  17 -
 .../apache/sis/coverage/grid/PixelTranslation.java |   3 +-
 .../org/apache/sis/feature/FeatureOperations.java  |   3 +-
 .../main/org/apache/sis/feature/Features.java      |   3 +-
 .../main/org/apache/sis/image/ImageProcessor.java  |  75 +---
 .../main/org/apache/sis/image/package-info.java    |   2 +-
 .../apache/sis/metadata/ModifiableMetadata.java    |  66 +---
 .../metadata/internal/shared/RecordSchemaSIS.java  | 108 ------
 .../apache/sis/metadata/iso/DefaultMetadata.java   |  19 +-
 .../sis/metadata/iso/citation/Citations.java       |   3 +-
 .../metadata/iso/citation/DefaultCitationDate.java |  17 +-
 .../iso/extent/DefaultGeographicDescription.java   |  41 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |  46 +--
 .../apache/sis/metadata/iso/extent/Extents.java    |  22 +-
 .../sis/metadata/iso/extent/package-info.java      |   6 +-
 .../maintenance/DefaultMaintenanceInformation.java |   4 +-
 .../org/apache/sis/metadata/iso/package-info.java  |   2 +-
 .../org/apache/sis/temporal/LenientDateFormat.java |   8 +-
 .../org/apache/sis/util/iso/DefaultNameSpace.java  |   6 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |  26 +-
 .../apache/sis/util/iso/DefaultRecordSchema.java   | 128 +++---
 .../org/apache/sis/util/iso/DefaultRecordType.java |  86 +++--
 .../main/org/apache/sis/util/iso/Names.java        |   3 +-
 .../main/org/apache/sis/util/iso/Types.java        |  63 +--
 .../main/org/apache/sis/util/iso/package-info.java |   9 +-
 .../main/org/apache/sis/xml/Namespaces.java        |   3 +-
 .../main/org/apache/sis/xml/XML.java               |   3 +-
 .../sis/metadata/iso/DefaultMetadataTest.java      | 105 +++--
 .../iso/quality/DefaultQuantitativeResultTest.java |  23 +-
 .../sis/util/iso/DefaultRecordSchemaTest.java      |  21 +-
 .../org/apache/sis/util/iso/DefaultRecordTest.java |  13 +-
 .../apache/sis/util/iso/DefaultRecordTypeTest.java |  10 +-
 .../sis/util/iso/SerializableRecordSchema.java     |  81 ----
 .../test/org/apache/sis/util/iso/TypesTest.java    |  17 +-
 .../apache/sis/profile/france/FrenchProfile.java   |   3 +-
 .../apache/sis/profile/japan/JapaneseProfile.java  |   4 +-
 .../main/module-info.java                          |   1 +
 .../main/org/apache/sis/geometry/Envelopes.java    |  25 +-
 .../apache/sis/geometry/GeneralDirectPosition.java |  12 +-
 .../main/org/apache/sis/geometry/Shapes2D.java     |   3 +-
 .../main/org/apache/sis/geometry/package-info.java |   2 +-
 .../main/org/apache/sis/io/wkt/Formatter.java      |  25 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   4 +-
 .../main/org/apache/sis/io/wkt/package-info.java   |   2 +-
 .../org/apache/sis/parameter/TensorParameters.java |  89 -----
 .../main/org/apache/sis/referencing/CRS.java       |   3 +-
 .../main/org/apache/sis/referencing/CommonCRS.java |  12 +-
 .../apache/sis/referencing/IdentifiedObjects.java  |   3 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |   4 +-
 .../sis/referencing/crs/AbstractSingleCRS.java     |   3 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |  15 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |  24 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  13 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |  13 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |  13 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |  13 +-
 .../org/apache/sis/referencing/crs/SubTypes.java   |   1 +
 .../apache/sis/referencing/crs/package-info.java   |   3 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |   1 +
 .../sis/referencing/cs/CoordinateSystems.java      |   3 +-
 .../org/apache/sis/referencing/cs/SubTypes.java    |   1 +
 .../sis/referencing/datum/AbstractDatum.java       |   7 +-
 .../sis/referencing/datum/DatumOrEnsemble.java     |   3 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |  15 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |   2 +-
 .../sis/referencing/datum/TimeDependentBWP.java    |  13 +-
 .../apache/sis/referencing/datum/package-info.java |   8 +-
 .../factory/GeodeticAuthorityFactory.java          |   2 +-
 .../referencing/factory/GeodeticObjectFactory.java |   9 +-
 .../factory/MultiAuthoritiesFactory.java           |  10 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |   3 +-
 .../factory/sql/InstallationScriptProvider.java    |  22 --
 .../internal/ParameterizedTransformBuilder.java    |  17 +
 .../internal/PositionalAccuracyConstant.java       |   4 +-
 .../{crs => legacy}/DefaultImageCRS.java           | 153 +++++---
 .../{datum => legacy}/DefaultImageDatum.java       |  20 +-
 .../{cs => legacy}/DefaultUserDefinedCS.java       |  46 +--
 .../sis/referencing/legacy/package-info.java       |  64 +++
 .../operation/CoordinateOperationFinder.java       |   4 +-
 .../operation/CoordinateOperationRegistry.java     |   5 +-
 .../referencing/operation/DefaultConversion.java   |   6 +-
 .../DefaultCoordinateOperationFactory.java         |  59 +--
 .../operation/InverseOperationMethod.java          |   4 +-
 .../operation/matrix/AffineTransforms2D.java       |   3 +-
 .../sis/referencing/operation/matrix/Matrices.java |   3 +-
 .../operation/projection/package-info.java         |  15 +-
 .../GeocentricAffineBetweenGeographic.java         |  15 +-
 .../operation/provider/MapProjection.java          |   8 +-
 .../operation/transform/AbstractMathTransform.java |  51 +--
 .../transform/DefaultMathTransformFactory.java     | 429 +--------------------
 .../transform/EllipsoidToCentricTransform.java     |  45 +--
 .../operation/transform/MathTransformProvider.java |  26 +-
 .../operation/transform/MathTransforms.java        |   3 +-
 .../operation/transform/package-info.java          |   2 +-
 .../org/apache/sis/referencing/package-info.java   |   2 +-
 .../xml/bind/referencing/CC_OperationMethod.java   |   4 +-
 .../sis/xml/bind/referencing/CD_ImageDatum.java    |   2 +-
 .../sis/xml/bind/referencing/CS_UserDefinedCS.java |   2 +-
 .../apache/sis/referencing/crs/HardCodedCRS.java   |   3 +-
 .../sis/referencing/datum/HardCodedDatum.java      |   3 +-
 .../{crs => legacy}/DefaultImageCRSTest.java       |   6 +-
 .../operation/CoordinateOperationFinderTest.java   |   5 +-
 .../DefaultCoordinateOperationFactoryTest.java     |  13 -
 .../transform/MathTransformFactoryMock.java        |   2 -
 .../sis/storage/geotiff/base/GeoCodesTest.java     |   4 +-
 .../main/org/apache/sis/storage/gpx/Metadata.java  |   5 +-
 .../main/org/apache/sis/storage/DataStores.java    |   3 +-
 .../main/org/apache/sis/storage/FeatureQuery.java  |  19 +-
 .../main/org/apache/sis/storage/package-info.java  |   2 +-
 .../main/org/apache/sis/io/IO.java                 |   3 +-
 .../main/org/apache/sis/math/DecimalFunctions.java |   3 +-
 .../main/org/apache/sis/math/MathFunctions.java    |   3 +-
 .../main/org/apache/sis/measure/Quantities.java    |   3 +-
 .../main/org/apache/sis/measure/Units.java         |   3 +-
 .../main/org/apache/sis/system/Environment.java    |   3 +-
 .../main/org/apache/sis/system/Loggers.java        |   3 +-
 .../main/org/apache/sis/system/Threads.java        |   3 +-
 .../main/org/apache/sis/util/ArgumentChecks.java   |  51 +--
 .../main/org/apache/sis/util/ArraysExt.java        |   2 +-
 .../main/org/apache/sis/util/CharSequences.java    |   2 +-
 .../main/org/apache/sis/util/Characters.java       |   2 +-
 .../main/org/apache/sis/util/Classes.java          |   2 +-
 .../main/org/apache/sis/util/Exceptions.java       |   2 +-
 .../main/org/apache/sis/util/Locales.java          |   2 +-
 .../main/org/apache/sis/util/Numbers.java          |   2 +-
 .../main/org/apache/sis/util/ObjectConverters.java |   2 +-
 .../main/org/apache/sis/util/Static.java           | 119 ------
 .../main/org/apache/sis/util/StringBuilders.java   |  31 +-
 .../main/org/apache/sis/util/Utilities.java        |   2 +-
 .../org/apache/sis/util/collection/Containers.java |   3 +-
 .../org/apache/sis/util/collection/TreeTables.java |   3 +-
 .../main/org/apache/sis/util/logging/Logging.java  |   3 +-
 .../main/org/apache/sis/util/package-info.java     |   2 +-
 .../test/org/apache/sis/test/TestCase.java         |   1 +
 geoapi/snapshot                                    |   2 +-
 .../main/org/apache/sis/geometries/Geometries.java |   6 +-
 140 files changed, 669 insertions(+), 2157 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
index ab2ebf406d,033046b050..9cc6be132a
--- 
a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
+++ 
b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
@@@ -336,7 -336,10 +336,9 @@@ final class TransformCommand extends Fo
              if (steps.size() > 1) {
                  var factory = DefaultCoordinateOperationFactory.provider();
                  var properties = IdentifiedObjects.getProperties(operation, 
CoordinateOperation.IDENTIFIERS_KEY);
-                 operation = factory.createConcatenatedOperation(properties, 
steps.toArray(CoordinateOperation[]::new));
+                 operation = factory.createConcatenatedOperation(
+                         properties,
 -                        null, null,     // Infer source and target CRS from 
the first and last steps.
+                         steps.toArray(CoordinateOperation[]::new));
              }
          }
          /*
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
index 4650bf6ee5,c3bf681961..36cb145e84
--- 
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
@@@ -1767,8 -1768,7 +1767,8 @@@ class GeodeticObjectParser extends Math
       * @return the {@code "ImageDatum"} element.
       * @throws ParseException if the {@code "ImageDatum"} element cannot be 
parsed.
       */
-     @SuppressWarnings("removal")
 -    private DefaultImageDatum parseImageDatum(final int mode, final Element 
parent) throws ParseException {
++    @SuppressWarnings("deprecation")
 +    private ImageDatum parseImageDatum(final int mode, final Element parent) 
throws ParseException {
          final Element element = parent.pullElement(mode, 
WKTKeywords.ImageDatum, WKTKeywords.IDatum);
          if (element == null) {
              return null;
@@@ -1875,8 -1869,7 +1875,8 @@@
       * @return the {@code "ImageCRS"} element as an {@link ImageCRS} object.
       * @throws ParseException if the {@code "ImageCRS"} element cannot be 
parsed.
       */
-     @SuppressWarnings("removal")
 -    private DefaultImageCRS parseImageCRS(final int mode, final Element 
parent) throws ParseException {
++    @SuppressWarnings("deprecation")
 +    private ImageCRS parseImageCRS(final int mode, final Element parent) 
throws ParseException {
          final Element element = parent.pullElement(mode, 
WKTKeywords.ImageCRS);
          if (element == null) {
              return null;
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/SubTypes.java
index 3e82a452fa,e02e655b75..6c4bf5ccee
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/SubTypes.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/SubTypes.java
@@@ -31,9 -31,6 +31,10 @@@ import org.opengis.referencing.cs.Ellip
  import org.opengis.referencing.cs.SphericalCS;
  import org.apache.sis.referencing.cs.AxesConvention;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.crs.ImageCRS;
++import org.apache.sis.referencing.legacy.DefaultImageCRS;
 +
  
  /**
   * Implementation of {@link AbstractCRS} methods that require knowledge about 
subclasses.
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/SubTypes.java
index 7b3175687f,af854c09a0..45cb1dfb1e
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/SubTypes.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/SubTypes.java
@@@ -30,9 -30,6 +30,10 @@@ import org.opengis.referencing.cs.TimeC
  import org.opengis.referencing.cs.VerticalCS;
  import org.apache.sis.referencing.internal.shared.AxisDirections;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.cs.UserDefinedCS;
++import org.apache.sis.referencing.legacy.DefaultUserDefinedCS;
 +
  
  /**
   * Implementation of {@link AbstractCS} methods that require knowledge about 
subclasses.
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
index 9cda8728df,6bbe6a10ce..c1694057e5
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
@@@ -210,10 -212,8 +211,8 @@@ public class AbstractDatum extends Abst
          }
          anchorEpoch = Containers.property(properties, ANCHOR_EPOCH_KEY, 
Temporal.class);
          if (anchorEpoch == null) {
-             Date date = Containers.property(properties, 
REALIZATION_EPOCH_KEY, Date.class);
-             if (date != null) {
-                 anchorEpoch = date.toInstant();
-             }
+             anchorEpoch = TemporalDate.toTemporal(
 -                    Containers.property(properties, "realizationEpoch", 
Date.class));       // Legacy name.
++                    Containers.property(properties, REALIZATION_EPOCH_KEY, 
Date.class));
          }
          publicationDate = Containers.property(properties, 
PUBLICATION_DATE_KEY, Temporal.class);
          conventionalRS  = Containers.property(properties, 
CONVENTIONAL_RS_KEY, IdentifiedObject.class);
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/package-info.java
index e5b9f5e459,57bb360e1d..0da2635703
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/package-info.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/package-info.java
@@@ -69,11 -68,9 +68,10 @@@
      @XmlJavaTypeAdapter(EX_Extent.class),
      @XmlJavaTypeAdapter(CD_Ellipsoid.class),
      @XmlJavaTypeAdapter(CD_PrimeMeridian.class),
 +    @XmlJavaTypeAdapter(CD_VerticalDatumType.class),
-     @XmlJavaTypeAdapter(CD_PixelInCell.class),
      @XmlJavaTypeAdapter(StringAdapter.class),
      @XmlJavaTypeAdapter(InternationalStringConverter.class),
-     @XmlJavaTypeAdapter(DateAdapter.class),
+     @XmlJavaTypeAdapter(DateAdapter.class)
  })
  package org.apache.sis.referencing.datum;
  
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
index 1502f29759,f59f109dc8..733b76ce23
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
@@@ -810,30 -750,6 +810,30 @@@ public abstract class GeodeticAuthority
          return cast(EngineeringDatum.class, createDatum(code), code);
      }
  
 +    /**
 +     * Creates a datum defining the origin of an image coordinate reference 
system.
 +     * An image datum is used in a local context only.
 +     * For an image datum, the anchor point is usually either the centre of 
the image or the corner of the image.
 +     *
 +     * <h4>Default implementation</h4>
 +     * The default implementation delegates to {@link #createDatum(String)} 
and casts the result.
 +     * If the result cannot be casted, then a {@link 
NoSuchAuthorityCodeException} is thrown.
 +     *
 +     * @param  code  value allocated by authority.
 +     * @return the datum for the given code.
 +     * @throws NoSuchAuthorityCodeException if the specified {@code code} was 
not found.
 +     * @throws FactoryException if the object creation failed for some other 
reason.
 +     *
-      * @see org.apache.sis.referencing.datum.DefaultImageDatum
++     * @see org.apache.sis.referencing.legacy.DefaultImageDatum
 +     *
 +     * @deprecated The {@code ImageDatum} class has been removed in ISO 
19111:2019.
 +     *             It is replaced by {@code EngineeringDatum}.
 +     */
 +    @Deprecated(since = "1.5")
 +    public ImageDatum createImageDatum(final String code) throws 
NoSuchAuthorityCodeException, FactoryException {
 +        return cast(ImageDatum.class, createDatum(code), code);
 +    }
 +
      /**
       * Creates a geometric figure that can be used to describe the 
approximate shape of the earth.
       * In mathematical terms, it is a surface formed by the rotation of an 
ellipse about its minor axis.
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
index 308dda420a,c6210c1a8c..64593b9891
--- 
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
@@@ -64,6 -64,6 +64,11 @@@ import org.apache.sis.util.logging.Logg
  import org.apache.sis.io.wkt.Parser;
  import org.apache.sis.xml.XML;
  
++// Specific the the main and geoapi-3.1 branches:
++import org.apache.sis.referencing.legacy.DefaultImageCRS;
++import org.apache.sis.referencing.legacy.DefaultImageDatum;
++import org.apache.sis.referencing.legacy.DefaultUserDefinedCS;
++
  
  /**
   * Creates Coordinate Reference System (CRS) implementations, with their 
Coordinate System (CS) and Datum components.
@@@ -366,31 -366,6 +371,31 @@@ public class GeodeticObjectFactory exte
          return unique("createGeodeticCRS", crs);
      }
  
 +    /**
 +     * Creates a geocentric coordinate reference system from a Cartesian 
coordinate system.
 +     *
 +     * @param  properties  name and other properties to give to the new 
object.
 +     * @param  datum       the geodetic datum to use in created CRS.
 +     * @param  cs          the three-dimensional Cartesian coordinate system 
for the created CRS.
 +     * @throws FactoryException if the object creation failed.
 +     *
 +     * @deprecated ISO 19111:2019 does not define an explicit class for 
geocentric CRS.
 +     * Use {@link #createGeodeticCRS(Map, GeodeticDatum, CartesianCS)} 
instead.
 +     */
 +    @Override
 +    @Deprecated(since = "2.0")  // Temporary version number until this branch 
is released.
 +    public GeocentricCRS createGeocentricCRS(final Map<String,?> properties,
 +            final GeodeticDatum datum, final CartesianCS cs) throws 
FactoryException
 +    {
 +        final DefaultGeocentricCRS crs;
 +        try {
-             crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
++            crs = new DefaultGeocentricCRS(complete(properties), datum, null, 
cs);
 +        } catch (IllegalArgumentException exception) {
 +            throw new InvalidGeodeticParameterException(exception);
 +        }
 +        return unique("createGeocentricCRS", crs);
 +    }
 +
      /**
       * Creates a three-dimensional Cartesian coordinate system from the given 
set of axis.
       * This coordinate system can be used with geocentric, engineering and 
derived CRS.
@@@ -479,31 -454,6 +484,31 @@@
          return unique("createGeodeticCRS", crs);
      }
  
 +    /**
 +     * Creates a geocentric coordinate reference system from a spherical 
coordinate system.
 +     *
 +     * @param  properties  name and other properties to give to the new 
object.
 +     * @param  datum       the geodetic datum to use in created CRS.
 +     * @param  cs          the three-dimensional Cartesian coordinate system 
for the created CRS.
 +     * @throws FactoryException if the object creation failed.
 +     *
 +     * @deprecated ISO 19111:2019 does not define an explicit class for 
geocentric CRS.
 +     * Use {@link #createGeodeticCRS(Map, GeodeticDatum, SphericalCS)} 
instead.
 +     */
 +    @Override
 +    @Deprecated(since = "2.0")  // Temporary version number until this branch 
is released.
 +    public GeocentricCRS createGeocentricCRS(final Map<String,?> properties,
 +            final GeodeticDatum datum, final SphericalCS cs) throws 
FactoryException
 +    {
 +        final DefaultGeocentricCRS crs;
 +        try {
-             crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
++            crs = new DefaultGeocentricCRS(complete(properties), datum, null, 
cs);
 +        } catch (IllegalArgumentException exception) {
 +            throw new InvalidGeodeticParameterException(exception);
 +        }
 +        return unique("createGeocentricCRS", crs);
 +    }
 +
      /**
       * Creates a spherical coordinate system from the given set of axis.
       * This coordinate system can be used with geocentric, engineering and 
derived CRS.
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
index 7bc525f03f,b6dd73c42d..2fb3afd587
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
@@@ -1665,11 -1601,14 +1665,13 @@@ public class MultiAuthoritiesFactory ex
                       * yet support swapping roles of source and target CRS if 
an implied-reverse coordinate
                       * operation is included.
                       */
-                     final CoordinateOperation[] ops = (CoordinateOperation[]) 
components;
-                     String name = 
IdentifiedObjects.getIdentifierOrName(ops[0]) + " ⟶ "
-                                 + 
IdentifiedObjects.getIdentifierOrName(ops[ops.length - 1]);
+                     final CoordinateOperation[] steps = 
(CoordinateOperation[]) components;
+                     String name = 
IdentifiedObjects.getIdentifierOrName(steps[0]) + " ⟶ "
+                                 + 
IdentifiedObjects.getIdentifierOrName(steps[steps.length - 1]);
                      combined = DefaultCoordinateOperationFactory.provider()
-                             
.createConcatenatedOperation(Map.of(CoordinateOperation.NAME_KEY, name), ops);
+                             .createConcatenatedOperation(
+                                     Map.of(CoordinateOperation.NAME_KEY, 
name),
 -                                    null, null,     // Infer source and 
target CRS from the first and last steps.
+                                     steps);
                  }
                  break;
              }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java
index df5b3187c0,0b2aee0320..4034b5a263
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java
@@@ -22,16 -24,18 +24,22 @@@ import jakarta.xml.bind.annotation.XmlE
  import jakarta.xml.bind.annotation.XmlRootElement;
  import org.opengis.referencing.cs.AffineCS;
  import org.opengis.referencing.cs.CartesianCS;
+ import org.opengis.referencing.crs.SingleCRS;
+ import org.apache.sis.referencing.CommonCRS;
  import org.apache.sis.referencing.AbstractReferenceSystem;
  import org.apache.sis.referencing.internal.shared.WKTKeywords;
- import org.apache.sis.referencing.cs.AxesConvention;
- import org.apache.sis.referencing.cs.AbstractCS;
+ import org.apache.sis.referencing.internal.shared.NilReferencingObject;
+ import org.apache.sis.referencing.crs.AbstractCRS;
+ import org.apache.sis.metadata.internal.shared.ImplementationHelper;
  import org.apache.sis.io.wkt.Formatter;
+ import org.apache.sis.util.ComparisonMode;
+ import org.apache.sis.util.Utilities;
+ import org.apache.sis.util.collection.BackingStoreException;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.crs.ImageCRS;
 +import org.opengis.referencing.datum.ImageDatum;
 +
  
  /**
   * A 2-dimensional engineering coordinate reference system applied to 
locations in images.
@@@ -68,12 -62,22 +66,24 @@@
      "datum"
  })
  @XmlRootElement(name = "ImageCRS")
- public final class DefaultImageCRS extends AbstractSingleCRS<ImageDatum> 
implements ImageCRS {
 -public final class DefaultImageCRS extends AbstractCRS implements SingleCRS {
++@SuppressWarnings("deprecation")
++public final class DefaultImageCRS extends AbstractCRS implements ImageCRS {
      /**
       * Serial number for inter-operability with different versions.
       */
      private static final long serialVersionUID = 7222610270977351462L;
  
+     /**
+      * The datum, or {@code null} if the <abbr>CRS</abbr> is associated only 
to a datum ensemble.
+      *
+      * <p><b>Consider this field as final!</b>
+      * This field is non-final only for construction convenience and for 
unmarshalling.</p>
+      *
+      * @see #getDatum()
+      */
 -    private DefaultImageDatum datum;
++    @SuppressWarnings("serial")
++    private ImageDatum datum;
+ 
      /**
       * Creates a coordinate reference system from the given properties, datum 
and coordinate system.
       * The properties given in argument follow the same rules as for the
@@@ -112,68 -116,23 +122,53 @@@
       * @param  properties  the properties to be given to the coordinate 
reference system.
       * @param  datum       the datum.
       * @param  cs          the coordinate system.
-      *
-      * @see 
org.apache.sis.referencing.factory.GeodeticObjectFactory#createImageCRS(Map, 
ImageDatum, AffineCS)
       */
      public DefaultImageCRS(final Map<String,?> properties,
 -                           final DefaultImageDatum datum,
 -                           final AffineCS cs)
 +                           final ImageDatum    datum,
 +                           final AffineCS      cs)
      {
-         super(properties, ImageDatum.class, datum, null, cs);
-     }
- 
-     /**
-      * Creates a new CRS derived from the specified one, but with different 
axis order or unit.
-      * This is for implementing the {@link #createSameType(AbstractCS)} 
method only.
-      */
-     private DefaultImageCRS(final DefaultImageCRS original, final AbstractCS 
cs) {
-         super(original, null, cs);
+         super(properties, cs);
+         this.datum = Objects.requireNonNull(datum);
      }
  
 +    /**
 +     * Constructs a new coordinate reference system with the same values as 
the specified one.
 +     * This copy constructor provides a way to convert an arbitrary 
implementation into a SIS one
 +     * or a user-defined one (as a subclass), usually in order to leverage 
some implementation-specific API.
 +     *
 +     * <p>This constructor performs a shallow copy, i.e. the properties are 
not cloned.</p>
 +     *
 +     * @param  crs  the coordinate reference system to copy.
 +     *
 +     * @see #castOrCopy(ImageCRS)
 +     */
 +    protected DefaultImageCRS(final ImageCRS crs) {
 +        super(crs);
 +    }
 +
 +    /**
 +     * Returns a SIS coordinate reference system implementation with the same 
values as the given
 +     * arbitrary implementation. If the given object is {@code null}, then 
this method returns {@code null}.
 +     * Otherwise if the given object is already a SIS implementation, then 
the given object is returned unchanged.
 +     * Otherwise a new SIS implementation is created and initialized to the 
attribute values of the given object.
 +     *
 +     * @param  object  the object to get as a SIS implementation, or {@code 
null} if none.
 +     * @return a SIS implementation containing the values of the given object 
(may be the
 +     *         given object itself), or {@code null} if the argument was null.
 +     */
 +    public static DefaultImageCRS castOrCopy(final ImageCRS object) {
 +        return (object == null) || (object instanceof DefaultImageCRS)
 +                ? (DefaultImageCRS) object : new DefaultImageCRS(object);
 +    }
 +
      /**
       * Returns the GeoAPI interface implemented by this class.
-      * The SIS implementation returns {@code ImageCRS.class}.
-      *
-      * <h4>Note for implementers</h4>
-      * Subclasses usually do not need to override this method since GeoAPI 
does not define {@code ImageCRS}
-      * sub-interface. Overriding possibility is left mostly for implementers 
who wish to extend GeoAPI with
-      * their own set of interfaces.
       *
-      * @return {@code ImageCRS.class} or a user-defined sub-interface.
+      * @return the coordinate reference system interface implemented by this 
class.
       */
      @Override
 -    public Class<? extends SingleCRS> getInterface() {
 -        return SingleCRS.class;
 +    public Class<? extends ImageCRS> getInterface() {
 +        return ImageCRS.class;
      }
  
      /**
@@@ -181,10 -140,9 +176,10 @@@
       *
       * @return the datum.
       */
 +    @Override
      @XmlElement(name = "imageDatum", required = true)
 -    public DefaultImageDatum getDatum() {
 +    public ImageDatum getDatum() {
-         return super.getDatum();
+         return datum;
      }
  
      /**
@@@ -257,7 -222,8 +259,9 @@@
       * <strong>This is not a valid object.</strong> This constructor is 
strictly
       * reserved to JAXB, which will assign values to the fields using 
reflection.
       */
++    @SuppressWarnings("unused")
      private DefaultImageCRS() {
+         super(Map.of(NAME_KEY, NilReferencingObject.UNNAMED), 
CommonCRS.Engineering.DISPLAY.crs().getCoordinateSystem());
          /*
           * The datum and the coordinate system are mandatory for SIS working. 
We do not verify their presence
           * here because the verification would have to be done in an 
'afterMarshal(…)' method and throwing an
@@@ -271,8 -237,12 +275,13 @@@
       *
       * @see #getDatum()
       */
 -    private void setDatum(final DefaultImageDatum value) {
++    @SuppressWarnings("unused")
 +    private void setDatum(final ImageDatum value) {
-         setDatum("imageDatum", value);
+         if (datum == null) {
+             datum = value;
+         } else {
+             ImplementationHelper.propertyAlreadySet(getClass(), "setDatum", 
"imageDatum");
+         }
      }
  
      /**
@@@ -298,14 -268,34 +307,38 @@@
       *
       * @see <a href="http://issues.apache.org/jira/browse/SIS-166";>SIS-166</a>
       */
-     @XmlElement(name = "cartesianCS") private CartesianCS getCartesianCS() 
{return getCoordinateSystem(CartesianCS.class);}
-     @XmlElement(name = "affineCS")    private AffineCS    getAffineCS()    
{return getCoordinateSystem(AffineCS.class);}
++    @SuppressWarnings("unused")
+     @XmlElement(name = "cartesianCS")
+     private CartesianCS getCartesianCS() {
+         final AffineCS cs = getCoordinateSystem();
+         return (cs instanceof CartesianCS) ? (CartesianCS) cs : null;
+     }
+ 
++    @SuppressWarnings("unused")
+     @XmlElement(name = "affineCS")
+     private AffineCS getAffineCS() {
+         final AffineCS cs = getCoordinateSystem();
+         return (cs instanceof CartesianCS) ? null : cs;
+     }
  
      /**
       * Used by JAXB only (invoked by reflection).
       *
       * @see #getCartesianCS()
       */
-     private void setCartesianCS(final CartesianCS cs) 
{setCoordinateSystem("cartesianCS", cs);}
-     private void setAffineCS   (final AffineCS    cs) 
{setCoordinateSystem("affineCS",    cs);}
++    @SuppressWarnings("unused")
+     private void setCartesianCS(final CartesianCS cs) {
+         setAffineCS(cs);
+     }
+ 
++    @SuppressWarnings("unused")
+     private void setAffineCS(final AffineCS cs) {
+         try {
+             Field coordinateSystem = 
AbstractCRS.class.getDeclaredField("coordinateSystem");
+             coordinateSystem.setAccessible(true);
+             coordinateSystem.set(this, cs);
+         } catch (ReflectiveOperationException e) {
+             throw new BackingStoreException(e);
+         }
+     }
  }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java
index b1f7d1e645,8b58c01e80..9d706c2f6b
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java
@@@ -21,17 -21,18 +21,19 @@@ import java.util.Objects
  import jakarta.xml.bind.annotation.XmlType;
  import jakarta.xml.bind.annotation.XmlElement;
  import jakarta.xml.bind.annotation.XmlRootElement;
 -import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 -import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
  import org.opengis.util.GenericName;
  import org.opengis.util.InternationalString;
+ import org.apache.sis.referencing.datum.AbstractDatum;
  import org.apache.sis.referencing.internal.shared.WKTKeywords;
+ import org.apache.sis.referencing.internal.shared.NilReferencingObject;
  import org.apache.sis.metadata.internal.shared.ImplementationHelper;
  import org.apache.sis.io.wkt.Formatter;
 -import org.apache.sis.io.wkt.ElementKind;
  import org.apache.sis.util.ComparisonMode;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.datum.PixelInCell;
 +import org.opengis.referencing.datum.ImageDatum;
 +
  // Specific to the geoapi-3.1 and geoapi-4.0 branches:
  import org.opengis.metadata.Identifier;
  
@@@ -46,21 -47,13 +48,14 @@@
   * given to the constructor are also immutable. Unless otherwise noted in the 
javadoc, this condition holds if
   * all components were created using only SIS factories and static constants.
   *
-  * @deprecated The {@code ImageDatum} class has been removed in ISO 
19111:2019.
-  *             It is replaced by {@code EngineeringDatum}.
-  *
   * @author  Martin Desruisseaux (IRD, Geomatys)
-  * @version 1.5
-  *
-  * @see org.apache.sis.referencing.crs.DefaultImageCRS
-  * @see 
org.apache.sis.referencing.factory.GeodeticAuthorityFactory#createImageDatum(String)
   *
-  * @since 0.4
+  * @see DefaultImageCRS
   */
- @Deprecated(since="1.5", forRemoval=true)   // Actually to be moved to an 
internal package for GML and WKT purposes.
++@SuppressWarnings("deprecation")
  @XmlType(name = "ImageDatumType")
  @XmlRootElement(name = "ImageDatum")
 -public final class DefaultImageDatum extends AbstractDatum {
 +public final class DefaultImageDatum extends AbstractDatum implements 
ImageDatum {
      /**
       * Serial number for inter-operability with different versions.
       */
@@@ -121,10 -114,8 +116,8 @@@
       *
       * @param  properties   the properties to be given to the identified 
object.
       * @param  pixelInCell  the way the image grid is associated with the 
image data attributes.
-      *
-      * @see 
org.apache.sis.referencing.factory.GeodeticObjectFactory#createImageDatum(Map, 
PixelInCell)
       */
 -    public DefaultImageDatum(final Map<String,?> properties, final String 
pixelInCell) {
 +    public DefaultImageDatum(final Map<String,?> properties, final 
PixelInCell pixelInCell) {
          super(properties);
          this.pixelInCell = Objects.requireNonNull(pixelInCell);
      }
@@@ -275,7 -210,8 +268,9 @@@
       * <strong>This is not a valid object.</strong> This constructor is 
strictly
       * reserved to JAXB, which will assign values to the fields using 
reflection.
       */
++    @SuppressWarnings("unused")
      private DefaultImageDatum() {
+         super(Map.of(NAME_KEY, NilReferencingObject.UNNAMED));
      }
  
      /**
@@@ -283,7 -219,7 +278,8 @@@
       *
       * @see #getPixelInCell()
       */
 -    private void setPixelInCell(final String value) {
++    @SuppressWarnings("unused")
 +    private void setPixelInCell(final PixelInCell value) {
          if (pixelInCell == null) {
              pixelInCell = value;
          } else {
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java
index 525b514ee2,5dfab47009..b12b1f3532
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java
@@@ -19,11 -19,10 +19,13 @@@ package org.apache.sis.referencing.lega
  import java.util.Map;
  import jakarta.xml.bind.annotation.XmlType;
  import jakarta.xml.bind.annotation.XmlRootElement;
+ import org.apache.sis.referencing.cs.AbstractCS;
+ import org.apache.sis.referencing.internal.shared.NilReferencingObject;
  import org.opengis.referencing.cs.CoordinateSystemAxis;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.cs.UserDefinedCS;
 +
  
  /**
   * A 2- or 3-dimensional coordinate system for any combination of coordinate 
axes not covered by other CS types.
@@@ -45,15 -44,10 +47,10 @@@
   * constants.
   *
   * @author  Martin Desruisseaux (IRD, Geomatys)
-  * @version 1.5
-  * @since   0.4
-  *
-  * @deprecated The {@code UserDefinedCS} class has been removed from ISO 
19111:2019.
   */
- @Deprecated(since="1.5", forRemoval=true)   // Actually to be moved to an 
internal package for GML and WKT purposes.
  @XmlType(name = "UserDefinedCSType")
  @XmlRootElement(name = "UserDefinedCS")
 -public final class DefaultUserDefinedCS extends AbstractCS {
 +public final class DefaultUserDefinedCS extends AbstractCS implements 
UserDefinedCS {
      /**
       * Serial number for inter-operability with different versions.
       */
@@@ -123,84 -113,7 +116,52 @@@
          super(properties, axis0, axis1, axis2);
      }
  
-     /**
-      * Creates a new CS derived from the specified one, but with different 
axis order or unit.
-      *
-      * @see #createForAxes(String, CoordinateSystemAxis[])
-      */
-     private DefaultUserDefinedCS(DefaultUserDefinedCS original, String name, 
CoordinateSystemAxis[] axes) {
-         super(original, name, axes);
-     }
- 
 +    /**
 +     * Creates a new coordinate system with the same values as the specified 
one.
 +     * This copy constructor provides a way to convert an arbitrary 
implementation into a SIS one
 +     * or a user-defined one (as a subclass), usually in order to leverage 
some implementation-specific API.
 +     *
 +     * <p>This constructor performs a shallow copy, i.e. the properties are 
not cloned.</p>
 +     *
 +     * @param  original  the coordinate system to copy.
 +     *
 +     * @see #castOrCopy(UserDefinedCS)
 +     */
 +    protected DefaultUserDefinedCS(final UserDefinedCS original) {
 +        super(original);
 +    }
 +
 +    /**
 +     * Returns a SIS coordinate system implementation with the same values as 
the given arbitrary implementation.
 +     * If the given object is {@code null}, then this method returns {@code 
null}.
 +     * Otherwise if the given object is already a SIS implementation, then 
the given object is returned unchanged.
 +     * Otherwise a new SIS implementation is created and initialized to the 
attribute values of the given object.
 +     *
 +     * @param  object  the object to get as a SIS implementation, or {@code 
null} if none.
 +     * @return a SIS implementation containing the values of the given object 
(may be the
 +     *         given object itself), or {@code null} if the argument was null.
 +     */
 +    public static DefaultUserDefinedCS castOrCopy(final UserDefinedCS object) 
{
 +        return (object == null) || (object instanceof DefaultUserDefinedCS)
 +                ? (DefaultUserDefinedCS) object : new 
DefaultUserDefinedCS(object);
 +    }
 +
 +    /**
 +     * Returns the GeoAPI interface implemented by this class.
 +     * The SIS implementation returns {@code UserDefinedCS.class}.
 +     *
 +     * <h4>Note for implementers</h4>
 +     * Subclasses usually do not need to override this method since GeoAPI 
does not define {@code UserDefinedCS}
 +     * sub-interface. Overriding possibility is left mostly for implementers 
who wish to extend GeoAPI with their
 +     * own set of interfaces.
 +     *
 +     * @return {@code UserDefinedCS.class} or a user-defined sub-interface.
 +     */
 +    @Override
 +    public Class<? extends UserDefinedCS> getInterface() {
 +        return UserDefinedCS.class;
 +    }
  
-     /**
-      * {@inheritDoc}
-      *
-      * @return {@inheritDoc}
-      */
-     @Override
-     public DefaultUserDefinedCS forConvention(final AxesConvention 
convention) {
-         return (DefaultUserDefinedCS) super.forConvention(convention);
-     }
- 
-     /**
-      * Returns a coordinate system with different axes.
-      */
-     @Override
-     final AbstractCS createForAxes(final String name, final 
CoordinateSystemAxis[] axes) {
-         switch (axes.length) {
-             case 2: // Fall through
-             case 3: return new DefaultUserDefinedCS(this, name, axes);
-             default: throw unexpectedDimension(axes, 2, 3);
-         }
-     }
- 
- 
  
  
      /*
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/package-info.java
index 0000000000,254a1087b2..0eb36f4c4b
mode 000000,100644..100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/package-info.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/package-info.java
@@@ -1,0 -1,63 +1,64 @@@
+ /*
+  * 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.
+  */
+ 
+ /**
+  * Referencing objects that existed in legacy international standards but 
have been removed in more recent editions.
+  * Those objects are kept for compatibility with, for example, Geographic 
Markup Language (<abbr>GML</abbr>) but are
+  * not anymore in public <abbr>API</abbr>.
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @author  Cédric Briançon (Geomatys)
+  */
+ @XmlSchema(location = 
"http://schemas.opengis.net/gml/3.2.1/coordinateReferenceSystems.xsd";,
+            elementFormDefault = XmlNsForm.QUALIFIED, namespace = 
Namespaces.GML, xmlns =
+ {
+     @XmlNs(prefix = "gml", namespaceURI = Namespaces.GML),
+     @XmlNs(prefix = "gmd", namespaceURI = LegacyNamespaces.GMD),
+     @XmlNs(prefix = "gco", namespaceURI = Namespaces.GCO),
+     @XmlNs(prefix = "xsi", namespaceURI = Namespaces.XSI)
+ })
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlJavaTypeAdapters({
+     /*
+      * Do NOT declare the following adapters in this package-info:
+      *
+      *   - CS_CoordinateSystem
+      *   - SC_SingleCRS
+      *   - SC_CRS
+      *
+      * Because the above types are the base type of many other types,
+      * adding the above adapters is a cause of confusion for JAXB.
+      *
+      * Note: be careful with CS_AffineCS and CS_CartesianCS relationship.
+      */
+     @XmlJavaTypeAdapter(CD_ImageDatum.class),
++    @XmlJavaTypeAdapter(CD_PixelInCell.class),
+     @XmlJavaTypeAdapter(CS_CartesianCS.class),      // Must be before 
CS_AffineCS.
+     @XmlJavaTypeAdapter(CS_AffineCS.class)
+ })
+ package org.apache.sis.referencing.legacy;
+ 
+ import jakarta.xml.bind.annotation.XmlNs;
+ import jakarta.xml.bind.annotation.XmlNsForm;
+ import jakarta.xml.bind.annotation.XmlSchema;
+ import jakarta.xml.bind.annotation.XmlAccessType;
+ import jakarta.xml.bind.annotation.XmlAccessorType;
+ import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+ import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
+ import org.apache.sis.xml.Namespaces;
+ import org.apache.sis.xml.bind.referencing.*;
+ import org.apache.sis.xml.internal.shared.LegacyNamespaces;
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index 23c530fa78,58a2f1df00..65c37a4e28
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@@ -1097,8 -1087,10 +1097,9 @@@ class CoordinateOperationRegistry 
          switch (operations.size()) {
              case 0:  return null;
              case 1:  return operations.get(0);
-             default: return 
factory.createConcatenatedOperation(derivedFrom(operation),
-                                         
operations.toArray(CoordinateOperation[]::new));
+             default: return factory.createConcatenatedOperation(
+                     derivedFrom(operation),
 -                    null, null,     // Take source and target CRS from the 
first and last steps.
+                     operations.toArray(CoordinateOperation[]::new));
          }
      }
  
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
index 54abf78062,65397554b0..0cf9b63dbe
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
@@@ -24,14 -24,8 +24,10 @@@ import java.util.Objects
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.ConcurrentMap;
  import java.util.concurrent.atomic.AtomicReference;
- import java.util.logging.Level;
- import java.io.Serializable;
  import java.lang.reflect.Constructor;
 +import org.opengis.parameter.ParameterValueGroup;
  import org.opengis.parameter.ParameterNotFoundException;
- import org.opengis.referencing.crs.GeodeticCRS;
 +import org.opengis.referencing.cs.CoordinateSystem;
- import org.opengis.referencing.cs.EllipsoidalCS;
  import org.opengis.referencing.datum.Ellipsoid;
  import org.opengis.referencing.operation.Matrix;
  import org.opengis.referencing.operation.MathTransform;
@@@ -498,531 -477,6 +491,111 @@@ public class DefaultMathTransformFactor
          return new ParameterizedTransformBuilder(this, 
getOperationMethod(method));
      }
  
 +    /**
 +     * Returns the default parameter values for a math transform using the 
given operation method.
 +     * The {@code method} argument is the name of any {@code OperationMethod} 
instance returned by
 +     * <code>{@link #getAvailableMethods(Class) 
getAvailableMethods}({@linkplain SingleOperation}.class)</code>.
 +     * Valid names are <a 
href="https://sis.apache.org/tables/CoordinateOperationMethods.html";>listed 
here</a>.
 +     *
 +     * <p>This function creates new parameter instances at every call.
 +     * Parameters are intended to be modified by the user before to be given 
to the
 +     * {@link #createParameterizedTransform createParameterizedTransform(…)} 
method.</p>
 +     *
 +     * @param  method  the case insensitive name of the coordinate operation 
method to search for.
 +     * @return a new group of parameter values for the {@code 
OperationMethod} identified by the given name.
 +     * @throws NoSuchIdentifierException if there is no method registered for 
the given name or identifier.
 +     *
 +     * @see #getAvailableMethods(Class)
 +     * @see #createParameterizedTransform(ParameterValueGroup)
 +     * @see AbstractMathTransform#getParameterValues()
 +     *
 +     * @deprecated This {@linkplain #createParameterizedTransform way to 
create parameterized transform} is ambiguous.
 +     * Use {@link #builder(String)} instead.
 +     */
 +    @Override
 +    @Deprecated(since="1.5")
 +    public ParameterValueGroup getDefaultParameters(final String method) 
throws NoSuchIdentifierException {
 +        return getOperationMethod(method).getParameters().createValue();
 +    }
 +
-     /**
-      * Source and target coordinate systems for which a new parameterized 
transform is going to be used.
-      *
-      * @author  Martin Desruisseaux (Geomatys)
-      * @version 1.5
-      * @since   0.7
-      *
-      * @deprecated Replaced by {@link #builder(String)}.
-      */
-     @SuppressWarnings("serial")
-     @Deprecated(since="1.5", forRemoval=true)
-     public static class Context implements MathTransformProvider.Context, 
Serializable {
-         /**
-          * The factory to use if the provider needs to create other math 
transforms as operation steps.
-          *
-          * @see #getFactory()
-          */
-         private transient DefaultMathTransformFactory factory;
- 
-         /**
-          * Coordinate system of the source or target points.
-          */
-         private CoordinateSystem sourceCS, targetCS;
- 
-         /**
-          * The ellipsoid of the source or target ellipsoidal coordinate 
system, or {@code null} if it does not apply.
-          */
-         private Ellipsoid sourceEllipsoid, targetEllipsoid;
- 
-         /**
-          * The builder, created when first needed.
-          */
-         private ParameterizedTransformBuilder builder;
- 
-         /**
-          * The parameters actually used.
-          */
-         private ParameterValueGroup parameters;
- 
-         /**
-          * Creates a new context with all properties initialized to {@code 
null}.
-          */
-         public Context() {
-         }
- 
-         /**
-          * Sets the source coordinate system to the given value.
-          * The source ellipsoid is unconditionally set to {@code null}.
-          *
-          * @param  cs  the coordinate system to set as the source (can be 
{@code null}).
-          * @deprecated Replaced by {@link 
MathTransform.Builder#setSourceAxes(CoordinateSystem, Ellipsoid)}.
-          */
-         @Deprecated(since="1.5", forRemoval=true)
-         public void setSource(final CoordinateSystem cs) {
-             sourceCS = cs;
-             sourceEllipsoid = null;
-             builder = null;
-         }
- 
-         /**
-          * Sets the source coordinate system and related ellipsoid to the 
components of given CRS.
-          * The {@link Ellipsoid}, fetched from the geodetic reference frame, 
is often used together with an {@link EllipsoidalCS},
-          * but not necessarily. The geodetic CRS may also be associated with 
a spherical or Cartesian coordinate system,
-          * and the ellipsoid information may still be needed even with those 
non-ellipsoidal coordinate systems.
-          *
-          * <p><strong>This method is not for datum shifts.</strong>
-          * All datum information other than the ellipsoid are ignored.</p>
-          *
-          * @param  crs  the coordinate system and ellipsoid to set as the 
source, or {@code null}.
-          *
-          * @since 1.3
-          * @deprecated Replaced by {@link 
MathTransform.Builder#setSourceAxes(CoordinateSystem, Ellipsoid)}.
-          */
-         @Deprecated(since="1.5", forRemoval=true)
-         public void setSource(final GeodeticCRS crs) {
-             if (crs != null) {
-                 sourceCS = crs.getCoordinateSystem();
-                 sourceEllipsoid = 
DatumOrEnsemble.getEllipsoid(crs).orElse(null);
-             } else {
-                 sourceCS = null;
-                 sourceEllipsoid = null;
-             }
-             builder = null;
-         }
- 
-         /**
-          * Sets the target coordinate system to the given value.
-          * The target ellipsoid is unconditionally set to {@code null}.
-          *
-          * @param  cs  the coordinate system to set as the target (can be 
{@code null}).
-          * @deprecated Replaced by {@link 
MathTransform.Builder#setTargetAxes(CoordinateSystem, Ellipsoid)}.
-          */
-         @Deprecated(since="1.5", forRemoval=true)
-         public void setTarget(final CoordinateSystem cs) {
-             targetCS = cs;
-             targetEllipsoid = null;
-             builder = null;
-         }
- 
-         /**
-          * Sets the target coordinate system and related ellipsoid to the 
components of given CRS.
-          * The {@link Ellipsoid}, fetched from the geodetic reference frame, 
is often used together with an {@link EllipsoidalCS},
-          * but not necessarily. The geodetic CRS may also be associated with 
a spherical or Cartesian coordinate system,
-          * and the ellipsoid information may still be needed even with those 
non-ellipsoidal coordinate systems.
-          *
-          * <p><strong>This method is not for datum shifts.</strong>
-          * All datum information other than the ellipsoid are ignored.</p>
-          *
-          * @param  crs  the coordinate system and ellipsoid to set as the 
target, or {@code null}.
-          *
-          * @since 1.3
-          * @deprecated Replaced by {@link 
MathTransform.Builder#setTargetAxes(CoordinateSystem, Ellipsoid)}.
-          */
-         @Deprecated(since="1.5", forRemoval=true)
-         public void setTarget(final GeodeticCRS crs) {
-             if (crs != null) {
-                 targetCS = crs.getCoordinateSystem();
-                 targetEllipsoid = 
DatumOrEnsemble.getEllipsoid(crs).orElse(null);
-             } else {
-                 targetCS = null;
-                 targetEllipsoid = null;
-             }
-             builder = null;
-         }
- 
-         /**
-          * Returns the source coordinate system, or {@code null} if 
unspecified.
-          *
-          * @return the source coordinate system, or {@code null}.
-          */
-         public CoordinateSystem getSourceCS() {
-             return sourceCS;
-         }
- 
-         /**
-          * Returns the ellipsoid used together with the source coordinate 
system, or {@code null} if none.
-          *
-          * @return the ellipsoid used together with the source coordinate 
system, or {@code null} if none.
-          */
-         public Ellipsoid getSourceEllipsoid() {
-             return sourceEllipsoid;
-         }
- 
-         /**
-          * Returns the target coordinate system, or {@code null} if 
unspecified.
-          *
-          * @return the target coordinate system, or {@code null}.
-          */
-         public CoordinateSystem getTargetCS() {
-             return targetCS;
-         }
- 
-         /**
-          * Returns the ellipsoid used together with the target coordinate 
system, or {@code null} if none.
-          *
-          * @return the ellipsoid used together with the target coordinate 
system, or {@code null} if none.
-          */
-         public Ellipsoid getTargetEllipsoid() {
-             return targetEllipsoid;
-         }
- 
-         /**
-          * Returns the builder to which to delegate the {@code MathTransform} 
creation.
-          */
-         final ParameterizedTransformBuilder builder() throws FactoryException 
{
-             if (builder == null) {
-                 if (factory == null) {
-                     factory = provider();
-                 }
-                 builder = new ParameterizedTransformBuilder(factory, null);
-                 if (parameters != null) {
-                     builder.setParameters(parameters, false);
-                 }
-             }
-             return builder;
-         }
- 
-         /**
-          * Returns the matrix that represent the affine transform to 
concatenate before or after
-          * the parameterized transform. The {@code role} argument specifies 
which matrix is desired:
-          *
-          * <ul class="verbose">
-          *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#NORMALIZATION
-          *       NORMALIZATION} for the conversion from the {@linkplain 
#getSourceCS() source coordinate system} to
-          *       a {@linkplain AxesConvention#NORMALIZED normalized} 
coordinate system, usually with
-          *       (<var>longitude</var>, <var>latitude</var>) axis order in 
degrees or
-          *       (<var>easting</var>, <var>northing</var>) in metres.
-          *       This normalization needs to be applied <em>before</em> the 
parameterized transform.</li>
-          *
-          *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#DENORMALIZATION
-          *       DENORMALIZATION} for the conversion from a normalized 
coordinate system to the
-          *       {@linkplain #getTargetCS() target coordinate system}, for 
example with
-          *       (<var>latitude</var>, <var>longitude</var>) axis order.
-          *       This denormalization needs to be applied <em>after</em> the 
parameterized transform.</li>
-          *
-          *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#INVERSE_NORMALIZATION
 INVERSE_NORMALIZATION} and
-          *       {@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#INVERSE_DENORMALIZATION
 INVERSE_DENORMALIZATION}
-          *       are also supported but rarely used.</li>
-          * </ul>
-          *
-          * This method is invoked by {@link 
DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, Context)}.
-          * Users can override this method if they need to customize the 
normalization process.
-          *
-          * @param  role  whether the normalization or denormalization matrix 
is desired.
-          * @return the requested matrix, or {@code null} if this {@code 
Context} has no information about the coordinate system.
-          * @throws FactoryException if an error occurred while computing the 
matrix.
-          *
-          * @see DefaultMathTransformFactory#createAffineTransform(Matrix)
-          * @see 
DefaultMathTransformFactory#createParameterizedTransform(ParameterValueGroup, 
Context)
-          */
-         @SuppressWarnings("fallthrough")
-         public Matrix getMatrix(final ContextualParameters.MatrixRole role) 
throws FactoryException {
-             return builder().getMatrix(role);
-         }
- 
-         /**
-          * Returns the operation method used for the math transform creation.
-          * This is the same information as {@link #getLastMethodUsed()} but 
more stable
-          * (not affected by transforms created with other contexts).
-          *
-          * @return the operation method used by the factory.
-          * @throws IllegalStateException if {@link 
#createParameterizedTransform(ParameterValueGroup, Context)}
-          *         has not yet been invoked.
-          *
-          * @deprecated Replaced by {@link MathTransform.Builder#getMethod()}.
-          *
-          * @since 1.3
-          */
-         @Deprecated(since="1.5", forRemoval=true)
-         public OperationMethod getMethodUsed() {
-             return (builder != null) ? builder.getMethod().orElse(null) : 
null;
-         }
- 
-         /**
-          * Returns the names of parameters that have been inferred from the 
context.
-          * The set of keys can contain any of {@code "dim"},
-          * {@code     "semi_major"}, {@code     "semi_minor"},
-          * {@code "src_semi_major"}, {@code "src_semi_minor"},
-          * {@code "tgt_semi_major"}, {@code "tgt_semi_minor"} and/or
-          * {@code "inverse_flattening"}, depending on the operation method 
used.
-          * The parameters named in that set are included in the parameters
-          * returned by {@link #getCompletedParameters()}.
-          *
-          * <h4>Associated Boolean values</h4>
-          * The associated Boolean in the map tells whether the named 
parameter value is really contextual.
-          * The Boolean is {@code FALSE} if the user explicitly specified a 
value in the parameters given to
-          * the {@link #createParameterizedTransform(ParameterValueGroup, 
Context)} method,
-          * and that value is different than the value inferred from the 
context.
-          * Such inconsistencies are also logged at {@link Level#WARNING}.
-          * In all other cases
-          * (no value specified by the user, or a value was specified but is 
consistent with the context),
-          * the associated Boolean in the map is {@code TRUE}.
-          *
-          * @deprecated Replaced by {@link 
MathTransformProvider.Context#getContextualParameters()}.
-          *
-          * @return names of parameters inferred from context.
-          *
-          * @since 1.3
-          */
-         @Override
-         @Deprecated(since="1.5", forRemoval=true)
-         public Map<String,Boolean> getContextualParameters() {
-             try {
-                 return builder().getContextualParameters();
-             } catch (FactoryException e) {
-                 throw new IllegalStateException(MESSAGE, e);
-             }
-         }
- 
-         /**
-          * Returns the parameter values used for the math transform creation,
-          * including the parameters completed by the factory.
-          * This is the union of {@link #parameters} with {@link 
#getContextualParameters()}.
-          * The completed parameters may only have additional parameters 
compared to the user-supplied parameters.
-          * Parameter values that were explicitly set by the user are not 
overwritten.
-          *
-          * <p>After this method has been invoked, the {@link #setSourceAxes 
setSourceAxes(…)}
-          * and {@link #setTargetAxes setTargetAxes(…)} methods can no longer 
be invoked.</p>
-          *
-          * @deprecated Replaced by {@link 
MathTransformProvider.Context#getCompletedParameters()}.
-          *
-          * @return the parameter values used by the factory.
-          */
-         @Override
-         @Deprecated(since="1.5", forRemoval=true)
-         public ParameterValueGroup getCompletedParameters() {
-             try {
-                 return builder().getCompletedParameters();
-             } catch (FactoryException e) {
-                 throw new IllegalStateException(MESSAGE, e);
-             }
-         }
- 
-         /**
-          * The "{@code createParameterizedTransform} has not been invoked" 
error message.
-          */
-         private static final String MESSAGE = "createParameterizedTransform 
has not been invoked.";
- 
-         /**
-          * Returns a string representation of this context for debugging 
purposes.
-          * The current implementation writes the name of source/target 
coordinate systems and ellipsoids.
-          * If the {@linkplain #getContextualParameters() contextual 
parameters} have already been inferred,
-          * then their names are appended with inconsistent parameters (if 
any) written on a separated line.
-          *
-          * @return a string representation of this context.
-          */
-         @Override
-         public String toString() {
-             return (builder != null) ? builder.toString() : super.toString();
-         }
-     }
- 
 +    /**
 +     * Creates a transform from a group of parameters.
 +     * The set of expected parameters varies for each operation.
 +     * The easiest way to provide parameter values is to get an initially 
empty group for the desired
 +     * operation by calling {@link #getDefaultParameters(String)}, then to 
fill the parameter values.
 +     * Example:
 +     *
 +     * {@snippet lang="java" :
 +     *     ParameterValueGroup group = 
factory.getDefaultParameters("Transverse_Mercator");
 +     *     group.parameter("semi_major").setValue(6378137.000);
 +     *     group.parameter("semi_minor").setValue(6356752.314);
 +     *     MathTransform mt = factory.createParameterizedTransform(group);
 +     *     }
 +     *
 +     * Sometimes the {@code "semi_major"} and {@code "semi_minor"} parameter 
values are not explicitly provided,
 +     * but rather inferred from the {@linkplain 
org.opengis.referencing.datum.GeodeticDatum geodetic
 +     * reference frame} of the source Coordinate Reference System.
 +     *
 +     * @param  parameters  the parameter values. The {@linkplain 
ParameterDescriptorGroup#getName() parameter group name}
 +     *         shall be the name of the desired {@linkplain 
DefaultOperationMethod operation method}.
 +     * @return the transform created from the given parameters.
 +     * @throws NoSuchIdentifierException if there is no method for the given 
parameter group name.
 +     * @throws FactoryException if the object creation failed. This exception 
is thrown
 +     *         if some required parameter has not been supplied, or has 
illegal value.
 +     *
 +     * @see #getDefaultParameters(String)
 +     * @see #getAvailableMethods(Class)
 +     * @see #getLastMethodUsed()
 +     * @see 
org.apache.sis.parameter.ParameterBuilder#createGroupForMapProjection(ParameterDescriptor...)
 +     *
 +     * @deprecated This constructor is ambiguous when axis directions are 
parts of the map projection definition
 +     * as in <q>Transverse Mercator (South Orientated)</q>.
 +     * Use {@link #builder(String)} instead for allowing the implementation 
to resolve such ambiguities.
 +     */
 +    @Override
 +    @Deprecated(since="1.5")
 +    public MathTransform createParameterizedTransform(final 
ParameterValueGroup parameters)
 +            throws NoSuchIdentifierException, FactoryException
 +    {
 +        final var builder = new ParameterizedTransformBuilder(this, null);
 +        builder.setParameters(parameters, false);
 +        return builder.create();
 +    }
 +
-     /**
-      * Creates a transform from a group of parameters and a context.
-      *
-      * @param  parameters  the parameter values.
-      * @param  context     information about the context, or {@code null} if 
none.
-      * @return the transform created from the given parameters.
-      * @throws NoSuchIdentifierException if there is no method for the given 
parameter group name.
-      * @throws FactoryException if the object creation failed.
-      * @deprecated Replaced by a builder pattern with {@link 
#builder(String)}.
-      */
-     @Deprecated(since="1.5", forRemoval=true)
-     public MathTransform createParameterizedTransform(final 
ParameterValueGroup parameters,
-             final Context context) throws NoSuchIdentifierException, 
FactoryException
-     {
-         if (context == null) {
-             return createParameterizedTransform(parameters);
-         }
-         context.builder    = null;
-         context.factory    = this;
-         context.parameters = parameters;
-         return context.builder().create();
-     }
- 
-     /**
-      * Given a transform between normalized spaces,
-      * creates a transform taking in account axis directions, units of 
measurement and longitude rotation.
-      * This method {@linkplain #createConcatenatedTransform concatenates} the 
given parameterized transform
-      * with any other transform required for performing units changes and 
coordinates swapping.
-      *
-      * <p>The given {@code parameterized} transform shall expect
-      * {@linkplain org.apache.sis.referencing.cs.AxesConvention#NORMALIZED 
normalized} input coordinates and
-      * produce normalized output coordinates. See {@link 
org.apache.sis.referencing.cs.AxesConvention} for more
-      * information about what Apache SIS means by "normalized".</p>
-      *
-      * <h4>Example</h4>
-      * The most typical examples of transforms with normalized inputs/outputs 
are normalized
-      * map projections expecting (<var>longitude</var>, <var>latitude</var>) 
inputs in degrees
-      * and calculating (<var>x</var>, <var>y</var>) coordinates in metres,
-      * both of them with ({@linkplain 
org.opengis.referencing.cs.AxisDirection#EAST East},
-      * {@linkplain org.opengis.referencing.cs.AxisDirection#NORTH North}) 
axis orientations.
-      *
-      * <h4>Controlling the normalization process</h4>
-      * Users who need a different normalized space than the default one may 
find more convenient to
-      * override the {@link Context#getMatrix 
Context.getMatrix(ContextualParameters.MatrixRole)} method.
-      *
-      * @param  parameterized  a transform for normalized input and output 
coordinates.
-      * @param  context        source and target coordinate systems in which 
the transform is going to be used.
-      * @return a transform taking in account unit conversions and axis 
swapping.
-      * @throws FactoryException if the object creation failed.
-      *
-      * @see org.apache.sis.referencing.cs.AxesConvention#NORMALIZED
-      * @see 
org.apache.sis.referencing.operation.DefaultConversion#DefaultConversion(Map, 
OperationMethod, MathTransform, ParameterValueGroup)
-      *
-      * @since 0.7
-      *
-      * @deprecated Considered internal API because the definition of 
"normalized" is implementation-dependent.
-      */
-     @Deprecated(since="1.5", forRemoval=true)
-     public MathTransform swapAndScaleAxes(final MathTransform parameterized, 
final Context context) throws FactoryException {
-         context.builder = null;
-         context.factory = this;
-         return context.builder().swapAndScaleAxes(parameterized);
-     }
- 
 +    /**
 +     * Creates a transform from a base CRS to a derived CS using the given 
parameters.
 +     * If this method needs to set the values of {@code "semi_major"} and 
{@code "semi_minor"} parameters,
 +     * then it sets those values directly on the given {@code parameters} 
instance – not on a clone – for
 +     * allowing the caller to get back the complete parameter values.
 +     * However, this method only fills missing values, it never modify 
existing values.
 +     *
 +     * @param  baseCRS     the source coordinate reference system.
 +     * @param  parameters  the parameter values for the transform.
 +     * @param  derivedCS   the target coordinate system.
 +     * @return the parameterized transform from {@code baseCRS} to {@code 
derivedCS},
 +     *         including unit conversions and axis swapping.
 +     * @throws NoSuchIdentifierException if there is no transform registered 
for the coordinate operation method.
 +     * @throws FactoryException if the object creation failed. This exception 
is thrown
 +     *         if some required parameter has not been supplied, or has 
illegal value.
 +     *
 +     * @deprecated Replaced by {@link #builder(String)}.
 +     */
 +    @Override
 +    @Deprecated(since="0.7")
 +    public MathTransform createBaseToDerived(final CoordinateReferenceSystem 
baseCRS,
 +            final ParameterValueGroup parameters, final CoordinateSystem 
derivedCS)
 +            throws NoSuchIdentifierException, FactoryException
 +    {
 +        ArgumentChecks.ensureNonNull("baseCRS",    baseCRS);
 +        ArgumentChecks.ensureNonNull("parameters", parameters);
 +        ArgumentChecks.ensureNonNull("derivedCS",  derivedCS);
 +        final var builder = new ParameterizedTransformBuilder(this, null);
 +        builder.setParameters(parameters, true);
 +        builder.setSourceAxes(baseCRS);
 +        builder.setTargetAxes(derivedCS, null);
 +        return builder.create();
 +    }
 +
-     /**
-      * Creates a math transform that represent a change of coordinate system. 
If exactly one argument is
-      * an {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS 
ellipsoidal coordinate systems},
-      * then the {@code ellipsoid} argument is mandatory. In all other cases 
(including the case where both
-      * coordinate systems are ellipsoidal), the ellipsoid argument is ignored 
and can be {@code null}.
-      *
-      * <h4>Design note</h4>
-      * This method does not accept separated ellipsoid arguments for {@code 
source} and {@code target} because
-      * this method should not be used for datum shifts. If the two given 
coordinate systems are ellipsoidal,
-      * then they are assumed to use the same ellipsoid. If different 
ellipsoids are desired, then a
-      * {@linkplain #createParameterizedTransform parameterized transform} 
like <q>Molodensky</q>,
-      * <q>Geocentric translations</q>, <q>Coordinate Frame Rotation</q> or
-      * <q>Position Vector transformation</q> should be used instead.
-      *
-      * @param  source     the source coordinate system.
-      * @param  target     the target coordinate system.
-      * @param  ellipsoid  the ellipsoid of {@code EllipsoidalCS}, or {@code 
null} if none.
-      * @return a conversion from the given source to the given target 
coordinate system.
-      * @throws FactoryException if the conversion cannot be created.
-      *
-      * @since 0.8
-      *
-      * @deprecated Replaced by the following pattern:
-      *
-      * {@snippet lang="java" :
-      * var builder = builder("Coordinate system conversion");
-      * builder.setSourceAxes(source, ellipsoid);
-      * builder.setTargetAxes(target, ellipsoid);
-      * return builder.create();
-      * }
-      */
-     @Deprecated(since="1.5", forRemoval=true)
-     public MathTransform createCoordinateSystemChange(final CoordinateSystem 
source, final CoordinateSystem target,
-             final Ellipsoid ellipsoid) throws FactoryException
-     {
-         ArgumentChecks.ensureNonNull("source", source);
-         ArgumentChecks.ensureNonNull("target", target);
-         lastMethod.remove();                                // In case an 
exception is thrown before completion.
-         final var builder = builder(Constants.COORDINATE_SYSTEM_CONVERSION);
-         builder.setSourceAxes(source, ellipsoid);
-         builder.setTargetAxes(target, ellipsoid);
-         return builder.create();
-     }
- 
      /**
       * Creates an affine transform from a matrix. If the transform input 
dimension is {@code M},
       * and output dimension is {@code N}, then the matrix will have size 
{@code [N+1][M+1]}. The
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_ImageDatum.java
index b3eaa6bb7b,2c5bbdfe68..bf868b5f53
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_ImageDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_ImageDatum.java
@@@ -18,11 -18,8 +18,11 @@@ package org.apache.sis.xml.bind.referen
  
  import jakarta.xml.bind.annotation.XmlElement;
  import org.apache.sis.xml.bind.gco.PropertyType;
- import org.apache.sis.referencing.datum.DefaultImageDatum;
+ import org.apache.sis.referencing.legacy.DefaultImageDatum;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.datum.ImageDatum;
 +
  
  /**
   * JAXB adapter mapping implementing class to the GeoAPI interface. See
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CS_UserDefinedCS.java
index c1022ef664,7900672d33..1ae5d4b8fc
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CS_UserDefinedCS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CS_UserDefinedCS.java
@@@ -17,12 -17,9 +17,12 @@@
  package org.apache.sis.xml.bind.referencing;
  
  import jakarta.xml.bind.annotation.XmlElement;
- import org.apache.sis.referencing.cs.DefaultUserDefinedCS;
+ import org.apache.sis.referencing.legacy.DefaultUserDefinedCS;
  import org.apache.sis.xml.bind.gco.PropertyType;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.cs.UserDefinedCS;
 +
  
  /**
   * JAXB adapter mapping implementing class to the GeoAPI interface. See
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/HardCodedCRS.java
index fe0a120af7,f0949b31d8..853d08213a
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/HardCodedCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/HardCodedCRS.java
@@@ -323,9 -321,9 +324,9 @@@ public final class HardCodedCRS 
       * this CS cannot be reprojected to a geographic coordinate reference 
system for example).
       *
       * <p>The {@code pixelInCell} attribute of the associated {@code 
ImageDatum}
 -     * is set to {@link 
org.apache.sis.coverage.grid.PixelInCell#CELL_CENTER}.</p>
 +     * is set to {@link PixelInCell#CELL_CENTER}.</p>
       */
-     @SuppressWarnings("removal")
+     @SuppressWarnings("exports")
      public static final DefaultImageCRS IMAGE = new DefaultImageCRS(
              getProperties(HardCodedDatum.IMAGE), HardCodedDatum.IMAGE, 
HardCodedCS.GRID);
  
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
index 6835ce3c59,b1d86a1c5f..255dbdae5c
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
@@@ -155,12 -153,12 +156,12 @@@ public final class HardCodedDatum 
              properties("Day of year", null, null));
  
      /**
 -     * Image with {@link 
org.apache.sis.coverage.grid.PixelInCell#CELL_CENTER}.
 +     * Image with {@link PixelInCell#CELL_CENTER}.
       */
-     @SuppressWarnings("removal")
+     @SuppressWarnings("exports")
      public static final DefaultImageDatum IMAGE = new DefaultImageDatum(
              properties("Image", null, null),
 -            "cell center");
 +            PixelInCell.CELL_CENTER);
  
      /**
       * An engineering datum for unknown coordinate reference system. Such CRS 
are usually
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/legacy/DefaultImageCRSTest.java
index fddc9ccf66,9b25e5ec04..d426f736bf
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/legacy/DefaultImageCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/legacy/DefaultImageCRSTest.java
@@@ -36,9 -35,6 +35,11 @@@ import org.apache.sis.referencing.cs.Ha
  import static org.apache.sis.metadata.Assertions.assertXmlEquals;
  import static org.apache.sis.referencing.Assertions.assertWktEquals;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.datum.PixelInCell;
++import org.apache.sis.referencing.legacy.DefaultImageCRS;
++import org.apache.sis.referencing.legacy.DefaultImageDatum;
 +
  // Specific to the geoapi-3.1 and geoapi-4.0 branches:
  import static org.opengis.test.Assertions.assertAxisDirectionsEqual;
  
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
index e11160d4c7,059e817a19..b9812f5a92
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
@@@ -42,6 -42,6 +42,7 @@@ import org.opengis.referencing.operatio
  import org.apache.sis.referencing.CommonCRS;
  import org.apache.sis.referencing.CRS;
  import org.apache.sis.referencing.internal.PositionalAccuracyConstant;
++import org.apache.sis.referencing.internal.shared.CoordinateOperations;
  import org.apache.sis.referencing.operation.transform.LinearTransform;
  import org.apache.sis.referencing.operation.transform.MathTransforms;
  import org.apache.sis.referencing.operation.matrix.Matrices;
diff --cc 
endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Metadata.java
index 4d49a51d10,bbd3d7bb09..eb0d4f845d
--- 
a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Metadata.java
+++ 
b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Metadata.java
@@@ -48,11 -49,8 +49,11 @@@ import org.apache.sis.metadata.iso.cita
  import org.apache.sis.metadata.iso.identification.DefaultKeywords;
  import org.apache.sis.metadata.iso.extent.Extents;
  import org.apache.sis.referencing.CommonCRS;
- import org.apache.sis.util.iso.Types;
+ import org.apache.sis.temporal.TemporalDate;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.metadata.citation.ResponsibleParty;
 +
  // Specific to the geoapi-3.1 and geoapi-4.0 branches:
  import org.opengis.metadata.citation.Responsibility;
  import org.apache.sis.metadata.iso.citation.Citations;
diff --cc geoapi/snapshot
index ec781af595,8cc86e44c8..4b998b7f66
--- a/geoapi/snapshot
+++ b/geoapi/snapshot
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit ec781af595a5b8a234550237ea5d6f4e4eb876f8
 -Subproject commit 8cc86e44c8cebbb07cd65cd666354d1397a2e975
++Subproject commit 4b998b7f663fc2ec95e1a8533597dc42f886b094

Reply via email to