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 94cdd0cb3b Complete the support of the new WKT keywords for 
`GeographicCRS` and other CRS types. Change the default unit of measurement of 
`PARAMETER` as clarified in ISO 19162:2019. Replace usage of `Date` by 
`java.time` in WKT parsing of temporal CRS.
94cdd0cb3b is described below

commit 94cdd0cb3b68225c53773abc86b2bcfa77c4ff19
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Sep 8 11:59:11 2025 +0200

    Complete the support of the new WKT keywords for `GeographicCRS` and other 
CRS types.
    Change the default unit of measurement of `PARAMETER` as clarified in ISO 
19162:2019.
    Replace usage of `Date` by `java.time` in WKT parsing of temporal CRS.
---
 .../org/apache/sis/console/CRSCommandTest.java     |   2 +-
 .../org/apache/sis/temporal/LenientDateFormat.java |   4 +-
 .../sis/coordinate/DefaultCoordinateMetadata.java  |   2 +-
 .../main/org/apache/sis/io/wkt/Convention.java     |  57 +++----
 .../main/org/apache/sis/io/wkt/Element.java        |  16 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   4 +-
 .../main/org/apache/sis/io/wkt/Formatter.java      |  48 +++---
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  59 +++++---
 .../main/org/apache/sis/io/wkt/WKTFormat.java      |   6 +-
 .../sis/parameter/DefaultParameterValue.java       | 165 ++++++++++-----------
 .../sis/referencing/AbstractIdentifiedObject.java  |   4 +-
 .../main/org/apache/sis/referencing/CRS.java       |   2 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |   4 +
 .../sis/referencing/crs/DefaultGeodeticCRS.java    |  13 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |   4 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |   2 +-
 .../org/apache/sis/referencing/crs/DynamicCRS.java |   2 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |   2 +-
 .../referencing/factory/GeodeticObjectFactory.java |   2 +-
 .../org/apache/sis/referencing/internal/Epoch.java |  18 +--
 .../apache/sis/referencing/privy/WKTKeywords.java  |  11 +-
 .../apache/sis/referencing/privy/WKTUtilities.java |   4 +-
 .../test/org/apache/sis/io/wkt/ElementTest.java    |   4 +-
 .../sis/io/wkt/GeodeticObjectParserTest.java       |   8 +-
 .../sis/parameter/DefaultParameterValueTest.java   |   3 +-
 .../referencing/crs/DefaultCompoundCRSTest.java    |   2 +-
 .../sis/referencing/crs/DefaultDerivedCRSTest.java |   2 +-
 .../referencing/crs/DefaultGeographicCRSTest.java  |   6 +-
 .../referencing/crs/DefaultProjectedCRSTest.java   |  14 +-
 .../datum/DefaultGeodeticDatumTest.java            |   1 +
 .../apache/sis/referencing/internal/EpochTest.java |  11 +-
 .../operation/CoordinateOperationFinderTest.java   |   6 +-
 .../operation/CoordinateOperationRegistryTest.java |  10 +-
 .../DefaultConcatenatedOperationTest.java          |   4 +-
 .../DefaultCoordinateOperationFactoryTest.java     |   6 +-
 .../org/apache/sis/gui/referencing/WKTPane.java    |   2 +
 36 files changed, 272 insertions(+), 238 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
 
b/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
index ac42465ab6..9fd80d809e 100644
--- 
a/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
+++ 
b/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
@@ -43,7 +43,7 @@ public final class CRSCommandTest extends TestCase {
     public CRSCommandTest() {
         final String name = "\"WGS\\E\\s?(?:19)?\\Q84\"";                      
                 // Accept "WGS 84" or "WGS 1984".
         WGS84 = "(?m)\\Q" +                                                    
                 // Multilines.
-            "GeodeticCRS[" + name + ",\n" +
+            "GeographicCRS[" + name + ",\n" +
             "  Ensemble[\"World Geodetic System 1984\\E\\s?\\w*\\Q\",\n" +     
                 // Ignore any suffix in the name.
             "\\E(?:    Member\\[\".+\"\\],\n)+\\Q" +                           
                 // At least one MEMBER[…].
             "    Ellipsoid[" + name + ", 6378137.0, 298.257223563],\n" +
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/temporal/LenientDateFormat.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/temporal/LenientDateFormat.java
index 4649c7c3be..c564507a2b 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/temporal/LenientDateFormat.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/temporal/LenientDateFormat.java
@@ -367,7 +367,7 @@ replace:    if (Character.isWhitespace(c)) {
     @Override
     public Date parse(final String text, final ParsePosition position) {
         try {
-            return Date.from(TemporalDate.toInstant(format.parse(text, 
position), getZone()));
+            return 
TemporalDate.toDate(TemporalDate.toInstant(format.parse(text, position), 
getZone()));
         } catch (DateTimeException | ArithmeticException e) {
             position.setErrorIndex(getErrorIndex(e, position));
             return null;
@@ -384,7 +384,7 @@ replace:    if (Character.isWhitespace(c)) {
     @Override
     public Date parse(final String text) throws ParseException {
         try {
-            return Date.from(TemporalDate.toInstant(format.parse(toISO(text, 
0, text.length())), getZone()));
+            return 
TemporalDate.toDate(TemporalDate.toInstant(format.parse(toISO(text, 0, 
text.length())), getZone()));
         } catch (RuntimeException e) {
             throw (ParseException) new ParseException(e.getLocalizedMessage(), 
getErrorIndex(e, null)).initCause(e);
         }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/coordinate/DefaultCoordinateMetadata.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/coordinate/DefaultCoordinateMetadata.java
index 74911cd66b..45181647ca 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/coordinate/DefaultCoordinateMetadata.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/coordinate/DefaultCoordinateMetadata.java
@@ -199,7 +199,7 @@ public class DefaultCoordinateMetadata extends 
FormattableObject
     protected String formatTo(final Formatter formatter) {
         formatter.append(WKTUtilities.toFormattable(crs));
         if (epoch != null) {
-            formatter.append(new Epoch(epoch, false));
+            formatter.append(new Epoch(epoch, WKTKeywords.Epoch));
         }
         return WKTKeywords.CoordinateMetadata;
     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Convention.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Convention.java
index 7fc4c24e13..714363fe7f 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Convention.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Convention.java
@@ -26,9 +26,9 @@ import org.apache.sis.metadata.iso.citation.Citations;
  * This enumeration specifies whether to use the <i>Well Known Text</i> format 
defined by <abbr>ISO</abbr> 19162
  * (also known as “WKT 2”), or whether to use the format previously defined in 
OGC 01-009 (referenced as “WKT 1”).
  *
- * <h2>WKT 1 variants</h2>
- * The WKT 2 format should be parsed and formatted consistently by all 
software products.
- * But the WKT 1 format has been interpreted differently by various 
implementers.
+ * <h2><abbr title="Well Known Text">WKT</abbr> 1 variants</h2>
+ * The <abbr>WKT</abbr> 2 format should be parsed and formatted consistently 
by all software products.
+ * But the <abbr>WKT</abbr> 1 format has been interpreted differently by 
various implementers.
  * Apache SIS can adapt itself to different WKT variants, sometimes 
automatically. But some aspects cannot be guessed.
  * One noticeable source of confusion is the unit of measurement of {@code 
PRIMEM[…]} and {@code PARAMETER[…]} elements:
  *
@@ -44,7 +44,7 @@ import org.apache.sis.metadata.iso.citation.Citations;
  * Despite the first interpretation being specified by both OGC 01-009 and ISO 
19162 standards, the second
  * interpretation appears to be in wide use for WKT 1. Apache SIS uses the 
standard interpretation by default,
  * but the {@link #WKT1_COMMON_UNITS} enumeration allows parsing and 
formatting using the older interpretation.
- * The {@link #WKT1_IGNORE_AXES} enumeration mimics the most minimalist WKT 1 
parsers,
+ * The {@link #WKT1_IGNORE_AXES} enumeration mimics the most minimalist 
<abbr>WKT</abbr> 1 parsers,
  * but should be avoided when not imposed by compatibility reasons.
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -67,7 +67,7 @@ public enum Convention {
      * <p>This is the default convention used by {@link 
FormattableObject#toWKT()}
      * and for new {@link WKTFormat} instances.</p>
      */
-    WKT2(true, false),
+    WKT2(true),
 
     /**
      * The ISO 19162 format with omission of some optional elements. This 
convention is identical
@@ -100,7 +100,7 @@ public enum Convention {
      *
      * <p>This is the default convention used by {@link 
FormattableObject#toString()}.</p>
      */
-    WKT2_SIMPLIFIED(false, false),
+    WKT2_SIMPLIFIED(false),
 
     /**
      * The ISO 19162:2019 format, also known as “WKT 2”.
@@ -112,7 +112,7 @@ public enum Convention {
      *
      * @since 1.5
      */
-    WKT2_2019(true, false),
+    WKT2_2019(true),
 
     /**
      * The ISO 19162:2015 format, also known as “WKT 2”.
@@ -124,7 +124,7 @@ public enum Convention {
      *
      * @since 1.5
      */
-    WKT2_2015(true, false),
+    WKT2_2015(true),
 
     /**
      * The OGC 01-009 format, also known as “WKT 1”.
@@ -162,7 +162,7 @@ public enum Convention {
      * </table>
      * </div></div>
      */
-    WKT1(true, false),
+    WKT1(true),
 
     /**
      * The <cite>Simple Feature</cite> format, also known as “WKT 1”.
@@ -179,7 +179,7 @@ public enum Convention {
      *       (e.g. <q>meter</q> instead of <q>metre</q>).</li>
      * </ul>
      */
-    WKT1_COMMON_UNITS(true, true),
+    WKT1_COMMON_UNITS(true),
 
     /**
      * The <cite>Simple Feature</cite> format without parsing of axis elements.
@@ -196,7 +196,7 @@ public enum Convention {
      *
      * @since 0.6
      */
-    WKT1_IGNORE_AXES(true, true),
+    WKT1_IGNORE_AXES(true),
 
     /**
      * A special convention for formatting objects as stored internally by 
Apache SIS.
@@ -222,7 +222,7 @@ public enum Convention {
      * This convention is used only for debugging purpose.
      */
     @Debug
-    INTERNAL(false, false);
+    INTERNAL(false);
 
     /**
      * The default conventions.
@@ -234,25 +234,11 @@ public enum Convention {
      */
     final boolean toUpperCase;
 
-    /**
-     * {@code true} for a frequently-used convention about units instead of 
the standard one.
-     * <ul>
-     *   <li>If {@code true}, forces {@code PRIMEM} and {@code PARAMETER} 
angular units to degrees
-     *       instead of inferring the unit from the context. The standard 
value is {@code false},
-     *       which means that the angular units are inferred from the context 
as required by the
-     *       WKT 1 specification.</li>
-     *   <li>If {@code true}, uses US unit names instead of the international 
names.
-     *       For example, Americans said {@code "meter"} instead of {@code 
"metre"}.</li>
-     * </ul>
-     */
-    final boolean usesCommonUnits;
-
     /**
      * Creates a new enumeration value.
      */
-    private Convention(final boolean toUpperCase, final boolean 
usesCommonUnits) {
-        this.toUpperCase     = toUpperCase;
-        this.usesCommonUnits = usesCommonUnits;
+    private Convention(final boolean toUpperCase) {
+        this.toUpperCase = toUpperCase;
     }
 
     /**
@@ -290,6 +276,21 @@ public enum Convention {
         return this == WKT2_SIMPLIFIED || ordinal() >= WKT1.ordinal();
     }
 
+    /**
+     * {@code true} for a frequently-used convention about units instead of 
the standard one.
+     * <ul>
+     *   <li>If {@code true}, forces {@code PRIMEM} and {@code PARAMETER} 
angular units to degrees
+     *       instead of inferring the unit from the context. The standard 
value is {@code false},
+     *       which means that the angular units are inferred from the context 
as required by the
+     *       WKT 1 specification.</li>
+     *   <li>If {@code true}, uses <abbr>US</abbr> unit names instead of the 
international names.
+     *       For example, Americans said {@code "meter"} instead of {@code 
"metre"}.</li>
+     * </ul>
+     */
+    final boolean usesCommonUnits() {
+        return this == WKT1_COMMON_UNITS || this == WKT1_IGNORE_AXES;
+    }
+
     /**
      * Returns the default authority to look for when fetching identified 
object names and identifiers.
      * The difference between various authorities are most easily seen in 
projection and parameter names.
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
index e34dddbdd8..b627aaa0d0 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
@@ -16,14 +16,13 @@
  */
 package org.apache.sis.io.wkt;
 
-import java.util.Date;
 import java.util.Map;
 import java.util.Set;
 import java.util.List;
 import java.util.LinkedList;
 import java.util.Iterator;
 import java.util.Locale;
-import java.time.Instant;
+import java.time.temporal.Temporal;
 import java.text.ParsePosition;
 import java.text.ParseException;
 import org.opengis.referencing.cs.CoordinateSystem;
@@ -34,6 +33,7 @@ import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.referencing.internal.Resources;
+import org.apache.sis.temporal.TemporalDate;
 import org.apache.sis.util.privy.CollectionsExt;
 import static org.apache.sis.util.CharSequences.skipLeadingWhitespaces;
 
@@ -342,7 +342,7 @@ final class Element {
                         valueType = 
ArraysExt.containsIgnoreCase(TIME_KEYWORDS, keyword) ? TEMPORAL : NUMERIC;
                     }
                     switch (valueType) {
-                        case TEMPORAL: value = parser.parseDate  (text, 
position); break;
+                        case TEMPORAL: value = 
TemporalDate.toTemporal(parser.parseDate(text, position)); break;
                         case NUMERIC:  value = parser.parseNumber(text, 
position); break;
                         default: throw new AssertionError(valueType);          
             // Should never happen.
                     }
@@ -549,19 +549,19 @@ final class Element {
     }
 
     /**
-     * Removes the next {@link Date} from the children and returns it.
+     * Removes the next {@link Temporal} from the children and returns it.
      *
      * @param  key  the parameter name. Used for formatting an error message 
if no date is found.
-     * @return the next {@link Date} among the children.
+     * @return the next {@link Temporal} among the children.
      * @throws ParseException if no more date is available.
      */
-    public Instant pullDate(final String key) throws ParseException {
+    public Temporal pullTime(final String key) throws ParseException {
         final Iterator<Object> iterator = children.iterator();
         while (iterator.hasNext()) {
             final Object object = iterator.next();
-            if (object instanceof Date) {
+            if (object instanceof Temporal) {
                 iterator.remove();
-                return ((Date) object).toInstant();
+                return (Temporal) object;
             }
         }
         throw missingComponent(key);
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/FormattableObject.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/FormattableObject.java
index 89f6451925..d87c8bc983 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/FormattableObject.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/FormattableObject.java
@@ -220,11 +220,11 @@ public abstract class FormattableObject implements 
Printable {
      * This method is automatically invoked by {@link WKTFormat} when a 
formattable element is found.
      *
      * <p>Keywords, opening and closing brackets shall not be formatted here.
-     * For example if this formattable element is for a {@code GeodeticCRS[…]} 
element,
+     * For example if this formattable element is for a {@code 
GeographicCRS[…]} element,
      * then this method shall write the content starting at the insertion 
point shown below:</p>
      *
      * <pre class="text">
-     *   GeodeticCRS[ ]
+     *   GeographicCRS[ ]
      *               ↑
      *       (insertion point)</pre>
      *
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
index 8aa6c12db6..608d66edd6 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
@@ -85,6 +85,7 @@ import org.apache.sis.referencing.DefaultObjectDomain;
 import org.apache.sis.referencing.ImmutableIdentifier;
 import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.referencing.privy.WKTUtilities;
+import org.apache.sis.referencing.internal.Epoch;
 import org.apache.sis.referencing.internal.Resources;
 import org.apache.sis.geometry.AbstractDirectPosition;
 import org.apache.sis.geometry.AbstractEnvelope;
@@ -375,7 +376,7 @@ public class Formatter implements Localized {
         this.unitFormat       = new UnitFormat(symbols.getLocale());
         this.buffer           = new StringBuffer();
         unitFormat.setStyle(UnitFormat.Style.NAME);
-        if (convention.usesCommonUnits) {
+        if (convention.usesCommonUnits()) {
             unitFormat.setLocale(Locale.US);
         }
     }
@@ -438,7 +439,7 @@ public class Formatter implements Localized {
         this.indentation    = indentation;
         this.listSizeLimit  = listSizeLimit;
         this.transliterator = (convention == Convention.INTERNAL) ? 
Transliterator.IDENTITY : Transliterator.DEFAULT;
-        unitFormat.setLocale(convention.usesCommonUnits ? Locale.US : 
Locale.ROOT);
+        unitFormat.setLocale(convention.usesCommonUnits() ? Locale.US : 
Locale.ROOT);
     }
 
     /**
@@ -508,6 +509,8 @@ public class Formatter implements Localized {
     /**
      * Appends in the {@linkplain #buffer} the ANSI escape sequence for the 
given kind of element.
      * This method does nothing unless syntax coloring has been explicitly 
enabled.
+     *
+     * @param  type  the key of the colors to apply if syntax coloring is 
enabled, or {@code null} if none.
      */
     private void setColor(final ElementKind type) {
         if (colors != null) {
@@ -898,14 +901,13 @@ public class Formatter implements Localized {
      * {@link ReferenceSystem} and {@link CoordinateOperation} objects.
      */
     private void appendForSubtypes(final IdentifiedObject object) {
-        InternationalString anchor = null, scope = null;
-        Extent area = null;
         if (object instanceof Datum) {
-            anchor = ((Datum) object).getAnchorDefinition().orElse(null);
+            final var datum = (Datum) object;
+            appendOnNewLine(WKTKeywords.Anchor, 
datum.getAnchorDefinition().orElse(null), null);
+            datum.getAnchorEpoch().ifPresent((epoch) -> append(new 
Epoch(epoch, WKTKeywords.AnchorEpoch)));
         } else if (!(object instanceof ReferenceSystem || object instanceof 
CoordinateOperation)) {
             return;
         }
-        appendOnNewLine(WKTKeywords.Anchor, anchor, null);
         final boolean usage = convention.supports(Convention.WKT2_2019);
         for (final ObjectDomain domain : object.getDomains()) {
             if (usage) {
@@ -914,8 +916,8 @@ public class Formatter implements Localized {
                 appendFormattable(domain, DefaultObjectDomain::castOrCopy);
             } else {
                 // ISO 19162:2015
-                scope = domain.getScope();
-                area = domain.getDomainOfValidity();
+                InternationalString scope = domain.getScope();
+                Extent area = domain.getDomainOfValidity();
                 if (scope != null || area != null) {
                     append(scope, area);
                     break;
@@ -1091,10 +1093,9 @@ public class Formatter implements Localized {
      * @param  keyword  the {@linkplain KeywordCase#CAMEL_CASE camel-case} 
keyword.
      *                  Example: {@code "Scope"}, {@code "Area"} or {@code 
"Remarks"}.
      * @param  text     the text, or {@code null} if none.
-     * @param  type     the key of the colors to apply if syntax coloring is 
enabled.
+     * @param  type     the key of the colors to apply if syntax coloring is 
enabled, or {@code null} if none.
      */
     private void appendOnNewLine(final String keyword, final 
InternationalString text, final ElementKind type) {
-        ArgumentChecks.ensureNonNull("keyword", keyword);
         if (text != null) {
             String localized = text.toString(locale);
             if (localized != null && !(localized = 
localized.strip()).isEmpty()) {
@@ -1134,6 +1135,9 @@ public class Formatter implements Localized {
      * Appends the given string as a quoted text. If the given string contains 
the closing quote character,
      * that character will be doubled (WKT 2) or deleted (WKT 1). We check for 
the closing quote only because
      * it is the character that the parser will look for determining the text 
end.
+     *
+     * @param  text  the text to append.
+     * @param  type  the key of the colors to apply if syntax coloring is 
enabled, or {@code null} if none.
      */
     private void quote(String text, final ElementKind type) {
         setColor(type);
@@ -1231,7 +1235,7 @@ public class Formatter implements Localized {
         if (date != null) {
             appendSeparator();
             if (date instanceof Instant) {
-                dateFormat.format(Date.from((Instant) date), buffer, dummy);
+                dateFormat.format(TemporalDate.toDate((Instant) date), buffer, 
dummy);
             } else {
                 // Preserve the data structure (e.g. whether there is hours or 
not, timezone or not).
                 buffer.append(date);
@@ -1746,7 +1750,7 @@ public class Formatter implements Localized {
     }
 
     /**
-     * Returns {@code true} if the element at the given depth specified a 
contextual unit.
+     * Returns {@code true} if the element at the given depth has specified a 
contextual unit.
      * This method returns {@code true} if the formattable object given by 
{@code getEnclosingElement(depth)}
      * has invoked {@link #addContextualUnit(Unit)} with a non-null unit at 
least once.
      *
@@ -1770,8 +1774,9 @@ public class Formatter implements Localized {
      * <p>If the given unit is null, then this method does nothing and returns 
{@code null}.</p>
      *
      * <h4>Special case</h4>
-     * If the WKT conventions are {@code WKT1_COMMON_UNITS}, then this method 
ignores the given unit
-     * and returns {@code null}. See {@link Convention#WKT1_COMMON_UNITS} 
javadoc for more information.
+     * If the <abbr>WKT</abbr> conventions are {@code WKT1_COMMON_UNITS} or 
{@code WKT1_IGNORE_AXES},
+     * then this method ignores the given unit and returns {@code null}.
+     * See {@link Convention#WKT1_COMMON_UNITS} javadoc for more information.
      *
      * @param  <Q>   the unit quantity.
      * @param  unit  the contextual unit to add, or {@code null} if none.
@@ -1779,7 +1784,7 @@ public class Formatter implements Localized {
      */
     @SuppressWarnings("unchecked")
     public <Q extends Quantity<Q>> Unit<Q> addContextualUnit(final Unit<Q> 
unit) {
-        if (unit == null || convention.usesCommonUnits) {
+        if (unit == null || convention.usesCommonUnits()) {
             return null;
         }
         hasContextualUnit |= 1;
@@ -1807,11 +1812,11 @@ public class Formatter implements Localized {
             if (unit != null && units.remove(unit.getSystemUnit()) != unit) {
                 /*
                  * The unit that we removed was not the expected one. Probably 
the user has invoked
-                 * addContextualUnit(…) again without a matching call to 
`restoreContextualUnit(…)`.
-                 * However, this check does not work in 
`Convention.WKT1_COMMON_UNITS` mode, since the
-                 * map is always empty in that mode.
+                 * `addContextualUnit(…)` again without a matching call to 
`restoreContextualUnit(…)`.
+                 * However, this check does not work in 
`Convention.WKT1_COMMON_UNITS` mode,
+                 * because the map is always empty in that mode.
                  */
-                if (!convention.usesCommonUnits) {
+                if (!convention.usesCommonUnits()) {
                     throw new IllegalStateException();
                 }
             }
@@ -1819,10 +1824,7 @@ public class Formatter implements Localized {
         } else if (units.put(previous.getSystemUnit(), previous) != unit) {
             /*
              * The unit that we replaced was not the expected one. Probably 
the user has invoked
-             * addContextualUnit(…) again without a matching call to 
`restoreContextualUnit(…)`.
-             * Note that this case should never happen in 
`Convention.WKT1_COMMON_UNITS` mode,
-             * since `previous` should never be non-null in that mode (if the 
user followed
-             * the documented pattern).
+             * `addContextualUnit(…)` again without a matching call to 
`restoreContextualUnit(…)`.
              */
             throw new IllegalStateException();
         }
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 96e320971d..be3ca10f52 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
@@ -31,7 +31,7 @@ import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.text.ParsePosition;
 import java.text.ParseException;
-import java.time.Instant;
+import java.time.LocalDate;
 import java.time.temporal.Temporal;
 import static java.util.Collections.singletonMap;
 import javax.measure.Unit;
@@ -220,7 +220,7 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
     {
         super(sourceFile, fragments, symbols, numberFormat, dateFormat, 
unitFormat, factories, errorLocale);
         this.transliterator = transliterator;
-        usesCommonUnits = convention.usesCommonUnits;
+        usesCommonUnits = convention.usesCommonUnits();
         ignoreAxes      = convention == Convention.WKT1_IGNORE_AXES;
     }
 
@@ -515,12 +515,11 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
      * String, IdentifiedObject)} method. If an anchor has been found, its 
value is stored in the returned map.
      */
     private Map<String,Object> parseAnchorAndClose(final Element element, 
final String name) throws ParseException {
-        final Element anchor = element.pullElement(OPTIONAL, 
WKTKeywords.Anchor);
+        String   anchor = pullElementAsString(element, WKTKeywords.Anchor);
+        Temporal epoch  = Epoch.fromYear(pullElementAsDouble(element, 
WKTKeywords.AnchorEpoch, OPTIONAL), 0);
         final Map<String,Object> properties = parseMetadataAndClose(element, 
name, null);
-        if (anchor != null) {
-            properties.put(Datum.ANCHOR_DEFINITION_KEY, 
anchor.pullString("anchorDefinition"));
-            anchor.close(ignoredElements);
-        }
+        if (anchor != null) properties.put(Datum.ANCHOR_DEFINITION_KEY, 
anchor);
+        if (epoch  != null) properties.put(Datum.ANCHOR_EPOCH_KEY, epoch);
         return properties;
     }
 
@@ -593,8 +592,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
                 element.close(ignoredElements);
                 warning(parent, element, 
Errors.formatInternational(Errors.Keys.UnsupportedType_1, 
"TimeExtent[String,String]"), null);
             } else {
-                final Instant startTime = element.pullDate("startTime");
-                final Instant endTime   = element.pullDate("endTime");
+                final Temporal startTime = element.pullTime("startTime");
+                final Temporal endTime   = element.pullTime("endTime");
                 element.close(ignoredElements);
                 final var t = new DefaultTemporalExtent(startTime, endTime);
                 if (extent == null) extent = new DefaultExtent();
@@ -1267,7 +1266,7 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
         final Map<String,?> properties = parseMetadataAndClose(element, name, 
null);
         final DatumFactory datumFactory = factories.getDatumFactory();
         try {
-            if (inverseFlattening == 0) {                           // OGC 
convention for a sphere.
+            if (inverseFlattening == 0) {       // OGC and ISO 19162 
convention for a sphere.
                 return datumFactory.createEllipsoid(properties, semiMajorAxis, 
semiMajorAxis, unit);
             } else {
                 return datumFactory.createFlattenedSphere(properties, 
semiMajorAxis, inverseFlattening, unit);
@@ -1359,8 +1358,18 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
      * @throws ParseException if the {@code "Method"} element cannot be parsed.
      */
     private Conversion parseDerivingConversion(final int mode, Element parent, 
final String wrapper,
-            final Unit<?> defaultUnit, final Unit<Angle> defaultAngularUnit) 
throws ParseException
+            Unit<?> defaultUnit, Unit<Angle> defaultAngularUnit) throws 
ParseException
     {
+        /*
+         * ISO 19162:2015 was not very specific about the default units of 
measurement for parameters.
+         * ISO 19162:2019 clarified the policy by saying that default units 
should be metres or degrees.
+         * This is different than our understanding of OGC 01-009, which seems 
to inherit the units from
+         * the context.
+         */
+        if (wrapper != null) {
+            defaultUnit = Units.METRE;
+            defaultAngularUnit = Units.DEGREE;
+        }
         final String name;
         if (wrapper == null) {
             name = null;  // Will actually be ignored. WKT 1 does not provide 
name for Conversion objects.
@@ -1518,7 +1527,10 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
     private GeodeticDatum parseDatum(final int mode, final Element parent, 
final PrimeMeridian meridian, final Temporal epoch)
             throws ParseException
     {
-        final Element element = parent.pullElement(mode, WKTKeywords.Datum, 
WKTKeywords.GeodeticDatum);
+        final Element element = parent.pullElement(mode,
+                WKTKeywords.GeodeticDatum,
+                WKTKeywords.Datum,
+                WKTKeywords.TRF);
         if (element == null) {
             return null;
         }
@@ -1562,7 +1574,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
         final Element element = parent.pullElement(mode,
                 WKTKeywords.VerticalDatum,
                 WKTKeywords.VDatum,
-                WKTKeywords.Vert_Datum);
+                WKTKeywords.Vert_Datum,
+                WKTKeywords.VRF);
         if (element == null) {
             return null;
         }
@@ -1593,6 +1606,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
      *     TimeDatum["<name>", TimeOrigin[<time origin>] {,<authority>}]
      *     }
      *
+     * @todo {@code CALANDAR[…]} element is not yet supported.
+     *
      * @param  mode    {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
      * @param  parent  the parent element.
      * @return the {@code "TimeDatum"} element as a {@link TemporalDatum} 
object.
@@ -1603,10 +1618,16 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
         if (element == null) {
             return null;
         }
-        final String  name   = element.pullString ("name");
-        final Element origin = element.pullElement(MANDATORY, 
WKTKeywords.TimeOrigin);
-        final Instant epoch  = origin .pullDate("origin");
-        origin.close(ignoredElements);
+        final String   name = element.pullString ("name");
+        final Element  origin = element.pullElement(OPTIONAL, 
WKTKeywords.TimeOrigin);
+        final Temporal epoch;
+        if (origin != null) {
+            epoch = origin .pullTime("origin");
+            origin.close(ignoredElements);
+        } else {
+            // Default to the date of signing of the Convention du Mètre (from 
ISO 19162:2019 specification)
+            epoch = LocalDate.of(1875, 5, 20);
+        }
         final DatumFactory datumFactory = factories.getDatumFactory();
         try {
             return 
datumFactory.createTemporalDatum(parseAnchorAndClose(element, name), epoch);
@@ -2068,8 +2089,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
                  * 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.
                  *
-                 * TODO: remove this hack. It is mostly for old standard. The 
check for dynamic datum
-                 * is a dirty trick for checking if we have a newer standard.
+                 * Note: we exclude the reconstruction of dynamic datum for 
simplicity in the use of the factory.
+                 * This block is a dirty trick anyway (a workaround for a 
metadata excluded from the WKT standard).
                  */
                 if (method == null && datum != null && !(datum instanceof 
DynamicReferenceFrame)) {
                     var type = 
VerticalDatumTypes.fromDatum(datum.getName().getCode(), datum.getAlias(), 
cs.getAxis(0));
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
index 72c02f399d..e3fa29c0a6 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
@@ -89,14 +89,14 @@ import org.opengis.metadata.Identifier;
  *
  * <h3>Example</h3>
  * In the example below, the {@code $WGS84} substring which appear in the 
argument given to the
- * {@code parseObject(…)} method will be expanded into the full {@code 
GeodeticCRS[“WGS84”, …]}
+ * {@code parseObject(…)} method will be expanded into the full {@code 
GeographicCRS[“WGS84”, …]}
  * string before the parsing proceed.
  *
  * <blockquote><code>
  * {@linkplain #addFragment addFragment}("deg", "AngleUnit[“degree”, 
0.0174532925199433]");<br>
  * {@linkplain #addFragment addFragment}("lat", "Axis[“Latitude”, NORTH, 
<strong>$deg</strong>]");<br>
  * {@linkplain #addFragment addFragment}("lon", "Axis[“Longitude”, EAST, 
<strong>$deg</strong>]");<br>
- * {@linkplain #addFragment addFragment}("MyBaseCRS", "GeodeticCRS[“WGS84”, 
Datum[</code> <i>…etc…</i> <code>],
+ * {@linkplain #addFragment addFragment}("MyBaseCRS", "GeographicCRS[“WGS84”, 
Datum[</code> <i>…etc…</i> <code>],
  * CS[</code> <i>…etc…</i> <code>], <strong>$lat</strong>, 
<strong>$lon</strong>]");<br>
  * Object crs = {@linkplain #parseObject(String) 
parseObject}("ProjectedCRS[“Mercator_1SP”, <strong>$MyBaseCRS</strong>,
  * </code> <i>…etc…</i> <code>]");
@@ -858,7 +858,7 @@ public class WKTFormat extends CompoundFormat<Object> {
      * (WKT after the ellipsoid omitted for brevity):
      *
      * {@snippet lang="java" :
-     *     Object crs = parseObject("GeodeticCRS[“Tokyo”, Datum[“Tokyo”, 
$MyEllipsoid], …]");
+     *     Object crs = parseObject("GeographicCRS[“Tokyo”, Datum[“Tokyo”, 
$MyEllipsoid], …]");
      *     }
      *
      * For removing a fragment, use <code>{@linkplain 
#getFragmentNames()}.remove(name)</code>.
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
index 315009eda6..4467e9c98e 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
@@ -38,6 +38,7 @@ import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.InvalidParameterTypeException;
 import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.operation.MathTransform;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.Convention;
@@ -51,6 +52,7 @@ import org.apache.sis.referencing.internal.Resources;
 import org.apache.sis.referencing.privy.WKTUtilities;
 import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.math.DecimalFunctions;
+import org.apache.sis.measure.Units;
 import org.apache.sis.system.Loggers;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.ArgumentChecks;
@@ -1058,7 +1060,7 @@ convert:            if (componentType != null) {
      * <p><b>WKT 2:</b></p>
      * {@snippet lang="wkt" :
      *   ProjectedCRS[…
-     *     BaseGeodCRS[…
+     *     BaseGeogCRS[…
      *       AngleUnit[“grad”, 0.015707963267948967]],
      *     Conversion[“Lambert zone II”,
      *       Method[“Lambert Conic Conformal (1SP)”],
@@ -1088,105 +1090,98 @@ convert:            if (componentType != null) {
                 return WKTKeywords.ParameterFile;
             } else {
                 formatter.appendAny(value);
+                return WKTKeywords.Parameter;
             }
-        } else {
+        }
+        /*
+         * In the WKT 1 specification, the unit of measurement is given by the 
context.
+         * If this parameter value does not use the same unit, we will need to 
convert it.
+         * Otherwise we can write the value as-is.
+         *
+         * Note that we take the descriptor unit as a starting point instead 
of this parameter unit
+         * in order to give precedence to the descriptor units in 
Convention.WKT1_COMMON_UNITS mode.
+         */
+        Unit<?> contextualUnit;
+        if (descriptor == null || (contextualUnit = descriptor.getUnit()) == 
null) {
+            // Should be very rare (probably a buggy descriptor), but we try 
to be safe.
+            contextualUnit = unit;
+        }
+        contextualUnit = formatter.toContextualUnit(contextualUnit);
+        if (isWKT1) {
+            unit = contextualUnit;
+        } else if (convention != Convention.INTERNAL) {
+            unit = WKTUtilities.toFormattable(unit);
+        }
+        double value;
+        try {
+            value = doubleValue(unit);
+        } catch (IllegalStateException exception) {
             /*
-             * In the WKT 1 specification, the unit of measurement is given by 
the context.
-             * If this parameter value does not use the same unit, we will 
need to convert it.
-             * Otherwise we can write the value as-is.
-             *
-             * Note that we take the descriptor unit as a starting point 
instead of this parameter unit
-             * in order to give precedence to the descriptor units in 
Convention.WKT1_COMMON_UNITS mode.
+             * May happen if a parameter is mandatory (e.g. "semi-major") but 
no value has been set for this parameter.
+             * The name of the problematic parameter (needed for producing an 
error message) is given by the descriptor.
+             * Null descriptor should be illegal but may happen after 
unmarshalling of invalid GML.
+             * We make this WKT formatting robust since it is used by 
`toString()` implementation.
              */
-            Unit<?> contextualUnit;
-            if (descriptor == null || (contextualUnit = descriptor.getUnit()) 
== null) {
-                // Should be very rare (probably a buggy descriptor), but we 
try to be safe.
-                contextualUnit = unit;
-            }
-            contextualUnit = formatter.toContextualUnit(contextualUnit);
-            boolean ignoreUnits;
-            if (isWKT1) {
-                unit = contextualUnit;
-                ignoreUnits = true;
+            if (descriptor != null) {
+                formatter.setInvalidWKT(descriptor, exception);
             } else {
-                if (convention != Convention.INTERNAL) {
-                    unit = WKTUtilities.toFormattable(unit);
-                }
-                ignoreUnits = unit.equals(contextualUnit);
+                formatter.setInvalidWKT(DefaultParameterValue.class, 
exception);
             }
-            double value;
-            try {
-                value = doubleValue(unit);
-            } catch (IllegalStateException exception) {
+            value = Double.NaN;
+        }
+        formatter.append(value);
+        /*
+         * In the WKT 2 specification, the unit and the identifier are 
optional but recommended.
+         * We follow that recommendation in strict WKT2 mode, but omit unit in 
non-strict modes.
+         * Except if the parameter unit is not the same as the contextual 
unit, in which case it
+         * is not possible to omit the unit (unless the value is the same in 
both units, like 0).
+         */
+        boolean ignoreUnits = false;
+        if (convention.isSimplified()) {
+            /*
+             * The contextual units may be defined either in the direct 
parent, or in the parent of the parent,
+             * depending if we are formatting WKT 1 or WKT 2 respectively. 
This is because WKT 2 wraps the
+             * parameters in an additional `CONVERSION[…]` element which is 
not present in WKT 1.
+             * Taking the example documented in the Javadoc of this method:
+             *
+             * - in WKT 1, `PROJCS[…]` is the immediate parent of 
`PARAMETER[…]`, but
+             * - in WKT 2, `ProjectedCRS[…]` is the parent of `Conversion[…]`,
+             *   which is the parent of `Parameter[…]`.
+             */
+            if (formatter.hasContextualUnit(isWKT1 ? 1 : 2) ||
+                formatter.getEnclosingElement(1) instanceof MathTransform)
+            {
+                ignoreUnits = Double.isNaN(value)
+                        ? unit.equals(contextualUnit)
+                        : doubleValue(contextualUnit) == value;   // 
Equivalent to above line but more aggressive.
                 /*
-                 * May happen if a parameter is mandatory (e.g. "semi-major")
-                 * but no value has been set for this parameter.
+                 * ISO 19162:2019 became more restrictive than older standards 
about contextual units in parameters.
+                 * For avoiding ambiguity, allow the omission only for decimal 
degrees and base units.
                  */
-                if (descriptor != null) {
-                    formatter.setInvalidWKT(descriptor, exception);
-                } else {
-                    /*
-                     * Null descriptor should be illegal but may happen after 
unmarshalling of invalid GML.
-                     * We make this WKT formatting robust since it is used by 
'toString()' implementation.
-                     */
-                    formatter.setInvalidWKT(DefaultParameterValue.class, 
exception);
+                if (ignoreUnits && !isWKT1) {
+                    ignoreUnits = Units.isAngular(unit)
+                            ? Units.DEGREE.equals(unit)
+                            : Units.toStandardUnit(unit) == 1;
                 }
-                value = Double.NaN;
-            }
-            formatter.append(value);
-            /*
-             * In the WKT 2 specification, the unit and the identifier are 
optional but recommended.
-             * We follow that recommendation in strict WKT2 mode, but omit 
them in non-strict modes.
-             * The only exception is when the parameter unit is not the same 
as the contextual unit,
-             * in which case we have no choice: we must format that unit, 
unless the numerical value
-             * is identical in both units (typically the 0 value).
-             */
-            if (!ignoreUnits && !Double.isNaN(value)) {
-                // Test equivalent to unit.equals(contextualUnit) but more 
aggressive.
-                ignoreUnits = Numerics.equals(value, 
doubleValue(contextualUnit));
-            }
-            if (ignoreUnits && convention != Convention.INTERNAL) {
-                // One last check about if we are really allowed to ignore 
units.
-                ignoreUnits = convention.isSimplified() && 
hasContextualUnit(formatter);
             }
-            if (!ignoreUnits) {
-                if (!isWKT1) {
-                    formatter.append(unit);
-                } else if (!ignoreUnits) {
-                    if (descriptor != null) {
-                        formatter.setInvalidWKT(descriptor, null);
-                    } else {
-                        /*
-                         * Null descriptor should be illegal but may happen 
after unmarshalling of invalid GML.
-                         * We make this WKT formatting robust since it is used 
by 'toString()' implementation.
-                         */
-                        formatter.setInvalidWKT(DefaultParameterValue.class, 
null);
-                    }
-                }
+        }
+        if (!ignoreUnits) {
+            if (!isWKT1) {
+                formatter.append(unit);
+            } else if (descriptor != null) {
+                formatter.setInvalidWKT(descriptor, null);
+            } else {
+                /*
+                 * Null descriptor should be illegal but may happen after 
unmarshalling of invalid GML.
+                 * We make this WKT formatting robust since it is used by 
`toString()` implementation.
+                 */
+                formatter.setInvalidWKT(DefaultParameterValue.class, null);
             }
         }
         // ID will be added by the Formatter itself.
         return WKTKeywords.Parameter;
     }
 
-    /**
-     * Returns {@code true} if the given formatter has contextual units, in 
which case the WKT format can omit
-     * the unit of measurement. The contextual units may be defined either in 
the direct parent or in the parent
-     * of the parent, depending if we are formatting WKT1 or WKT2 
respectively. This is because WKT2 wraps the
-     * parameters in an additional {@code CONVERSION[…]} element which is not 
present in WKT1.
-     *
-     * <p>Taking the example documented in {@link #formatTo(Formatter)}:</p>
-     * <ul>
-     *   <li>in WKT 1, {@code PROJCS[…]} is the immediate parent of {@code 
PARAMETER[…]}, but</li>
-     *   <li>in WKT 2, {@code ProjectedCRS[…]} is the parent of {@code 
Conversion[…]},
-     *       which is the parent of {@code Parameter[…]}.</li>
-     * </ul>
-     */
-    private static boolean hasContextualUnit(final Formatter formatter) {
-        return formatter.hasContextualUnit(1) ||    // In WKT1
-               formatter.hasContextualUnit(2);      // In WKT2
-    }
-
 
 
 
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java
index 720f251bcb..645680f0de 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java
@@ -891,13 +891,13 @@ public class AbstractIdentifiedObject extends 
FormattableObject implements Ident
      * </ul>
      *
      * Keywords and metadata (scope, extent, identifier and remarks) shall not 
be formatted here.
-     * For example if this formattable element is for a {@code GeodeticCRS[…]} 
element,
+     * For example if this formattable element is for a {@code 
GeographicCRS[…]} element,
      * then subclasses shall write the content starting at the insertion point 
shown below:
      *
      * <div class="horizontal-flow">
      * <div><p><b>WKT example</b></p>
      * <pre class="text">
-     *   GeodeticCRS["WGS 84", ID["EPSG", 4326]]
+     *   GeographicCRS["WGS 84", ID["EPSG", 4326]]
      *                       ↑
      *               (insertion point)</pre>
      * </div><div>
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 85a52f9802..a534aeacc8 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
@@ -304,7 +304,7 @@ public final class CRS extends Static {
      *
      * {@snippet lang="wkt" :
      *   ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
-     *     BaseGeodCRS["SIRGAS 2000",
+     *     BaseGeogCRS["SIRGAS 2000",
      *       Datum["Sistema de Referencia Geocentrico para las Americas 2000",
      *         Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
      *     Conversion["Petrobras Mercator",
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
index 72119d0ec0..fb7b9fd5c6 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
@@ -36,6 +36,7 @@ import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.crs.EngineeringCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.VerticalCS;
 import org.opengis.referencing.cs.TimeCS;
 import org.opengis.referencing.operation.Conversion;
@@ -680,6 +681,9 @@ public class DefaultDerivedCRS extends AbstractDerivedCRS 
implements DerivedCRS
 
         /** Returns the WKT keyword for this derived CRS type. */
         @Override String keyword(final Formatter formatter) {
+            if (formatter.getConvention().supports(Convention.WKT2_2019) && 
getCoordinateSystem() instanceof EllipsoidalCS) {
+                return formatter.shortOrLong(WKTKeywords.GeogCRS, 
WKTKeywords.GeographicCRS);
+            }
             return formatter.shortOrLong(WKTKeywords.GeodCRS, 
WKTKeywords.GeodeticCRS);
         }
 
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
index bbc1e2e742..7071186029 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
@@ -173,7 +173,7 @@ class DefaultGeodeticCRS extends 
AbstractSingleCRS<GeodeticDatum> implements Geo
     }
 
     /**
-     * Formats this CRS as a <i>Well Known Text</i> {@code GeodeticCRS[…]} 
element.
+     * Formats this CRS as a <i>Well Known Text</i> {@code GeodeticCRS[…]} or 
{@code GeographicCRS[…]} element.
      * More information about the WKT format is documented in subclasses.
      *
      * @return {@code "GeodeticCRS"} (WKT 2) or {@code "GeogCS"}/{@code 
"GeocCS"} (WKT 1).
@@ -184,8 +184,8 @@ class DefaultGeodeticCRS extends 
AbstractSingleCRS<GeodeticDatum> implements Geo
         CoordinateSystem cs = getCoordinateSystem();
         final Convention convention = formatter.getConvention();
         final boolean isWKT1 = (convention.majorVersion() == 1);
-        final boolean isGeographicWKT1 = isWKT1 && (cs instanceof 
EllipsoidalCS);
-        if (isGeographicWKT1 && cs.getDimension() == 3) {
+        final boolean isGeographic = (cs instanceof EllipsoidalCS);
+        if (isWKT1 && isGeographic && cs.getDimension() == 3) {
             /*
              * Version 1 of WKT format did not have three-dimensional 
GeographicCRS. Instead, such CRS were formatted
              * as a CompoundCRS made of a two-dimensional GeographicCRS with a 
VerticalCRS for the ellipsoidal height.
@@ -237,7 +237,7 @@ class DefaultGeodeticCRS extends 
AbstractSingleCRS<GeodeticDatum> implements Geo
          */
         final boolean isBaseCRS;
         if (isWKT1) {
-            if (!isGeographicWKT1) {                        // If not 
geographic, then presumed geocentric.
+            if (!isGeographic) {                            // If not 
geographic, then presumed geocentric.
                 if (cs instanceof CartesianCS) {
                     cs = Legacy.forGeocentricCRS((CartesianCS) cs, true);
                 } else {
@@ -271,7 +271,10 @@ class DefaultGeodeticCRS extends 
AbstractSingleCRS<GeodeticDatum> implements Geo
          * have a GeodeticCRS. We need to make the choice in this base class. 
The CS type is a sufficient criterion.
          */
         if (isWKT1) {
-            return isGeographicWKT1 ? WKTKeywords.GeogCS : WKTKeywords.GeocCS;
+            return isGeographic ? WKTKeywords.GeogCS : WKTKeywords.GeocCS;
+        } else if (isGeographic && convention.supports(Convention.WKT2_2019)) {
+            return isBaseCRS ? WKTKeywords.BaseGeogCRS
+                   : formatter.shortOrLong(WKTKeywords.GeogCRS, 
WKTKeywords.GeographicCRS);
         } else {
             return isBaseCRS ? WKTKeywords.BaseGeodCRS
                    : formatter.shortOrLong(WKTKeywords.GeodCRS, 
WKTKeywords.GeodeticCRS);
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
index 72cd05a3d1..219b2fda34 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
@@ -366,14 +366,14 @@ public class DefaultGeographicCRS extends 
DefaultGeodeticCRS implements Geograph
     }
 
     /**
-     * Formats this CRS as a <i>Well Known Text</i> {@code GeodeticCRS[…]} 
element.
+     * Formats this CRS as a <i>Well Known Text</i> {@code GeographicCRS[…]} 
element.
      *
      * <h4>Example</h4>
      * Well-Known Text (version 2)
      * of a geographic coordinate reference system using the WGS 84 datum.
      *
      * {@snippet lang="wkt" :
-     *   GeodeticCRS["WGS 84",
+     *   GeographicCRS["WGS 84",
      *      Datum["World Geodetic System 1984",
      *        Ellipsoid["WGS84", 6378137.0, 298.257223563, LengthUnit["metre", 
1]]],
      *        PrimeMeridian["Greenwich", 0.0, AngleUnit["degree", 
0.017453292519943295]],
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
index bc289ee30f..d07064f1b0 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
@@ -338,7 +338,7 @@ public class DefaultProjectedCRS extends AbstractDerivedCRS 
implements Projected
      *
      * {@snippet lang="wkt" :
      *   ProjectedCRS[“NTF (Paris) / Lambert zone II”,
-     *     BaseGeodCRS[“NTF (Paris)”,
+     *     BaseGeogCRS[“NTF (Paris)”,
      *       Datum[“Nouvelle Triangulation Francaise”,
      *         Ellipsoid[“NTF”, 6378249.2, 293.4660212936269, 
LengthUnit[“metre”, 1]]],
      *         PrimeMeridian[“Paris”, 2.5969213, AngleUnit[“grad”, 
0.015707963267948967]]],
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DynamicCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DynamicCRS.java
index 31bbc386b1..23290ce2aa 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DynamicCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DynamicCRS.java
@@ -67,7 +67,7 @@ final class DynamicCRS extends FormattableObject {
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        formatter.append(new Epoch(epoch, true));
+        formatter.append(new Epoch(epoch, WKTKeywords.FrameEpoch));
         return WKTKeywords.Dynamic;
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
index 2e1c286114..ca097b7b45 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
@@ -315,7 +315,7 @@ public class DefaultPrimeMeridian extends 
AbstractIdentifiedObject implements Pr
      *
      * {@snippet lang="wkt" :
      *   ProjectedCRS[“NTF (Paris) / Lambert zone II”,
-     *     BaseGeodCRS[“NTF (Paris)”,
+     *     BaseGeogCRS[“NTF (Paris)”,
      *       Datum[“Nouvelle Triangulation Francaise”,
      *         Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],
      *       PrimeMeridian[“Paris”, 2.5969213],
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 ff3f7e2713..f20b2fa4de 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
@@ -1795,7 +1795,7 @@ public class GeodeticObjectFactory extends 
AbstractFactory implements CRSFactory
      *
      * {@snippet lang="wkt" :
      *   ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
-     *     BaseGeodCRS["SIRGAS 2000",
+     *     BaseGeogCRS["SIRGAS 2000",
      *       Datum["Sistema de Referencia Geocentrico para las Americas 2000",
      *         Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
      *     Conversion["Petrobras Mercator",
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
index 0c3f131d3d..7544caea8c 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
@@ -27,7 +27,6 @@ import java.time.temporal.ChronoField;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.math.DecimalFunctions;
-import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.util.privy.Constants;
 
 
@@ -50,18 +49,19 @@ public final class Epoch extends FormattableObject {
     public final int precision;
 
     /**
-     * Whether this epoch is the frame epoch instead of the coordinate epoch.
+     * The keyword of the <abbr>WKT</abbr> element which will contain the 
epoch.
+     * This is {@code "Epoch"}, {@code "FrameEpoch"} or {@code "AnchorEpoch"}.
      */
-    private final boolean frame;
+    private final String keyword;
 
     /**
      * Converts the given epoch to a fractional year.
      *
-     * @param  epoch  the epoch to express as a fractional year.
-     * @param  frame  whether this epoch is the frame epoch instead of the 
coordinate epoch
+     * @param  epoch    the epoch to express as a fractional year.
+     * @param  keyword  the keyword of the <abbr>WKT</abbr> element which will 
contain the epoch.
      */
-    public Epoch(Temporal epoch, final boolean frame) {
-        this.frame = frame;
+    public Epoch(Temporal epoch, final String keyword) {
+        this.keyword = keyword;
         if (epoch instanceof Instant) {
             epoch = OffsetDateTime.ofInstant((Instant) epoch, ZoneOffset.UTC);
         }
@@ -140,11 +140,11 @@ public final class Epoch extends FormattableObject {
      * Formats this epoch as a <i>Well Known Text</i> {@code 
CoordinateMetadata[…]} element.
      *
      * @param  formatter  the formatter where to format the inner content of 
this WKT element.
-     * @return {@code "Epoch"} or {@code "FrameEpoch"}.
+     * @return {@code "Epoch"}, {@code "FrameEpoch"} or {@code "AnchorEpoch"}.
      */
     @Override
     protected String formatTo(final Formatter formatter) {
         formatter.append(value, precision);
-        return frame ? WKTKeywords.FrameEpoch : WKTKeywords.Epoch;
+        return keyword;
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTKeywords.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTKeywords.java
index 76bf6005cd..9f9f340642 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTKeywords.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTKeywords.java
@@ -55,10 +55,10 @@ public final class WKTKeywords extends Static {
             URI       = "URI",
             Citation  = "Citation",
             Authority = "Authority",
-            Anchor    = "Anchor",
             Usage     = "Usage",
             Scope     = "Scope",
             Area      = "Area",
+            BBox      = "BBox",
             Remark    = "Remark";
 
     /**
@@ -100,7 +100,9 @@ public final class WKTKeywords extends Static {
      * and {@link org.apache.sis.referencing.crs.DefaultGeographicCRS}.
      */
     public static final String
-            BBox          = "BBox",
+            Anchor        = "Anchor",
+            AnchorEpoch   = "AnchorEpoch",
+            TRF           = "TRF",
             Datum         = "Datum",
             GeodeticDatum = "GeodeticDatum",
             GeodeticCRS   = "GeodeticCRS",
@@ -120,6 +122,7 @@ public final class WKTKeywords extends Static {
             VerticalDatum  = "VerticalDatum",
             VerticalCRS    = "VerticalCRS",
             BaseVertCRS    = "BaseVertCRS",
+            VRF            = "VRF",
             VDatum         = "VDatum",
             Vert_Datum     = "Vert_Datum",
             VertCRS        = "VertCRS",
@@ -269,9 +272,9 @@ public final class WKTKeywords extends Static {
          * `Datum` subtypes.
          */
         subtypes = new String[][] {
-            addType(org.opengis.referencing.datum.GeodeticDatum.class,    
GeodeticDatum,    Datum),
+            addType(org.opengis.referencing.datum.GeodeticDatum.class,    
GeodeticDatum,    Datum, TRF),
             addType(org.opengis.referencing.datum.TemporalDatum.class,    
TimeDatum,        TDatum),
-            addType(org.opengis.referencing.datum.VerticalDatum.class,    
VerticalDatum,    VDatum, Vert_Datum),
+            addType(org.opengis.referencing.datum.VerticalDatum.class,    
VerticalDatum,    VDatum, Vert_Datum, VRF),
             addType(org.opengis.referencing.datum.EngineeringDatum.class, 
EngineeringDatum, EDatum, Local_Datum)
         };
         addType(org.opengis.referencing.datum.Datum.class, 
ArraysExt.concatenate(subtypes));
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTUtilities.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTUtilities.java
index 71e7ed7df4..ca583fd6dd 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTUtilities.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/WKTUtilities.java
@@ -157,8 +157,8 @@ public final class WKTUtilities extends Static {
     }
 
     /**
-     * If the given unit is one of the unit that cannot be formatted without 
ambiguity in WKT format,
-     * return a proposed replacement. Otherwise returns {@code unit} unchanged.
+     * If the given unit is one of the units that cannot be formatted without 
ambiguity in <abbr>WKT</abbr> format,
+     * returns a proposed replacement. Otherwise returns {@code unit} 
unchanged.
      *
      * @param  <Q>   the unit dimension.
      * @param  unit  the unit to test.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
index d8ab00ab64..df20596fca 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
@@ -182,7 +182,7 @@ public final class ElementTest extends TestCase {
     public void testPullDate() throws ParseException {
         Element element = parse("TimeOrigin[1858-11-17T00:00:00.0Z]");
         assertEquals("TimeOrigin", element.keyword);
-        assertEquals(Instant.parse("1858-11-17T00:00:00Z"), 
element.pullDate("date"));
+        assertEquals(Instant.parse("1858-11-17T00:00:00Z"), 
element.pullTime("date"));
         element.close(null);
     }
 
@@ -222,7 +222,7 @@ public final class ElementTest extends TestCase {
         assertEquals("Modified Julian", element.pullString("name"));
         Element inner = element.pullElement(AbstractParser.MANDATORY, 
"TimeOrigin");
         assertEquals("TimeOrigin", inner.keyword);
-        assertEquals(Instant.parse("1858-11-17T00:00:00Z"), 
inner.pullDate("date"));
+        assertEquals(Instant.parse("1858-11-17T00:00:00Z"), 
inner.pullTime("date"));
         inner.close(null);
         element.close(null);
     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
index 77c961fd07..2ab3b9764b 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
@@ -774,8 +774,8 @@ public final class GeodeticObjectParserTest extends 
EPSGDependentTestCase {
                      "    Parameter[“Latitude of natural origin”, 52.0, 
AngleUnit[“grad”, 0.015707963267948967]],\n" +
                      "    Parameter[“Longitude of natural origin”, 0.0],\n" +
                      "    Parameter[“Scale factor at natural origin”, 
0.99987742],\n" +
-                     "    Parameter[“False easting”, 600.0],\n" +
-                     "    Parameter[“False northing”, 2200.0]],\n" +
+                     "    Parameter[“False easting”, 600.0, 
LengthUnit[“kilometre”, 1000]],\n" +
+                     "    Parameter[“False northing”, 2200.0, 
LengthUnit[“kilometre”, 1000]]],\n" +
                      "  CS[Cartesian, 2],\n" +
                      "    Axis[“Easting (E)”, east],\n" +
                      "    Axis[“Northing (N)”, north],\n" +
@@ -810,8 +810,8 @@ public final class GeodeticObjectParserTest extends 
EPSGDependentTestCase {
                      "    Parameter[“Latitude of natural origin”, 52.0, 
AngleUnit[“grad”, 0.015707963267948967]],\n" +
                      "    Parameter[“Longitude of natural origin”, 0.0],\n" +
                      "    Parameter[“Scale factor at natural origin”, 
0.99987742],\n" +
-                     "    Parameter[“False easting”, 600.0],\n" +
-                     "    Parameter[“False northing”, 2200.0]],\n" +
+                     "    Parameter[“False easting”, 600.0, 
LengthUnit[“kilometre”, 1000]],\n" +
+                     "    Parameter[“False northing”, 2200.0, 
LengthUnit[“kilometre”, 1000]]],\n" +
                      "  CS[Cartesian, 2],\n" +
                      "    Axis[“Easting (E)”, east],\n" +
                      "    Axis[“Northing (N)”, north],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/DefaultParameterValueTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/DefaultParameterValueTest.java
index ae70183ebb..79c7a2a391 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/DefaultParameterValueTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/DefaultParameterValueTest.java
@@ -537,7 +537,8 @@ public final class DefaultParameterValueTest extends 
TestCase {
         DefaultParameterValue<Double> p = create("Angle", 10.3, 
degreesAndMinutes);
         assertWktEquals(Convention.WKT1,     "PARAMETER[“Angle”, 10.3]", p);  
// 10.3 DM  ==  10.5°
         assertWktEquals(Convention.WKT2,     "PARAMETER[“Angle”, 10.5, 
ANGLEUNIT[“degree”, 0.017453292519943295]]", p);
-        assertWktEquals(Convention.INTERNAL, "Parameter[“Angle”, 10.3]", p);   
// Value in same unit as descriptor.
+        assertWktEquals(Convention.INTERNAL, "Parameter[“Angle”, 10.3, 
Unit[“D.M”, 0.017453292519943295, Id[“EPSG”, 9111]]]", p);
+        // In above line, the parameter value in `INTERNAL` mode was formatted 
in the same unit as the descriptor.
 
         p = create("Angle", 0, Units.DEGREE);
         p.setValue(10.3, degreesAndMinutes);  // Cannot be formatted in WKT1.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
index 2d78dbffd9..779fba8196 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
@@ -294,7 +294,7 @@ public final class DefaultCompoundCRSTest extends TestCase {
     public void testWKT2_Simplified() {
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "CompoundCRS[“WGS 84 + height + time”,\n" +
-                "  GeodeticCRS[“WGS 84”,\n" +
+                "  GeographicCRS[“WGS 84”,\n" +
                 "    Datum[“World Geodetic System 1984”,\n" +
                 "      Ellipsoid[“WGS84”, 6378137.0, 298.257223563]],\n" +
                 "    CS[ellipsoidal, 2],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
index 7630a761e0..a8080a1dd2 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
@@ -212,7 +212,7 @@ public final class DefaultDerivedCRSTest extends TestCase {
     public void testWKT2_Simplified() {
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "GeodeticCRS[“Back to Greenwich”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Francaise”,\n" +
                 "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213, Unit[“grad”, 
0.015707963267948967]],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
index 5d52def9d4..2064a0ecfd 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
@@ -197,7 +197,7 @@ public final class DefaultGeographicCRSTest extends 
TestCase {
     @Test
     public void testWKT2_Simplified() {
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
-                "GeodeticCRS[“WGS 84”,\n" +
+                "GeographicCRS[“WGS 84”,\n" +
                 "  Datum[“World Geodetic System 1984”,\n" +
                 "    Ellipsoid[“WGS84”, 6378137.0, 298.257223563]],\n" +
                 "  CS[ellipsoidal, 2],\n" +
@@ -216,7 +216,7 @@ public final class DefaultGeographicCRSTest extends 
TestCase {
     @Test
     public void testWKT2_Internal() {
         assertWktEquals(Convention.INTERNAL,
-                "GeodeticCRS[“WGS 84”,\n" +
+                "GeographicCRS[“WGS 84”,\n" +
                 "  Datum[“World Geodetic System 1984”,\n" +
                 "    Ellipsoid[“WGS84”, 6378137.0, 298.257223563],\n" +
                 "    Usage[\n" +
@@ -242,7 +242,7 @@ public final class DefaultGeographicCRSTest extends 
TestCase {
     @Test
     public void testWKT2_ForNonGreenwich() {
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  Datum[“Nouvelle Triangulation Francaise”,\n" +           // 
Formatter should replace "ç" by "c".
                 "    Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "    PrimeMeridian[“Paris”, 2.5969213, Unit[“grad”, 
0.015707963267948967]],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
index 9392c3a5fc..9c576bbb8b 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
@@ -266,7 +266,7 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
         ProjectedCRS crs = create(HardCodedCRS.NTF);
         assertWktEquals(Convention.INTERNAL,
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Française”,\n" +
                 "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269],\n" +
                 "      Usage[\n" +
@@ -279,7 +279,7 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
                 "      Unit[“grad”, 0.015707963267948967, Id[“EPSG”, 
9105]]],\n" +
                 "  Conversion[“Lambert zone II”,\n" +
                 "    Method[“Lambert Conic Conformal (1SP)”, Id[“EPSG”, 9801], 
Id[“GeoTIFF”, 9]],\n" +
-                "    Parameter[“Latitude of natural origin”, 52.0, Id[“EPSG”, 
8801], Id[“GeoTIFF”, 3081]],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0, 
Unit[“grad”, 0.015707963267948967, Id[“EPSG”, 9105]], Id[“EPSG”, 8801], 
Id[“GeoTIFF”, 3081]],\n" +
                 "    Parameter[“Longitude of natural origin”, 0.0, Id[“EPSG”, 
8802], Id[“GeoTIFF”, 3080]],\n" +
                 "    Parameter[“Scale factor at natural origin”, 0.99987742, 
Id[“EPSG”, 8805], Id[“GeoTIFF”, 3092]],\n" +
                 "    Parameter[“False easting”, 600000.0, Id[“EPSG”, 8806], 
Id[“GeoTIFF”, 3082]],\n" +
@@ -304,14 +304,14 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
         ProjectedCRS crs = create(HardCodedCRS.NTF);
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Francaise”,\n" +
                 "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "    Unit[“grad”, 0.015707963267948967]],\n" +
                 "  Conversion[“Lambert zone II”,\n" +
                 "    Method[“Lambert Conic Conformal (1SP)”],\n" +
-                "    Parameter[“Latitude of natural origin”, 52.0],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0, 
Unit[“grad”, 0.015707963267948967]],\n" +
                 "    Parameter[“Longitude of natural origin”, 0.0],\n" +
                 "    Parameter[“Scale factor at natural origin”, 
0.99987742],\n" +
                 "    Parameter[“False easting”, 600000.0],\n" +
@@ -329,7 +329,7 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
         crs = create(HardCodedCRS.NTF_NORMALIZED_AXES);
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Francaise”,\n" +
                 "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213, Unit[“grad”, 
0.015707963267948967]],\n" +
@@ -382,7 +382,7 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
 
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Francaise”,\n" +
                 "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213, Unit[“grad”, 
0.015707963267948967]],\n" +
@@ -467,7 +467,7 @@ public final class DefaultProjectedCRSTest extends 
TestCase.WithLogs {
 
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "ProjectedCRS[“Equidistant Cylindrical (Spherical)”,\n" +
-                "  BaseGeodCRS[“WGS 84”,\n" +
+                "  BaseGeogCRS[“WGS 84”,\n" +
                 "    Datum[“World Geodetic System 1984”,\n" +
                 "      Ellipsoid[“WGS84”, 6378137.0, 298.257223563]],\n" +
                 "    Unit[“degree”, 0.017453292519943295]],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
index a1445d78dd..66da7ea085 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
@@ -343,6 +343,7 @@ public final class DefaultGeodeticDatumTest extends 
TestCase {
                 "  Ellipsoid[“WGS 84”, 6378137.0, 298.257223563, Id[“EPSG”, 
7030],\n" +
                 "    Remark[“Defining parameters cited in EPSG 
database.”]],\n" +
                 "  Anchor[“Station coordinates changed by a few centimetres in 
1994, 1997, 2002 and 2012.”],\n" +
+                "  AnchorEpoch[1984.000],\n" +  // The 3 digits are because of 
<gml:realizationEpoch> in test file.
                 "  Usage[\n" +
                 "    Scope[“Satellite navigation.”],\n" +
                 "    Area[“World.”],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/EpochTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/EpochTest.java
index 5a0a91bfee..603ea383d0 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/EpochTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/EpochTest.java
@@ -21,6 +21,7 @@ import java.time.YearMonth;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
+import org.apache.sis.referencing.privy.WKTKeywords;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
@@ -47,7 +48,7 @@ public final class EpochTest extends TestCase {
      */
     @Test
     public void testYear() {
-        var epoch = new Epoch(Year.of(2010), false);
+        var epoch = new Epoch(Year.of(2010), WKTKeywords.Epoch);
         assertEquals(2010, epoch.value);
         assertEquals(0, epoch.precision);
         assertEquals("Epoch[2010]", epoch.toString());
@@ -58,12 +59,12 @@ public final class EpochTest extends TestCase {
      */
     @Test
     public void testYearMonth() {
-        var epoch = new Epoch(YearMonth.of(2016, 1), false);
+        var epoch = new Epoch(YearMonth.of(2016, 1), WKTKeywords.Epoch);
         assertEquals(2016, epoch.value);
         assertEquals(2, epoch.precision);
         assertEquals("Epoch[2016.00]", epoch.toString());
 
-        epoch = new Epoch(YearMonth.of(2016, 7), false);
+        epoch = new Epoch(YearMonth.of(2016, 7), WKTKeywords.Epoch);
         assertEquals(2016.49726775956, epoch.value, 1E-11);
         assertEquals(2, epoch.precision);
         assertEquals("Epoch[2016.50]", epoch.toString());
@@ -74,7 +75,7 @@ public final class EpochTest extends TestCase {
      */
     @Test
     public void testLocalDate() {
-        var epoch = new Epoch(LocalDate.of(2016, 7, 20), false);
+        var epoch = new Epoch(LocalDate.of(2016, 7, 20), WKTKeywords.Epoch);
         assertEquals(2016.54918032787, epoch.value, 1E-11);
         assertEquals(3, epoch.precision);
         assertEquals("Epoch[2016.549]", epoch.toString());
@@ -85,7 +86,7 @@ public final class EpochTest extends TestCase {
      */
     @Test
     public void testLocalDateTime() {
-        var epoch = new Epoch(LocalDateTime.of(2014, 2, 15, 10, 40), false);
+        var epoch = new Epoch(LocalDateTime.of(2014, 2, 15, 10, 40), 
WKTKeywords.Epoch);
         assertEquals(2014.12450532725, epoch.value, 1E-11);
         assertEquals(8, epoch.precision);
         assertEquals("Epoch[2014.12450533]", epoch.toString());
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
index e8488c69c5..f2b47dbd5c 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
@@ -240,7 +240,7 @@ public final class CoordinateOperationFinderTest extends 
MathTransformTestCase {
     @Test
     public void testGeocentricTranslationInGeographic3D() throws 
ParseException, FactoryException, TransformException {
         final GeographicCRS sourceCRS = (GeographicCRS) parse(
-                "GeodeticCRS[“NAD27”,\n" +
+                "GeographicCRS[“NAD27”,\n" +
                 "  Datum[“North American Datum 1927”,\n" +
                 "    Ellipsoid[“Clarke 1866”, 6378206.4, 
294.9786982138982],\n" +
                 "    ToWGS84[-8, 160, 176]]," +                                
     // See comment in above test.
@@ -318,7 +318,7 @@ public final class CoordinateOperationFinderTest extends 
MathTransformTestCase {
     @Test
     public void testLongitudeRotation() throws ParseException, 
FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”, $NTF,\n" +
+                "GeographicCRS[“NTF (Paris)”, $NTF,\n" +
                 "  PrimeMeridian[“Paris”, 2.5969213],\n" +          // in 
grads, not degrees.
                 "  CS[ellipsoidal, 2],\n" +
                 "    Axis[“Latitude (φ)”, NORTH],\n" +
@@ -947,7 +947,7 @@ public final class CoordinateOperationFinderTest extends 
MathTransformTestCase {
     public void testProjected4D_to_2D() throws ParseException, 
FactoryException, TransformException {
         final CoordinateReferenceSystem targetCRS = parse(
                 "ProjectedCRS[“WGS 84 / World Mercator”,\n" +
-                "  BaseGeodCRS[“WGS 84”,\n" +
+                "  BaseGeogCRS[“WGS 84”,\n" +
                 "    Datum[“World Geodetic System 1984”,\n" +
                 "      Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]]],\n" +
                 "  Conversion[“WGS 84 / World Mercator”,\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
index d6c33c5849..7d2a5b1e59 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
@@ -150,7 +150,7 @@ public final class CoordinateOperationRegistryTest extends 
MathTransformTestCase
     @Test
     public void testLongitudeRotationBetweenConformCRS() throws 
ParseException, FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "  CS[ellipsoidal, 2],\n" +
@@ -188,7 +188,7 @@ public final class CoordinateOperationRegistryTest extends 
MathTransformTestCase
     @Test
     public void testLongitudeRotationBetweenNormalizedCRS() throws 
ParseException, FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.33722917],\n" +
                 "  CS[ellipsoidal, 2],\n" +
@@ -218,7 +218,7 @@ public final class CoordinateOperationRegistryTest extends 
MathTransformTestCase
     @Test
     public void testInverse() throws ParseException, FactoryException, 
TransformException {
         final CoordinateReferenceSystem targetCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "  CS[ellipsoidal, 2],\n" +
@@ -249,7 +249,7 @@ public final class CoordinateOperationRegistryTest extends 
MathTransformTestCase
     @Test
     public void testLongitudeRotationBetweenGeographic3D() throws 
ParseException, FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "  CS[ellipsoidal, 3],\n" +
@@ -282,7 +282,7 @@ public final class CoordinateOperationRegistryTest extends 
MathTransformTestCase
     @Test
     public void testLongitudeRotationBetweenNormalizedGeographic3D() throws 
ParseException, FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
-                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "GeographicCRS[“NTF (Paris)”,\n" +
                 "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.33722917],\n" +
                 "  CS[ellipsoidal, 3],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
index 440eb63f24..c46636d736 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
@@ -107,14 +107,14 @@ public final class DefaultConcatenatedOperationTest 
extends TestCase {
         final DefaultConcatenatedOperation op = createGeocentricTranslation();
         assertWktEquals(Convention.WKT2_SIMPLIFIED,                            
 // Pseudo-WKT actually.
                 "ConcatenatedOperation[“Tokyo to JGD2000”,\n" +
-                "  SourceCRS[GeodeticCRS[“Tokyo”,\n" +
+                "  SourceCRS[GeographicCRS[“Tokyo”,\n" +
                 "    Datum[“Tokyo 1918”,\n" +
                 "      Ellipsoid[“Bessel 1841”, 6377397.155, 299.1528128]],\n" 
+
                 "    CS[ellipsoidal, 3],\n" +
                 "      Axis[“Longitude (L)”, east, Unit[“degree”, 
0.017453292519943295]],\n" +
                 "      Axis[“Latitude (B)”, north, Unit[“degree”, 
0.017453292519943295]],\n" +
                 "      Axis[“Ellipsoidal height (h)”, up, Unit[“metre”, 
1]]]],\n" +
-                "  TargetCRS[GeodeticCRS[“JGD2000”,\n" +
+                "  TargetCRS[GeographicCRS[“JGD2000”,\n" +
                 "    Datum[“Japanese Geodetic Datum 2000”,\n" +
                 "      Ellipsoid[“GRS 1980”, 6378137.0, 298.257222101]],\n" +
                 "    CS[ellipsoidal, 3],\n" +
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
index b96ed6d376..270dc42282 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
@@ -83,14 +83,14 @@ public final class DefaultCoordinateOperationFactoryTest 
extends MathTransformTe
         parser  = new WKTFormat();
         parser.addFragment("NTF",
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
-                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "  BaseGeogCRS[“NTF (Paris)”,\n" +
                 "    Datum[“Nouvelle Triangulation Française (Paris)”,\n" +
                 "      Ellipsoid[“Clarke 1880 (IGN)”, 6378249.2, 
293.4660212936269]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "    Unit[“grad”, 0.015707963267948967]]\n," +
                 "  Conversion[“Lambert zone II”,\n" +
                 "    Method[“Lambert Conic Conformal (1SP)”],\n" +
-                "    Parameter[“Latitude of natural origin”, 52.0],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0, 
Unit[“grad”, 0.015707963267948967]],\n" +
                 "    Parameter[“Scale factor at natural origin”, 
0.99987742],\n" +
                 "    Parameter[“False easting”, 600000.0],\n" +
                 "    Parameter[“False northing”, 2200000.0]],\n" +
@@ -102,7 +102,7 @@ public final class DefaultCoordinateOperationFactoryTest 
extends MathTransformTe
 
         parser.addFragment("Mercator",
                 "ProjectedCRS[“WGS 84 / World Mercator”,\n" +
-                "  BaseGeodCRS[“WGS 84”,\n" +
+                "  BaseGeogCRS[“WGS 84”,\n" +
                 "    Datum[“World Geodetic System 1984”,\n" +
                 "      Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]],\n" +
                 "    Unit[“degree”, 0.017453292519943295]],\n" +
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/WKTPane.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/WKTPane.java
index 2818320b00..98cd70a217 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/WKTPane.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/WKTPane.java
@@ -76,6 +76,7 @@ final class WKTPane extends StringConverter<Convention> 
implements ChangeListene
         final Convention[] sc = {           // Selected conventions in the 
order we want them to appear.
             Convention.WKT2_SIMPLIFIED,
             Convention.WKT2,
+            Convention.WKT2_2015,
             Convention.WKT1,
             Convention.WKT1_COMMON_UNITS
         };
@@ -104,6 +105,7 @@ final class WKTPane extends StringConverter<Convention> 
implements ChangeListene
         switch (c) {
             case WKT2_SIMPLIFIED:   simplified = true;         // Fall through.
             case WKT2:              version = 2; break;
+            case WKT2_2015:         version = "2 (2015)"; break;
             case WKT1:              version = 1; break;
             case WKT1_COMMON_UNITS: version = "GDAL 1-2"; break;
             default: return c.name();


Reply via email to