This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/sis.git
commit 42a3d15915c33d0395e0620117b64b5e13b7ba63 Merge: 95d808c404 cb32b1b2f0 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Tue Jun 24 18:21:42 2025 +0200 Merge branch 'geoapi-3.1', excluding the `org.apache.sis.geometry` module (incubator). That geometry module depends on GeoAPI interfaces that are not released (and may not). A review of the geometry module is necessary before it can be merged to the main branch. buildSrc/build.gradle.kts | 2 +- .../main/org/apache/sis/console/AboutCommand.java | 2 +- .../main/org/apache/sis/coverage/CategoryList.java | 10 +- .../coverage/grid/CoordinateOperationFinder.java | 116 ++- .../sis/coverage/internal/CompoundTransform.java | 8 +- .../sis/geometry/wrapper/GeometryFactories.java | 2 +- .../org/apache/sis/geometry/wrapper/jts/JTS.java | 96 +++ .../main/org/apache/sis/image/AnnotatedImage.java | 2 +- .../main/org/apache/sis/image/ErrorHandler.java | 2 +- .../org/apache/sis/image/privy/TileOpExecutor.java | 2 +- .../sis/coverage/grid/GridDerivationTest.java | 28 + .../apache/sis/coverage/grid/GridGeometryTest.java | 61 +- .../apache/sis/metadata/sql/CachedStatement.java | 2 +- .../apache/sis/metadata/sql/MetadataSource.java | 4 +- .../apache/sis/metadata/sql/MetadataWriter.java | 2 +- .../apache/sis/metadata/sql/privy/Initializer.java | 6 +- .../main/org/apache/sis/util/iso/Types.java | 2 +- .../main/org/apache/sis/xml/bind/Context.java | 2 +- .../apache/sis/xml/privy/ExceptionSimplifier.java | 2 +- .../org/apache/sis/metadata/sql/TestDatabase.java | 3 +- .../main/org/apache/sis/io/wkt/Warnings.java | 4 +- .../factory/AuthorityFactoryIdentifier.java | 4 +- .../factory/ConcurrentAuthorityFactory.java | 4 +- .../referencing/factory/GeodeticObjectFactory.java | 2 +- .../referencing/factory/IdentifiedObjectSet.java | 2 +- .../factory/MultiAuthoritiesFactory.java | 4 +- .../referencing/factory/sql/EPSGDataAccess.java | 14 +- .../sis/referencing/factory/sql/EPSGInstaller.java | 13 +- .../factory/sql/InstallationScriptProvider.java | 4 +- .../internal/ParameterizedTransformBuilder.java | 9 +- .../apache/sis/referencing/internal/Resources.java | 10 + .../sis/referencing/internal/Resources.properties | 2 + .../referencing/internal/Resources_fr.properties | 2 + .../apache/sis/referencing/operation/CRSPair.java | 4 +- .../operation/CoordinateOperationFinder.java | 33 +- .../operation/CoordinateOperationRegistry.java | 2 +- .../referencing/operation/SubOperationInfo.java | 174 ++-- .../referencing/operation/gridded/GridFile.java | 5 +- .../referencing/operation/gridded/LoadedGrid.java | 2 +- .../projection/EquidistantCylindrical.java | 25 + .../referencing/operation/projection/Mercator.java | 41 +- .../operation/projection/NormalizedProjection.java | 7 +- .../provider/FranceGeocentricInterpolation.java | 2 +- .../operation/provider/Interpolation1D.java | 10 +- .../sis/referencing/operation/provider/NTv2.java | 4 +- .../operation/transform/AbstractMathTransform.java | 379 +-------- .../transform/AbstractMathTransform1D.java | 24 +- .../transform/AbstractMathTransform2D.java | 6 +- .../operation/transform/ConcatenatedTransform.java | 428 +++++----- .../transform/ConcatenatedTransformDirect.java | 4 +- .../operation/transform/ConstantTransform1D.java | 8 +- .../transform/CoordinateSystemTransform.java | 23 +- .../operation/transform/CopyTransform.java | 2 +- .../operation/transform/DatumShiftTransform.java | 22 +- .../transform/DefaultMathTransformFactory.java | 3 +- .../transform/EllipsoidToCentricTransform.java | 18 +- .../transform/EllipsoidToRadiusTransform.java | 10 +- .../transform/ExponentialTransform1D.java | 15 +- .../operation/transform/IdentityTransform.java | 16 +- .../operation/transform/IdentityTransform1D.java | 8 +- .../operation/transform/InterpolatedTransform.java | 2 +- .../operation/transform/LinearInterpolator1D.java | 7 +- .../operation/transform/LinearTransform1D.java | 10 +- .../transform/LogarithmicTransform1D.java | 33 +- .../operation/transform/MathTransforms.java | 77 +- .../operation/transform/MolodenskyTransform.java | 48 +- .../operation/transform/PassThroughTransform.java | 94 +- .../operation/transform/PowerTransform1D.java | 17 +- .../operation/transform/ProjectiveTransform.java | 2 +- .../operation/transform/ScaleTransform.java | 2 +- .../operation/transform/TransformJoiner.java | 945 +++++++++++++++++++++ .../operation/transform/TransformSeparator.java | 2 +- .../operation/transform/TranslationTransform.java | 2 +- .../operation/transform/UnitConversion.java | 10 +- .../operation/transform/WraparoundTransform.java | 321 +++---- .../sis/referencing/privy/DefinitionVerifier.java | 2 +- .../apache/sis/geometry/EnvelopeReducerTest.java | 7 +- .../referencing/crs/DefaultProjectedCRSTest.java | 5 +- .../DefaultCoordinateOperationFactoryTest.java | 4 +- .../operation/projection/ObliqueMercatorTest.java | 4 +- .../transform/ConcatenatedTransformTest.java | 69 +- .../transform/EllipsoidToCentricTransformTest.java | 4 +- .../transform/EllipsoidToRadiusTransformTest.java | 22 + .../operation/transform/MathTransformWrapper.java | 8 +- .../transform/MolodenskyTransformTest.java | 56 +- .../transform/PassThroughTransformTest.java | 36 +- .../transform/TransformResultComparator.java | 9 +- .../transform/TransformSeparatorTest.java | 4 +- .../transform/WraparoundTransformTest.java | 2 +- .../sis/storage/geotiff/ImageFileDirectory.java | 2 +- .../sis/storage/geotiff/reader/CRSBuilder.java | 2 +- .../sis/storage/netcdf/NetcdfStoreProvider.java | 2 +- .../apache/sis/storage/netcdf/base/Decoder.java | 2 +- .../org/apache/sis/storage/netcdf/base/Grid.java | 3 +- .../sis/storage/netcdf/base/NamedElement.java | 2 +- .../apache/sis/storage/sql/feature/Database.java | 2 +- .../sis/storage/sql/feature/SelectionClause.java | 2 +- .../apache/sis/storage/sql/postgis/Postgres.java | 6 +- .../sis/storage/AbstractGridCoverageResource.java | 2 +- .../main/org/apache/sis/storage/URLDataSource.java | 9 +- .../sis/storage/base/DocumentedStoreProvider.java | 2 +- .../org/apache/sis/storage/base/URIDataStore.java | 6 +- .../sis/storage/csv/MovingFeatureBuilder.java | 9 +- .../main/org/apache/sis/storage/csv/Store.java | 2 +- .../org/apache/sis/storage/wkt/StoreFormat.java | 2 +- .../main/org/apache/sis/system/DataDirectory.java | 2 +- .../org/apache/sis/system/OptionalDependency.java | 6 +- .../main/org/apache/sis/system/Supervisor.java | 2 +- .../org/apache/sis/util/collection/WeakEntry.java | 2 +- .../main/org/apache/sis/util/resources/Errors.java | 2 +- .../apache/sis/util/resources/Errors.properties | 2 +- .../apache/sis/util/resources/Errors_fr.properties | 2 +- .../sis/util/resources/IndexedResourceBundle.java | 55 +- .../resources/ResourceInternationalString.java | 2 +- .../util/resources/IndexedResourceBundleTest.java | 8 +- incubator/build.gradle.kts | 6 +- .../apache/sis/storage/geoheif/GeoHeifStore.java | 2 +- .../org/apache/sis/storage/isobmff/Reader.java | 2 +- netbeans-project/ivy.xml | 16 +- netbeans-project/nbproject/project.xml | 1 + .../main/org/apache/sis/storage/gdal/GDAL.java | 2 +- .../apache/sis/storage/panama/LibraryLoader.java | 2 +- settings.gradle.kts | 12 +- 123 files changed, 2399 insertions(+), 1289 deletions(-) diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/SubOperationInfo.java index e845b6e2a5,b6ab6e89f7..f58a9eaaf7 --- 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 @@@ -18,16 -18,17 +18,20 @@@ package org.apache.sis.referencing.oper import java.util.List; import org.opengis.referencing.crs.*; + import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.OperationNotFoundException; + import org.opengis.referencing.operation.NoninvertibleTransformException; import org.opengis.referencing.operation.TransformException; import org.opengis.util.FactoryException; + 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; +// Specific to the main branch: +import org.apache.sis.referencing.crs.DefaultParametricCRS; + /** * Information about the operation from a source component to a target component in {@code CompoundCRS} instances. diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java index 28d98f6fc6,8e7f6cf19f..aa73abba1f --- 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 @@@ -49,12 -46,10 +46,10 @@@ import org.apache.sis.util.Utilities import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.LenientComparable; import org.apache.sis.util.OptionalCandidate; - import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.util.resources.Errors; - import org.apache.sis.util.logging.Logging; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.coordinate.MismatchedDimensionException; +// Specific to the main branch: +import org.opengis.geometry.MismatchedDimensionException; /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java index 4551bcdfb2,fef35f5bcb..e0f30cac58 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java @@@ -135,8 -147,8 +147,8 @@@ public abstract class AbstractMathTrans if (point == null) { coordinate = Double.NaN; } else { - ensureDimensionMatches("point", 1, point); + ensureDimensionMatches("point", DIMENSION, point); - coordinate = point.getCoordinate(0); + coordinate = point.getOrdinate(0); } return new Matrix1(derivative(coordinate)); } @@@ -214,8 -226,8 +226,8 @@@ if (point == null) { coordinate = Double.NaN; } else { - ensureDimensionMatches("point", 1, point); + ensureDimensionMatches("point", DIMENSION, point); - coordinate = point.getCoordinate(0); + coordinate = point.getOrdinate(0); } return new Matrix1(derivative(coordinate)); } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java index 7c776b623a,26b85b0af3..0564d0c7a9 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java @@@ -294,8 -294,11 +294,9 @@@ public final class MathTransforms exten * * @param preimage the input values (<var>x</var>) in the function domain, or {@code null}. * @param values the output values (<var>y</var>) in the function range, or {@code null}. + * @throws IllegalArgumentException if {@code preimage} is non-null and the sequence of values is not monotonic. * @return the <i>y=f(x)</i> function. * - * @see org.opengis.coverage.InterpolationMethod - * * @since 0.7 */ public static MathTransform1D interpolate(final double[] preimage, final double[] values) { diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java index 517c8fadde,bbae27f48e..a77cb57d68 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java @@@ -26,7 -25,12 +25,8 @@@ import org.apache.sis.parameter.Paramet // Test dependencies import org.junit.jupiter.api.Test; + import org.apache.sis.referencing.datum.HardCodedDatum; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.util.FactoryException; -import org.opengis.test.ToleranceModifier; - /** * Tests the {@link ObliqueMercator} class. diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java index 9b15e1d5cf,8315b68eef..d118a1f2b8 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java @@@ -158,6 -161,48 +161,48 @@@ public final class ConcatenatedTransfor assertEquals(4, transform.getTargetDimensions()); } + /** + * Test pass-through which is build-in the transform. + * + * @throws FactoryException if an error occurred while creating the math transform to test. + */ + @Test + public void testBuildinPassthrough() throws FactoryException { + final var kernel = new PseudoTransform(2, 2) { + /** Whether the pass-through optimization has been applied. */ + private boolean done; + + /** Tries to apply the pass-through optimization. */ + @Override protected void tryConcatenate(final TransformJoiner context) throws FactoryException { + if (context.replacePassThrough(Map.of(1, 1))) { + assertFalse(done); + done = true; + } + } + }; + final Matrix3 before, after; + before = new Matrix3(0.25, 0, -45, + 0, -0.25, 90, + 0, 0, 1); + + after = new Matrix3(1, 0, 45, + 0, -1, 90, + 0, 0, 1); + + transform = MathTransforms.concatenate(MathTransforms.linear(before), kernel, MathTransforms.linear(after)); + final List<MathTransform> steps = MathTransforms.getSteps(transform); + assertEquals(3, steps.size()); + assertSame(kernel, steps.get(1)); + /* + * The optimization should have moved the -1 factor from `after` to `before` + * in order to simplify `after` to a matrix doing only a translation. + */ + after .m11 = -after .m11; after .m12 = 0; + before.m11 = -before.m11; before.m12 = 0; - assertMatrixEquals(before, MathTransforms.getMatrix(steps.get(0)), null, "before"); - assertMatrixEquals(after, MathTransforms.getMatrix(steps.get(2)), null, "after"); ++ assertMatrixEquals(before, MathTransforms.getMatrix(steps.get(0)), STRICT, "before"); ++ assertMatrixEquals(after, MathTransforms.getMatrix(steps.get(2)), STRICT, "after"); + } + /** * Tests concatenation of transforms built from non-square matrices. The transforms are invertible * when taken separately, but the transform resulting from concatenation cannot be inverted unless diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransformTest.java index 09513a4b3f,d4c6831e94..4530cfd75a --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransformTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransformTest.java @@@ -24,8 -26,9 +26,10 @@@ import org.apache.sis.referencing.opera // Test dependencies import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.*; import org.apache.sis.referencing.datum.HardCodedDatum; import static org.apache.sis.test.Assertions.assertSerializedEquals; ++import static org.apache.sis.test.GeoapiAssert.assertMatrixEquals; /** @@@ -103,6 -106,24 +107,24 @@@ public final class EllipsoidToRadiusTra }); } + /** + * Tests a concatenation of transform that can be simplified by moving an offset of the longitude value. + */ + @Test + public void testPassThrough() { + transform = new EllipsoidToRadiusTransform(HardCodedDatum.WGS84.getEllipsoid()); + transform = MathTransforms.concatenate(MathTransforms.scale(2, 3), transform, MathTransforms.translation(-5, 0, 0)); + final ConcatenatedTransform c = assertInstanceOf(ConcatenatedTransform.class, transform); + final EllipsoidToRadiusTransform tr2 = assertInstanceOf(EllipsoidToRadiusTransform.class, c.transform2); + assertEquals(0.006694379990141317, tr2.eccentricitySquared, 1E-17); + final Matrix tr1 = MathTransforms.getMatrix(c.transform1); + assertNotNull(tr1); + assertMatrixEquals(new Matrix3( + 2, 0, -5, + 0, 3, 0, - 0, 0, 1), tr1, null, null); ++ 0, 0, 1), tr1, 0, null); + } + /** * Tests serialization. * diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java index 04255fa62c,699e340af0..72ee28d56f --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java @@@ -31,13 -33,24 +33,14 @@@ import org.apache.sis.referencing.privy // Test dependencies import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; - import org.apache.sis.referencing.operation.provider.FranceGeocentricInterpolationTest; - import org.apache.sis.referencing.operation.provider.GeocentricTranslationTest; import org.apache.sis.test.TestUtilities; + import org.apache.sis.referencing.datum.GeodeticDatumMock; import org.apache.sis.referencing.datum.HardCodedDatum; + import org.apache.sis.referencing.operation.provider.FranceGeocentricInterpolationTest; + import org.apache.sis.referencing.operation.provider.GeocentricTranslationTest; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import java.io.IOException; -import org.opengis.referencing.operation.MathTransform; -import org.apache.sis.referencing.operation.provider.AbridgedMolodensky; -import org.apache.sis.math.StatisticsFormat; -import org.apache.sis.math.Statistics; -import static org.apache.sis.metadata.privy.ReferencingServices.NAUTICAL_MILE; -import org.opengis.test.CalculationType; -import org.opengis.test.ToleranceModifier; -import org.opengis.test.ToleranceModifiers; -import org.opengis.test.referencing.ParameterizedTransformTest; -import org.apache.sis.test.TestCase; +// Specific to the main branch: +import static org.apache.sis.referencing.privy.CoordinateOperations.builder; /** @@@ -63,8 -76,69 +66,8 @@@ public final class MolodenskyTransformT tolerance = Formulas.ANGULAR_TOLERANCE; // Tolerance for longitude and latitude in degrees } - /** - * Compares the Molodensky (non-abridged) transform with a geocentric translation. - * Molodensky is an approximation of geocentric translation, so we test here how good this approximation is. - * If {@link TestCase#VERBOSE} is {@code true}, then this method will print error statistics. - * - * @throws FactoryException if an error occurred while creating a transform step. - * @throws TransformException if a transformation failed. - * @throws IOException should never happen. - * - * @see #compareWithGeocentricTranslation() - */ - @SuppressWarnings("fallthrough") - private void compareWithGeocentricTranslation( - final Ellipsoid source, final Ellipsoid target, - final double tX, final double tY, final double tZ, - final double xmin, final double ymin, final double zmin, - final double xmax, final double ymax, final double zmax) - throws FactoryException, TransformException, IOException - { - final MathTransform reference; - final MathTransformFactory factory = DefaultMathTransformFactory.provider(); - transform = MolodenskyTransform.createGeodeticTransformation(factory, source, true, target, true, tX, tY, tZ, false); - reference = GeocentricTranslationTest.createDatumShiftForGeographic3D(factory, source, target, tX, tY, tZ); - final float[] srcPts = verifyInDomain( - new double[] {xmin, ymin, zmin}, - new double[] {xmax, ymax, zmax}, - new int[] { 10, 10, 10}, - TestUtilities.createRandomNumberGenerator(103627524044558476L)); - /* - * Transform the same input coordinates using Molodensky transform (actual) and using the reference - * implementation (expected). If we were asked to print statistics, compute them before to test the - * values since the statistics may be a useful information in case of problem. - */ - final double[] actual = new double[srcPts.length]; - final double[] expected = new double[srcPts.length]; - transform.transform(srcPts, 0, actual, 0, srcPts.length / 3); - reference.transform(srcPts, 0, expected, 0, srcPts.length / 3); - if (TestCase.VERBOSE) { - final Statistics[] stats = { - new Statistics("|Δλ| (~cm)"), - new Statistics("|Δφ| (~cm)"), - new Statistics("|Δh| (cm)") - }; - for (int i=0; i<srcPts.length; i++) { - double Δ = actual[i] - expected[i]; - final int j = i % stats.length; - switch (j) { - case 0: Δ *= cos(toRadians(expected[i+1])); // Fall through - case 1: Δ *= 60 * NAUTICAL_MILE; break; // Approximate conversion to metres - } - Δ *= 100; // Conversion to centimetres. - stats[j].accept(abs(Δ)); - } - StatisticsFormat.getInstance().format(stats, TestCase.out); - } - assertCoordinatesEqual(3, expected, 0, - actual, 0, expected.length / 3, - CalculationType.DIRECT_TRANSFORM, - "Comparison of Molodensky and geocentric translation"); - } - /** - * Creates a Molodensky transform for a datum shift from WGS84 to ED50. + * Creates a three-dimensional Molodensky transform for a datum shift from WGS84 to ED50. * Tolerance thresholds are also initialized. * * @throws FactoryException if an error occurred while creating a transform step. @@@ -266,6 -391,49 +269,49 @@@ validate(); } + /** + * Tests the concatenation of a 3-dimensional transform with a "3D to 2D" transform. + * + * @throws FactoryException if an error occurred while creating a transform step. + * @throws TransformException if an error occurred while requesting the inverse transform. + */ + @Test + public void testRedimension3Dto2D() throws FactoryException, TransformException { - final MathTransformFactory factory = DefaultMathTransformFactory.provider(); ++ final DefaultMathTransformFactory factory = DefaultMathTransformFactory.provider(); + transform = new MolodenskyTransform( + HardCodedDatum.WGS84.getEllipsoid(), true, + GeodeticDatumMock.ED50.getEllipsoid(), true, + GeocentricTranslationTest.TX, + GeocentricTranslationTest.TY, + GeocentricTranslationTest.TZ, + false); + validate(); + MolodenskyTransform forward, inverse; + + // Verify initial conditions. + forward = assertInstanceOf(MolodenskyTransform.class, transform); + inverse = assertInstanceOf(MolodenskyTransform.class, transform.inverse()); + assertSame(forward, inverse.inverse()); + assertEquals(3, forward.getSourceDimensions()); + assertEquals(3, forward.getTargetDimensions()); + + // Drop target dimension. + transform = MathTransforms.concatenate(transform, factory.builder(Geographic3Dto2D.NAME).create()); + forward = assertInstanceOf(MolodenskyTransform.class, transform); + inverse = assertInstanceOf(MolodenskyTransform.class, transform.inverse()); + assertSame(forward, inverse.inverse()); + assertEquals(3, forward.getSourceDimensions()); + assertEquals(2, forward.getTargetDimensions()); + + // Drop source dimension. + transform = MathTransforms.concatenate(factory.builder(Geographic2Dto3D.NAME).create(), transform); + forward = assertInstanceOf(MolodenskyTransform.class, transform); + inverse = assertInstanceOf(MolodenskyTransform.class, transform.inverse()); + assertSame(forward, inverse.inverse()); + assertEquals(2, forward.getSourceDimensions()); + assertEquals(2, forward.getTargetDimensions()); + } + /** * Tests the standard Well Known Text (version 1) formatting. * The result is what we show to users, but may quite different than what SIS has in memory. diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PassThroughTransformTest.java index 6af766cdab,132e1aa42e..be6207c87c --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PassThroughTransformTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PassThroughTransformTest.java @@@ -335,4 -349,35 +336,35 @@@ public final class PassThroughTransform new double[] {2, 1, -1, 0.2, 0.1, 9, 2, 8, 4, -1}, new double[] {2, 4, -1, 1600.6, 2700.7, 9, 10, 8, 4, 6}); } + + /** + * Tests a concatenation that delegates the work to {@link TransformJoiner#replacePassThrough(Map)}. + * + * @see <a href="https://issues.apache.org/jira/browse/SIS-384">SIS-384</a> + */ + @Test + public void testTransformJoiner() { + final Matrix before = Matrices.createIdentity(5); + final Matrix after = Matrices.createIdentity(5); + final Matrix expected = Matrices.createIdentity(5); + List.of(before, expected).forEach((m) -> { + m.setElement(0, 0, 0.025); + m.setElement(1, 1, -0.025); + m.setElement(0, 4, 3.0125); + m.setElement(1, 4, 44.9875); + }); + List.of(after, expected).forEach((m) -> { + m.setElement(3, 3, 3600000.0); + m.setElement(3, 4, 1.5127128E12); + }); + final var interpolate = MathTransforms.interpolate(null, new double[] {2.0, 10.0, 20.0, 35.0, 50.0, 75.0, 100.0}); + final var passThrough = PassThroughTransform.create(2, interpolate, 1); + transform = MathTransforms.concatenate(MathTransforms.linear(before), passThrough, MathTransforms.linear(after)); + + final var c = assertInstanceOf(ConcatenatedTransform.class, transform); + final Matrix m = MathTransforms.getMatrix(c.transform1); + assertNotNull(m); + assertSame(passThrough, c.transform2); - assertMatrixEquals(expected, m, null, null); ++ assertMatrixEquals(expected, m, 0, null); + } } diff --cc endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java index 4f29d64996,c456c25856..ff31e233f0 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java @@@ -354,10 -355,10 +354,10 @@@ public final class SelectionClause exte */ @Override public void accept(final WarningEvent event) { - final LogRecord record = resources().getLogRecord( + final LogRecord record = resources().createLogRecord( Level.WARNING, Resources.Keys.IncompatibleLiteralCRS_2, - event.getOperatorType().map(CodeList::identifier).orElse("?"), + event.getOperatorType().map(Enum::name).orElse("?"), event.getParameter(ValueReference.class).map(ValueReference<?,?>::getXPath).orElse("?")); record.setThrown(event.exception); log(record); diff --cc netbeans-project/ivy.xml index bfee97924e,84d86ca69e..6d7cb0ccdf --- a/netbeans-project/ivy.xml +++ b/netbeans-project/ivy.xml @@@ -11,14 -11,12 +11,14 @@@ <ivy-module version="2.0"> <info organisation="org.apache" module="sis"/> <dependencies defaultconf="default"> + <dependency org="org.opengis" name="geoapi" rev="3.0.2"/> + <dependency org="org.opengis" name="geoapi-conformance" rev="3.0.2"/> <dependency org="javax.measure" name="unit-api" rev="2.1.3"/> <dependency org="org.glassfish.jaxb" name="jaxb-runtime" rev="4.0.5"/> - <dependency org="org.eclipse" name="yasson" rev="3.0.3"/> + <dependency org="org.eclipse" name="yasson" rev="3.0.4"/> <dependency org="com.esri.geometry" name="esri-geometry-api" rev="2.2.4"/> <dependency org="org.locationtech.jts" name="jts-core" rev="1.20.0"/> - <dependency org="org.postgresql" name="postgresql" rev="42.7.3"/> + <dependency org="org.postgresql" name="postgresql" rev="42.7.7"/> <dependency org="edu.ucar" name="cdm-core" rev="5.5.3"/> <dependency org="edu.ucar" name="udunits" rev="5.5.3"/> <dependency org="org.jdom" name="jdom2" rev="2.0.6"/>