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

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

commit 45c820c45fdb9b5349b5a501dcc04edab3f0ca22
Merge: 7b052340a2 87f745fce9
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Nov 3 12:23:48 2026 +0100

    Merge branch 'geoapi-3.1' (bug fixes mostly in referencing modules).

 README.md                                          |   2 +-
 endorsed/build.gradle.kts                          |   2 +-
 .../org/apache/sis/feature/internal/Resources.java |   5 +
 .../sis/feature/internal/Resources.properties      |   1 +
 .../sis/feature/internal/Resources_fr.properties   |   1 +
 .../apache/sis/filter/BinaryGeometryFilter.java    |  16 +-
 .../main/org/apache/sis/filter/DistanceFilter.java |   6 +-
 .../main/org/apache/sis/filter/package-info.java   |   2 +-
 .../org/apache/sis/filter/sqlmm/ST_Transform.java  |   2 +-
 .../org/apache/sis/filter/sqlmm/TwoGeometries.java |  19 +-
 .../apache/sis/geometry/wrapper/Dimensions.java    |  91 +++++++++
 .../apache/sis/geometry/wrapper/GeometryType.java  |   6 +-
 .../sis/geometry/wrapper/GeometryWrapper.java      | 156 ++++++++++----
 .../geometry/wrapper/SpatialOperationContext.java  | 192 ++++++++----------
 .../apache/sis/geometry/wrapper/esri/Wrapper.java  |  15 +-
 .../sis/geometry/wrapper/j2d/PointWrapper.java     |  10 +
 .../geometry/wrapper/jts/GeometryTransform.java    |   5 +-
 .../sis/geometry/wrapper/jts/GeometryWalker.java   |  35 +++-
 .../org/apache/sis/geometry/wrapper/jts/JTS.java   | 121 +----------
 .../apache/sis/geometry/wrapper/jts/Wrapper.java   |  96 ++++-----
 .../sis/filter/BinarySpatialFilterTestCase.java    |   1 +
 .../filter/BinarySpatialFilterUsingESRI_Test.java  |   1 +
 .../filter/BinarySpatialFilterUsingJTS_Test.java   |   1 +
 .../BinarySpatialFilterUsingJava2D_Test.java       |   1 +
 .../sis/geometry/wrapper/DimensionsTest.java       |  95 +++++++++
 .../apache/sis/geometry/wrapper/jts/JTSTest.java   |  46 +++--
 .../org/apache/sis/geometry/AbstractEnvelope.java  |   6 +-
 .../pending/geoapi/referencing/MissingMethods.java |  10 +-
 .../main/org/apache/sis/referencing/CRS.java       | 225 +++++++++++----------
 .../main/org/apache/sis/referencing/CommonCRS.java |   2 +-
 .../referencing/EllipsoidalHeightSeparator.java    |  73 +++----
 .../apache/sis/referencing/IdentifiedObjects.java  |   3 +-
 .../sis/referencing/StandardDefinitions.java       |  20 +-
 .../main/org/apache/sis/referencing/cs/Codes.java  |  55 +++--
 .../sis/referencing/cs/CoordinateSystems.java      |  92 ++++-----
 .../apache/sis/referencing/cs/package-info.java    |   2 +-
 .../internal/shared/EllipsoidalHeightCombiner.java | 113 ++++++++---
 .../shared/ReferencingFactoryContainer.java        |   6 +-
 .../internal/shared/ReferencingUtilities.java      |  15 +-
 .../operation/AbstractCoordinateOperation.java     |   5 +-
 .../operation/CoordinateOperationFinder.java       |   2 +-
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../operation/projection/AuthalicMercator.java     |   5 +-
 .../referencing/operation/projection/Mercator.java |   8 +-
 .../operation/projection/NormalizedProjection.java |  42 ++--
 .../operation/projection/TransverseMercator.java   |  10 +-
 .../operation/projection/ZonedGridSystem.java      |   8 +-
 .../operation/transform/AbstractMathTransform.java |  32 ++-
 .../operation/transform/DomainDefinition.java      |  75 +++++--
 .../transform/GeometryTransformException.java      |  67 ++++++
 .../operation/transform/MathTransforms.java        |  14 +-
 .../operation/transform/package-info.java          |   4 +-
 .../test/org/apache/sis/referencing/CRSTest.java   |  32 ++-
 .../org/apache/sis/referencing/cs/CodesTest.java   |  35 +++-
 .../shared/EllipsoidalHeightCombinerTest.java      |   6 +-
 .../sis/storage/sql/feature/GeometryGetter.java    |  41 +++-
 .../sis/storage/internal/InputStreamAdapter.java   |   2 +-
 .../main/org/apache/sis/pending/jdk/JDK12.java}    |  18 +-
 .../main/org/apache/sis/util/Classes.java          |   3 +-
 optional/README.md                                 |   2 +-
 optional/src/org.apache.sis.gui/bundle/README      |   2 +-
 parent/overview.html                               |   2 +-
 parent/pom.xml                                     |   4 +-
 63 files changed, 1223 insertions(+), 748 deletions(-)

diff --cc endorsed/build.gradle.kts
index 88dac5b578,d2d53a4cd9..87bb91af04
--- a/endorsed/build.gradle.kts
+++ b/endorsed/build.gradle.kts
@@@ -100,7 -100,8 +100,7 @@@ dependencies 
   */
  var srcDir = file("src")            // Must be the same as the hard-coded 
value in `BuildHelper.java`.
  tasks.compileJava {
-     options.release.set(12)         // The version of both Java source code 
and compiled byte code.
 -    dependsOn(":geoapi:rebuild")
+     options.release.set(11)         // The version of both Java source code 
and compiled byte code.
  }
  tasks.compileTestJava {
      options.compilerArgs.add("-source")         // "source", not "release", 
because we accept any target version.
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java
index 09d7809012,f8d32fab1a..005037277d
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java
@@@ -206,13 -225,14 +215,14 @@@ abstract class BinaryGeometryFilter<R> 
               */
              final GeometryWrapper geometry = wrapper.apply(null);
              if (geometry != null) try {
-                 final GeometryWrapper transformed = 
geometry.transform(optimization.findExpectedCRS(other).orElse(null));
-                 if (geometry != transformed) {
+                 final CoordinateReferenceSystem crs = 
optimization.findExpectedCRS(other).orElse(null);
+                 final GeometryWrapper transformed = geometry.transform(crs, 
true);
+                 if (geometry != transformed && transformed.isFinite2D()) {
 -                    literal = Optimization.literal(transformed);
 +                    literal = (Literal<R,?>) 
Optimization.literal(transformed);
                      if (literal == effective1) effective1 = literal;
                      else effective2 = literal;
                  }
-             } catch (IllegalArgumentException | TransformException e) {
 -            } catch (PropertyNotFoundException | FactoryException | 
TransformException e) {
++            } catch (IllegalArgumentException | FactoryException | 
TransformException e) {
                  optimization.warning(e, false);
              }
              /*
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java
index 8320d2d727,a31bbac647..37456c446f
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java
@@@ -83,7 -93,7 +92,7 @@@ class TwoGeometries<R> extends SpatialF
                      effective[1] = Optimization.literal(transformed);
                      return recreate(effective);
                  }
-             } catch (IllegalArgumentException | TransformException e) {
 -            } catch (PropertyNotFoundException | FactoryException | 
TransformException e) {
++            } catch (IllegalArgumentException | FactoryException | 
TransformException e) {
                  optimization.warning(e, false);
              }
          }
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java
index 496824204f,08f6552d25..07f2e5cd6a
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java
@@@ -27,26 -27,36 +27,31 @@@ import javax.measure.quantity.Length
  import org.opengis.geometry.DirectPosition;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
  import org.opengis.referencing.operation.CoordinateOperation;
 -import org.opengis.referencing.operation.TransformException;
  import org.opengis.referencing.operation.MathTransform;
 +import org.opengis.referencing.operation.TransformException;
  import org.opengis.util.FactoryException;
+ import org.apache.sis.geometry.AbstractEnvelope;
  import org.apache.sis.geometry.GeneralEnvelope;
+ import org.apache.sis.feature.internal.Resources;
  import org.apache.sis.filter.sqlmm.SQLMM;
  import org.apache.sis.referencing.CRS;
- import org.apache.sis.referencing.operation.transform.MathTransforms;
+ import org.apache.sis.referencing.operation.transform.DomainDefinition;
+ import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
  import 
org.apache.sis.referencing.operation.transform.TransformFactoryException;
- import org.apache.sis.referencing.internal.shared.ReferencingUtilities;
+ import 
org.apache.sis.referencing.operation.transform.GeometryTransformException;
+ import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.Classes;
  import org.apache.sis.util.Debug;
  import org.apache.sis.util.UnconvertibleObjectException;
  import org.apache.sis.util.collection.BackingStoreException;
  import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.logging.Logging;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import java.util.Set;
 -import org.opengis.geometry.Geometry;
 -import org.opengis.geometry.Boundary;
 -import org.opengis.geometry.TransfiniteSet;
 -import org.opengis.geometry.complex.Complex;
 -import org.opengis.filter.SpatialOperatorName;
 -import org.opengis.filter.DistanceOperatorName;
 -import org.opengis.coordinate.MismatchedDimensionException;
 +// Specific to the main branch:
 +import org.apache.sis.pending.geoapi.geometry.Geometry;
 +import org.apache.sis.pending.geoapi.filter.SpatialOperatorName;
 +import org.apache.sis.pending.geoapi.filter.DistanceOperatorName;
  
  
  /**
@@@ -159,8 -178,9 +173,8 @@@ public abstract class GeometryWrapper e
       *
       * @return the coordinate dimension.
       */
-     public int getCoordinateDimension() {
-         return Geometries.BIDIMENSIONAL;
 -    @Override
+     public final int getCoordinateDimension() {
+         return getCoordinateDimensions().count;
      }
  
      /**
@@@ -550,13 -573,12 +566,11 @@@
       * @throws BackingStoreException if the operation failed because of 
another checked exception.
       *
       * @see #getCoordinateReferenceSystem()
+      * @see SpatialOperationContext#transform(GeometryWrapper)
       */
-     public GeometryWrapper transform(final CoordinateReferenceSystem 
targetCRS) throws TransformException {
-         if (targetCRS == null || targetCRS == crs || crs == null) {
-             return this;
-         }
 -    @Override
+     public final GeometryWrapper transform(final CoordinateReferenceSystem 
targetCRS) throws TransformException {
          try {
-             return transform(CRS.findOperation(crs, targetCRS, null), false);
+             return transform(targetCRS, false);
          } catch (FactoryException e) {
              throw new TransformFactoryException(e);
          }
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java
index 0ab07c53ef,448b726ee6..6b46d58f76
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java
@@@ -400,9 -388,9 +386,9 @@@ select:     if (commonCRS == null) 
               */
              final CoordinateSystem cs = geometryCRS.getCoordinateSystem();
              double latitude = Double.NaN, longitude = Double.NaN;
-             for (int i=0; i<BIDIMENSIONAL; i++) {
+             for (int i = 0; i < Geometries.BIDIMENSIONAL; i++) {
                  final CoordinateSystemAxis axis = cs.getAxis(i);
 -                double coordinate = centroid.getCoordinate(i);
 +                double coordinate = centroid.getOrdinate(i);
                  coordinate = 
axis.getUnit().getConverterToAny(Units.DEGREE).convert(coordinate);
                  final AxisDirection direction = axis.getDirection();
                       if (direction == AxisDirection.NORTH) latitude  =  
coordinate;
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java
index 6b46e04271,b17187ab17..cc1a8ecc15
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java
@@@ -43,11 -43,9 +43,9 @@@ import org.locationtech.jts.simplify.To
  import org.opengis.util.FactoryException;
  import org.opengis.geometry.DirectPosition;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
- import org.opengis.referencing.operation.CoordinateOperation;
 -import org.opengis.referencing.operation.TransformException;
  import org.opengis.referencing.operation.MathTransform;
 +import org.opengis.referencing.operation.TransformException;
  import org.apache.sis.referencing.CRS;
- import 
org.apache.sis.referencing.operation.transform.TransformFactoryException;
  import org.apache.sis.geometry.DirectPosition2D;
  import org.apache.sis.geometry.GeneralDirectPosition;
  import org.apache.sis.geometry.GeneralEnvelope;
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java
index 8b9e51db73,0000000000..2e633d753b
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,292 -1,0 +1,292 @@@
 +/*
 + * 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.Collection;
 +import java.util.function.Function;
 +import java.time.temporal.Temporal;
 +import org.opengis.util.FactoryException;
 +import org.opengis.referencing.cs.*;
 +import org.opengis.referencing.crs.*;
 +import org.opengis.referencing.datum.*;
 +import org.opengis.metadata.quality.PositionalAccuracy;
 +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.crs.DefaultParametricCRS;
 +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;
 +
 +
 +/**
 + * 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.
++     * @param  crs  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.
++     * @param  crs  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.
++     * @param  crs  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.
++     * @param  crs  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.
++     * @param  crs  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 datum ensemble. This method requires the <abbr>SIS</abbr> 
factory
 +     * since datum ensembles were not available in GeoAPI 3.0.
 +     *
 +     * @param  <D>         the type of datum contained in the ensemble.
 +     * @param  properties  name and other properties to give to the new 
object.
 +     * @param  members     datum or reference frames which are members of the 
datum ensemble.
 +     * @param  accuracy    inaccuracy introduced through use of the given 
collection of datums.
 +     * @return the datum ensemble for the given properties.
 +     * @throws FactoryException if the object creation failed.
 +     */
 +    public static <D extends Datum> DefaultDatumEnsemble<D> 
createDatumEnsemble(
 +            final Map<String,?> properties,
 +            final Collection<? extends D> members,
 +            final PositionalAccuracy accuracy,
 +            DatumFactory factory) throws FactoryException
 +    {
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createDatumEnsemble(properties, members, accuracy);
 +    }
 +
 +    /**
 +     * 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 <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 DefaultParametricCRS createParametricCRS(final 
Map<String,?> properties, final DefaultParametricDatum datum,
 +            final DefaultParametricCS cs, CRSFactory factory) throws 
FactoryException
 +    {
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createParametricCRS(properties, datum, cs);
 +    }
 +
 +    /**
 +     * 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);
 +    }
 +
 +    public static VerticalDatum createVerticalDatum(final Map<String,?> 
properties, final VerticalDatumType type,
 +            final Temporal epoch, DatumFactory factory) throws 
FactoryException
 +    {
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createVerticalDatum(properties, type, epoch);
 +    }
 +
 +    public static GeodeticDatum createGeodeticDatum(final Map<String,?> 
properties, final Ellipsoid ellipsoid,
 +            final PrimeMeridian primeMeridian, final Temporal epoch, 
DatumFactory factory) throws FactoryException
 +    {
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createGeodeticDatum(properties, ellipsoid, primeMeridian, epoch);
 +    }
 +
 +    public static GeographicCRS createGeographicCRS(final Map<String,?> 
properties, final GeodeticDatum datum,
 +            final DefaultDatumEnsemble<GeodeticDatum> ensemble, final 
EllipsoidalCS cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createGeographicCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createGeographicCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static GeodeticCRS createGeodeticCRS(final Map<String,?> 
properties, final GeodeticDatum datum,
 +            final DefaultDatumEnsemble<GeodeticDatum> ensemble, final 
SphericalCS cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createGeocentricCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createGeodeticCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static GeodeticCRS createGeodeticCRS(final Map<String,?> 
properties, final GeodeticDatum datum,
 +            final DefaultDatumEnsemble<GeodeticDatum> ensemble, final 
CartesianCS cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createGeocentricCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createGeodeticCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static VerticalCRS createVerticalCRS(final Map<String,?> 
properties, final VerticalDatum datum,
 +            final DefaultDatumEnsemble<VerticalDatum> ensemble, final 
VerticalCS cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createVerticalCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createVerticalCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static TemporalCRS createTemporalCRS(final Map<String,?> 
properties, final TemporalDatum datum,
 +            final DefaultDatumEnsemble<TemporalDatum> ensemble, final TimeCS 
cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createTemporalCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createTemporalCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static DefaultParametricCRS createParametricCRS(final 
Map<String,?> properties, final DefaultParametricDatum datum,
 +            final DefaultDatumEnsemble<DefaultParametricDatum> ensemble, 
final DefaultParametricCS cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createParametricCRS(properties, datum, ensemble, cs);
 +    }
 +
 +    public static EngineeringCRS createEngineeringCRS(final Map<String,?> 
properties, final EngineeringDatum datum,
 +            final DefaultDatumEnsemble<EngineeringDatum> ensemble, final 
CoordinateSystem cs, CRSFactory factory)
 +            throws FactoryException
 +    {
 +        if (ensemble == null) {
 +            return factory.createEngineeringCRS(properties, datum, cs);
 +        }
 +        if (!(factory instanceof GeodeticObjectFactory)) {
 +            factory = GeodeticObjectFactory.provider();
 +        }
 +        return ((GeodeticObjectFactory) 
factory).createEngineeringCRS(properties, datum, ensemble, cs);
 +    }
 +}
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java
index ed7dfcb8ac,024fd3188d..79505c4359
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java
@@@ -88,9 -78,9 +78,8 @@@ import org.apache.sis.referencing.datum
  import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
  import org.apache.sis.referencing.operation.CoordinateOperationContext;
  import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
- import org.apache.sis.referencing.operation.DefiningConversion;
  import org.apache.sis.referencing.factory.GeodeticObjectFactory;
  import org.apache.sis.referencing.factory.UnavailableFactoryException;
 -import org.apache.sis.coordinate.DefaultCoordinateMetadata;
  import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
  import org.apache.sis.metadata.iso.extent.Extents;
  import org.apache.sis.util.ArgumentChecks;
@@@ -107,11 -97,11 +97,10 @@@ import org.apache.sis.coordinate.Defaul
  // Specific to the main and geoapi-3.1 branches:
  import org.opengis.referencing.crs.GeneralDerivedCRS;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.referencing.ObjectDomain;
 -import org.opengis.referencing.datum.DatumEnsemble;
 -import org.opengis.referencing.datum.DynamicReferenceFrame;
 -import org.opengis.coordinate.CoordinateMetadata;
 +// Specific to the main branch:
 +import org.apache.sis.referencing.crs.AbstractCRS;
 +import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
 +import org.apache.sis.referencing.datum.DefaultVerticalDatum;
- import static 
org.apache.sis.pending.geoapi.referencing.MissingMethods.getDatumEnsemble;
  
  
  /**
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java
index 1e6a13ff7b,ec1bfaaa8b..d511d92388
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java
@@@ -134,15 -122,21 +122,21 @@@ final class EllipsoidalHeightSeparator 
                  throw new IllegalArgumentException(Errors.format(
                          Errors.Keys.UnsupportedCoordinateSystem_1, 
IdentifiedObjects.getName(cs, null)));
              }
-             final CommonCRS ref = CommonCRS.WGS84;
-             if 
(Utilities.equalsIgnoreMetadata(ref.geographic().getCoordinateSystem(), cs)) {
-                 final CommonCRS c = CommonCRS.forDatum(datum, ensemble);
-                 if (c != null) return c.geographic();
-             } else if 
(Utilities.equalsIgnoreMetadata(ref.normalizedGeographic().getCoordinateSystem(),
 cs)) {
-                 final CommonCRS c = CommonCRS.forDatum(datum, ensemble);
-                 if (c != null) return c.normalizedGeographic();
+             final var source = (GeodeticCRS) crs;
+             final GeodeticDatum datum = source.getDatum();
 -            final DatumEnsemble<GeodeticDatum> ensemble = 
source.getDatumEnsemble();
++            final DefaultDatumEnsemble<GeodeticDatum> ensemble = 
getDatumEnsemble(source);
+             final CommonCRS predefined = CommonCRS.forDatum(datum, ensemble);
+             if (predefined != null && 
predefined.datum(true).equals(DatumOrEnsemble.asDatum(source))) {
+                 // We require an equal datum because a datum change in this 
operation would be confusing.
+                 boolean normalized = false;
+                 do {
+                     GeographicCRS candidate = normalized ? 
predefined.normalizedGeographic() : predefined.geographic();
+                     if 
(Utilities.equalsIgnoreMetadata(candidate.getCoordinateSystem(), cs)) {
+                         return candidate;
+                     }
+                 } while ((normalized = !normalized) == true);
              }
-             return 
factory().createGeographicCRS(getPropertiesForModifiedCRS(crs), pseudo, 
(EllipsoidalCS) cs);
 -            return 
factory().createGeographicCRS(getPropertiesForModifiedCRS(source), datum, 
ensemble, (EllipsoidalCS) cs);
++            return 
factory().createGeographicCRS(getPropertiesForModifiedCRS(source), 
DatumOrEnsemble.asDatum(source), (EllipsoidalCS) cs);
          }
          /*
           * In the projected CRS case, in addition of reducing the number of 
dimensions in the CartesianCS,
@@@ -166,7 -161,15 +161,15 @@@
                      getPropertiesForModifiedCRS(projection),
                      projection.getMethod(), null,
                      projection.getParameterValues());
-             return 
factory().createProjectedCRS(getPropertiesForModifiedCRS(crs), baseCRS, 
projection, (CartesianCS) cs);
+             return 
factory().createProjectedCRS(getPropertiesForModifiedCRS(source), baseCRS, 
projection, (CartesianCS) cs);
+         }
+         /*
+          * Horizontal engineering CRS requested. The axis directions have 
already been verified by `accept(…)`.
+          */
+         if (crs instanceof EngineeringCRS) {
+             final var source = (EngineeringCRS) crs;
+             return factory().createEngineeringCRS(
 -                    getPropertiesForModifiedCRS(source), source.getDatum(), 
source.getDatumEnsemble(), cs);
++                    getPropertiesForModifiedCRS(source), 
DatumOrEnsemble.asDatum(source), cs);
          }
          throw new 
IllegalArgumentException(Errors.format(Errors.Keys.UnsupportedType_1, 
crs.getClass()));
      }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java
index b6e6aeb716,37c7de7a2f..3133460464
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java
@@@ -35,11 -36,24 +37,18 @@@ import org.opengis.referencing.datum.Ve
  import org.opengis.referencing.operation.Conversion;
  import org.opengis.referencing.operation.CoordinateOperationFactory;
  import org.apache.sis.referencing.IdentifiedObjects;
+ import org.apache.sis.referencing.cs.CoordinateSystems;
  import org.apache.sis.referencing.datum.DatumOrEnsemble;
+ import org.apache.sis.metadata.iso.citation.Citations;
  import org.apache.sis.metadata.iso.extent.Extents;
+ import org.apache.sis.system.Loggers;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.ArraysExt;
+ import org.apache.sis.util.Classes;
+ import org.apache.sis.util.logging.Logging;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.internal.shared.Constants;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.referencing.ObjectDomain;
 -
 -// Specific to the geoapi-3.1 branch:
 -import org.opengis.referencing.crs.GeographicCRS;
 -
  
  /**
   * A class in charges of combining two-dimensional geographic or projected 
CRS with an ellipsoidal height into a
@@@ -137,20 -143,32 +138,32 @@@ public final class EllipsoidalHeightCom
                      axes[axisPosition++   ] = cs2D.getAxis(0);
                      axes[axisPosition++   ] = cs2D.getAxis(1);
                      axes[axisPosition %= 3] = 
vertical.getCoordinateSystem().getAxis(0);
-                     final Map<String,?> csProps  = 
IdentifiedObjects.getProperties(cs2D, CoordinateSystem.IDENTIFIERS_KEY);
-                     final Map<String,?> crsProps = (components.length == 2) ? 
properties
-                                                  : 
IdentifiedObjects.getProperties(crs, CoordinateReferenceSystem.IDENTIFIERS_KEY);
+                     final String epsgCode = getEpsgCode(cs2D, axes);
+                     /*
+                      * If the 3D CRS created in this block will be the CRS to 
return, the `properties` given in
+                      * argument to this method are used directly. Otherwise 
we need to derive something else.
+                      * Current implementation reuses the properties of the 
two-dimensional CRS.
+                      */
+                     final Map<String, ?> crsProps = (components.length == 2)
+                             ? properties : 
ReferencingUtilities.getPropertiesForModifiedCRS(crs);
                      if (crs instanceof GeodeticCRS) {
                          final var geod = (GeodeticCRS) crs;
-                         final EllipsoidalCS cs3D;
-                         cs3D = factories.getCSFactory() 
.createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
-                         crs  = 
factories.getCRSFactory().createGeographicCRS(crsProps, 
DatumOrEnsemble.asDatum(geod), cs3D);
-                     } else {
-                         final ProjectedCRS proj = (ProjectedCRS) crs;
+                         EllipsoidalCS cs3D = null;
+                         if (epsgCode != null) try {
+                             cs3D = 
factories.getCSAuthorityFactory().createEllipsoidalCS(epsgCode);
+                         } catch (NoSuchAuthorityCodeException e) {
+                             warning(e);
+                         }
+                         if (cs3D == null) {
+                             cs3D = 
factories.getCSFactory().createEllipsoidalCS(
+                                     
ReferencingUtilities.getPropertiesForModifiedCRS(cs2D), axes[0], axes[1], 
axes[2]);
+                         }
 -                        crs = 
factories.getCRSFactory().createGeographicCRS(crsProps, geod.getDatum(), 
geod.getDatumEnsemble(), cs3D);
++                        crs = 
factories.getCRSFactory().createGeographicCRS(crsProps, 
DatumOrEnsemble.asDatum(geod), cs3D);
+                     } else if (crs instanceof ProjectedCRS) {
+                         final var proj = (ProjectedCRS) crs;
                          GeographicCRS base = proj.getBaseCRS();
                          if (base.getCoordinateSystem().getDimension() == 2) {
-                             base = (GeographicCRS) createCompoundCRS(
-                                     IdentifiedObjects.getProperties(base, 
GeographicCRS.IDENTIFIERS_KEY), base, vertical);
+                             base = (GeographicCRS) 
createCompoundCRS(ReferencingUtilities.getPropertiesForModifiedCRS(base), base, 
vertical);
                          }
                          /*
                           * In Apache SIS implementation, the Conversion 
contains the source and target CRS together with
@@@ -221,11 -277,13 +272,11 @@@
              ArgumentChecks.ensureNonNullElement("components", i, crs);
              if (i != 0) name.append(" + ");
              name.append(crs.getName().getCode());
 -            for (ObjectDomain obj : crs.getDomains()) {
 -                domain = Extents.intersection(domain, 
obj.getDomainOfValidity());
 -            }
 +            domain = Extents.intersection(domain, crs.getDomainOfValidity());
          }
-         final var properties = new HashMap<String,Object>(4);
+         final var properties = new HashMap<String, Object>(4);
          properties.put(CoordinateReferenceSystem.NAME_KEY, name.toString());
 -        properties.put(ObjectDomain.DOMAIN_OF_VALIDITY_KEY, domain);
 +        properties.put(CoordinateReferenceSystem.DOMAIN_OF_VALIDITY_KEY, 
domain);
          return properties;
      }
  }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java
index 5f35e8ce3f,054c17b0bf..2a34bb1433
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java
@@@ -201,10 -147,7 +201,7 @@@ public final class ReferencingUtilitie
       * @see org.apache.sis.referencing.internal.VerticalDatumTypes#ELLIPSOIDAL
       */
      public static boolean isEllipsoidalHeight(final VerticalDatum datum) {
-         if (datum != null) {
-             return 
VerticalDatumTypes.ellipsoidal(datum.getVerticalDatumType());
-         }
-         return false;
 -        return (datum != null) && 
datum.getRealizationMethod().filter(VerticalDatumTypes::ellipsoidal).isPresent();
++        return (datum != null) && 
VerticalDatumTypes.ellipsoidal(datum.getVerticalDatumType());
      }
  
      /**
@@@ -301,8 -245,8 +298,8 @@@
       * @return the identified object properties.
       */
      public static Map<String,?> getPropertiesWithoutIdentifiers(final 
IdentifiedObject object, final Map<String,?> overwrite) {
-         final Map<String,?> properties = 
IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY);
+         final Map<String, ?> properties = 
IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY);
 -        final Identifier name = object.getName();
 +        final ReferenceIdentifier name = object.getName();
          final boolean keepName = name.getCodeSpace() == null && 
name.getAuthority() == null;
          if (keepName && overwrite == null) {
              return properties;
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
index d85260a2d2,225aef63e6..e8cc1e34cc
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
@@@ -50,11 -53,9 +53,9 @@@ import org.apache.sis.referencing.opera
  import org.apache.sis.referencing.operation.provider.MapProjection;
  import org.apache.sis.referencing.internal.shared.Formulas;
  import org.apache.sis.system.Modules;
- import org.apache.sis.util.internal.shared.Constants;
- import org.apache.sis.util.internal.shared.Numerics;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.metadata.Identifier;
 +// Specific to the main branch:
 +import org.opengis.referencing.ReferenceIdentifier;
  
  
  /**
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java
index 0000000000,734853398d..02044c58bf
mode 000000,100644..100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java
@@@ -1,0 -1,67 +1,67 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ package org.apache.sis.referencing.operation.transform;
+ 
+ import org.opengis.referencing.operation.TransformException;
+ 
+ 
+ /**
+  * Thrown when a transform cannot be applied on a given geometry or envelope 
instance.
+  * This exception is usually thrown when a geometric prerequisite has not 
been met.
+  * The failed check may be before any attempt to actually transform a point.
+  * For example, the geometry may be an instance of an unrecognized type,
+  * or the geometry envelope may be outside the
+  * {@linkplain AbstractMathTransform#getDomain transform domain}.
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @version 1.8
+  * @since   1.8
+  */
+ public class GeometryTransformException extends TransformException {
+     /**
+      * For cross-version compatibility.
+      */
+     private static final long serialVersionUID = -9058827495784393813L;
+ 
+     /**
+      * Creates an exception with the specified detail message.
+      *
+      * @param message  the detail message, saved for later retrieval by the 
{@link #getMessage()} method.
+      */
+     public GeometryTransformException(String message) {
+         super(message);
+     }
+ 
+     /**
+      * Creates an exception with the specified cause.
+      *
+      * @param cause  the cause, saved for later retrieval by the {@link 
#getCause()} method.
+      */
+     public GeometryTransformException(Throwable cause) {
 -        super(cause);
++        super(null, cause);
+     }
+ 
+     /**
+      * Creates an exception with the specified detail message and cause.
+      *
+      * @param message  the detail message, saved for later retrieval by the 
{@link #getMessage()} method.
+      * @param cause    the cause, saved for later retrieval by the {@link 
#getCause()} method.
+      */
+     public GeometryTransformException(String message, Throwable cause) {
+         super(message, cause);
+     }
+ }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java
index fa410d70cc,81f0645bb5..02f9cf0359
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java
@@@ -798,7 -798,7 +796,7 @@@ public final class MathTransforms 
       * @throws TransformException if the domain cannot be estimated.
       *
       * @see AbstractMathTransform#getDomain(DomainDefinition)
--     * @see org.opengis.referencing.operation.CoordinateOperation#getDomains()
++     * @see 
org.opengis.referencing.operation.CoordinateOperation#getDomainOfValidity()
       *
       * @since 1.3
       */
diff --cc endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java
index 1b0b56bbc6,d772cb2d83..c7337299d5
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java
@@@ -34,10 -34,8 +34,11 @@@ import java.lang.reflect.GenericDeclara
  import java.lang.reflect.ParameterizedType;
  import java.lang.reflect.Modifier;
  import org.opengis.annotation.UML;
+ import org.apache.sis.pending.jdk.JDK12;
  
 +// Specific to the main branch:
 +import org.opengis.util.InternationalString;
 +
  
  /**
   * Static methods working on {@link Class} objects.

Reply via email to