Ema Bakar created SIS-638:
-----------------------------
Summary: CRS.findOperations(EPSG:4326 → EPSG:4267) fails because
the inverse of EPSG:8647 fails step-chaining validation
Key: SIS-638
URL: https://issues.apache.org/jira/browse/SIS-638
Project: Spatial Information Systems
Issue Type: Bug
Components: Referencing
Affects Versions: 1.7
Environment: sis-referencing 1.7 + sis-embedded-data 1.7 (embedded
EPSG dataset 13.101), OpenJDK 11.0.25
Reporter: Ema Bakar
{{CRS.findOperations}} from WGS 84 to NAD27 throws instead of returning
operations. It works on 1.4. Found while upgrading the same application from
1.4 (see SIS-629).
{code:java}
CoordinateReferenceSystem source = CRS.forCode("EPSG:4326");
CoordinateReferenceSystem target = CRS.forCode("EPSG:4267");
List<CoordinateOperation> ops = CRS.findOperations(source, target, null);
{code}
{noformat}
org.apache.sis.referencing.factory.InvalidGeodeticParameterException: Invalid
coordinate operation step 1, because the reference system “NAD83” cannot be
followed by “NAD83(CSRS)”.
at
org.apache.sis.referencing.operation.DefaultConcatenatedOperation.verifyStepChaining(DefaultConcatenatedOperation.java:369)
at
org.apache.sis.referencing.operation.CoordinateOperationRegistry.getSteps(CoordinateOperationRegistry.java:870)
at
org.apache.sis.referencing.operation.CoordinateOperationRegistry.inverse(CoordinateOperationRegistry.java:834)
at
org.apache.sis.referencing.operation.CoordinateOperationRegistry.search(CoordinateOperationRegistry.java:714)
at
org.apache.sis.referencing.operation.CoordinateOperationRegistry.createOperations(CoordinateOperationRegistry.java:546)
at
org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperations(CoordinateOperationFinder.java:279)
at
org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory.createOperations(DefaultCoordinateOperationFactory.java:796)
at org.apache.sis.referencing.CRS.findOperations(CRS.java:883)
at org.apache.sis.referencing.CRS.findOperations(CRS.java:845)
{noformat}
*Cause*
EPSG has 78 operations from 4267 to 4326 and none from 4326 to 4267, so SIS
builds the inverses. One of them is EPSG:8647 "NAD27 to WGS 84 (78)", a
concatenated operation whose steps don't chain in the EPSG data:
* step 1: EPSG:1313 "NAD27 to NAD83 (4)", NAD27 (4267) → NAD83 (4269)
* step 2: EPSG:1946 "NAD83(CSRS) to WGS 84 (2)", NAD83(CSRS) (4617) → WGS 84
(4326)
The forward direction is accepted. {{createCoordinateOperation("EPSG:8647")}}
returns a {{DefaultConcatenatedOperation}}, and {{CRS.findOperations(EPSG:4267
→ EPSG:4326)}} succeeds. Only the inverse goes through {{verifyStepChaining}}
in {{CoordinateOperationRegistry.inverse}}. The exception then ends the whole
search, so the other 77 valid inverse operations are not returned either.
On 1.4 the same call returned all 78 operations, including the inverse of 8647
with its mismatched steps unchanged.
*Workaround*
Catch the {{InvalidGeodeticParameterException}} from {{findOperations(source,
target)}}, call {{findOperations(target, source)}} instead, and invert each
result:
* single operations with
{{DefaultCoordinateOperationFactory.createSingleOperation}}, using an "Inverse
of <method>" method and {{getMathTransform().inverse()}};
* concatenated operations by inverting their steps in reverse order and passing
them to {{createConcatenatedOperation}}.
{{createConcatenatedOperation}} applies the same step-chaining check, so it
rejects the inverse of 8647 on its own (we skip it on that exception) and
returns the other 77. Their order and first result match 1.4.
*Expected*
{{findOperations}} returns the 77 valid inverse operations and skips EPSG:8647,
ideally logging a warning. Alternatively, the inverse could be validated the
same way as the forward operation, but then the forward and inverse results
should at least agree.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)