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 6ec7df4c02 Concatenated operation handle automatically the change of
coordinate system in the last step. For example, if the target CRS of the last
`SingleOperation` uses a CartesianCS but the target CRS of the
`ConcatenatedOperation` uses a SphericalCS, a conversion will be added
automatically.
6ec7df4c02 is described below
commit 6ec7df4c0263d91bdf92d60c589b607ed490c5f3
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Jan 15 19:42:19 2024 +0100
Concatenated operation handle automatically the change of coordinate system
in the last step.
For example, if the target CRS of the last `SingleOperation` uses a
CartesianCS but the target CRS
of the `ConcatenatedOperation` uses a SphericalCS, a conversion will be
added automatically.
---
.../main/org/apache/sis/referencing/CommonCRS.java | 13 ++--
.../operation/DefaultConcatenatedOperation.java | 14 +++-
.../transform/CoordinateSystemTransform.java | 88 ++++++++++++++++++++--
.../transform/DefaultMathTransformFactory.java | 6 +-
4 files changed, 105 insertions(+), 16 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 6a436a84fb..136ff858a3 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.time.Instant;
-import static java.util.Collections.singletonMap;
import javax.measure.Unit;
import javax.measure.quantity.Time;
import org.opengis.metadata.Identifier;
@@ -1919,7 +1918,7 @@ public enum CommonCRS {
* <tr><th>Unit:</th> <td>{@link Units#UNITY}</td></tr>
* </table></blockquote>
*/
- GRID(new
DefaultEngineeringDatum(singletonMap(EngineeringDatum.NAME_KEY, "Cell
indices"))),
+ GRID(new DefaultEngineeringDatum(Map.of(EngineeringDatum.NAME_KEY,
"Cell indices"))),
/**
* A single-dimensional coordinate system for time in seconds since an
unknown epoch.
@@ -1936,7 +1935,7 @@ public enum CommonCRS {
*
* @see Temporal
*/
- TIME(new
DefaultEngineeringDatum(singletonMap(EngineeringDatum.NAME_KEY, "Time")));
+ TIME(new DefaultEngineeringDatum(Map.of(EngineeringDatum.NAME_KEY,
"Time")));
/**
* The datum.
@@ -1964,7 +1963,7 @@ public enum CommonCRS {
if (crs == null) {
final String x, y;
final AxisDirection dx, dy;
- final Map<String,Object> pcs =
singletonMap(CartesianCS.NAME_KEY, datum.getName());
+ final Map<String,Object> pcs = Map.of(CartesianCS.NAME_KEY,
datum.getName());
final Map<String,Object> properties = new HashMap<>(pcs);
CoordinateSystem cs = null;
switch (this) {
@@ -1988,15 +1987,15 @@ public enum CommonCRS {
x = y = "t";
dx = dy = AxisDirection.FUTURE;
cs = new DefaultTimeCS(pcs, new
DefaultCoordinateSystemAxis(
- singletonMap(TimeCS.NAME_KEY, x), x, dx,
Units.SECOND));
+ Map.of(TimeCS.NAME_KEY, x), x, dx,
Units.SECOND));
break;
}
default: throw new AssertionError(this);
}
if (cs == null) {
cs = new DefaultCartesianCS(pcs,
- new
DefaultCoordinateSystemAxis(singletonMap(CartesianCS.NAME_KEY, x), x, dx,
Units.PIXEL),
- new
DefaultCoordinateSystemAxis(singletonMap(CartesianCS.NAME_KEY, y), y, dy,
Units.PIXEL));
+ new
DefaultCoordinateSystemAxis(Map.of(CartesianCS.NAME_KEY, x), x, dx,
Units.PIXEL),
+ new
DefaultCoordinateSystemAxis(Map.of(CartesianCS.NAME_KEY, y), y, dy,
Units.PIXEL));
}
crs = new DefaultEngineeringCRS(properties, datum, cs);
}
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 9fb03672f2..519fb54e7f 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
@@ -38,6 +38,7 @@ import
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactor
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.referencing.util.PositionalAccuracyConstant;
import org.apache.sis.referencing.util.CoordinateOperations;
+import org.apache.sis.referencing.util.ReferencingUtilities;
import org.apache.sis.referencing.internal.Resources;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.ComparisonMode;
@@ -167,8 +168,16 @@ final class DefaultConcatenatedOperation extends
AbstractCoordinateOperation imp
final List<CoordinateOperation> flattened = new
ArrayList<>(operations.length);
final CoordinateReferenceSystem crs = initialize(properties,
operations, flattened, mtFactory,
sourceCRS, (sourceCRS == null), (coordinateOperationAccuracy
== null));
+
if (targetCRS == null) {
targetCRS = crs;
+ } else if (mtFactory instanceof DefaultMathTransformFactory) {
+ final var dmf = (DefaultMathTransformFactory) mtFactory;
+ final MathTransform t = dmf.createCoordinateSystemChange(
+ crs.getCoordinateSystem(),
+ targetCRS.getCoordinateSystem(),
+ ReferencingUtilities.getEllipsoid(crs));
+ transform = dmf.createConcatenatedTransform(transform, t);
}
/*
* At this point we should have flattened.size() >= 2, except if some
operations
@@ -305,7 +314,10 @@ final class DefaultConcatenatedOperation extends
AbstractCoordinateOperation imp
}
}
}
- verifyStepChaining(properties, operations.length, target, targetCRS,
null);
+ if (!(mtFactory instanceof DefaultMathTransformFactory)) {
+ verifyStepChaining(properties, operations.length, target,
targetCRS, null);
+ // Else verification will be done by the caller.
+ }
return previous;
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
index d133e7756e..95d51daa4d 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
@@ -17,6 +17,8 @@
package org.apache.sis.referencing.operation.transform;
import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
import javax.measure.IncommensurableException;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
@@ -38,6 +40,7 @@ import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.cs.CoordinateSystems;
+import org.apache.sis.referencing.cs.DefaultCompoundCS;
import org.apache.sis.referencing.operation.DefaultOperationMethod;
@@ -182,12 +185,87 @@ abstract class CoordinateSystemTransform extends
AbstractMathTransform {
}
/**
- * Implementation of {@link
DefaultMathTransformFactory#createCoordinateSystemChange(CoordinateSystem,
- * CoordinateSystem, Ellipsoid)}, defined here for reducing the {@code
DefaultMathTransformFactory}
- * weight in the common case where the conversions handled by this class
are not needed.
+ * Adds the components of the given coordinate system in the specified
list.
+ * This method may invoke itself recursively if there is nested compound
CS.
+ * The returned list is always a copy and can be safely modified.
*/
- static MathTransform create(final MathTransformFactory factory, final
CoordinateSystem source,
- final CoordinateSystem target, final ThreadLocal<OperationMethod>
lastMethod) throws FactoryException
+ private static void getComponents(final CoordinateSystem cs, final
List<CoordinateSystem> addTo) {
+ if (cs instanceof DefaultCompoundCS) {
+ addTo.addAll(((DefaultCompoundCS) cs).getComponents());
+ } else {
+ addTo.add(cs);
+ }
+ }
+
+ /**
+ * Implementation of {@code createCoordinateSystemChange(…)}, defined here
for reducing the
+ * {@link DefaultMathTransformFactory} weight in the common case where the
conversions handled
+ * by this class are not needed.
+ *
+ * @todo Handle the case where coordinate system components are not in the
same order.
+ *
+ * @param factory the factory to use for creating math transforms.
+ * @param source the source coordinate system.
+ * @param target the target coordinate system.
+ * @param lastMethod where to set the coordinate operation method used.
+ * @return the transform from the given source CS to the given target CS.
+ * @throws FactoryException if an error occurred while creating a
transform.
+ */
+ static MathTransform create(final MathTransformFactory factory,
+ final CoordinateSystem source,
+ final CoordinateSystem target,
+ final ThreadLocal<OperationMethod> lastMethod)
+ throws FactoryException
+ {
+ final var sources = new ArrayList<CoordinateSystem>(3);
getComponents(source, sources);
+ final var targets = new ArrayList<CoordinateSystem>(3);
getComponents(target, targets);
+ final int count = sources.size();
+ /*
+ * Current implementation expects the same number of components, in
the same order
+ * and with the same number of dimensions in each component. A future
version will
+ * need to improve on that.
+ */
+ MathTransform result = null;
+ if (count == targets.size()) {
+ final int dimension = source.getDimension();
+ int firstAffectedCoordinate = 0;
+ for (int i=0; i<count; i++) {
+ final CoordinateSystem s = sources.get(i);
+ final CoordinateSystem t = targets.get(i);
+ final int sd = s.getDimension();
+ if (t.getDimension() != sd) {
+ result = null;
+ break;
+ }
+ final MathTransform subTransform =
factory.createPassThroughTransform(
+ firstAffectedCoordinate,
+ single(factory, s, t, lastMethod),
+ dimension - (firstAffectedCoordinate + sd));
+ if (result == null) {
+ result = subTransform;
+ } else {
+ result = factory.createConcatenatedTransform(result,
subTransform);
+ }
+ firstAffectedCoordinate += sd;
+ }
+ }
+ // If we couldn't process components separately, try with the compound
CS as a whole.
+ if (result == null) {
+ result = single(factory, source, target, lastMethod);
+ }
+ return result;
+ }
+
+ /**
+ * Implementation of {@code create(…)} for a single component.
+ * This implementation performs can handle changes of coordinate system
type between
+ * {@link CartesianCS}, {@link SphericalCS}, {@link CylindricalCS} and
{@link PolarCS}.
+ */
+ private static MathTransform single(final MathTransformFactory factory,
+ final CoordinateSystem source,
+ final CoordinateSystem target,
+ final ThreadLocal<OperationMethod>
lastMethod)
+ throws FactoryException
{
int passthrough = 0;
CoordinateSystemTransform kernel = null;
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
index 3afd8d1f4b..4ac8bd5642 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
@@ -163,7 +163,7 @@ import org.apache.sis.util.resources.Errors;
* There is typically only one {@code MathTransformFactory} instance for the
whole application.
*
* @author Martin Desruisseaux (Geomatys, IRD)
- * @version 1.4
+ * @version 1.5
*
* @see MathTransformProvider
* @see AbstractMathTransform
@@ -729,7 +729,7 @@ public class DefaultMathTransformFactory extends
AbstractFactory implements Math
* </ul>
*
* This method is invoked by {@link
DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, Context)}.
- * Users an override this method if they need to customize the
normalization process.
+ * Users can override this method if they need to customize the
normalization process.
*
* @param role whether the normalization or denormalization matrix
is desired.
* @return the requested matrix, or {@code null} if this {@code
Context} has no information about the coordinate system.
@@ -1296,7 +1296,7 @@ public class DefaultMathTransformFactory extends
AbstractFactory implements Math
* {@linkplain org.opengis.referencing.cs.AxisDirection#NORTH North}) axis
orientations.
*
* <h4>Controlling the normalization process</h4>
- * Users who need a different normalized space than the default one way
find more convenient to
+ * Users who need a different normalized space than the default one may
find more convenient to
* override the {@link Context#getMatrix
Context.getMatrix(ContextualParameters.MatrixRole)} method.
*
* @param parameterized a transform for normalized input and output
coordinates.