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)); + } + } }
