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

commit 812908fc7b6ff5609b4a86bce7a00943ed4dcbfd
Author: jsorel <[email protected]>
AuthorDate: Thu Oct 29 10:43:56 2026 +0100

    fix(DGGRS): fix case where code index order was incorrect
---
 .../rs/internal/shared/CodeOperations.java         |  42 ++++++++-
 .../sis/referencing/rs/CodeOperationTest.java      | 101 +++++++++++++++++++++
 2 files changed, 140 insertions(+), 3 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.referencing.dggs/main/org/apache/sis/referencing/rs/internal/shared/CodeOperations.java
 
b/incubator/src/org.apache.sis.referencing.dggs/main/org/apache/sis/referencing/rs/internal/shared/CodeOperations.java
index 1d0a73c184..9d28286bd3 100644
--- 
a/incubator/src/org.apache.sis.referencing.dggs/main/org/apache/sis/referencing/rs/internal/shared/CodeOperations.java
+++ 
b/incubator/src/org.apache.sis.referencing.dggs/main/org/apache/sis/referencing/rs/internal/shared/CodeOperations.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.rs.internal.shared;
 
 import java.util.Arrays;
+import java.util.List;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -149,12 +150,40 @@ public final class CodeOperations {
 
         private final ReferenceSystem sourceRs;
         private final ReferenceSystem targetRs;
+        /**
+         * For each target component, the index of the source component.
+         */
         private final int[] targetMapping;
+        /**
+         * For each source component, the offset of its first ordinate.
+         */
+        private final int[] componentOffsets;
+        /**
+         * For each source component, the number of ordinates.
+         */
+        private final int[] componentDimensions;
+        private final int dimRes;
 
         public Reorder(ReferenceSystem sourceRs, ReferenceSystem targetRs, 
int[] targetMapping) {
             this.sourceRs = sourceRs;
             this.targetRs = targetRs;
             this.targetMapping = targetMapping;
+
+            //same decomposition as ReferenceSystems.findOperation
+            final List<ReferenceSystem> components = 
ReferenceSystems.getSingleComponents(sourceRs, false);
+            componentOffsets = new int[components.size()];
+            componentDimensions = new int[components.size()];
+            int offset = 0;
+            for (int i = 0; i < componentOffsets.length; i++) {
+                componentOffsets[i] = offset;
+                componentDimensions[i] = 
ReferenceSystems.getDimension(components.get(i));
+                offset += componentDimensions[i];
+            }
+            int dim = 0;
+            for (int k : targetMapping) {
+                dim += componentDimensions[k];
+            }
+            dimRes = dim;
         }
 
         @Override
@@ -185,8 +214,15 @@ public final class CodeOperations {
 
         @Override
         public Code transform(Code source, Code target) throws 
TransformException {
-            if (target == null) return new Code(targetRs);
-            target.setOrdinates(source.getOrdinates());
+            final Object[] ordinates = source.getOrdinates();
+            final Object[] result = new Object[dimRes];
+            int k = 0;
+            for (int c : targetMapping) {
+                System.arraycopy(ordinates, componentOffsets[c], result, k, 
componentDimensions[c]);
+                k += componentDimensions[c];
+            }
+            if (target == null) return new Code(targetRs, result);
+            target.setOrdinates(result);
             return target;
         }
 
@@ -450,7 +486,7 @@ public final class CodeOperations {
 
         public Compound(CodeOperation op1, CodeOperation op2, ReferenceSystem 
sourceRS, ReferenceSystem targetRS) {
             this.sourceRS = sourceRS == null ? 
ReferenceSystems.createCompound(op1.getSourceRS(), op2.getSourceRS()) : 
sourceRS;
-            this.targetRS = targetRS == null ? 
ReferenceSystems.createCompound(op1.getTargetRS(), op2.getTargetRS()) : 
sourceRS;
+            this.targetRS = targetRS == null ? 
ReferenceSystems.createCompound(op1.getTargetRS(), op2.getTargetRS()) : 
targetRS;
             this.op1 = op1;
             this.op2 = op2;
             this.dim1 = ReferenceSystems.getDimension(op1.getSourceRS());
diff --git 
a/incubator/src/org.apache.sis.referencing.dggs/test/org/apache/sis/referencing/rs/CodeOperationTest.java
 
b/incubator/src/org.apache.sis.referencing.dggs/test/org/apache/sis/referencing/rs/CodeOperationTest.java
index a69506abfb..cc51538bea 100644
--- 
a/incubator/src/org.apache.sis.referencing.dggs/test/org/apache/sis/referencing/rs/CodeOperationTest.java
+++ 
b/incubator/src/org.apache.sis.referencing.dggs/test/org/apache/sis/referencing/rs/CodeOperationTest.java
@@ -174,4 +174,105 @@ public class CodeOperationTest {
         }
 
     }
+
+    /**
+     * Tests {@link CodeOperations.Reorder} selecting a single component.
+     */
+    @Test
+    public void reorderSelect() throws TransformException {
+        {   //first component
+            final ReferenceSystem source = 
ReferenceSystems.createCompound(MGRS, TIME_JAVA);
+            final CodeOperation operation = CodeOperations.reorder(source, 
MGRS, new int[]{0});
+            final Code code = operation.transform(new Code(source, "4Q FJ 12 
67", 1000.0), null);
+            assertEquals(MGRS, code.getReferenceSystem());
+            assertArrayEquals(new Object[]{"4Q FJ 12 67"}, 
code.getOrdinates());
+        }
+        {   //second component
+            final ReferenceSystem source = 
ReferenceSystems.createCompound(TIME_JAVA, MGRS);
+            final CodeOperation operation = CodeOperations.reorder(source, 
MGRS, new int[]{1});
+            final Code code = operation.transform(new Code(source, 1000.0, "4Q 
FJ 12 67"), null);
+            assertEquals(MGRS, code.getReferenceSystem());
+            assertArrayEquals(new Object[]{"4Q FJ 12 67"}, 
code.getOrdinates());
+        }
+    }
+
+    /**
+     * Tests {@link CodeOperations.Reorder} swapping components, and its 
inverse.
+     */
+    @Test
+    public void reorderSwap() throws TransformException {
+        final ReferenceSystem source = ReferenceSystems.createCompound(MGRS, 
TIME_JAVA);
+        final ReferenceSystem target = 
ReferenceSystems.createCompound(TIME_JAVA, MGRS);
+        final CodeOperation operation = CodeOperations.reorder(source, target, 
new int[]{1, 0});
+
+        final Code code = operation.transform(new Code(source, "4Q FJ 12 67", 
1000.0), null);
+        assertEquals(target, code.getReferenceSystem());
+        assertArrayEquals(new Object[]{1000.0, "4Q FJ 12 67"}, 
code.getOrdinates());
+
+        final CodeOperation inverse = operation.inverse();
+        assertEquals(target, inverse.getSourceRS());
+        assertEquals(source, inverse.getTargetRS());
+        final Code back = inverse.transform(code, null);
+        assertEquals(source, back.getReferenceSystem());
+        assertArrayEquals(new Object[]{"4Q FJ 12 67", 1000.0}, 
back.getOrdinates());
+    }
+
+    /**
+     * Tests {@link CodeOperations.Reorder} with a component of more than one 
dimension,
+     * the mapping is on components, not on ordinates.
+     */
+    @Test
+    public void reorderMultiDimensionalComponent() throws TransformException {
+        final ReferenceSystem geographic = 
CommonCRS.WGS84.normalizedGeographic();
+        final ReferenceSystem source = 
ReferenceSystems.createCompound(geographic, TIME_JAVA);
+        {   //swap
+            final ReferenceSystem target = 
ReferenceSystems.createCompound(TIME_JAVA, geographic);
+            final CodeOperation operation = CodeOperations.reorder(source, 
target, new int[]{1, 0});
+            final Code code = operation.transform(new Code(source, 10.0, 20.0, 
1000.0), null);
+            assertArrayEquals(new Object[]{1000.0, 10.0, 20.0}, 
code.getOrdinates());
+        }
+        {   //select the multi-dimensional component
+            final CodeOperation operation = CodeOperations.reorder(source, 
geographic, new int[]{0});
+            final Code code = operation.transform(new Code(source, 10.0, 20.0, 
1000.0), null);
+            assertArrayEquals(new Object[]{10.0, 20.0}, code.getOrdinates());
+        }
+        {   //select the one-dimensional component after it
+            final CodeOperation operation = CodeOperations.reorder(source, 
TIME_JAVA, new int[]{1});
+            final Code code = operation.transform(new Code(source, 10.0, 20.0, 
1000.0), null);
+            assertArrayEquals(new Object[]{1000.0}, code.getOrdinates());
+        }
+    }
+
+    /**
+     * Tests {@link CodeOperations.Reorder} writing in a given target code.
+     */
+    @Test
+    public void reorderInTarget() throws TransformException {
+        final ReferenceSystem source = ReferenceSystems.createCompound(MGRS, 
TIME_JAVA);
+        final CodeOperation operation = CodeOperations.reorder(source, MGRS, 
new int[]{0});
+        final Code target = new Code(MGRS);
+        final Code code = operation.transform(new Code(source, "4Q FJ 12 67", 
1000.0), target);
+        assertSame(target, code);
+        assertArrayEquals(new Object[]{"4Q FJ 12 67"}, code.getOrdinates());
+    }
+
+    /**
+     * Tests operations found by {@link ReferenceSystems#findOperation} which 
drop a component.
+     */
+    @Test
+    public void reorderFromFindOperation() throws FactoryException, 
TransformException {
+        {   //only a reorder is needed
+            final ReferenceSystem mrgs3d = 
ReferenceSystems.createCompound(MGRS, TIME_JAVA);
+            final CodeOperation operation = 
ReferenceSystems.findOperation(mrgs3d, MGRS, null);
+            assertTrue(operation instanceof CodeOperations.Reorder);
+            final Code code = operation.transform(new Code(mrgs3d, "4Q FJ 12 
67", 1000.0), null);
+            assertArrayEquals(new Object[]{"4Q FJ 12 67"}, 
code.getOrdinates());
+        }
+        {   //reorder followed by a conversion
+            final ReferenceSystem mrgs3d = 
ReferenceSystems.createCompound(TIME_JAVA, MGRS);
+            final CodeOperation operation = 
ReferenceSystems.findOperation(mrgs3d, GEOHASH, null);
+            final Code code = operation.transform(new Code(mrgs3d, 1000.0, "4Q 
FJ 12 67"), null);
+            assertEquals("87z9y8fhdbff", code.getOrdinate(0));
+        }
+    }
 }

Reply via email to