This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits 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 5107e0afa6 Fix an `IndexOutOfBoundsException` when the CRS component
which is present in only the target CRS is not the last one.
5107e0afa6 is described below
commit 5107e0afa6afef69deed8fedf66a9b24ed6aab15
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Fri Jul 24 17:50:41 2026 +0200
Fix an `IndexOutOfBoundsException` when the CRS component which is present
in only the target CRS is not the last one.
---
.../operation/CoordinateOperationFinder.java | 9 ++---
.../referencing/operation/SubOperationInfo.java | 40 ++++++++++++++++++++--
2 files changed, 42 insertions(+), 7 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index 8b95682a0f..9b963d3e8d 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -925,6 +925,7 @@ public class CoordinateOperationFinder extends
CoordinateOperationRegistry {
}
/*
* At this point, a coordinate operation has been found for all
components of the target CRS.
+ * That coordinate operation may be explicit (non-null) or implicit (a
coordinate coordinate).
* However, the CoordinateOperation.getSourceCRS() values are not
necessarily in the same order
* than in the `sourceComponents` list given to this method, and some
dimensions may be dropped.
* The matrix computed by sourceToSelected(…) gives us the
rearrangement needed for the coordinate
@@ -934,9 +935,9 @@ public class CoordinateOperationFinder extends
CoordinateOperationRegistry {
final Matrix select =
SubOperationInfo.sourceToSelected(sourceCRS.getCoordinateSystem().getDimension(),
infos);
/*
* First, we need a CRS matching the above-cited rearrangement. That
CRS will be named `stepSourceCRS`
- * and its components will be named `stepComponents`. Then we will
execute a loop in which each component
- * is progressively (one by one) updated from a source component to a
target component. A new step CRS is
- * recreated each time, since it will be needed for each
PassThroughOperation.
+ * and its components will be named `stepComponents`. Then we will
execute a loop in which each
+ * component is progressively (one by one) updated from a source
component to a target component.
+ * A new step CRS is recreated each time, since it will be needed for
each PassThroughOperation.
*/
CoordinateReferenceSystem stepSourceCRS;
CoordinateOperation operation;
@@ -972,7 +973,7 @@ public class CoordinateOperationFinder extends
CoordinateOperationRegistry {
* Only after the loop finished, `stepTargetCRS` will become the
complete target definition.
*/
final CoordinateReferenceSystem stepTargetCRS;
- stepComponents[info.targetComponentIndex] = target;
+ stepComponents[info.targetComponentIndex()] = target;
if (i >= indexOfFinal) {
stepTargetCRS = targetCRS; // If all remaining
transforms are identity, we reached the final CRS.
} else if (info.isIdentity()) {
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/SubOperationInfo.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/SubOperationInfo.java
index 3fb21d253b..764ba76372 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/SubOperationInfo.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/SubOperationInfo.java
@@ -31,6 +31,9 @@ import org.apache.sis.referencing.internal.Resources;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.measure.NumberRange;
+import org.apache.sis.util.Classes;
+import org.apache.sis.util.internal.shared.Strings;
// Specific to the geoapi-4.0 branch:
import org.apache.sis.referencing.legacy.DefaultImageCRS;
@@ -104,6 +107,9 @@ final class SubOperationInfo {
/**
* The first dimension (inclusive) and the last dimension (exclusive)
where the
* {@link SingleCRS} starts/ends in the full (usually compound)
<abbr>CRS</abbr>.
+ * The source dimension may be equal to the target dimension if the
component does
+ * not exist in the source <abbr>CRS</abbr>, in which case {@link
#constantCoordinates}
+ * should be specified.
*
* @see #sourceToSelected(int, SubOperationInfo[])
*/
@@ -111,10 +117,13 @@ final class SubOperationInfo {
targetLowerDimension, targetUpperDimension;
/**
- * Index of this instance in the array of {@code SubOperationInfo}
instances,
- * before the reordering applied by {@link
#getSourceCRS(SubOperationInfo[])}.
+ * Index of this instance in the array of {@code SubOperationInfo}
instances.
+ * This is initially the index in the array returned by {@link
#createSteps createSteps(…)},
+ * then is modified by the reordering applied by {@link
#getSourceCRS(SubOperationInfo[])}.
+ *
+ * @see #targetComponentIndex()
*/
- final int targetComponentIndex;
+ private int targetComponentIndex;
/**
* The component of the target <abbr>CRS</abbr> which is managed by this
{@code SubOperationInfo}.
@@ -313,6 +322,10 @@ searchSrc: while (sourceComponentIndex <
sourceComponentIsUsed.length) {
if (component.operation == null) {
System.arraycopy(selected, i+1, selected, i, last - i);
selected[last] = component;
+ component.targetComponentIndex = last;
+ for (int j = last; --j >= i;) {
+ selected[j].targetComponentIndex--;
+ }
n--;
i--;
}
@@ -396,6 +409,15 @@ searchSrc: while (sourceComponentIndex <
sourceComponentIsUsed.length) {
return select;
}
+ /**
+ * Returns the index of this instance in the array of {@code
SubOperationInfo} instances.
+ * The returned value may differ depending on whether this method is
invoked before or after
+ * {@link #getSourceCRS(SubOperationInfo[])}.
+ */
+ final int targetComponentIndex() {
+ return targetComponentIndex;
+ }
+
/**
* Returns {@code true} if the coordinate operation wrapped by this object
is an identity transform.
*/
@@ -485,4 +507,16 @@ otherRow: for (int j = last.getNumRow() - 1; --j
>= 0;) { // Ignor
final boolean resultWasContextSensitive() {
return constantCoordinates != null;
}
+
+ /**
+ * Returns a string representation for debugging purposes.
+ */
+ @Override
+ public String toString() {
+ return Strings.toString(getClass(),
+ "index", targetComponentIndex,
+ "type", Classes.getShortClassName(targetComponent),
+ "source", new NumberRange<>(Integer.class,
sourceLowerDimension, true, sourceUpperDimension, false),
+ "target", new NumberRange<>(Integer.class,
targetLowerDimension, true, targetUpperDimension, false));
+ }
}