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