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 a37595c `CRS.findOperation(…)` should accept `EngineeringCRS` with
same datum but different axis directions.
a37595c is described below
commit a37595ce05c6df1a018169e1c4144ffa83843cec
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Mar 6 21:24:36 2021 +0100
`CRS.findOperation(…)` should accept `EngineeringCRS` with same datum but
different axis directions.
---
.../operation/CoordinateOperationFinder.java | 20 ++++++++
.../operation/CoordinateOperationFinderTest.java | 60 +++++++++++++++++++++-
.../src/main/java/org/apache/sis/util/Classes.java | 14 ++---
3 files changed, 86 insertions(+), 8 deletions(-)
diff --git
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index f31c746..dd4988e 100644
---
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -353,6 +353,26 @@ public class CoordinateOperationFinder extends
CoordinateOperationRegistry {
}
////////////////////////////////////////////////////////////////////////////////
////
////
+ //// Any single CRS ↔ CRS of the same type
////
+ ////
////
+
////////////////////////////////////////////////////////////////////////////////
+ if (sourceCRS instanceof SingleCRS && targetCRS instanceof SingleCRS) {
+ final Datum sourceDatum = ((SingleCRS) sourceCRS).getDatum();
+ final Datum targetDatum = ((SingleCRS) targetCRS).getDatum();
+ if (equalsIgnoreMetadata(sourceDatum, targetDatum)) try {
+ /*
+ * Because the CRS type is determined by the datum type
(sometime completed by the CS type),
+ * having equivalent datum and compatible CS should be a
sufficient criterion.
+ */
+ return asList(createFromAffineTransform(AXIS_CHANGES,
sourceCRS, targetCRS,
+
CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(),
+
targetCRS.getCoordinateSystem())));
+ } catch (IllegalArgumentException | IncommensurableException e) {
+ throw new FactoryException(notFoundMessage(sourceCRS,
targetCRS), e);
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////
+ ////
////
//// Compound ↔ various CRS
////
////
////
////////////////////////////////////////////////////////////////////////////////
diff --git
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
index 3ab3dea..4b19d48 100644
---
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
+++
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.text.ParseException;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.GeocentricCRS;
import org.opengis.referencing.crs.VerticalCRS;
@@ -42,11 +43,16 @@ import
org.apache.sis.internal.referencing.PositionalAccuracyConstant;
import org.apache.sis.referencing.operation.transform.LinearTransform;
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.cs.DefaultCartesianCS;
+import org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis;
+import org.apache.sis.referencing.datum.DefaultEngineeringDatum;
+import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
import org.apache.sis.referencing.crs.DefaultCompoundCRS;
import org.apache.sis.referencing.crs.DefaultDerivedCRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.CRS;
import org.apache.sis.io.wkt.WKTFormat;
+import org.apache.sis.measure.Units;
import static org.apache.sis.internal.referencing.Formulas.LINEAR_TOLERANCE;
import static org.apache.sis.internal.referencing.Formulas.ANGULAR_TOLERANCE;
@@ -887,7 +893,15 @@ public final strictfp class CoordinateOperationFinderTest
extends MathTransformT
* Convenience method for creating a compound CRS.
*/
private static CompoundCRS compound(final String name, final
CoordinateReferenceSystem... components) {
- return new
DefaultCompoundCRS(Collections.singletonMap(CompoundCRS.NAME_KEY, name),
components);
+ return new DefaultCompoundCRS(properties(name), components);
+ }
+
+ /**
+ * Returns property map with a value assigned to the "name" property.
+ * This is a convenience method for construction of geodetic objects.
+ */
+ private static Map<String,String> properties(final String name) {
+ return Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY,
name);
}
/**
@@ -1025,4 +1039,48 @@ public final strictfp class
CoordinateOperationFinderTest extends MathTransformT
}), ((LinearTransform) transform).getMatrix(), STRICT);
validate();
}
+
+ /**
+ * Tests conversion between two engineering CRS.
+ *
+ * @throws FactoryException if the operation can not be created.
+ */
+ @Test
+ public void testEngineeringCRS() throws FactoryException {
+ DefaultEngineeringCRS sourceCRS = createEngineering("Screen display",
AxisDirection.DISPLAY_DOWN);
+ DefaultEngineeringCRS targetCRS = createEngineering("Another device",
AxisDirection.DISPLAY_DOWN);
+ try {
+ finder.createOperation(sourceCRS, targetCRS);
+ fail("Should not create operation between CRS of different
datum.");
+ } catch (OperationNotFoundException e) {
+ final String message = e.getMessage();
+ assertTrue(message, message.contains("A test CRS"));
+ }
+ targetCRS = createEngineering("Screen display",
AxisDirection.DISPLAY_UP);
+ final CoordinateOperation operation =
finder.createOperation(sourceCRS, targetCRS);
+ assertSame("sourceCRS", sourceCRS, operation.getSourceCRS());
+ assertSame("targetCRS", targetCRS, operation.getTargetCRS());
+
+ transform = operation.getMathTransform();
+ assertInstanceOf("transform", LinearTransform.class, transform);
+ assertEquals("sourceDimensions", 2, transform.getSourceDimensions());
+ assertEquals("targetDimensions", 2, transform.getTargetDimensions());
+ Assert.assertMatrixEquals("transform.matrix", Matrices.create(3, 3,
new double[] {
+ 1, 0, 0,
+ 0, -1, 0,
+ 0, 0, 1
+ }), ((LinearTransform) transform).getMatrix(), STRICT);
+ validate();
+ }
+
+ /**
+ * Constructs an axis the given abbreviation and axis direction.
+ */
+ private static DefaultEngineeringCRS createEngineering(final String
datumName, final AxisDirection yDirection) {
+ return new DefaultEngineeringCRS(properties("A test CRS"),
+ new DefaultEngineeringDatum(properties(datumName)),
+ new DefaultCartesianCS(properties("A test CS"),
+ new DefaultCoordinateSystemAxis(properties("x"), "x",
AxisDirection.DISPLAY_RIGHT, Units.METRE),
+ new DefaultCoordinateSystemAxis(properties("y"), "y",
yDirection, Units.METRE)));
+ }
}
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
b/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
index 4cfa397..5924b87 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
@@ -574,9 +574,9 @@ next: for (final Class<?> candidate : candidates) {
}
/**
- * Returns {@code true} if the two specified objects implements exactly
the same set
- * of interfaces. Only interfaces assignable to {@code baseInterface} are
compared.
- * Declaration order doesn't matter.
+ * Returns {@code true} if the two specified objects implements exactly
the same set of interfaces.
+ * Only interfaces assignable to {@code baseInterface} are compared.
+ * Declaration order does not matter.
*
* <div class="note"><b>Example:</b>
* in ISO 19111, different interfaces exist for different coordinate
system (CS) geometries
@@ -585,14 +585,14 @@ next: for (final Class<?> candidate : candidates) {
*
* {@preformat java
* if (implementSameInterfaces(cs1, cs2, CoordinateSystem.class)) {
- * // The two Coordinate System are of the same kind.
+ * // The two Coordinate Systems are of the same kind.
* }
* }
* </div>
*
- * @param object1 the first object to check for interfaces.
- * @param object2 the second object to check for interfaces.
- * @param baseInterface the parent of all interfaces to check.
+ * @param object1 the first object to check for interfaces.
+ * @param object2 the second object to check for interfaces.
+ * @param baseInterface the parent of all interfaces to check.
* @return {@code true} if both objects implement the same set of
interfaces,
* considering only sub-interfaces of {@code baseInterface}.
*/