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 817ba92db8 Consolidation: add a missing `tryConcatenate(Joiner) implementation and minor refactoring of 3 other implementations. Add missing documentation (also in GeoTIFF module). 817ba92db8 is described below commit 817ba92db847e9f841d5cb4f669a9023c1f4199a Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Fri Jan 19 23:08:04 2024 +0100 Consolidation: add a missing `tryConcatenate(Joiner) implementation and minor refactoring of 3 other implementations. Add missing documentation (also in GeoTIFF module). --- .../operation/transform/AbstractMathTransform.java | 18 +--------- .../transform/CoordinateSystemTransform.java | 11 ++++-- .../transform/EllipsoidToCentricTransform.java | 41 +++++++++++----------- .../operation/transform/PassThroughTransform.java | 27 ++++++++++---- .../operation/transform/WraparoundTransform.java | 26 +++++++++++--- .../sis/storage/geotiff/reader/CRSBuilder.java | 10 ++++-- 6 files changed, 79 insertions(+), 54 deletions(-) diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java index 6ea6e41f49..fe11619614 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java @@ -1066,23 +1066,6 @@ public abstract class AbstractMathTransform extends FormattableObject return (step instanceof LinearTransform) || (step instanceof AffineTransform); } - /** - * Concatenates the two given transforms, swapping their order if {@code swap} is {@code true}. - * - * @param first the first math transform. - * @param second the second math transform. - * @param swap whether the given transforms should be swapped. - * @return the concatenated transform. - * @throws FactoryException if the factory cannot perform the concatenation. - */ - MathTransform concatenate(MathTransform first, MathTransform second, boolean swap) throws FactoryException { - if (swap) { - return factory.createConcatenatedTransform(second, first); - } else { - return factory.createConcatenatedTransform(first, second); - } - } - /** * Requests to replace the enclosing transform and neighbor transforms by the given transform. * The {@code bound} argument specifies which neighbors are replaced by the specified transform: @@ -1099,6 +1082,7 @@ public abstract class AbstractMathTransform extends FormattableObject * * This method can be invoked only once per {@code Joiner} instance. * + * @param bound relative index of first (if negative) or last (if positive) transform to replace. * @param concatenation the transform to use instead of the enclosing and neighbor ones. * @throws IllegalStateException if a {@code replace(…)} method has already been invoked. */ 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 5858add515..ec51e3b240 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 @@ -250,9 +250,14 @@ concat: if (info.isLinear(-linearTransformPosition, true)) { for (int j : linearDimensions) { angular.setNumber(j, j, scale); } - MathTransform t = info.factory.createAffineTransform(angular); - t = info.concatenate(t, this, linearTransformPosition < 0); - info.replace(linearTransformPosition, t); + MathTransform first = info.factory.createAffineTransform(angular); + MathTransform other = this; + if (linearTransformPosition < 0) { + other = first; + first = this; + } + first = info.factory.createConcatenatedTransform(first, other); + info.replace(linearTransformPosition, first); return; } } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java index d44836b495..2b34b208b7 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java @@ -998,33 +998,32 @@ next: while (--numPts >= 0) { * instead of a transform based on a matrix of size 4×3.</li> * </ul> * - * @return the combined math transform, or {@code null} if no optimized combined transform is available. + * @param context information about the neighbor transforms, and the object where to set the result. * @throws FactoryException if an error occurred while combining the transforms. */ @Override - protected MathTransform tryConcatenate(final boolean applyOtherFirst, final MathTransform other, - final MathTransformFactory factory) throws FactoryException - { - if (applyOtherFirst && withHeight && other instanceof LinearTransform && other.getSourceDimensions() == 2) { - /* - * Found a 4×3 matrix before this transform. We can reduce to a 3×3 matrix only if the row that we are - * about to drop unconditionally set the height to zero (i.e. all coefficients in that row are zero). - */ - Matrix matrix = ((LinearTransform) other).getMatrix(); - if (matrix.getElement(2,0) == 0 && - matrix.getElement(2,1) == 0 && - matrix.getElement(2,2) == 0) - { - matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3); - final MathTransform tr2D = create2D(); - if (factory != null) { - return factory.createConcatenatedTransform(factory.createAffineTransform(matrix), tr2D); - } else { - return ConcatenatedTransform.create(MathTransforms.linear(matrix), tr2D, factory); + protected void tryConcatenate(final Joiner context) throws FactoryException { + if (withHeight) { + final MathTransform other = context.getTransform(-1).orElse(null); + if (other instanceof LinearTransform && other.getSourceDimensions() == 2) { + /* + * Found a 4×3 matrix before this transform. We can reduce to a 3×3 matrix only if the row that we are + * about to drop unconditionally set the height to zero (i.e. all coefficients in that row are zero). + */ + Matrix matrix = ((LinearTransform) other).getMatrix(); + if (matrix.getElement(2,0) == 0 && + matrix.getElement(2,1) == 0 && + matrix.getElement(2,2) == 0) + { + matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3); + final MathTransform tr2D = create2D(); + MathTransform next = context.factory.createAffineTransform(matrix); + context.replace(-1, context.factory.createConcatenatedTransform(next, tr2D)); + return; } } } - return super.tryConcatenate(applyOtherFirst, other, factory); + super.tryConcatenate(context); } /** diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PassThroughTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PassThroughTransform.java index 53dcc5a4ef..09b380bb9f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PassThroughTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PassThroughTransform.java @@ -726,6 +726,24 @@ public class PassThroughTransform extends AbstractMathTransform implements Seria return sub; } + /** + * Concatenates the sub-transform with the given transform. + * + * @param context information about the neighbor transforms, and the object where to set the result. + * @param relativeIndex index of the transform to replace, relatively to this transform. + * @param other the other transform to concatenate with {@link #subTransform}. + */ + private void concatenateSubTransform(final Joiner context, final int relativeIndex, MathTransform other) throws FactoryException { + MathTransform first = subTransform; + if (relativeIndex < 0) { + first = other; + other = subTransform; + } + other = context.factory.createConcatenatedTransform(first, other); + other = context.factory.createPassThroughTransform(firstAffectedCoordinate, other, numTrailingCoordinates); + context.replace(relativeIndex, other); + } + /** * Concatenates or pre-concatenates in an optimized way this transform with a neighbor, if possible. * This method applies the following special cases: @@ -751,9 +769,7 @@ public class PassThroughTransform extends AbstractMathTransform implements Seria if (other instanceof PassThroughTransform) { final PassThroughTransform opt = (PassThroughTransform) other; if (opt.firstAffectedCoordinate == firstAffectedCoordinate && opt.numTrailingCoordinates == numTrailingCoordinates) { - MathTransform tr = context.concatenate(subTransform, opt.subTransform, relativeIndex < 0); - tr = context.factory.createPassThroughTransform(firstAffectedCoordinate, tr, numTrailingCoordinates); - context.replace(relativeIndex, tr); + concatenateSubTransform(context, relativeIndex, opt.subTransform); return; } } @@ -767,10 +783,7 @@ public class PassThroughTransform extends AbstractMathTransform implements Seria if (m != null) { final Matrix sub = toSubMatrix(relativeIndex < 0, m); if (sub != null) { - MathTransform tr = context.factory.createAffineTransform(sub); - tr = context.concatenate(subTransform, tr, relativeIndex < 0); - tr = context.factory.createPassThroughTransform(firstAffectedCoordinate, tr, numTrailingCoordinates); - context.replace(relativeIndex, tr); + concatenateSubTransform(context, relativeIndex, context.factory.createAffineTransform(sub)); return; } } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/WraparoundTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/WraparoundTransform.java index 7c7550a465..ac4a064f44 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/WraparoundTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/WraparoundTransform.java @@ -472,7 +472,7 @@ public class WraparoundTransform extends AbstractMathTransform implements Serial final Matrix remaining = remaining(applyOtherFirst, move, middle); final WraparoundTransform redim = redim(applyOtherFirst, remaining); if (redim != null) { - step1 = context.concatenate(move, redim, applyOtherFirst); + step1 = concatenate(context, move, redim, applyOtherFirst); middle = remaining; modified = true; } @@ -490,7 +490,7 @@ public class WraparoundTransform extends AbstractMathTransform implements Serial final Matrix remaining = remaining(!applyOtherFirst, move, middle); redim = redim.redim(!applyOtherFirst, remaining); if (redim != null) { - step2 = context.concatenate(redim, move, applyOtherFirst); + step2 = concatenate(context, redim, move, applyOtherFirst); middle = remaining; modified = true; } @@ -521,8 +521,8 @@ public class WraparoundTransform extends AbstractMathTransform implements Serial if (modified) { MathTransform tr = context.factory.createAffineTransform(middle); if (tr.getClass() != middleTr.getClass()) { // See above comment for rational. - tr = context.concatenate(tr, step2, applyOtherFirst); - tr = context.concatenate(step1, tr, applyOtherFirst); + tr = concatenate(context, tr, step2, applyOtherFirst); + tr = concatenate(context, step1, tr, applyOtherFirst); if (applyOtherFirst) { for (int i = count-2; --i >= 0;) { tr = context.factory.createConcatenatedTransform(steps.get(i), tr); @@ -617,6 +617,24 @@ public class WraparoundTransform extends AbstractMathTransform implements Serial : Matrices.multiply(middle, change); } + /** + * Concatenates the two given transforms, swapping their order if {@code swap} is {@code true}. + * + * @param first the first math transform. + * @param second the second math transform. + * @param swap whether the given transforms should be swapped. + * @return the concatenated transform. + * @throws FactoryException if the factory cannot perform the concatenation. + */ + private static MathTransform concatenate(Joiner context, MathTransform first, MathTransform second, boolean swap) throws FactoryException { + if (swap) { + var t = first; + first = second; + second = t; + } + return context.factory.createConcatenatedTransform(first, second); + } + /** * Returns the parameter descriptors for this math transform. * diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java index 038a019e03..6d99737689 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java @@ -113,9 +113,15 @@ public final class CRSBuilder extends ReferencingFactoryContainer { * * In such case, we will split the name into the components names to be stored in an array at indices * given by {@code GCRS}, {@code DATUM}, {@code ELLIPSOID} and {@code PRIMEM}. + * + * <h4>Implementation note:</h4> + * {@link #PRIMEM} must be the first element and {@link #GCRS} must be the last one. + * The {@link #getOrDefault(String[], int)} implementation depends on this assumption. + * + * @see #splitName(String) + * @see #getOrDefault(String[], int) */ static final int PRIMEM = 0, ELLIPSOID = 1, DATUM = 2, GCRS = 3; - // PRIMEM must be first and GCRS must be last. /** * Keys that may be used in the value associated to {@link GeoKeys#GeodeticCitation}. @@ -997,7 +1003,7 @@ public final class CRSBuilder extends ReferencingFactoryContainer { } /** - * Returns the name at the given index if non-null. If that name is null, search for a name in a sister element + * Returns the name at the given index if non-null. If that name is null, searches for a name in a sister element * (e.g. the datum name or the geographic CRS name). If none is found, returns {@code null}. */ private static String getOrDefault(final String[] names, int component) {