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

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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new adbe2180c3 ISO 19111 upgrade: VerticalDatumType removed, replaced by 
RealizationMethod.
adbe2180c3 is described below

commit adbe2180c30699c9b6db3b843a511d0d9f11dc2d
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Apr 19 17:32:26 2024 +0200

    ISO 19111 upgrade: VerticalDatumType removed, replaced by RealizationMethod.
---
 .../apache/sis/metadata/iso/extent/Extents.java    |  66 +++---
 .../sis/metadata/iso/extent/ExtentsTest.java       |   9 +-
 .../org/apache/sis/test/mock/VerticalCRSMock.java  |  25 +--
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  24 +-
 .../main/org/apache/sis/referencing/CRS.java       |   4 +-
 .../main/org/apache/sis/referencing/CommonCRS.java |  28 +--
 .../referencing/datum/DefaultVerticalDatum.java    | 143 +++---------
 .../apache/sis/referencing/datum/package-info.java |   1 -
 .../referencing/factory/GeodeticObjectFactory.java |  13 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    |   7 -
 .../referencing/factory/sql/EPSGDataAccess.java    |  14 +-
 .../referencing/internal/VerticalDatumTypes.java   | 242 ++++++++++-----------
 .../privy/EllipsoidalHeightCombiner.java           |   2 +-
 .../referencing/privy/ReferencingUtilities.java    |   8 +-
 .../xml/bind/referencing/CD_VerticalDatumType.java |  45 ----
 .../org/apache/sis/referencing/CommonCRSTest.java  |  24 +-
 .../datum/DefaultVerticalDatumTest.java            |  43 +---
 .../sis/referencing/datum/HardCodedDatum.java      |   6 +-
 .../referencing/datum/VerticalDatum (GML 3.1).xml  |   2 +-
 .../internal/VerticalDatumTypesTest.java           |  28 +--
 .../sis/test/integration/MetadataVerticalTest.java |   2 -
 .../apache/sis/storage/netcdf/base/CRSBuilder.java |   2 +-
 geoapi/snapshot                                    |   2 +-
 23 files changed, 262 insertions(+), 478 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
index 81cb4cbb9e..2fda0bf211 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
@@ -49,7 +49,7 @@ import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.apache.sis.metadata.InvalidMetadataException;
@@ -87,7 +87,7 @@ import 
org.opengis.geometry.MismatchedReferenceSystemException;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.5
  *
  * @see org.apache.sis.geometry.Envelopes
  *
@@ -357,37 +357,29 @@ public final class Extents extends Static {
     }
 
     /**
-     * Returns the union of chosen vertical ranges found in the given extent, 
or {@code null} if none.
-     * This method gives preference to heights above the Mean Sea Level when 
possible.
-     * Depths have negative height values: if the
-     * {@linkplain 
org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getDirection() axis 
direction}
-     * is toward down, then this method reverses the sign of minimum and 
maximum values.
-     *
-     * <h4>Multi-occurrences</h4>
+     * Returns the union of a subset of vertical ranges found in the given 
extent, or {@code null} if none.
      * If the given {@code Extent} object contains more than one vertical 
extent, then this method
      * performs a choice based on the vertical datum and the unit of 
measurement:
      *
      * <ul class="verbose">
-     *   <li><p><b>Choice based on vertical datum</b><br>
-     *   Only the extents associated (indirectly, through their CRS) to the 
same non-null {@link VerticalDatumType}
-     *   will be taken in account. If all datum types are null, then this 
method conservatively uses only the first
-     *   vertical extent. Otherwise the datum type used for filtering the 
vertical extents is:</p>
+     *   <li><p><b>Choice based on realization method</b><br>
+     *   Only the extents associated (indirectly, through their CRS) to the 
same non-null {@link RealizationMethod}
+     *   will be taken in account. If all realization methods are absent, then 
this method conservatively uses only
+     *   the first vertical extent. Otherwise the realization method used for 
filtering the vertical extents is:</p>
      *
      *   <ul>
-     *     <li>{@link VerticalDatumType#GEOIDAL} or {@link 
VerticalDatumType#DEPTH DEPTH} if at least one extent
-     *         uses those datum types. For this method, {@code DEPTH} is 
considered as equivalent to {@code GEOIDAL}
-     *         except for the axis direction.</li>
-     *     <li>Otherwise, the first non-null datum type found in iteration 
order.</li>
+     *     <li>{@link RealizationMethod#GEOID} if at least one extent uses 
this realization method.</li>
+     *     <li>Otherwise, {@link RealizationMethod#TIDAL} if at least one 
extent uses this realization method.</li>
+     *     <li>Otherwise, the first non-null realization type found in 
iteration order.</li>
      *   </ul>
      *
      *   <div class="note"><b>Rational:</b> like {@linkplain 
#getGeographicBoundingBox(Extent) geographic bounding box},
      *   the vertical range is an approximated information; the range returned 
by this method does not carry any
      *   information about the vertical CRS and this method does not attempt 
to perform coordinate transformation.
-     *   But this method is more useful if the returned ranges are close to a 
frequently used surface, like the
-     *   Mean Sea Level. The same simplification is applied in the
-     *   <a 
href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#31";>{@code 
VerticalExtent} element of
-     *   Well Known Text (WKT) format</a>, which specifies that <q>Vertical 
extent is an approximate description
-     *   of location; heights are relative to an unspecified mean sea 
level.</q></div></li>
+     *   But this method is more useful if the returned ranges are close to a 
frequently used surface, like the geoid.
+     *   The same simplification is applied in the {@code VerticalExtent} 
element of Well Known Text (WKT) format,
+     *   which specifies that <q>Vertical extent is an approximate description 
of location;
+     *   heights are relative to an unspecified mean sea level.</q></div></li>
      *
      *   <li><p><b>Choice based on units of measurement</b><br>
      *   If, after the choice based on the vertical datum described above, 
there is still more than one vertical
@@ -420,21 +412,18 @@ public final class Extents extends Static {
     @SuppressWarnings("deprecation")
     public static MeasurementRange<Double> getVerticalRange(final Extent 
extent) {
         MeasurementRange<Double> range = null;
-        VerticalDatumType selectedType = null;
+        RealizationMethod selectedMethod = null;
         if (extent != null) {
             for (final VerticalExtent element : 
nonNull(extent.getVerticalElements())) {
                 double min = element.getMinimumValue();
                 double max = element.getMaximumValue();
                 final VerticalCRS crs = element.getVerticalCRS();
-                VerticalDatumType type = null;
+                RealizationMethod method = null;
                 Unit<?> unit = null;
                 if (crs != null) {
                     final VerticalDatum datum = crs.getDatum();
                     if (datum != null) {
-                        type = datum.getVerticalDatumType();
-                        if (type == VerticalDatumType.DEPTH) {
-                            type = VerticalDatumType.GEOIDAL;
-                        }
+                        method = datum.getRealizationMethod().orElse(method);
                     }
                     final CoordinateSystemAxis axis = 
crs.getCoordinateSystem().getAxis(0);
                     unit = axis.getUnit();
@@ -446,22 +435,25 @@ public final class Extents extends Static {
                 }
                 if (range != null) {
                     /*
-                     * If the new range does not specify any datum type or 
unit, then we do not know how to
-                     * convert the values before to perform the union 
operation. Conservatively do nothing.
+                     * If the new range does not specify any realization 
method or unit, we do not know how
+                     * to convert the values before to perform the union 
operation. Conservatively do nothing.
                      */
-                    if (type == null || unit == null) {
+                    if (method == null || unit == null) {
                         continue;
                     }
                     /*
                      * If the new range is not measured relative to the same 
kind of surface than the previous range,
-                     * then we do not know how to combine those ranges. Do 
nothing, unless the new range is a Mean Sea
-                     * Level Height in which case we forget all previous 
ranges and use the new one instead.
+                     * then we do not know how to combine those ranges. Do 
nothing, unless the new range is a geoidal
+                     * height in which case we forget all previous ranges and 
use the new one instead.
                      */
-                    if (!type.equals(selectedType)) {
-                        if (!type.equals(VerticalDatumType.GEOIDAL)) {
+                    if (method != selectedMethod) {
+                        if (selectedMethod == RealizationMethod.GEOID ||
+                                   (method != RealizationMethod.GEOID &&
+                                    method != RealizationMethod.TIDAL))
+                        {
                             continue;
                         }
-                    } else if (selectedType != null) {
+                    } else if (selectedMethod != null) {
                         /*
                          * If previous range did not specify any unit, then 
unconditionally replace it by
                          * the new range since it provides more information. 
If both ranges specify units,
@@ -478,7 +470,7 @@ public final class Extents extends Static {
                     }
                 }
                 range = MeasurementRange.create(min, true, max, true, unit);
-                selectedType = type;
+                selectedMethod = method;
             }
         }
         return range;
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/ExtentsTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/ExtentsTest.java
index 7aeec6045f..848979dc2f 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/ExtentsTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/ExtentsTest.java
@@ -31,6 +31,9 @@ import org.apache.sis.measure.Units;
 import org.apache.sis.measure.MeasurementRange;
 import static org.apache.sis.metadata.privy.ReferencingServices.NAUTICAL_MILE;
 
+// Specific to the geoapi-3.1 and geoapi-4.0 branches:
+import org.opengis.referencing.datum.RealizationMethod;
+
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
@@ -70,7 +73,7 @@ public final class ExtentsTest extends TestCase {
                 new DefaultVerticalExtent( -200,  -100, 
VerticalCRSMock.HEIGHT),
                 new DefaultVerticalExtent(  150,   300, VerticalCRSMock.DEPTH),
                 new DefaultVerticalExtent(  0.1,   0.2, 
VerticalCRSMock.SIGMA_LEVEL),
-                new DefaultVerticalExtent( -600,  -300, 
VerticalCRSMock.HEIGHT_ft), // [91.44 … 182.88] metres
+                new DefaultVerticalExtent( -600,  -300, 
VerticalCRSMock.HEIGHT_ft),         // [91.44 … 182.88] metres
                 new DefaultVerticalExtent(10130, 20260, 
VerticalCRSMock.BAROMETRIC_HEIGHT)
         );
         Collections.shuffle(extents, 
TestUtilities.createRandomNumberGenerator());
@@ -82,7 +85,7 @@ public final class ExtentsTest extends TestCase {
         Unit<?> unit = null;
         for (final DefaultVerticalExtent e : extents) {
             unit = 
e.getVerticalCRS().getCoordinateSystem().getAxis(0).getUnit();
-            if (Units.isLinear(unit)) break;
+            if 
(e.getVerticalCRS().getDatum().getRealizationMethod().orElse(null) == 
RealizationMethod.GEOID) break;
         }
         final UnitConverter c = unit.getConverterToAny(Units.METRE);
         /*
@@ -93,7 +96,7 @@ public final class ExtentsTest extends TestCase {
         final MeasurementRange<Double> range = 
Extents.getVerticalRange(extent);
         assertNotNull(range);
         assertSame   (unit,   range.unit());
-        assertEquals (-300,   c.convert(range.getMinDouble()), 0.001);
+        assertEquals (-200,   c.convert(range.getMinDouble()), 0.001);
         assertEquals (-91.44, c.convert(range.getMaxDouble()), 0.001);
     }
 
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/test/mock/VerticalCRSMock.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/test/mock/VerticalCRSMock.java
index 93a0221081..4b9315783c 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/test/mock/VerticalCRSMock.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/test/mock/VerticalCRSMock.java
@@ -23,7 +23,6 @@ import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.RangeMeaning;
 import org.opengis.referencing.cs.VerticalCS;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.measure.Units;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
@@ -44,47 +43,37 @@ public final class VerticalCRSMock extends 
IdentifiedObjectMock
      * Height in metres.
      */
     public static final VerticalCRS HEIGHT = new VerticalCRSMock("Height",
-            RealizationMethod.GEOID,
-            VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, 
Double.POSITIVE_INFINITY, Units.METRE, true);
+            RealizationMethod.GEOID, Double.NEGATIVE_INFINITY, 
Double.POSITIVE_INFINITY, Units.METRE, true);
 
     /**
      * Height in feet.
      */
     public static final VerticalCRS HEIGHT_ft = new VerticalCRSMock("Height",
-            RealizationMethod.GEOID,
-            VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, 
Double.POSITIVE_INFINITY, Units.FOOT, true);
+            RealizationMethod.GEOID, Double.NEGATIVE_INFINITY, 
Double.POSITIVE_INFINITY, Units.FOOT, true);
 
     /**
      * Height estimated from hPa.
      */
     public static final VerticalCRS BAROMETRIC_HEIGHT = new 
VerticalCRSMock("Barometric height",
-            RealizationMethod.LEVELLING,
-            VerticalDatumType.BAROMETRIC, 0, Double.POSITIVE_INFINITY, 
Units.HECTOPASCAL, true);
+            RealizationMethod.LEVELLING, 0, Double.POSITIVE_INFINITY, 
Units.HECTOPASCAL, true);
 
     /**
      * Depth in metres.
      */
     public static final VerticalCRS DEPTH = new VerticalCRSMock("Depth",
-            RealizationMethod.TIDAL,
-            VerticalDatumType.DEPTH, 0, Double.POSITIVE_INFINITY, Units.METRE, 
false);
+            RealizationMethod.TIDAL, 0, Double.POSITIVE_INFINITY, Units.METRE, 
false);
 
     /**
      * Depth as a fraction of the sea floor depth at the location of the point 
for which the depth is evaluated.
      */
     public static final VerticalCRS SIGMA_LEVEL = new VerticalCRSMock("Sigma 
level",
-            null,
-            VerticalDatumType.OTHER_SURFACE, 0, 1, Units.UNITY, false);
+            null, 0, 1, Units.UNITY, false);
 
     /**
      * The realization method (geoid, tidal, <i>etc.</i>), or {@code null} if 
unspecified.
      */
     private final RealizationMethod method;
 
-    /**
-     * The datum type (geoidal, barometric, etc.).
-     */
-    private final VerticalDatumType type;
-
     /**
      * The minimum and maximum values.
      */
@@ -110,11 +99,10 @@ public final class VerticalCRSMock extends 
IdentifiedObjectMock
      * @param unit          the unit of measurement.
      * @param up            {@code true} if the axis direction is up, or 
{@code false} if down.
      */
-    private VerticalCRSMock(final String name, final RealizationMethod method, 
VerticalDatumType type,
+    private VerticalCRSMock(final String name, final RealizationMethod method,
             final double minimumValue, final double maximumValue, final 
Unit<?> unit, final boolean up)
     {
         super(name);
-        this.type         = type;
         this.method       = method;
         this.minimumValue = minimumValue;
         this.maximumValue = maximumValue;
@@ -132,7 +120,6 @@ public final class VerticalCRSMock extends 
IdentifiedObjectMock
 
     @Override public String                      getAbbreviation()      
{return up ? "h" : "d";}
     @Override public Optional<RealizationMethod> getRealizationMethod() 
{return Optional.ofNullable(method);}
-    @Override public VerticalDatumType           getVerticalDatumType() 
{return type;}
     @Override public VerticalDatum               getDatum()             
{return this;}
     @Override public VerticalCS                  getCoordinateSystem()  
{return this;}
     @Override public int                         getDimension()         
{return 1;}
diff --git 
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
index 2ab59defc8..659162db6a 100644
--- 
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
@@ -832,15 +832,15 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
                     nz        = "Height";
                     direction = AxisDirection.UP;
                     if (datum instanceof VerticalDatum) {
-                        final VerticalDatumType vt = ((VerticalDatum) 
datum).getVerticalDatumType();
-                        if (vt == VerticalDatumType.GEOIDAL) {
+                        final RealizationMethod vt = ((VerticalDatum) 
datum).getRealizationMethod().orElse(null);
+                        if (vt == RealizationMethod.GEOID) {
                             nz = AxisNames.GRAVITY_RELATED_HEIGHT;
                             z  = "H";
-                        } else if (vt == VerticalDatumType.DEPTH) {
+                        } else if (vt == RealizationMethod.TIDAL) {
                             direction = AxisDirection.DOWN;
                             nz = AxisNames.DEPTH;
                             z  = "D";
-                        } else if (vt == VerticalDatumTypes.ELLIPSOIDAL) {
+                        } else if (VerticalDatumTypes.ellipsoidal(vt)) {
                             // Not allowed by ISO 19111 as a standalone axis, 
but SIS is
                             // tolerant to this case since it is sometimes 
hard to avoid.
                             nz = AxisNames.ELLIPSOIDAL_HEIGHT;
@@ -1449,16 +1449,16 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
         }
         final String name = element.pullString("name");
         @SuppressWarnings("deprecation")
-        VerticalDatumType type = null;
+        RealizationMethod method = null;
         if (isWKT1) {
-            type = VerticalDatumTypes.fromLegacy(element.pullInteger("datum"));
+            method = 
VerticalDatumTypes.fromLegacy(element.pullInteger("datum"));
         }
-        if (type == null) {
-            type = VerticalDatumTypes.guess(name, null, null);
+        if (method == null) {
+            method = VerticalDatumTypes.guess(name, null, null);
         }
         final DatumFactory datumFactory = factories.getDatumFactory();
         try {
-            return 
datumFactory.createVerticalDatum(parseAnchorAndClose(element, name), type);
+            return 
datumFactory.createVerticalDatum(parseAnchorAndClose(element, name), method);
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
@@ -1930,13 +1930,13 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
                     return crsFactory.createDerivedCRS(properties, baseCRS, 
fromBase, cs);
                 }
                 /*
-                 * The `parseVerticalDatum(…)` method may have been unable to 
resolve the datum type.
+                 * The `parseVerticalDatum(…)` method may have been unable to 
resolve the realization method.
                  * But sometimes the axis (which was not available when we 
created the datum) provides
                  * more information. Verify if we can have a better type now, 
and if so rebuild the datum.
                  */
-                if (datum.getVerticalDatumType() == 
VerticalDatumType.OTHER_SURFACE) {
+                if (datum.getRealizationMethod().isEmpty()) {
                     var type = 
VerticalDatumTypes.guess(datum.getName().getCode(), datum.getAlias(), 
cs.getAxis(0));
-                    if (type != VerticalDatumType.OTHER_SURFACE) {
+                    if (type != null) {
                         final DatumFactory datumFactory = 
factories.getDatumFactory();
                         datum = 
datumFactory.createVerticalDatum(IdentifiedObjects.getProperties(datum), type);
                     }
diff --git 
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
index 5e8ac70fa7..433ef775ab 100644
--- 
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
@@ -991,8 +991,8 @@ public final class CRS extends Static {
      * of the domain of validity of all components.
      *
      * <h4>Ellipsoidal height</h4>
-     * If a two-dimensional geographic or projected CRS if followed or 
preceded by a vertical CRS with ellipsoidal
-     * {@linkplain 
org.apache.sis.referencing.datum.DefaultVerticalDatum#getVerticalDatumType() 
datum type}, then
+     * If a two-dimensional geographic or projected CRS is followed or 
preceded by a vertical CRS with ellipsoidal
+     * {@linkplain 
org.apache.sis.referencing.datum.DefaultVerticalDatum#getRealizationMethod() 
realization method},
      * this method combines them in a single three-dimensional geographic or 
projected CRS.  Note that standalone
      * ellipsoidal heights are not allowed according ISO 19111. But if such 
situation is nevertheless found, then
      * the action described here fixes the issue. This is the reverse of 
<code>{@linkplain #getVerticalComponent
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 0a436f01a3..de5cd6e482 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -47,9 +47,9 @@ import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.PrimeMeridian;
-import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.opengis.referencing.datum.TemporalDatum;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.opengis.referencing.datum.EngineeringDatum;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
@@ -1214,7 +1214,6 @@ public enum CommonCRS {
      *   <tr><td>Mean Sea Level height</td>              <td>CRS</td>         
<td>{@link #MEAN_SEA_LEVEL}</td></tr>
      *   <tr><td>NAVD88 height</td>                      <td>CRS</td>         
<td>{@link #NAVD88}</td></tr>
      *   <tr><td>North American Vertical Datum 1988</td> <td>Datum</td>       
<td>{@link #NAVD88}</td></tr>
-     *   <tr><td>Other surface</td>                      <td>CRS, Datum</td>  
<td>{@link #OTHER_SURFACE}</td></tr>
      * </table></blockquote>
      *
      * <div class="note"><b>Note:</b>
@@ -1234,8 +1233,6 @@ public enum CommonCRS {
          * Height measured by atmospheric pressure in hectopascals (hPa).
          * Hectopascals are the units of measurement used by the worldwide 
meteorological community.
          * The datum is not specific to any location or epoch.
-         *
-         * @see VerticalDatumType#BAROMETRIC
          */
         BAROMETRIC(false, Vocabulary.Keys.BarometricAltitude, 
Vocabulary.Keys.ConstantPressureSurface),
 
@@ -1251,7 +1248,7 @@ public enum CommonCRS {
          *   <tr><th>Unit:</th>                 <td>{@link 
Units#METRE}</td></tr>
          * </table></blockquote>
          *
-         * @see VerticalDatumType#GEOIDAL
+         * @see RealizationMethod#TIDAL
          */
         MEAN_SEA_LEVEL(true, (short) 5714, (short) 5100),
 
@@ -1266,7 +1263,7 @@ public enum CommonCRS {
          *   <tr><th>Unit:</th>                 <td>{@link 
Units#METRE}</td></tr>
          * </table></blockquote>
          *
-         * @see VerticalDatumType#GEOIDAL
+         * @see RealizationMethod#TIDAL
          */
         DEPTH(true, (short) 5715, (short) 5100),
 
@@ -1303,8 +1300,9 @@ public enum CommonCRS {
          * Height measured above other kind of surface, for example a 
geological feature.
          * The unit of measurement is metres.
          *
-         * @see VerticalDatumType#OTHER_SURFACE
+         * @deprecated More specific vertical datum should be used.
          */
+        @Deprecated(since = "1.5", forRemoval = true)
         OTHER_SURFACE(false, Vocabulary.Keys.Height, 
Vocabulary.Keys.OtherSurface);
 
         /**
@@ -1334,9 +1332,8 @@ public enum CommonCRS {
          * Creates a new enumeration value of the given name.
          *
          * <h4>API design note</h4>
-         * This constructor does not expect {@link VerticalDatumType} constant 
in order to avoid too
-         * early class initialization. In particular, we do not want early 
dependency to the SIS-specific
-         * {@code VerticalDatumTypes.ELLIPSOIDAL} constant.
+         * This constructor does not expect {@link RealizationMethod} constant 
in order to avoid
+         * the creation of non-standard code list value before they are 
actually needed.
          */
         private Vertical(final boolean isEPSG, final short crs, final short 
datum) {
             this.isEPSG = isEPSG;
@@ -1377,7 +1374,6 @@ public enum CommonCRS {
          *   <!-- <del>Ellipsoidal height</del> intentionally omitted -->
          *   <tr><td>Mean Sea Level depth</td>      <td>{@link #DEPTH}</td>    
          <td>5715</td></tr>
          *   <tr><td>Mean Sea Level height</td>     <td>{@link 
#MEAN_SEA_LEVEL}</td>     <td>5714</td></tr>
-         *   <tr><td>Other surface</td>             <td>{@link 
#OTHER_SURFACE}</td>      <td></td></tr>
          * </table></blockquote>
          *
          * @return the CRS associated to this enum.
@@ -1446,7 +1442,6 @@ public enum CommonCRS {
          *   <tr><td>Barometric altitude</td>       <td>{@link 
#BAROMETRIC}</td>         <td></td></tr>
          *   <!-- <del>Ellipsoidal height</del> intentionally omitted -->
          *   <tr><td>Mean Sea Level</td>            <td>{@link 
#MEAN_SEA_LEVEL}</td>     <td>5100</td></tr>
-         *   <tr><td>Other surface</td>             <td>{@link 
#OTHER_SURFACE}</td>      <td></td></tr>
          * </table></blockquote>
          *
          * @return the datum associated to this enum.
@@ -1472,7 +1467,12 @@ public enum CommonCRS {
                         if (isEPSG) {
                             object = 
StandardDefinitions.createVerticalDatum(datum);
                         } else {
-                            object = new 
DefaultVerticalDatum(properties(datum), VerticalDatumType.valueOf(name()));
+                            // BAROMETRIC and ELLIPSOIDAL cases.
+                            RealizationMethod method = null;
+                            if (this != OTHER_SURFACE) {
+                                method = RealizationMethod.valueOf(name());
+                            }
+                            object = new 
DefaultVerticalDatum(properties(datum), method);
                         }
                         cached = object;
                     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
index f7584808d6..76e48235db 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
@@ -25,7 +25,6 @@ import jakarta.xml.bind.annotation.XmlRootElement;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.xml.bind.Context;
@@ -34,6 +33,10 @@ import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.referencing.internal.VerticalDatumTypes;
 import org.apache.sis.metadata.privy.ImplementationHelper;
 
+// Specific to the geoapi-4.0 branch:
+import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
+
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.referencing.datum.RealizationMethod;
 import org.opengis.metadata.Identifier;
@@ -59,7 +62,7 @@ import org.opengis.metadata.Identifier;
  *   <li>Create a {@code VerticalDatum} by invoking the {@code 
DatumFactory.createVerticalDatum(…)} method
  *       (implemented for example by {@link 
org.apache.sis.referencing.factory.GeodeticObjectFactory}).</li>
  *   <li>Create a {@code DefaultVerticalDatum} by invoking the
- *       {@linkplain #DefaultVerticalDatum(Map, VerticalDatumType) 
constructor}.</li>
+ *       {@linkplain #DefaultVerticalDatum(Map, RealizationMethod) 
constructor}.</li>
  * </ol>
  *
  * <b>Example:</b> the following code gets a vertical datum for height above 
the geoid:
@@ -96,16 +99,6 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      */
     private RealizationMethod method;
 
-    /**
-     * The type of this vertical datum.
-     * If {@code null}, a value will be inferred from the name by {@link 
#type()}.
-     *
-     * @see #type()
-     * @see #getVerticalDatumType()
-     */
-    @SuppressWarnings("deprecation")
-    private VerticalDatumType type;
-
     /**
      * Creates a vertical datum from the given properties. The properties map 
is given
      * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) 
super-class constructor}.
@@ -153,26 +146,10 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      *
      * @since 2.0
      */
-    @SuppressWarnings({"deprecation", "this-escape"})
+    @SuppressWarnings("this-escape")
     public DefaultVerticalDatum(final Map<String,?> properties, final 
RealizationMethod method) {
         super(properties);
         this.method = method;
-        type = VerticalDatum.super.getVerticalDatumType();
-    }
-
-    /**
-     * Creates a vertical datum from the given properties.
-     *
-     * @param  properties  the properties to be given to the identified object.
-     * @param  type        the type of this vertical datum.
-     *
-     * @deprecated As of ISO 19111:2019, the {@code VerticalDatumType} 
argument is replaced by {@code RealizationMethod}.
-     */
-    @Deprecated(since = "2.0")
-    public DefaultVerticalDatum(final Map<String,?> properties, final 
VerticalDatumType type) {
-        super(properties);
-        this.type = Objects.requireNonNull(type);
-        setRealizationMethod();
     }
 
     /**
@@ -186,13 +163,9 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      *
      * @see #castOrCopy(VerticalDatum)
      */
-    @SuppressWarnings("deprecation")
     protected DefaultVerticalDatum(final VerticalDatum datum) {
         super(datum);
-        type = datum.getVerticalDatumType();
-        if (datum instanceof DefaultVerticalDatum) {
-            method = ((DefaultVerticalDatum) datum).method;
-        }
+        method = datum.getRealizationMethod().orElse(null);
     }
 
     /**
@@ -230,70 +203,14 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      * Returns the method through which this vertical reference frame is 
realized.
      *
      * @return method through which this vertical reference frame is realized.
-     * @since 1.5
+     *
+     * @since 2.0
      */
     @Override
     public Optional<RealizationMethod> getRealizationMethod() {
         return Optional.ofNullable(method);
     }
 
-    /**
-     * Sets the realization method to a default value inferred from the legacy 
datum type.
-     */
-    @SuppressWarnings("deprecation")
-    private void setRealizationMethod() {
-        if (type == VerticalDatumType.GEOIDAL) {
-            method = RealizationMethod.GEOID;
-        } else if (type == VerticalDatumType.DEPTH) {
-            method = RealizationMethod.TIDAL;
-        } else if (type == VerticalDatumType.BAROMETRIC) {
-            method = RealizationMethod.LEVELLING;
-        }
-    }
-
-    /**
-     * Returns the type of this datum, or infers the type from the datum name 
if no type were specified.
-     * The latter case occurs after unmarshalling, since GML 3.2 does not 
contain any attribute for the datum type.
-     * It may also happen if the datum were created using reflection.
-     *
-     * <p>This method uses heuristic rules and may be changed in any future 
SIS version. If the type cannot be
-     * determined, default on the ellipsoidal type since it will usually 
implies no additional calculation.</p>
-     *
-     * <p>No synchronization needed; this is not a problem if this value is 
computed twice.
-     * This method returns only existing immutable instances.</p>
-     *
-     * @see #getVerticalDatumType()
-     * @see #getTypeElement()
-     */
-    @SuppressWarnings("deprecation")
-    private VerticalDatumType type() {
-        VerticalDatumType t = type;
-        if (t == null) {
-            final Identifier name = super.getName();
-            type = t = VerticalDatumTypes.guess(name != null ? name.getCode() 
: null, super.getAlias(), null);
-        }
-        return t;
-    }
-
-    /**
-     * Returns the type of this vertical datum.
-     *
-     * <h4>Historical note:</h4>
-     * This property was defined in the ISO 19111 specification published in 
2003,
-     * but removed from the revision published 2007.
-     * This property provides an information similar to the {@linkplain 
#getAnchorPoint() anchor definition},
-     * but in a programmatic way more suitable to coordinate transformation 
engines.
-     *
-     * @return the type of this vertical datum.
-     *
-     * @deprecated As of ISO 19111:2019, the {@code VerticalDatumType} 
argument is replaced by {@code RealizationMethod}.
-     */
-    @Override
-    @Deprecated(since = "2.0")
-    public VerticalDatumType getVerticalDatumType() {
-        return type();
-    }
-
     /**
      * Compares this vertical datum with the specified object for equality.
      *
@@ -304,7 +221,6 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      * @return {@code true} if both objects are equal.
      */
     @Override
-    @SuppressWarnings("deprecation")
     public boolean equals(final Object object, final ComparisonMode mode) {
         if (object == this) {
             return true;                                                    // 
Slight optimization.
@@ -315,19 +231,17 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
         switch (mode) {
             case STRICT: {
                 final var other = (DefaultVerticalDatum) object;
-                return Objects.equals(method, other.method) && 
type().equals(other.type());
+                return Objects.equals(method, other.method);
             }
             case BY_CONTRACT: {
                 final var other = (VerticalDatum) object;
-                return Objects.equals(getRealizationMethod(), 
other.getRealizationMethod()) &&
-                       Objects.equals(getVerticalDatumType(), 
other.getVerticalDatumType());
+                return Objects.equals(getRealizationMethod(), 
other.getRealizationMethod());
             }
             default: {
                 /*
-                 * VerticalDatumType is considered as metadata because it is 
related to the anchor definition,
+                 * RealizationMethod is considered as metadata because it is 
related to the anchor definition,
                  * which is itself considered as metadata. Furthermore, 
GeodeticObjectParser and EPSGDataAccess
-                 * do not always set this property to the same value: the 
former uses the information provided
-                 * by the coordinate system axis while the other does not.
+                 * do not always set this property to the same value, because 
of historical changes in the WKT.
                  */
                 return true;
             }
@@ -343,17 +257,17 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      */
     @Override
     protected long computeHashCode() {
-        return super.computeHashCode() + type().hashCode() + 37 * 
Objects.hashCode(method);
+        return super.computeHashCode() + 37 * Objects.hashCode(method);
     }
 
     /**
      * Formats this datum as a <i>Well Known Text</i> {@code VerticalDatum[…]} 
element.
      *
      * <h4>Compatibility note</h4>
-     * OGC 01-009 defined numerical codes for various vertical datum types, 
for example 2005 for geoidal height
-     * and 2002 for ellipsoidal height. Such codes were formatted for all 
{@code Datum} subtypes in WKT 1.
-     * Datum types became provided only for vertical datum in the ISO 
19111:2003 specification, then removed
-     * completely in ISO 19111:2007.
+     * OGC 01-009 defined numerical codes for various vertical datum types, 
for example 2005 for geoidal height.
+     * Such codes were formatted for all {@code Datum} subtypes in WKT 1. 
Datum types became specified only for
+     * vertical datum in the ISO 19111:2003 standard, then removed completely 
in the ISO 19111:2007 standard.
+     * They were reintroduced in a different form ({@link RealizationMethod}) 
in the ISO 19111:2019 standard.
      *
      * @return {@code "VerticalDatum"} (WKT 2) or {@code "Vert_Datum"} (WKT 1).
      *
@@ -363,7 +277,7 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
     protected String formatTo(final Formatter formatter) {
         super.formatTo(formatter);
         if (formatter.getConvention().majorVersion() == 1) {
-            formatter.append(VerticalDatumTypes.toLegacy(type()));
+            formatter.append(VerticalDatumTypes.toLegacy(method));
             return WKTKeywords.Vert_Datum;
         }
         return formatter.shortOrLong(WKTKeywords.VDatum, 
WKTKeywords.VerticalDatum);
@@ -399,22 +313,23 @@ public class DefaultVerticalDatum extends AbstractDatum 
implements VerticalDatum
      *
      * @see <a href="http://issues.apache.org/jira/browse/SIS-160";>SIS-160: 
Need XSLT between GML 3.1 and 3.2</a>
      */
-    @SuppressWarnings("deprecation")
     @XmlElement(name = "verticalDatumType")
-    private VerticalDatumType getTypeElement() {
-        return Context.isGMLVersion(Context.current(), 
LegacyNamespaces.VERSION_3_2) ? null : getVerticalDatumType();
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    private String getTypeElement() {
+        if (Context.isGMLVersion(Context.current(), 
LegacyNamespaces.VERSION_3_2)) {
+            return null;
+        }
+        return VerticalDatumTypes.toName(method);
     }
 
     /**
      * Invoked by JAXB only. The vertical datum type is set only if it has not 
already been specified.
      */
-    @SuppressWarnings("deprecation")
-    private void setTypeElement(final VerticalDatumType t) {
-        if (type == null) {
-            type = t;
-            setRealizationMethod();
+    private void setTypeElement(final String type) {
+        if (method == null) {
+            method = VerticalDatumTypes.fromName(type);
         } else {
-            
ImplementationHelper.propertyAlreadySet(DefaultVerticalDatum.class, 
"setTypeElement", "verticalDatumType");
+            
ImplementationHelper.propertyAlreadySet(DefaultVerticalDatum.class, "setType", 
"verticalDatumType");
         }
     }
 }
diff --git 
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
index 9a1b93de86..fa4d4444a7 100644
--- 
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,7 +69,6 @@
     @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),
diff --git 
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
index 0a7fe5b979..a3b869bed1 100644
--- 
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
@@ -891,7 +891,7 @@ public class GeodeticObjectFactory extends AbstractFactory 
implements CRSFactory
      * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, 
Unit)}</li>
      *   <li>{@link #createVerticalCS(Map, CoordinateSystemAxis)}</li>
-     *   <li>{@link #createVerticalDatum(Map, VerticalDatumType)}</li>
+     *   <li>{@link #createVerticalDatum(Map, RealizationMethod)}</li>
      * </ol>
      *
      * The default implementation creates a {@link DefaultVerticalCRS} 
instance.
@@ -922,22 +922,21 @@ public class GeodeticObjectFactory extends 
AbstractFactory implements CRSFactory
      * The default implementation creates a {@link DefaultVerticalDatum} 
instance.
      *
      * @param  properties  name and other properties to give to the new object.
-     * @param  type        the type of this vertical datum (often geoidal).
+     * @param  method      the realization method the vertical datum, or 
{@code null} if none.
      * @throws FactoryException if the object creation failed.
      *
-     * @see DefaultVerticalDatum#DefaultVerticalDatum(Map, VerticalDatumType)
+     * @see DefaultVerticalDatum#DefaultVerticalDatum(Map, RealizationMethod)
      * @see GeodeticAuthorityFactory#createVerticalDatum(String)
      *
-     * @deprecated As of ISO 19111:2019, the {@code VerticalDatumType} 
argument is replaced by {@code RealizationMethod}.
+     * @since 2.0
      */
     @Override
-    @Deprecated(since = "2.0")
     public VerticalDatum createVerticalDatum(final Map<String,?> properties,
-            final VerticalDatumType type) throws FactoryException
+            final RealizationMethod method) throws FactoryException
     {
         final DefaultVerticalDatum datum;
         try {
-            datum = new DefaultVerticalDatum(complete(properties), type);
+            datum = new DefaultVerticalDatum(complete(properties), method);
         } catch (IllegalArgumentException exception) {
             throw new InvalidGeodeticParameterException(exception);
         }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
index c3b1bfa3f0..53432a766e 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
@@ -39,7 +39,6 @@ import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.TemporalDatum;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
@@ -354,12 +353,6 @@ crs:    if (isInstance(CoordinateReferenceSystem.class, 
object)) {
                     return Set.of();
                 }
             } else {
-                if (isInstance(VerticalDatum.class, object)) {
-                    final VerticalDatumType type = ((VerticalDatum) 
object).getVerticalDatumType();
-                    if (type != null && 
!type.equals(EPSGDataAccess.VERTICAL_DATUM_TYPE)) {
-                        return Set.of();
-                    }
-                }
                 filters = new Condition[] {
                     Condition.NAME
                 };
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index ba8f9caf19..7f7a4fdf29 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -175,12 +175,6 @@ public class EPSGDataAccess extends 
GeodeticAuthorityFactory implements CRSAutho
      */
     static final Logger LOGGER = Logger.getLogger(Loggers.CRS_FACTORY);
 
-    /**
-     * The vertical datum type, which is fixed to a hard-coded value for all 
vertical datum for now.
-     * Note that vertical datum type is no longer part of ISO 19111:2007.
-     */
-    static final VerticalDatumType VERTICAL_DATUM_TYPE = 
VerticalDatumType.GEOIDAL;
-
     /**
      * EPSG codes of parameters containing the EPSG code of another object.
      * Those parameters are integers (stored as {@code double} in the database)
@@ -1717,14 +1711,8 @@ codes:  for (int i=0; i<codes.length; i++) {
                         datum = datumFactory.createGeodeticDatum(properties, 
ellipsoid, meridian);
                         break;
                     }
-                    /*
-                     * Vertical datum type is hard-coded to geoidal. It would 
be possible to infer other
-                     * types by looking at the coordinate system, but it could 
result in different datum
-                     * associated to the same EPSG code.  Since vertical datum 
type is no longer part of
-                     * ISO 19111:2007, it is probably not worth to handle such 
cases.
-                     */
                     case "vertical": {
-                        datum = datumFactory.createVerticalDatum(properties, 
VERTICAL_DATUM_TYPE);
+                        datum = datumFactory.createVerticalDatum(properties, 
null);
                         break;
                     }
                     /*
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/VerticalDatumTypes.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/VerticalDatumTypes.java
index 416435cccb..b209366666 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/VerticalDatumTypes.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/VerticalDatumTypes.java
@@ -16,136 +16,170 @@
  */
 package org.apache.sis.referencing.internal;
 
+import java.util.Locale;
 import java.util.Collection;
-import java.util.function.Predicate;
 import javax.measure.Unit;
-import org.opengis.util.CodeList;
 import org.opengis.util.GenericName;
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.CharSequences;
-import org.apache.sis.util.StringBuilders;
-import org.apache.sis.util.privy.CodeLists;
 import org.apache.sis.measure.Units;
 
 
 /**
- * Extensions to the standard set of {@link VerticalDatumType}.
+ * Extensions to the standard set of {@link RealizationEpoch}.
+ * Some of those constants are derived from a legacy {@code VerticalDatumType} 
code list.
  * Those constants are not in public API because they were intentionally 
omitted from ISO 19111,
  * and the ISO experts said that they should really not be public.
  *
- * <p>This class implements {@link Predicate} for opportunist reasons.
- * This implementation convenience may change in any future SIS version.</p>
- *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  */
-@SuppressWarnings("deprecation")
-public final class VerticalDatumTypes implements Predicate<CodeList<?>> {
+public final class VerticalDatumTypes {
     /**
-     * A vertical datum for ellipsoidal heights that are measured along the
-     * normal to the ellipsoid used in the definition of horizontal datum.
+     * A pseudo-realization method for ellipsoidal heights that are measured 
along
+     * the normal to the ellipsoid used in the definition of horizontal datum.
      *
      * <p>Identifier: {@code CS_DatumType.CS_VD_Ellipsoidal}</p>
      */
-    public static final VerticalDatumType ELLIPSOIDAL = 
VerticalDatumType.valueOf("ELLIPSOIDAL");
+    private static final String ELLIPSOIDAL = "ELLIPSOIDAL";
 
     /**
      * A vertical datum for orthometric heights that are measured along the 
plumb line.
      *
      * <p>Identifier: {@code CS_DatumType.CS_VD_Orthometric}</p>
      */
-    public static final VerticalDatumType ORTHOMETRIC = 
VerticalDatumType.valueOf("ORTHOMETRIC");
+    private static final String ORTHOMETRIC = "ORTHOMETRIC";
 
     /**
-     * Mapping from the numeric values used in legacy specification (OGC 
01-009) to {@link VerticalDatumType}.
-     * Indices in this array are the legacy codes minus 2000.
+     * A vertical datum for origin of the vertical axis based on atmospheric 
pressure.
      *
-     * <strong>This array shall not be fill before the above static 
constants.</strong>
+     * <p>Identifier: {@code CS_DatumType.CS_VD_AltitudeBarometric}</p>
      */
-    private static final VerticalDatumType[] TYPES;
+    private static final String BAROMETRIC = "BAROMETRIC";
 
     /**
-     * Mapping from {@link VerticalDatumType} to the numeric values used in 
legacy specification (OGC 01-009).
+     * Do not allow instantiation of this class.
      */
-    private static final short[] LEGACY_CODES;
-    static {
-        TYPES = new VerticalDatumType[7];
-        LEGACY_CODES = new short[Math.max(ELLIPSOIDAL.ordinal(), 
ORTHOMETRIC.ordinal()) + 1];
-        for (short code = 2000; code <= 2006; code++) {
-            final VerticalDatumType type;
-            switch (code) {
-                case 2000: type = VerticalDatumType .OTHER_SURFACE; break;  // 
CS_VD_Other
-                case 2001: type = VerticalDatumTypes.ORTHOMETRIC;   break;  // 
CS_VD_Orthometric
-                case 2002: type = VerticalDatumTypes.ELLIPSOIDAL;   break;  // 
CS_VD_Ellipsoidal
-                case 2003: type = VerticalDatumType .BAROMETRIC;    break;  // 
CS_VD_AltitudeBarometric
-                case 2005: type = VerticalDatumType .GEOIDAL;       break;  // 
CS_VD_GeoidModelDerived
-                case 2006: type = VerticalDatumType .DEPTH;         break;  // 
CS_VD_Depth
-                default:   continue;
-            }
-            TYPES[code - 2000] = type;
-            LEGACY_CODES[type.ordinal()] = code;
-        }
+    private VerticalDatumTypes() {
+    }
+
+    /**
+     * Returns a pseudo-realization method for ellipsoidal heights.
+     *
+     * @return the ellipsoidal pseudo-realization method.
+     */
+    public static RealizationMethod ellipsoidal() {
+        return RealizationMethod.valueOf(ELLIPSOIDAL);
+    }
+
+    /**
+     * Returns {@code true} if the given value is the ellipsoidal 
pseudo-realization method.
+     *
+     * @param  method  the method to test, or {@code null}.
+     * @return whether the given method is the ellipsoidal pseudo-realization 
method.
+     */
+    public static boolean ellipsoidal(final RealizationMethod method) {
+        return (method != null) && ELLIPSOIDAL.equalsIgnoreCase(method.name());
     }
 
     /**
      * Returns the vertical datum type from a legacy code. The legacy codes 
were defined in
-     * <a href="https://www.ogc.org/standards/ct";>OGC 01-009</a>
-     * (<cite>Coordinate Transformation Services)</cite>, which also defined 
the version 1 of
-     * <a 
href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html";><cite>Well
-     * Known Text</cite></a> format (WKT 1). This method is used for WKT 1 
parsing.
+     * OGC 01-009 (<cite>Coordinate Transformation Services)</cite>, which 
also defined the version 1
+     * of <cite>Well Known Text</cite></a> format (WKT 1). This method is used 
for WKT 1 parsing.
      *
      * @param  code  the legacy vertical datum code.
-     * @return the vertical datum type, or {@code null} if the code is 
unrecognized.
+     * @return the vertical datum type, or {@code null} if none.
      */
-    public static VerticalDatumType fromLegacy(int code) {
-        code -= 2000;
-        return (code >= 0 && code < TYPES.length) ? TYPES[code] : null;
+    public static RealizationMethod fromLegacy(final int code) {
+        switch (code) {
+        //  case 2000: return null;                                     // 
CS_VD_Other
+            case 2001: return RealizationMethod.valueOf(ORTHOMETRIC);   // 
CS_VD_Orthometric
+            case 2002: return ellipsoidal();                            // 
CS_VD_Ellipsoidal
+            case 2003: return RealizationMethod.valueOf(BAROMETRIC);    // 
CS_VD_AltitudeBarometric
+            case 2005: return RealizationMethod.GEOID;                  // 
CS_VD_GeoidModelDerived
+            case 2006: return RealizationMethod.TIDAL;                  // 
CS_VD_Depth
+            default:   return null;
+        }
     }
 
     /**
-     * Returns the legacy code for the datum type, or 0 if unknown.
+     * Returns the legacy code for the datum type, or 2000 (other surface) if 
unknown.
      * This method is used for WKT 1 formatting.
      *
-     * @param  type  the vertical datum type, or {@code null} if unknown.
+     * @param  method  the realization method, or {@code null} if unknown.
      * @return the legacy code for the given datum type, or 0 if unknown.
      */
-    public static int toLegacy(final VerticalDatumType type) {
-        if (type != null) {
-            final int ordinal = type.ordinal();
-            if (ordinal >= 0 && ordinal < LEGACY_CODES.length) {
-                return LEGACY_CODES[ordinal];
+    public static int toLegacy(final RealizationMethod method) {
+        if (method != null) {
+            switch (method.name()) {
+                case ORTHOMETRIC: return 2001;      // CS_VD_Orthometric
+                case ELLIPSOIDAL: return 2002;      // CS_VD_Ellipsoidal
+                case BAROMETRIC:  return 2003;      // CS_VD_AltitudeBarometric
+                case "GEOID":     return 2005;      // CS_VD_GeoidModelDerived
+                case "TIDAL":     return 2006;      // CS_VD_Depth
             }
         }
-        return 0;
+        return 2000;
+    }
+
+    /**
+     * Returns the vertical datum type from a realization method.
+     * If the given method cannot be mapped to a legacy type, then this method 
returns "other surface".
+     * This is because the vertical datum type was a mandatory property in 
legacy OGC/ISO standards.
+     *
+     * @param  method  the realization method, or {@code null}.
+     * @return the vertical datum type name (never null).
+     */
+    public static String toName(final RealizationMethod method) {
+        if (method == RealizationMethod.GEOID) return "geoidal";
+        if (method == RealizationMethod.TIDAL) return "depth";
+        if (method != null) {
+            return method.name().toLowerCase(Locale.US);
+        }
+        return "other surface";
+    }
+
+    /**
+     * Returns the realization method from a name.
+     *
+     * @param  type  the vertical datum type, or {@code null}.
+     * @return the realization method, or {@code null} if none.
+     */
+    public static RealizationMethod fromName(final String type) {
+        if ("GEOIDAL"  .equalsIgnoreCase(type)) return RealizationMethod.GEOID;
+        if ("DEPTH"    .equalsIgnoreCase(type)) return RealizationMethod.TIDAL;
+        if (BAROMETRIC .equalsIgnoreCase(type)) return 
RealizationMethod.valueOf(BAROMETRIC);
+        if (ORTHOMETRIC.equalsIgnoreCase(type)) return 
RealizationMethod.valueOf(ORTHOMETRIC);
+        if (ELLIPSOIDAL.equalsIgnoreCase(type)) return ellipsoidal();
+        return null;
     }
 
     /**
-     * Guesses the type of a datum from its name, aliases or a given vertical 
axis. This is sometimes needed
-     * after XML unmarshalling or WKT parsing, since GML 3.2 and ISO 19162 do 
not contain any attribute for
-     * the datum type.
+     * Guesses the realization method of a datum from its name, aliases or a 
given vertical axis.
+     * This is sometimes needed after XML unmarshalling or WKT parsing, 
because GML 3.2 and ISO 19162
+     * do not contain any attribute for the datum type.
      *
-     * <p>This method uses heuristic rules and may be changed in any future 
SIS version.
-     * If the type cannot be determined, defaults to {@link 
VerticalDatumType#OTHER_SURFACE}.</p>
+     * <p>This method uses heuristic rules and may be changed in any future 
SIS version.</p>
      *
      * @param  name     the name of the datum for which to guess a type, or 
{@code null} if unknown.
      * @param  aliases  the aliases of the datum for which to guess a type, or 
{@code null} if unknown.
      * @param  axis     the vertical axis for which to guess a type, or {@code 
null} if unknown.
-     * @return a datum type, or {@link VerticalDatumType#OTHER_SURFACE} if 
none can be guessed.
+     * @return a datum type, or {@code null} if none can be guessed.
      */
-    public static VerticalDatumType guess(final String name, final 
Collection<? extends GenericName> aliases,
+    public static RealizationMethod guess(final String name, final 
Collection<? extends GenericName> aliases,
             final CoordinateSystemAxis axis)
     {
-        VerticalDatumType type = guess(name);
-        if (type != null) {
-            return type;
+        RealizationMethod method = guess(name);
+        if (method != null) {
+            return method;
         }
         if (aliases != null) {
             for (final GenericName alias : aliases) {
-                type = guess(alias.tip().toString());
-                if (type != null) {
-                    return type;
+                method = guess(alias.tip().toString());
+                if (method != null) {
+                    return method;
                 }
             }
         }
@@ -156,82 +190,38 @@ public final class VerticalDatumTypes implements 
Predicate<CodeList<?>> {
                 if (abbreviation.length() == 1) {
                     AxisDirection dir = AxisDirection.UP;               // 
Expected direction for accepting the type.
                     switch (abbreviation.charAt(0)) {
-                        case 'h': type = ELLIPSOIDAL; break;
-                        case 'H': type = VerticalDatumType.GEOIDAL; break;
-                        case 'D': type = VerticalDatumType.DEPTH; dir = 
AxisDirection.DOWN; break;
-                        default:  return VerticalDatumType.OTHER_SURFACE;
+                        case 'h': method = ellipsoidal(); break;
+                        case 'H': method = RealizationMethod.GEOID; break;
+                        case 'D': method = RealizationMethod.TIDAL; dir = 
AxisDirection.DOWN; break;
+                        default:  return null;
                     }
                     if (dir.equals(axis.getDirection())) {
-                        return type;
+                        return method;
                     }
                 }
             } else if (Units.isPressure(unit)) {
-                return VerticalDatumType.BAROMETRIC;
+                return RealizationMethod.valueOf(BAROMETRIC);
             }
         }
-        return VerticalDatumType.OTHER_SURFACE;
+        return null;
     }
 
     /**
-     * Guesses the type of a datum of the given name. This method attempts to 
guess only if the given name
-     * contains at least one letter. If the type cannot be determined, returns 
{@code null}.
+     * Guesses the realization method of a datum of the given name. This 
method attempts to guess only if
+     * the given name contains at least one letter. If the type cannot be 
determined, returns {@code null}.
      *
-     * @param  name  name of the datum for which to guess a type, or {@code 
null}.
-     * @return a datum type, or {@code null} if none can be guessed.
+     * @param  name  name of the datum for which to guess a realization 
method, or {@code null}.
+     * @return a realization method, or {@code null} if none can be guessed.
      */
-    private static VerticalDatumType guess(final String name) {
+    private static RealizationMethod guess(final String name) {
         if (name != null) {
             if (CharSequences.equalsFiltered("Mean Sea Level", name, 
Characters.Filter.LETTERS_AND_DIGITS, true)) {
-                return VerticalDatumType.GEOIDAL;
+                return RealizationMethod.TIDAL;
             }
-            for (int i=0; i<name.length();) {
-                final int c = name.codePointAt(i);
-                if (Character.isLetter(c)) {
-                    return CodeLists.find(VerticalDatumType.class, new 
VerticalDatumTypes(name));
-                }
-                i += Character.charCount(c);
+            if (name.contains("geoid")) {
+                return RealizationMethod.GEOID;
             }
         }
         return null;
     }
-
-    /**
-     * The name of a datum to compare against the list of datum types,
-     * in upper-case and (if possible) using US-ASCII characters.
-     */
-    private final StringBuilder datum;
-
-    /**
-     * Creates a new {@code CodeList.Filter} which will compare the given 
datum name against the list of datum types.
-     * The comparison is case-insensitive and ignores some non-ASCII 
characters. The exact algorithm applied here is
-     * implementation dependent and may change in any future version.
-     *
-     * @param  name  the datum name.
-     */
-    private VerticalDatumTypes(final String name) {
-        final int length = name.length();
-        datum = new StringBuilder(length);
-        for (int i=0; i<length;) {
-            final int c = name.codePointAt(i);
-            datum.appendCodePoint(Character.toUpperCase(c));
-            i += Character.charCount(c);
-        }
-        StringBuilders.toASCII(datum);
-    }
-
-    /**
-     * Returns {@code true} if the name of the given code is the prefix of a 
word in the datum name.
-     * We do not test the characters following the prefix because the word may 
be incomplete
-     * (e.g. {@code "geoid"} versus {@code "geoidal"}).
-     *
-     * <p>This method is public as an implementation side-effect and should be 
ignored.</p>
-     *
-     * @param  code  the code to test.
-     * @return {@code true} if the code matches the criterion.
-      */
-    @Override
-    public boolean test(final CodeList<?> code) {
-        final int i = datum.indexOf(code.name());
-        return (i == 0) || (i >= 0 && 
Character.isWhitespace(datum.codePointBefore(i)));
-    }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/EllipsoidalHeightCombiner.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/EllipsoidalHeightCombiner.java
index 249e950938..d87655d6cc 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/EllipsoidalHeightCombiner.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/EllipsoidalHeightCombiner.java
@@ -115,7 +115,7 @@ public final class EllipsoidalHeightCombiner {
             final CoordinateReferenceSystem vertical = components[i];
             if (vertical instanceof VerticalCRS) {
                 final VerticalDatum datum = ((VerticalCRS) 
vertical).getDatum();
-                if (datum != null && datum.getVerticalDatumType() == 
VerticalDatumTypes.ELLIPSOIDAL) {
+                if (datum != null && 
VerticalDatumTypes.ellipsoidal(datum.getRealizationMethod().orElse(null))) {
                     int axisPosition = 0;
                     CoordinateSystem cs = null;
                     CoordinateReferenceSystem crs = null;
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java
index 9f2fdeab8e..c4c66b60b4 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java
@@ -36,7 +36,6 @@ import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.PrimeMeridian;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.apache.sis.util.Static;
@@ -53,6 +52,7 @@ import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
+import org.apache.sis.referencing.internal.VerticalDatumTypes;
 import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.Context;
 
@@ -218,13 +218,9 @@ public final class ReferencingUtilities extends Static {
      *
      * @see org.apache.sis.referencing.internal.VerticalDatumTypes#ELLIPSOIDAL
      */
-    @SuppressWarnings("deprecation")
     public static boolean isEllipsoidalHeight(final VerticalDatum datum) {
         if (datum != null) {
-            final VerticalDatumType type = datum.getVerticalDatumType();
-            if (type != null) {
-                return "ELLIPSOIDAL".equalsIgnoreCase(type.name());
-            }
+            return 
datum.getRealizationMethod().map(VerticalDatumTypes::ellipsoidal).orElse(false);
         }
         return false;
     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_VerticalDatumType.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_VerticalDatumType.java
deleted file mode 100644
index a6eeffe0b8..0000000000
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/xml/bind/referencing/CD_VerticalDatumType.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.xml.bind.referencing;
-
-import org.opengis.referencing.datum.VerticalDatumType;
-import org.apache.sis.xml.bind.gml.CodeListAdapter;
-
-
-/**
- * JAXB adapter for (un)marshalling of GeoAPI code list.
- *
- * @author  Martin Desruisseaux (Geomatys)
- */
-@SuppressWarnings("deprecation")
-public final class CD_VerticalDatumType extends 
CodeListAdapter<VerticalDatumType> {
-    /**
-     * Empty constructor for JAXB only.
-     */
-    public CD_VerticalDatumType() {
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @return {@code VerticalDatumType.class}
-     */
-    @Override
-    protected Class<VerticalDatumType> getCodeListClass() {
-        return VerticalDatumType.class;
-    }
-}
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
index 33cb5ac12a..c109be58ca 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
@@ -33,7 +33,7 @@ import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.TemporalDatum;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.metadata.privy.AxisNames;
 import org.apache.sis.referencing.internal.VerticalDatumTypes;
@@ -217,15 +217,15 @@ public final class CommonCRSTest extends TestCase {
     @SuppressWarnings("deprecation")
     public void testVertical() {
         for (final CommonCRS.Vertical e : CommonCRS.Vertical.values()) {
-            final VerticalDatumType datumType;
+            final RealizationMethod method;
             final String axisName, datumName;
             switch (e) {
-                case NAVD88:         axisName = 
AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 
1988"; datumType = VerticalDatumType. GEOIDAL;       break;
-                case BAROMETRIC:     axisName = "Barometric altitude";         
   datumName = "Constant pressure surface";          datumType = 
VerticalDatumType. BAROMETRIC;    break;
-                case MEAN_SEA_LEVEL: axisName = 
AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level";                 
    datumType = VerticalDatumType. GEOIDAL;       break;
-                case DEPTH:          axisName = AxisNames.DEPTH;               
   datumName = "Mean Sea Level";                     datumType = 
VerticalDatumType. GEOIDAL;       break;
-                case ELLIPSOIDAL:    axisName = AxisNames.ELLIPSOIDAL_HEIGHT;  
   datumName = "Ellipsoid";                          datumType = 
VerticalDatumTypes.ELLIPSOIDAL;   break;
-                case OTHER_SURFACE:  axisName = "Height";                      
   datumName = "Other surface";                      datumType = 
VerticalDatumType. OTHER_SURFACE; break;
+                case NAVD88:         axisName = 
AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 
1988"; method = RealizationMethod. GEOID; break;
+                case BAROMETRIC:     axisName = "Barometric altitude";         
   datumName = "Constant pressure surface";          method = 
RealizationMethod.valueOf("BAROMETRIC"); break;
+                case MEAN_SEA_LEVEL: axisName = 
AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level";                 
    method = RealizationMethod. TIDAL; break;
+                case DEPTH:          axisName = AxisNames.DEPTH;               
   datumName = "Mean Sea Level";                     method = 
RealizationMethod. TIDAL; break;
+                case ELLIPSOIDAL:    axisName = AxisNames.ELLIPSOIDAL_HEIGHT;  
   datumName = "Ellipsoid";                          method = 
VerticalDatumTypes.ellipsoidal(); break;
+                case OTHER_SURFACE:  axisName = "Height";                      
   datumName = "Other surface";                      method = null; break;
                 default: throw new AssertionError(e);
             }
             final String        name  = e.name();
@@ -233,16 +233,18 @@ public final class CommonCRSTest extends TestCase {
             final VerticalCRS   crs   = e.crs();
             if (e.isEPSG) {
                 /*
-                 * BAROMETRIC, ELLIPSOIDAL and OTHER_SURFACE uses an axis 
named "Height", which is not
-                 * a valid axis name according ISO 19111. We skip the 
validation test for those enums.
+                 * BAROMETRIC and ELLIPSOIDAL uses an axis named "Height", 
which is not a valid
+                 * axis name according ISO 19111. We skip the validation test 
for those enums.
                  */
                 Validators.validate(crs);
             }
             assertSame(datum, e.datum(), name);                         // 
Datum before CRS creation.
             assertSame(crs.getDatum(), e.datum(), name);                // 
Datum after CRS creation.
             assertEquals(datumName, datum.getName().getCode(), name);
-            assertEquals(datumType, datum.getVerticalDatumType(), name);
             assertEquals(axisName,  
crs.getCoordinateSystem().getAxis(0).getName().getCode(), name);
+            if (!e.isEPSG) {  // Because the information is not in EPSG 
database 9.x.
+                assertEquals(method, 
datum.getRealizationMethod().orElse(null), name);
+            }
         }
     }
 
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
index aba9df56ff..9de1a8749b 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
@@ -18,11 +18,10 @@ package org.apache.sis.referencing.datum;
 
 import java.util.Map;
 import java.io.InputStream;
-import java.lang.reflect.Field;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 import jakarta.xml.bind.JAXBException;
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.apache.sis.referencing.internal.VerticalDatumTypes;
 import org.apache.sis.xml.XML;
 import org.apache.sis.xml.MarshallerPool;
@@ -66,46 +65,18 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
                        : "VerticalDatum.xml");
     }
 
-    /**
-     * Tests the {@link DefaultVerticalDatum#getVerticalDatumType()} method in 
a state
-     * simulating unmarshalling of GML 3.2 document.
-     *
-     * @throws NoSuchFieldException   Should never happen.
-     * @throws IllegalAccessException Should never happen.
-     */
-    @Test
-    public void testAfterUnmarshal() throws NoSuchFieldException, 
IllegalAccessException {
-        final Field typeField = 
DefaultVerticalDatum.class.getDeclaredField("type");
-        typeField.setAccessible(true);
-        assertEquals(VerticalDatumType .GEOIDAL,       typeForName(typeField, 
"Geoidal height"));
-        assertEquals(VerticalDatumType .DEPTH,         typeForName(typeField, 
"Some depth measurement"));
-        assertEquals(VerticalDatumTypes.ELLIPSOIDAL,   typeForName(typeField, 
"Ellipsoidal height"));
-        assertEquals(VerticalDatumType .OTHER_SURFACE, typeForName(typeField, 
"NotADepth"));
-    }
-
-    /**
-     * Returns the vertical datum type inferred by {@link 
DefaultVerticalDatum} for the given name.
-     */
-    private static VerticalDatumType typeForName(final Field typeField, final 
String name) throws IllegalAccessException {
-        final var datum = new DefaultVerticalDatum(
-                Map.of(DefaultVerticalDatum.NAME_KEY, name),
-                VerticalDatumType.OTHER_SURFACE);
-        typeField.set(datum, null);
-        return datum.getVerticalDatumType();
-    }
-
     /**
      * Tests {@link DefaultVerticalDatum#toWKT()}.
      */
     @Test
     public void testToWKT() {
         DefaultVerticalDatum datum;
-        datum = new DefaultVerticalDatum(Map.of(DefaultVerticalDatum.NAME_KEY, 
"Geoidal"), VerticalDatumType.GEOIDAL);
+        datum = new DefaultVerticalDatum(Map.of(DefaultVerticalDatum.NAME_KEY, 
"Geoidal"), RealizationMethod.GEOID);
         assertWktEquals(Convention.WKT1, "VERT_DATUM[“Geoidal”, 2005]", datum);
         assertWktEquals(Convention.WKT2, "VDATUM[“Geoidal”]", datum);
         assertWktEquals(Convention.WKT2_SIMPLIFIED, 
"VerticalDatum[“Geoidal”]", datum);
 
-        datum = new DefaultVerticalDatum(Map.of(DefaultVerticalDatum.NAME_KEY, 
"Ellipsoidal"), VerticalDatumTypes.ELLIPSOIDAL);
+        datum = new DefaultVerticalDatum(Map.of(DefaultVerticalDatum.NAME_KEY, 
"Ellipsoidal"), VerticalDatumTypes.ellipsoidal());
         assertWktEquals(Convention.WKT1, "VERT_DATUM[“Ellipsoidal”, 2002]", 
datum);
         assertWktEquals(Convention.WKT2, "VDATUM[“Ellipsoidal”]", datum);
         assertWktEquals(Convention.WKT2_SIMPLIFIED, 
"VerticalDatum[“Ellipsoidal”]", datum);
@@ -120,11 +91,7 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
     public void testXML() throws JAXBException {
         final DefaultVerticalDatum datum = 
unmarshalFile(DefaultVerticalDatum.class, openTestFile(false));
         assertIsMeanSeaLevel(datum, true);
-        /*
-         * Following attribute does not exist in GML 3.2, so it has been 
inferred.
-         * Our datum name is "Mean Sea Level", which is mapped to the geoidal 
type.
-         */
-        assertEquals(VerticalDatumType.GEOIDAL, datum.getVerticalDatumType());
+        assertTrue(datum.getRealizationMethod().isEmpty());
         /*
          * Values in the following tests are specific to our XML file.
          * The actual texts in the EPSG database are more descriptive.
@@ -156,7 +123,7 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
         /*
          * Following attribute exists in GML 3.1 only.
          */
-        assertEquals(VerticalDatumType.GEOIDAL, datum.getVerticalDatumType());
+        assertEquals(RealizationMethod.GEOID, 
datum.getRealizationMethod().orElse(null));
         /*
          * The name, anchor definition and domain of validity are lost because
          * those property does not have the same XML element name (SIS-160).
diff --git 
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
index 349a4016cf..9d07d25fe0 100644
--- 
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
@@ -20,7 +20,7 @@ import java.util.Date;
 import java.util.Map;
 import java.util.HashMap;
 import org.opengis.referencing.datum.PixelInCell;
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.referencing.internal.VerticalDatumTypes;
 import org.apache.sis.measure.Units;
@@ -121,7 +121,7 @@ public final class HardCodedDatum {
     @SuppressWarnings("deprecation")
     public static final DefaultVerticalDatum ELLIPSOID = new 
DefaultVerticalDatum(
             properties("Ellipsoid", null, getScope(SPHERE)),
-            VerticalDatumTypes.ELLIPSOIDAL);
+            VerticalDatumTypes.ellipsoidal());
 
     /**
      * Mean sea level, which can be used as an approximation of geoid.
@@ -129,7 +129,7 @@ public final class HardCodedDatum {
     @SuppressWarnings("deprecation")
     public static final DefaultVerticalDatum MEAN_SEA_LEVEL = new 
DefaultVerticalDatum(
             properties("Mean Sea Level", "5100", "Hydrography."),
-            VerticalDatumType.GEOIDAL);
+            RealizationMethod.GEOID);
 
     /**
      * Default datum for time measured since January 1st, 1970 at 00:00 UTC.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/VerticalDatum
 (GML 3.1).xml 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/VerticalDatum
 (GML 3.1).xml
index 53ae73e06c..a1e2127fd3 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/VerticalDatum
 (GML 3.1).xml 
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/VerticalDatum
 (GML 3.1).xml 
@@ -48,5 +48,5 @@
     </gml:boundingBox>
   </gml:validArea>
   <gml:scope>Hydrography.</gml:scope>
-  <gml:verticalDatumType codeSpace="EPSG">geoidal</gml:verticalDatumType>
+  <gml:verticalDatumType codeSpace="OGC">geoidal</gml:verticalDatumType>
 </gml:VerticalDatum>
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/VerticalDatumTypesTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/VerticalDatumTypesTest.java
index 8a92099e5a..4061d9b3c4 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/VerticalDatumTypesTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/VerticalDatumTypesTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.referencing.internal;
 
-import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.datum.RealizationMethod;
 import org.apache.sis.util.ArraysExt;
 
 // Test dependencies
@@ -43,29 +43,29 @@ public final class VerticalDatumTypesTest extends TestCase {
      */
     @Test
     public void testFromLegacy() {
-        assertEquals(VerticalDatumTypes.ELLIPSOIDAL, 
VerticalDatumTypes.fromLegacy(2002));
-        assertEquals(VerticalDatumType .GEOIDAL,     
VerticalDatumTypes.fromLegacy(2005));
-        assertEquals(VerticalDatumType .DEPTH,       
VerticalDatumTypes.fromLegacy(2006));
+        assertEquals(VerticalDatumTypes.ellipsoidal(), 
VerticalDatumTypes.fromLegacy(2002));
+        assertEquals(RealizationMethod .GEOID,         
VerticalDatumTypes.fromLegacy(2005));
+        assertEquals(RealizationMethod .TIDAL,         
VerticalDatumTypes.fromLegacy(2006));
     }
 
     /**
-     * Tests the {@link VerticalDatumTypes#toLegacy(VerticalDatumType)} method.
+     * Tests the {@link VerticalDatumTypes#toLegacy(RealizationMethod)} method.
      */
     @Test
     public void testToLegacy() {
-        assertEquals(2002, 
VerticalDatumTypes.toLegacy(VerticalDatumTypes.ELLIPSOIDAL));
-        assertEquals(2005, VerticalDatumTypes.toLegacy(VerticalDatumType 
.GEOIDAL));
-        assertEquals(2006, VerticalDatumTypes.toLegacy(VerticalDatumType 
.DEPTH));
+        assertEquals(2002, 
VerticalDatumTypes.toLegacy(VerticalDatumTypes.ellipsoidal()));
+        assertEquals(2005, VerticalDatumTypes.toLegacy(RealizationMethod 
.GEOID));
+        assertEquals(2006, VerticalDatumTypes.toLegacy(RealizationMethod 
.TIDAL));
     }
 
     /**
-     * Tests the list of vertical datum types. Note that {@link 
#testFromLegacy()} must be executed
-     * first for ensuring {@link VerticalDatumTypes} class initialization 
prior this test.
+     * Verifies the list of realization methods.
      */
     @Test
-    public void testVerticalDatumTypes() {
-        final VerticalDatumType[] types = VerticalDatumType.values();
-        assertEquals(VerticalDatumType.OTHER_SURFACE, types[0]);
-        assertTrue(ArraysExt.contains(types, VerticalDatumTypes.ELLIPSOIDAL));
+    public void verifyCodeList() {
+        final RealizationMethod expected = VerticalDatumTypes.ellipsoidal();   
 // Must be first.
+        final RealizationMethod[] types = RealizationMethod.values();
+        assertEquals(RealizationMethod.LEVELLING, types[0]);
+        assertTrue(ArraysExt.contains(types, expected));
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataVerticalTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataVerticalTest.java
index 57d29028b3..53095b9d1c 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataVerticalTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataVerticalTest.java
@@ -35,7 +35,6 @@ import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.VerticalCS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.system.Loggers;
 import org.apache.sis.xml.NilObject;
 import org.apache.sis.xml.NilReason;
@@ -169,7 +168,6 @@ public final class MetadataVerticalTest extends 
TestCase.WithLogs {
         final VerticalDatum datum = crs.getDatum();
         verifyIdentifiers("test2", datum);
         assertEquals("World", getScope(datum));
-        assertEquals(VerticalDatumType.DEPTH, datum.getVerticalDatumType());   
 // Inferred from the name.
         final VerticalCS cs = crs.getCoordinateSystem();
         verifyIdentifiers("test3", cs);
         final CoordinateSystemAxis axis = cs.getAxis(0);
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
index 7e2b7b8173..fbd2f01bb3 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
@@ -893,7 +893,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          */
         @SuppressWarnings("deprecation")
         @Override void createDatum(DatumFactory factory, Map<String,?> 
properties) throws FactoryException {
-            datum = factory.createVerticalDatum(properties, 
VerticalDatumType.GEOIDAL);
+            datum = factory.createVerticalDatum(properties, 
RealizationMethod.GEOID);
         }
 
         /**
diff --git a/geoapi/snapshot b/geoapi/snapshot
index 792044359e..42382222dc 160000
--- a/geoapi/snapshot
+++ b/geoapi/snapshot
@@ -1 +1 @@
-Subproject commit 792044359e4e5e2140678ba89bd126f0ca6b57ce
+Subproject commit 42382222dc30ef4158fb58cc96e1a517d2c44a6b


Reply via email to