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
commit 17ef3cb68ea24f0527e68d024903493ca8245199 Author: Martin Desruisseaux <[email protected]> AuthorDate: Tue Sep 9 14:02:23 2025 +0200 WKT 2 consolidation: * Support the `CoordinateMetadata` and `Version` elements. * Make `ConcatenatedOperation` formatting compliant with the standard. * Reorganize the list of keywords by alphabetical order for easier maintenance. --- .../sis/coverage/grid/ClippedGridCoverageTest.java | 2 +- .../apache/sis/io/wkt/GeodeticObjectParser.java | 84 +++++-- .../operation/AbstractCoordinateOperation.java | 61 +++-- .../operation/DefaultConcatenatedOperation.java | 11 +- .../apache/sis/referencing/privy/WKTKeywords.java | 267 ++++++++------------- .../DefaultConcatenatedOperationTest.java | 54 ++++- .../operation/DefaultTransformationTest.java | 3 +- 7 files changed, 264 insertions(+), 218 deletions(-) diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ClippedGridCoverageTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ClippedGridCoverageTest.java index cc80efe1dd..8ab2fa5ab6 100644 --- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ClippedGridCoverageTest.java +++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ClippedGridCoverageTest.java @@ -72,7 +72,7 @@ public final class ClippedGridCoverageTest extends TestCase { RenderedImage image = data; if (processor != null) { // We are not really interrested in statistics, we just want to get a different implementation class. - image = processor.imageProcessor.statistics(image, null, null); + image = processor.imageProcessor.statistics(image, null); } return new GridCoverageBuilder().setDomain(domain).setValues(image).build(); } 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 b1684dc0b2..93742a1ddf 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 @@ -81,6 +81,7 @@ import org.apache.sis.metadata.iso.extent.DefaultGeographicDescription; import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent; import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent; import org.apache.sis.metadata.privy.AxisNames; +import org.apache.sis.coordinate.DefaultCoordinateMetadata; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.privy.Constants; import org.apache.sis.util.privy.Numerics; @@ -89,6 +90,7 @@ import org.apache.sis.util.resources.Errors; import org.apache.sis.util.iso.Types; // Specific to the geoapi-3.1 and geoapi-4.0 branches: +import org.opengis.coordinate.CoordinateMetadata; import org.opengis.referencing.ObjectDomain; // Specific to the geoapi-4.0 branch: @@ -297,6 +299,13 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo return object; } + /** + * Returns the prime meridian to use by default when none is specified. + */ + private static PrimeMeridian greenwich() { + return CommonCRS.WGS84.primeMeridian(); + } + /** * Parses the next element in the specified <i>Well Know Text</i> (WKT) tree. * @@ -308,6 +317,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo final Object buildFromTree(final Element element) throws ParseException { Object object; if (null == (object = parseCoordinateReferenceSystem(element, false)) + && null == (object = parseCoordinateMetadata(FIRST, element)) && null == (object = parseMathTransform (element, false)) && null == (object = parseAxis (FIRST, element, null, Units.METRE )) && null == (object = parsePrimeMeridian (FIRST, element, false, Units.DEGREE)) @@ -378,6 +388,25 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo return crs; } + /** + * Parses a {@code "CoordinateMetadata"} element. + * + * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}. + * @param parent the parent element. + * @return the {@code "CoordinateMetadata"} element. + * @throws ParseException if the {@code "CoordinateMetadata"} element cannot be parsed. + */ + private CoordinateMetadata parseCoordinateMetadata(final int mode, final Element parent) throws ParseException { + final Element element = parent.pullElement(mode, WKTKeywords.CoordinateMetadata); + if (element == null) { + return null; + } + final CoordinateReferenceSystem crs = parseCoordinateReferenceSystem(element, true); + final Temporal epoch = parseEpoch(OPTIONAL, element, WKTKeywords.Epoch); + element.close(ignoredElements); + return new DefaultCoordinateMetadata(crs, epoch); + } + /** * Returns the value associated to {@link IdentifiedObject#IDENTIFIERS_KEY} as an {@code Identifier} object. * This method shall accept all value types that {@link #parseMetadataAndClose(Element, String, IdentifiedObject)} @@ -410,6 +439,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo * @return a properties map with the parent name and the optional authority code. * @throws ParseException if an element cannot be parsed. * + * @see #parseAnchorAndClose(Element, String) * @see #parseParametersAndClose(Element, String, OperationMethod) */ @SuppressWarnings("ReturnOfCollectionOrArrayField") @@ -510,19 +540,6 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo return properties; } - /** - * Parses the datum {@code ANCHOR[]} element and pass the values to the {@link #parseMetadataAndClose(Element, - * 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 { - 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); - if (epoch != null) properties.put(Datum.ANCHOR_EPOCH_KEY, epoch); - return properties; - } - /** * Parses the {@code AREA}, {@code BBOX}, {@code VERTICALEXTENT} and {@code TIMEEXTENT} elements if present. * These elements were directly inside the <abbr>CRS</abbr> element in <abbr>ISO</abbr> 19162:2015, but became @@ -1421,7 +1438,20 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo } /** - * Parses a {@code "FrameEoch"} (WKT 2) element. + * Parses an epoch. + * + * @param mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}. + * @param parent the parent element. + * @param keyword {@code "Epoch"}, {@code "FrameEpoch"} or {@code "AnchorEpoch"}. + * @return the epoch, or {@code null} if none. + * @throws ParseException if the epoch cannot be parsed. + */ + private Temporal parseEpoch(final int mode, final Element parent, final String keyword) throws ParseException { + return Epoch.fromYear(pullElementAsDouble(parent, keyword, mode), 0); + } + + /** + * Parses a {@code "FrameEpoch"} (WKT 2) element. * * @param parent the parent element. * @return the frame epoch, or {@code null} if none. @@ -1432,11 +1462,24 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo if (element == null) { return null; } - Temporal epoch = Epoch.fromYear(pullElementAsDouble(element, WKTKeywords.FrameEpoch, MANDATORY), 0); + Temporal epoch = parseEpoch(MANDATORY, element, WKTKeywords.FrameEpoch); element.close(ignoredElements); return epoch; } + /** + * Parses the datum {@code ANCHOR[]} element and pass the values to the {@link #parseMetadataAndClose(Element, + * 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 { + String anchor = pullElementAsString(element, WKTKeywords.Anchor); + Temporal epoch = parseEpoch(OPTIONAL, element, WKTKeywords.AnchorEpoch); + final Map<String,Object> properties = parseMetadataAndClose(element, name, null); + if (anchor != null) properties.put(Datum.ANCHOR_DEFINITION_KEY, anchor); + if (epoch != null) properties.put(Datum.ANCHOR_EPOCH_KEY, epoch); + return properties; + } + /** * Parses an {@code "Ensemble"} (WKT 2) element. * @@ -2462,12 +2505,16 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo return null; } final String name = element.pullString("name"); + final String version = pullElementAsString(element, WKTKeywords.Version); final CoordinateReferenceSystem sourceCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.SourceCRS); final CoordinateReferenceSystem targetCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.TargetCRS); final CoordinateReferenceSystem interpolationCRS = parseCoordinateReferenceSystem(element, OPTIONAL, WKTKeywords.InterpolationCRS); final OperationMethod method = parseMethod(element, WKTKeywords.Method); final double accuracy = pullElementAsDouble(element, WKTKeywords.OperationAccuracy, OPTIONAL); final Map<String,Object> properties = parseParametersAndClose(element, name, method); + if (version != null) { + properties.put(CoordinateOperation.OPERATION_VERSION_KEY, version); + } if (Double.isFinite(accuracy)) { properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, PositionalAccuracyConstant.transformation(accuracy)); @@ -2512,11 +2559,4 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo return DefaultCoordinateOperationFactory.provider(); } } - - /** - * Returns the prime meridian to use by default when none is specified. - */ - private static PrimeMeridian greenwich() { - return CommonCRS.WGS84.primeMeridian(); - } } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java index 7ba89eed2b..369e9182aa 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java @@ -953,25 +953,32 @@ check: for (int isTarget=0; ; isTarget++) { // 0 == source check; 1 @Override protected String formatTo(final Formatter formatter) { super.formatTo(formatter); + final Convention convention = formatter.getConvention(); + final boolean isWKT1 = (convention.majorVersion() == 1); + if (convention.supports(Convention.WKT2_2019)) { + getOperationVersion().ifPresent((version) -> { + formatter.append(new FormattableObject() { + @Override protected String formatTo(final Formatter formatter) { + formatter.append(version, null); + return WKTKeywords.Version; + } + }); + }); + } formatter.newLine(); @SuppressWarnings("LocalVariableHidesMemberVariable") final CoordinateReferenceSystem sourceCRS = getSourceCRS(), targetCRS = getTargetCRS(); - final Convention convention = formatter.getConvention(); - final boolean isWKT1 = (convention.majorVersion() == 1); /* - * If the WKT is a component of a ConcatenatedOperation, do not format the source CRS since it is identical - * to the target CRS of the previous step, or to the source CRS of the enclosing "ConcatenatedOperation" if - * this step is the first step. - * - * This decision is SIS-specific since the WKT 2 specification does not define concatenated operations. + * If the WKT is a component of a PassThroughOperation, do not format the source CRS since it is identical + * to a component of the Source CRS of the enclosing `PassThroughOperation`. This decision is SIS-specific + * because the WKT 2 specification does not define pass-through operations. * This choice may change in any future SIS version. */ final FormattableObject enclosing = formatter.getEnclosingElement(1); final boolean isSubOperation = (enclosing instanceof PassThroughOperation); - final boolean isComponent = (enclosing instanceof ConcatenatedOperation); boolean isGeogTran = false; - if (!isSubOperation && !isComponent) { + if (!isSubOperation) { isGeogTran = isWKT1 && (sourceCRS instanceof GeographicCRS) && (targetCRS instanceof GeographicCRS); if (isGeogTran) { // ESRI-specific, similar to WKT 1. @@ -1022,27 +1029,31 @@ check: for (int isTarget=0; ; isTarget++) { // 0 == source check; 1 } } /* - * Add interpolation CRS if we are formatting a top-level WKT 2 single operation. + * If formatting a WKT 1 string, we need to declare the string as invalid (because `CoordinateOperation` + * did not existed at that time) except if the CRS types are compliant with the ESRI extension and that + * extension was enabled. Even if the ESRI extensions are not enabled, we still use the ESRI keyword if + * applicable and use `setInvalidWKT(…)` for warning the user. */ - if (!isSubOperation && !isGeogTran && !(this instanceof ConcatenatedOperation)) { - append(formatter, getInterpolationCRS().orElse(null), WKTKeywords.InterpolationCRS); - WKTUtilities.appendElementIfPositive(WKTKeywords.OperationAccuracy, getLinearAccuracy(), formatter); - } - /* - * Verifies if what we wrote is allowed by the standard. - */ - if (isGeogTran) { - if (method == null || convention != Convention.WKT1_IGNORE_AXES) { + if (isWKT1) { + if (!(isGeogTran && method != null && convention == Convention.WKT1_IGNORE_AXES)) { formatter.setInvalidWKT(this, null); } - return WKTKeywords.GeogTran; + if (isGeogTran) { + return WKTKeywords.GeogTran; + } } - if (isWKT1) { - formatter.setInvalidWKT(this, null); + /* + * If the coordinate operation is a step in a chain of operations, returns "step". + * Otherwise, if formatting a top-level single operation, add the interpolation CRS. + */ + if (enclosing instanceof ConcatenatedOperation) { + return WKTKeywords.Step; } - if (isComponent) { - formatter.setInvalidWKT(this, null); - return "CoordinateOperationStep"; + if (isSubOperation) { + if (!(this instanceof ConcatenatedOperation)) { + append(formatter, getInterpolationCRS().orElse(null), WKTKeywords.InterpolationCRS); + } + WKTUtilities.appendElementIfPositive(WKTKeywords.OperationAccuracy, getLinearAccuracy(), formatter); } return WKTKeywords.CoordinateOperation; } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java index 11784505da..00aec82220 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java @@ -37,6 +37,7 @@ import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.referencing.datum.DatumOrEnsemble; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.referencing.factory.InvalidGeodeticParameterException; +import org.apache.sis.referencing.privy.WKTKeywords; import org.apache.sis.referencing.privy.CoordinateOperations; import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.internal.Resources; @@ -47,6 +48,7 @@ import org.apache.sis.util.collection.Containers; import org.apache.sis.util.privy.UnmodifiableArrayList; import org.apache.sis.util.privy.Constants; import org.apache.sis.util.resources.Errors; +import org.apache.sis.io.wkt.Convention; import org.apache.sis.io.wkt.Formatter; @@ -449,8 +451,7 @@ final class DefaultConcatenatedOperation extends AbstractCoordinateOperation imp } /** - * Formats this coordinate operation in pseudo-WKT. This is specific to Apache SIS since - * there is no concatenated operation in the Well Known Text (WKT) version 2 format. + * Formats this coordinate operation in Well Known Text (WKT) version 2 format. * * @param formatter the formatter to use. * @return {@code "ConcatenatedOperation"}. @@ -462,8 +463,10 @@ final class DefaultConcatenatedOperation extends AbstractCoordinateOperation imp formatter.newLine(); formatter.append(castOrCopy(component)); } - formatter.setInvalidWKT(this, null); - return "ConcatenatedOperation"; + if (!formatter.getConvention().supports(Convention.WKT2_2019)) { + formatter.setInvalidWKT(this, null); + } + return WKTKeywords.ConcatenatedOperation; } 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 9f9f340642..62a9bf6949 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 @@ -47,164 +47,118 @@ public final class WKTKeywords extends Static { } /** - * Related to {@link org.apache.sis.referencing.AbstractIdentifiedObject} - * (including {@link org.apache.sis.referencing.ImmutableIdentifier}). + * Keywords defined by <abbr>WKT</abbr> 2. Some of those keywords are inherited from <abbr>WKT</abbr> 1 + * but have been kept in <abbr>WKT</abbr> 2 for compatibility reasons. */ public static final String - Id = "Id", - URI = "URI", - Citation = "Citation", - Authority = "Authority", - Usage = "Usage", - Scope = "Scope", - Area = "Area", - BBox = "BBox", - Remark = "Remark"; + Anchor = "Anchor", + AnchorEpoch = "AnchorEpoch", + AngleUnit = "AngleUnit", + Area = "Area", + Authority = "Authority", + Axis = "Axis", + AxisMaxValue = "AxisMaxValue", + AxisMinValue = "AxisMinValue", + BaseEngCRS = "BaseEngCRS", + BaseGeodCRS = "BaseGeodCRS", + BaseGeogCRS = "BaseGeogCRS", + BaseParamCRS = "BaseParamCRS", + BaseProjCRS = "BaseProjCRS", + BaseTimeCRS = "BaseTimeCRS", + BaseVertCRS = "BaseVertCRS", + BBox = "BBox", + BoundCRS = "BoundCRS", + Citation = "Citation", + Compd_CS = "Compd_CS", + CompoundCRS = "CompoundCRS", + ConcatenatedOperation = "ConcatenatedOperation", + Conversion = "Conversion", + CoordinateMetadata = "CoordinateMetadata", + CoordinateOperation = "CoordinateOperation", + CS = "CS", + Datum = "Datum", + DerivingConversion = "DerivingConversion", + Dynamic = "Dynamic", + EDatum = "EDatum", + Ellipsoid = "Ellipsoid", + EngCRS = "EngCRS", + EngineeringCRS = "EngineeringCRS", + EngineeringDatum = "EngineeringDatum", + EnsembleAccuracy = "EnsembleAccuracy", + Ensemble = "Ensemble", + Epoch = "Epoch", + Formula = "Formula", + FrameEpoch = "FrameEpoch", + GeocCS = "GeocCS", + GeodCRS = "GeodCRS", + GeodeticCRS = "GeodeticCRS", + GeodeticDatum = "GeodeticDatum", + GeogCRS = "GeogCRS", + GeogCS = "GeogCS", + GeographicCRS = "GeographicCRS", + IDatum = "IDatum", + Id = "Id", + ImageCRS = "ImageCRS", + ImageDatum = "ImageDatum", + InterpolationCRS = "InterpolationCRS", + LengthUnit = "LengthUnit", + Local_CS = "Local_CS", + Local_Datum = "Local_Datum", + Member = "Member", + Meridian = "Meridian", + Method = "Method", + OperationAccuracy = "OperationAccuracy", + Order = "Order", + ParameterFile = "ParameterFile", + ParameterGroup = "ParameterGroup", + Parameter = "Parameter", + ParametricCRS = "ParametricCRS", + ParametricDatum = "ParametricDatum", + ParametricUnit = "ParametricUnit", + PDatum = "PDatum", + Point = "Point", + PrimeMeridian = "PrimeMeridian", + PrimeM = "PrimeM", + ProjCRS = "ProjCRS", + ProjCS = "ProjCS", + ProjectedCRS = "ProjectedCRS", + Projection = "Projection", + RangeMeaning = "RangeMeaning", + Remark = "Remark", + ScaleUnit = "ScaleUnit", + Scope = "Scope", + SourceCRS = "SourceCRS", + Spheroid = "Spheroid", + Step = "Step", + TargetCRS = "TargetCRS", + TDatum = "TDatum", + TemporalQuantity = "TemporalQuantity", + TimeCRS = "TimeCRS", + TimeDatum = "TimeDatum", + TimeExtent = "TimeExtent", + TimeOrigin = "TimeOrigin", + TimeUnit = "TimeUnit", + ToWGS84 = "ToWGS84", + TRF = "TRF", + Unit = "Unit", + URI = "URI", + Usage = "Usage", + VDatum = "VDatum", + Version = "Version", + VertCRS = "VertCRS", + Vert_CS = "Vert_CS", + Vert_Datum = "Vert_Datum", + VerticalCRS = "VerticalCRS", + VerticalDatum = "VerticalDatum", + VerticalExtent = "VerticalExtent", + VRF = "VRF"; /** - * Related to unit of measurements. - */ - public static final String - Unit = "Unit", - LengthUnit = "LengthUnit", - AngleUnit = "AngleUnit", - ScaleUnit = "ScaleUnit", - TimeUnit = "TimeUnit", - TemporalQuantity = "TemporalQuantity", - ParametricUnit = "ParametricUnit"; - - /** - * Related to {@link org.apache.sis.referencing.cs.AbstractCS} - * and {@link org.apache.sis.referencing.datum.AbstractDatum}. - */ - public static final String - CS = "CS", - Axis = "Axis", - AxisMinValue = "AxisMinValue", - AxisMaxValue = "AxisMaxValue", - RangeMeaning = "RangeMeaning", - Order = "Order", - Meridian = "Meridian", - PrimeMeridian = "PrimeMeridian", - PrimeM = "PrimeM", - Ellipsoid = "Ellipsoid", - Spheroid = "Spheroid", - Ensemble = "Ensemble", - Member = "Member", - EnsembleAccuracy = "EnsembleAccuracy", - Dynamic = "Dynamic", - ToWGS84 = "ToWGS84"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultGeocentricCRS} - * and {@link org.apache.sis.referencing.crs.DefaultGeographicCRS}. - */ - public static final String - Anchor = "Anchor", - AnchorEpoch = "AnchorEpoch", - TRF = "TRF", - Datum = "Datum", - GeodeticDatum = "GeodeticDatum", - GeodeticCRS = "GeodeticCRS", - GeographicCRS = "GeographicCRS", - BaseGeodCRS = "BaseGeodCRS", - BaseGeogCRS = "BaseGeogCRS", - GeodCRS = "GeodCRS", - GeogCRS = "GeogCRS", - GeogCS = "GeogCS", - GeocCS = "GeocCS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultVerticalCRS}. - */ - public static final String - VerticalExtent = "VerticalExtent", - VerticalDatum = "VerticalDatum", - VerticalCRS = "VerticalCRS", - BaseVertCRS = "BaseVertCRS", - VRF = "VRF", - VDatum = "VDatum", - Vert_Datum = "Vert_Datum", - VertCRS = "VertCRS", - Vert_CS = "Vert_CS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultTemporalCRS}. - */ - public static final String - TimeExtent = "TimeExtent", - TimeOrigin = "TimeOrigin", - TimeDatum = "TimeDatum", - TDatum = "TDatum", - TimeCRS = "TimeCRS", - BaseTimeCRS = "BaseTimeCRS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultParametricCRS}. - */ - public static final String - ParametricDatum = "ParametricDatum", - PDatum = "PDatum", - ParametricCRS = "ParametricCRS", - BaseParamCRS = "BaseParamCRS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultImageCRS} - * and {@link org.apache.sis.referencing.crs.DefaultEngineeringCRS}. - * Former can be seen as a special case of the latter. - */ - public static final String - ImageDatum = "ImageDatum", - ImageCRS = "ImageCRS", - IDatum = "IDatum", - EngineeringDatum = "EngineeringDatum", - EngineeringCRS = "EngineeringCRS", - BaseEngCRS = "BaseEngCRS", - EngCRS = "EngCRS", - EDatum = "EDatum", - Local_Datum = "Local_Datum", - Local_CS = "Local_CS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultCompoundCRS}. - */ - public static final String - CompoundCRS = "CompoundCRS", - Compd_CS = "Compd_CS"; - - /** - * Related to {@link org.apache.sis.referencing.crs.DefaultProjectedCRS}. - */ - public static final String - ProjectedCRS = "ProjectedCRS", - BaseProjCRS = "BaseProjCRS", - ProjCRS = "ProjCRS", - ProjCS = "ProjCS"; - - /** - * Related to {@link org.apache.sis.referencing.operation.AbstractCoordinateOperation}. - */ - public static final String - BoundCRS = "BoundCRS", - Method = "Method", - Formula = "Formula", - Projection = "Projection", - Conversion = "Conversion", - DerivingConversion = "DerivingConversion", - CoordinateOperation = "CoordinateOperation", - OperationAccuracy = "OperationAccuracy", - SourceCRS = "SourceCRS", - TargetCRS = "TargetCRS", - InterpolationCRS = "InterpolationCRS", - Parameter = "Parameter", - ParameterFile = "ParameterFile", - ParameterGroup = "ParameterGroup", - GeogTran = "GeogTran"; // ESRI-specific. - - /** - * Related to {@link org.apache.sis.referencing.operation.transform.AbstractMathTransform}. + * The following keywords are specific to <abbr>WKT</abbr> 1 or <abbr>ESRI</abbr>. + * Those keywords have not been kept in <abbr>WKT</abbr> 2. */ public static final String + GeogTran = "GeogTran", // ESRI-specific. Param_MT = "Param_MT", Inverse_MT = "Inverse_MT", Concat_MT = "Concat_MT", @@ -227,15 +181,6 @@ public final class WKTKeywords extends Static { temporal = "temporal", vertical = "vertical"; - /** - * Coordinates and epoch. - */ - public static final String - CoordinateMetadata = "CoordinateMetadata", - FrameEpoch = "FrameEpoch", - Epoch = "Epoch", - Point = "Point"; - /** * Mapping between types of object and WKT keywords. Each GeoAPI interfaces is associated to one * or many WKT keywords: new keywords defined by version 2 (sometimes with synonymous) and legacy 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 c46636d736..a8ac95a57c 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 @@ -105,7 +105,7 @@ public final class DefaultConcatenatedOperationTest extends TestCase { @Test public void testWKT() throws FactoryException, NoninvertibleTransformException { final DefaultConcatenatedOperation op = createGeocentricTranslation(); - assertWktEquals(Convention.WKT2_SIMPLIFIED, // Pseudo-WKT actually. + assertWktEquals(Convention.WKT2_SIMPLIFIED, "ConcatenatedOperation[“Tokyo to JGD2000”,\n" + " SourceCRS[GeographicCRS[“Tokyo”,\n" + " Datum[“Tokyo 1918”,\n" + @@ -121,14 +121,60 @@ public final class DefaultConcatenatedOperationTest extends TestCase { " 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" + - " CoordinateOperationStep[“Geographic to geocentric”,\n" + + " Step[“Geographic to geocentric”,\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[“Tokyo 1918”,\n" + + " Datum[“Tokyo 1918”,\n" + + " Ellipsoid[“Bessel 1841”, 6377397.155, 299.1528128]],\n" + + " CS[Cartesian, 3],\n" + + " Axis[“(X)”, geocentricX],\n" + + " Axis[“(Y)”, geocentricY],\n" + + " Axis[“(Z)”, geocentricZ],\n" + + " Unit[“metre”, 1]]],\n" + " Method[“Geographic/geocentric conversions”]],\n" + // Omit non-EPSG parameters for EPSG method. - " CoordinateOperationStep[“Tokyo to JGD2000 (GSI)”,\n" + + " Step[“Tokyo to JGD2000 (GSI)”, Version[“GSI-Jpn”],\n" + + " SourceCRS[GeodeticCRS[“Tokyo 1918”,\n" + + " Datum[“Tokyo 1918”,\n" + + " Ellipsoid[“Bessel 1841”, 6377397.155, 299.1528128]],\n" + + " CS[Cartesian, 3],\n" + + " Axis[“(X)”, geocentricX],\n" + + " Axis[“(Y)”, geocentricY],\n" + + " Axis[“(Z)”, geocentricZ],\n" + + " Unit[“metre”, 1]]],\n" + + " TargetCRS[GeodeticCRS[“JGD2000”,\n" + + " Datum[“Japanese Geodetic Datum 2000”,\n" + + " Ellipsoid[“GRS 1980”, 6378137.0, 298.257222101]],\n" + + " CS[Cartesian, 3],\n" + + " Axis[“(X)”, geocentricX],\n" + + " Axis[“(Y)”, geocentricY],\n" + + " Axis[“(Z)”, geocentricZ],\n" + + " Unit[“metre”, 1]]],\n" + " Method[“Geocentric translations”],\n" + " Parameter[“X-axis translation”, -146.414],\n" + " Parameter[“Y-axis translation”, 507.337],\n" + " Parameter[“Z-axis translation”, 680.507]],\n" + - " CoordinateOperationStep[“Geocentric to geographic”,\n" + + " Step[“Geocentric to geographic”,\n" + + " SourceCRS[GeodeticCRS[“JGD2000”,\n" + + " Datum[“Japanese Geodetic Datum 2000”,\n" + + " Ellipsoid[“GRS 1980”, 6378137.0, 298.257222101]],\n" + + " CS[Cartesian, 3],\n" + + " Axis[“(X)”, geocentricX],\n" + + " Axis[“(Y)”, geocentricY],\n" + + " Axis[“(Z)”, geocentricZ],\n" + + " Unit[“metre”, 1]]],\n" + + " TargetCRS[GeographicCRS[“JGD2000”,\n" + + " Datum[“Japanese Geodetic Datum 2000”,\n" + + " Ellipsoid[“GRS 1980”, 6378137.0, 298.257222101]],\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" + " Method[“Geographic/geocentric conversions”],\n" + " Parameter[“semi_major”, 6378137.0, Unit[“metre”, 1]],\n" + " Parameter[“semi_minor”, 6356752.314140356, Unit[“metre”, 1]]]]", op); diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultTransformationTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultTransformationTest.java index 7d25f20155..60ef8fa3f0 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultTransformationTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultTransformationTest.java @@ -95,6 +95,7 @@ public final class DefaultTransformationTest extends TestCase { */ final Map<String, Object> properties = new HashMap<>(4); properties.put(DefaultTransformation.NAME_KEY, "Tokyo to JGD2000 (GSI)"); + properties.put(DefaultTransformation.OPERATION_VERSION_KEY, "GSI-Jpn"); properties.put(CoordinateOperations.PARAMETERS_KEY, pg); return new DefaultTransformation(properties, createCRS(null, HardCodedDatum.TOKYO), // SourceCRS @@ -182,7 +183,7 @@ public final class DefaultTransformationTest extends TestCase { " PARAMETER[“Z-axis translation”, 680.507, ID[“EPSG”, 8607]]]", op); assertWktEquals(Convention.WKT2_SIMPLIFIED, - "CoordinateOperation[“Tokyo to JGD2000 (GSI)”,\n" + + "CoordinateOperation[“Tokyo to JGD2000 (GSI)”, Version[“GSI-Jpn”],\n" + " SourceCRS[GeodeticCRS[“Tokyo 1918”,\n" + " Datum[“Tokyo 1918”,\n" + " Ellipsoid[“Bessel 1841”, 6377397.155, 299.1528128]],\n" +
