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

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

commit 87f745fce9eafaec5459187b66ca795fd4bd7c99
Merge: f78936afd0 abee1eaf35
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Nov 3 10:51:09 2026 +0100

    Merge branch 'geoapi-4.0' into geoapi-3.1.

 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 +-
 .../main/org/apache/sis/referencing/CRS.java       | 227 +++++-----
 .../main/org/apache/sis/referencing/CommonCRS.java |   2 +-
 .../referencing/EllipsoidalHeightSeparator.java    |  68 +--
 .../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 | 117 +++--
 .../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        |  12 +-
 .../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 +-
 .../main/org/apache/sis/geometries/BBox.java       |  12 +-
 .../main/org/apache/sis/geometries/Curve.java      |  20 +-
 .../apache/sis/geometries/GeometryCollection.java  |  28 +-
 .../org/apache/sis/geometries/GeometryFactory.java |   4 +
 .../main/org/apache/sis/geometries/HyperPlane.java |   2 +-
 .../main/org/apache/sis/geometries/OBBox.java      |   9 +-
 .../main/org/apache/sis/geometries/Plane.java      |   2 +-
 .../main/org/apache/sis/geometries/Point.java      |   6 +-
 .../apache/sis/geometries/adapter/JTSAdapter.java  |   6 +-
 .../org/apache/sis/geometries/adapter/Wrapper.java |  84 +---
 .../apache/sis/geometries/curve/LineString.java    |  12 +
 .../apache/sis/geometries/curve/ProductCurve.java  |  18 +
 .../org/apache/sis/geometries/index/KdTree.java    | 114 +++--
 .../internal/shared/ArrayDataPoints.java           | 129 +++---
 .../sis/geometries/internal/shared/Centroids.java  | 352 +++++++++++++++
 .../geometries/internal/shared/DefaultBezier.java  |  10 +
 .../internal/shared/DefaultConicArc.java           |   2 +-
 .../internal/shared/DefaultCurvePolygon.java       |   3 +-
 .../internal/shared/DefaultGeometryCollection.java |  72 ++--
 .../internal/shared/DefaultLineString.java         |  11 -
 .../internal/shared/DefaultMultiPoint.java         |  20 -
 .../internal/shared/DefaultNurbCurve.java          |   2 +-
 .../internal/shared/DefaultNurbSurface.java        |   2 +-
 .../internal/shared/DefaultOffsetLineString.java   | 471 +++++++++++++++++++++
 .../geometries/internal/shared/DefaultPolygon.java |  12 +-
 .../sis/geometries/internal/shared/DefaultRay.java |   2 +-
 .../internal/shared/DefaultTriangle.java           |  26 ++
 .../sis/geometries/internal/shared/Vertex.java     |  99 +++++
 .../apache/sis/geometries/mesh/MeshPrimitive.java  | 350 +++++++--------
 .../geometries/mesh/MeshPrimitiveComparator.java   |   9 +-
 .../sis/geometries/mesh/MeshPrimitiveIndexes.java  |  12 +-
 .../sis/geometries/mesh/MeshPrimitiveVisitor.java  |  48 ++-
 .../sis/geometries/mesh/MultiMeshPrimitive.java    | 147 +------
 .../sis/geometries/operation/ComputeAttribute.java |   4 +-
 .../apache/sis/geometries/operation/Contains.java  |   4 +-
 .../geometries/operation/GeometryProcessor.java    |  43 +-
 .../sis/geometries/operation/Intersection.java     |   6 +-
 .../geometries/operation/SutherlandHodgman.java    |   2 +-
 .../org/apache/sis/geometries/operation/To3D.java  |  10 +-
 .../apache/sis/geometries/operation/Transform.java |   2 +-
 .../operation/simplify/greedyinsert/WTriangle.java |   8 +-
 .../operation/spatialanalysis2d/ISOBand.java       |   4 +-
 .../operation/spatialanalysis2d/ISOLine.java       |   4 +-
 .../operation/triangulate/delaunay/Delaunay.java   |  19 +-
 .../triangulate/delaunay/OrientedEdge.java         |  23 +-
 .../triangulate/delaunay/OrientedTriangle.java     |  11 +-
 .../sis/geometries/surface/CurvePolygon.java       |  31 ++
 .../sis/geometries/surface/PolyhedralSurface.java  |  31 ++
 .../apache/sis/geometries/surface/Triangle.java    |  36 ++
 .../main/org/apache/sis/maths/AbstractArray.java   |   2 +-
 .../main/org/apache/sis/maths/AbstractCursor.java  |  20 +-
 .../main/org/apache/sis/maths/AbstractVector.java  |   2 +-
 .../main/org/apache/sis/maths/Array.java           |  21 +-
 .../org/apache/sis/maths/ArrayConcatenated.java    |  17 +-
 .../main/org/apache/sis/maths/ArrayFactory.java    |   8 +-
 .../org/apache/sis/maths/ArraySpliterator.java     |   2 +-
 .../main/org/apache/sis/maths/Cursor.java          |  10 +-
 .../org/apache/sis/maths/CursorUnmodifiable.java   |  13 +-
 .../main/org/apache/sis/maths/NDArrays.java        |  30 +-
 .../main/org/apache/sis/maths/NDRange.java         |  12 +-
 .../main/org/apache/sis/maths/Vector.java          |  95 +++--
 .../main/org/apache/sis/maths/Vector1D.java        | 131 +-----
 .../main/org/apache/sis/maths/Vector2D.java        | 142 +------
 .../main/org/apache/sis/maths/Vector3D.java        | 156 +------
 .../main/org/apache/sis/maths/Vector4D.java        | 158 +------
 ...modifiable.java => VectorAsDirectPosition.java} |  41 +-
 .../main/org/apache/sis/maths/VectorND.java        |  95 +----
 .../org/apache/sis/maths/VectorUnmodifiable.java   | 146 -------
 .../main/org/apache/sis/maths/Vectors.java         | 209 ++-------
 .../main/org/apache/sis/scene/physics/Motion.java  |   8 +-
 .../org/apache/sis/geometries/CentroidTest.java    | 345 +++++++++++++++
 .../internal/shared/ArrayDataPointsTest.java       |  59 +++
 .../shared/DefaultOffsetLineStringTest.java        | 317 ++++++++++++++
 .../sis/geometries/mesh/PrimitiveVisitorTest.java  |   3 +-
 .../sis/geometries/operation/OffsetCurveTest.java  | 129 ++++++
 .../apache/sis/geometries/operation/To3DTest.java  |   4 +-
 .../sis/geometries/operation/ToPrimitiveTest.java  |  56 +++
 .../sis/geometries/operation/TransformTest.java    |   2 +-
 .../triangulate/delaunay/OrientedEdgeTest.java     |   2 +-
 .../org/apache/sis/maths/AbstractArrayTest.java    |   2 +-
 .../org/apache/sis/maths/AbstractVectorTest.java   |  25 +-
 .../apache/sis/maths/ArrayConcatenatedTest.java    |  12 +-
 .../test/org/apache/sis/maths/NDRangeTest.java     |  10 +-
 .../test/org/apache/sis/maths/Vector3DTest.java    |   2 +-
 .../test/org/apache/sis/maths/VectorTest.java      |   6 +-
 .../test/org/apache/sis/maths/VectorXbTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXdTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXfTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXiTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXlTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXsTest.java    |   8 +-
 .../test/org/apache/sis/maths/VectorXubTest.java   |   8 +-
 .../test/org/apache/sis/maths/VectorXuiTest.java   |   8 +-
 .../test/org/apache/sis/maths/VectorXusTest.java   |   8 +-
 .../rs/internal/shared/CodeOperations.java         |  42 +-
 .../dggs/DiscreteGlobalGridCoverageProcessor.java  |   2 +-
 .../storage/dggs/DiscreteGlobalGridGeometry.java   |  18 +-
 .../storage/dggs/DiscreteGlobalGridTransform.java  |  15 +-
 .../shared/ArrayDiscreteGlobalGridCoverage.java    |   4 +-
 .../FeatureSetAsDiscreteGlobalGridResource.java    |   3 +-
 .../shared/GridAsDiscreteGlobalGridResource.java   |   3 +-
 .../shared/MemoryDiscreteGlobalGridResource.java   |  14 +-
 .../TiledDiscreteGlobalGridCoverageResource.java   |   3 +-
 .../org/apache/sis/storage/rs/CodedDerivation.java | 466 ++++++++++++++++++++
 .../org/apache/sis/storage/rs/CodedGeometry.java   |  17 +
 .../org/apache/sis/storage/rs/CodedResource.java   |   6 +
 .../rs/internal/shared/AddDimCodedResource.java    |   3 +-
 .../rs/internal/shared/ArrayCodedCoverage.java     |  11 +-
 .../storage/rs/internal/shared/CodeTransforms.java |   5 +-
 .../storage/rs/internal/shared/CodedResources.java |  82 ++++
 .../rs/internal/shared/CompoundCodedResource.java  | 184 ++++----
 .../rs/internal/shared/GridAsCodedResource.java    |   1 +
 .../rs/internal/shared/MemoryCodedResource.java    |  12 +-
 .../rs/internal/shared/ReducedCodedResource.java   | 229 ++++++++++
 .../rs/internal/shared/ResampledCodedCoverage.java |   7 +-
 .../sis/storage/rs/internal/shared/s2/Wrapper.java |   7 -
 .../sis/referencing/dggs/AbstractDggrsTest.java    |   7 +-
 .../sis/referencing/rs/CodeOperationTest.java      | 101 +++++
 .../apache/sis/storage/rs/CodedDerivationTest.java | 229 ++++++++++
 .../rs/internal/shared/CodedResourcesTest.java     | 123 ++++++
 .../internal/shared/ReducedCodedResourceTest.java  | 197 +++++++++
 optional/README.md                                 |   2 +-
 optional/src/org.apache.sis.gui/bundle/README      |   2 +-
 parent/overview.html                               |   2 +-
 parent/pom.xml                                     |   4 +-
 183 files changed, 5764 insertions(+), 2685 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java
index 826f0432a1,3da5724255..08f6552d25
--- 
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,15 -27,19 +27,19 @@@ 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.MathTransform;
  import org.opengis.referencing.operation.TransformException;
 +import org.opengis.referencing.operation.MathTransform;
  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;
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java
index de196daf8a,184477b7fc..448b726ee6
--- 
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
@@@ -54,9 -51,12 +54,9 @@@ import org.opengis.referencing.crs.Gene
  import org.opengis.filter.SpatialOperatorName;
  import org.opengis.filter.DistanceOperatorName;
  
 -// Specific to the geoapi-4.0 branch:
 -import org.opengis.referencing.crs.DerivedCRS;
 -
  
  /**
-  * Context (such as desired CRS) in which a spatial operator will be executed.
+  * Context (such as desired <abbr>CRS</abbr>) in which a spatial operator 
will be executed.
   *
   * <p>Instances of this class are immutable and thread-safe.</p>
   *
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java
index 47a7fd010e,b7ded1be96..b17187ab17
--- 
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.MathTransform;
  import org.opengis.referencing.operation.TransformException;
 +import org.opengis.referencing.operation.MathTransform;
  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/referencing/CRS.java
index 8811113bc8,2c1ae978c8..024fd3188d
--- 
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
@@@ -104,12 -94,9 +94,11 @@@ import org.apache.sis.util.internal.sha
  import org.apache.sis.util.resources.Errors;
  import org.apache.sis.util.logging.Logging;
  
 +// 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.crs.DerivedCRS;
  import org.opengis.referencing.datum.DatumEnsemble;
  import org.opengis.referencing.datum.DynamicReferenceFrame;
  import org.opengis.coordinate.CoordinateMetadata;
@@@ -543,7 -530,7 +532,7 @@@ public final class CRS 
       * Suggests a coordinate reference system which could be a common target 
for coordinate operations having the
       * given sources. This method compares the {@linkplain 
#getGeographicBoundingBox(CoordinateReferenceSystem)
       * domain of validity} of all given CRSs. If a CRS has a domain of 
validity that contains the domain of all other
--     * CRS, then that CRS is returned. Otherwise this method verifies if a 
{@linkplain DerivedCRS#getBaseCRS()
++     * CRS, then that CRS is returned. Otherwise this method verifies if a 
{@linkplain GeneralDerivedCRS#getBaseCRS()
       * base CRS} (usually a {@linkplain 
org.apache.sis.referencing.crs.DefaultGeographicCRS geographic CRS} instance)
       * would be suitable. If no suitable CRS is found, then this method 
returns {@code null}.
       *
@@@ -1133,7 -1120,7 +1122,7 @@@
      /**
       * Returns the geodetic reference frame used by the given coordinate 
reference system.
       * If the given <abbr>CRS</abbr> is a {@link GeodeticCRS}, then this 
method returns the <abbr>CRS</abbr>'s datum.
--     * If the given <abbr>CRS</abbr> is a {@link DerivedCRS} and if its base 
<abbr>CRS</abbr> is a {@link GeodeticCRS},
++     * If the given <abbr>CRS</abbr> is a {@link GeneralDerivedCRS} and if 
its base <abbr>CRS</abbr> is a {@link GeodeticCRS},
       * then this method returns the base <abbr>CRS</abbr>'s datum.
       * Otherwise, if the given <abbr>CRS</abbr> is a {@link CompoundCRS},
       * then this method performs the above checks on each component.
@@@ -1163,6 -1144,19 +1146,19 @@@
                  }
              }
          }
+         for (;;) {
+             // Need to be tested before the base CRS because a derived CRS 
can also be geodetic.
+             if (crs instanceof GeodeticCRS) {
+                 return 
Optional.ofNullable(DatumOrEnsemble.asDatum((GeodeticCRS) crs));
+             }
 -            if (crs instanceof DerivedCRS) {
++            if (crs instanceof GeneralDerivedCRS) {
+                 // Paranoic check for avoiding never-ending loop.
 -                if (crs != (crs = ((DerivedCRS) crs).getBaseCRS())) {
++                if (crs != (crs = ((GeneralDerivedCRS) crs).getBaseCRS())) {
+                     continue;
+                 }
+             }
+             break;
+         }
          return Optional.empty();
      }
  
@@@ -1271,7 -1265,7 +1267,7 @@@
           * Since this criterion matches <abbr>CRS</abbr> with the same datum,
           * it indirectly requires the matched <abbr>CRS</abbr>s to be of the 
same type ignoring specializations
           * (<i>e.g.</i>, the difference between {@link GeographicCRS} and 
geocentric <abbr>CRS</abbr> is ignored).
--         * Furthermore, a {@link DerivedCRS} is considered equivalent to its 
base <abbr>CRS</abbr>.</p>
++         * Furthermore, a {@link GeneralDerivedCRS} is considered equivalent 
to its base <abbr>CRS</abbr>.</p>
           *
           * @see SingleCRS#getDatum()
           */
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java
index 21458aa75e,de23e9e09b..ec1bfaaa8b
--- 
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
@@@ -27,6 -28,8 +28,7 @@@ import org.opengis.referencing.crs.Sing
  import org.opengis.referencing.crs.VerticalCRS;
  import org.opengis.referencing.crs.ProjectedCRS;
  import org.opengis.referencing.crs.GeodeticCRS;
 -import org.opengis.referencing.crs.GeographicCRS;
+ import org.opengis.referencing.crs.EngineeringCRS;
  import org.opengis.referencing.datum.GeodeticDatum;
  import org.opengis.referencing.operation.Conversion;
  import org.apache.sis.referencing.internal.shared.AxisDirections;
@@@ -142,11 -141,12 +143,12 @@@ final class EllipsoidalHeightSeparator 
           * we also need to reduce the number of dimensions in the base CRS 
and in the conversion.
           */
          if (crs instanceof ProjectedCRS) {
-             GeographicCRS baseCRS = ((ProjectedCRS) crs).getBaseCRS();
+             final var source = (ProjectedCRS) crs;
 -            GeodeticCRS baseCRS = source.getBaseCRS();
++            GeographicCRS baseCRS = source.getBaseCRS();
              if (CRS.getDimensionOrZero(baseCRS) != CRS.BIDIMENSIONAL) {
 -                baseCRS = (GeodeticCRS) separate(baseCRS);
 +                baseCRS = (GeographicCRS) separate(baseCRS);
              }
-             Conversion projection = ((ProjectedCRS) 
crs).getConversionFromBase();
+             Conversion projection = source.getConversionFromBase();
              /*
               * The conversion object of the given CRS has a base (source) CRS 
and a target CRS that are not
               * the ones of the new `ProjectedCRS` to create. In addition it 
has a `MathTransform` expecting
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java
index 6abfa5ce6b,a8ee20c8ee..37c7de7a2f
--- 
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
@@@ -43,6 -51,6 +51,9 @@@ import org.apache.sis.util.internal.sha
  // 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
@@@ -140,20 -140,32 +143,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, geod.getDatum(), 
geod.getDatumEnsemble(), 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);
+                     } else if (crs instanceof ProjectedCRS) {
+                         final var proj = (ProjectedCRS) crs;
 -                        GeodeticCRS base = proj.getBaseCRS();
 +                        GeographicCRS base = proj.getBaseCRS();
                          if (base.getCoordinateSystem().getDimension() == 2) {
-                             base = (GeographicCRS) createCompoundCRS(
-                                     IdentifiedObjects.getProperties(base, 
GeographicCRS.IDENTIFIERS_KEY), base, vertical);
 -                            base = (GeodeticCRS) 
createCompoundCRS(ReferencingUtilities.getPropertiesForModifiedCRS(base), base, 
vertical);
++                            base = (GeographicCRS) 
createCompoundCRS(ReferencingUtilities.getPropertiesForModifiedCRS(base), base, 
vertical);
                          }
                          /*
                           * In Apache SIS implementation, the Conversion 
contains the source and target CRS together with

Reply via email to