This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-3.1
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 3abad8c520052db486b9a48656a7310daa618e18
Merge: ffa96dbde4 f416e5744b
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Jun 11 10:25:38 2025 +0200

    Merge branch 'geoapi-4.0' into geoapi-3.1.
    Contains support for conversion from geographic to spherical coordinates 
without going through Cartesian coordinates,
    and improvements in `SQLStore` with projections (in SQL sense) of 
properties that are links (e.g. "sis:identifier").

 README.md                                          |   4 +-
 .../org/apache/sis/cloud/aws/s3/FileService.java   |   2 +-
 .../sis/coverage/grid/ResampledGridCoverage.java   |   2 +-
 .../apache/sis/feature/AbstractIdentifiedType.java |  90 ++-
 .../org/apache/sis/feature/AbstractOperation.java  |  65 +-
 .../apache/sis/feature/DefaultAssociationRole.java |  15 +-
 .../apache/sis/feature/DefaultAttributeType.java   |  15 +-
 .../org/apache/sis/feature/EnvelopeOperation.java  | 196 +++--
 .../org/apache/sis/feature/FeatureOperations.java  |  18 +-
 .../main/org/apache/sis/feature/Features.java      |   4 +-
 .../sis/feature/GroupAsPolylineOperation.java      |  42 +-
 .../main/org/apache/sis/feature/LinkOperation.java |  16 +
 .../apache/sis/feature/StringJoinOperation.java    |  80 ++-
 .../feature/builder/AssociationRoleBuilder.java    |   2 +-
 .../sis/feature/builder/AttributeTypeBuilder.java  |   2 +-
 .../feature/builder/CharacteristicTypeBuilder.java |   2 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |   6 +-
 .../sis/feature/builder/OperationWrapper.java      |  37 +
 .../sis/feature/builder/PropertyTypeBuilder.java   |  13 +
 .../apache/sis/feature/builder/TypeBuilder.java    |   2 +-
 .../org/apache/sis/feature/internal/Resources.java |   5 +
 .../sis/feature/internal/Resources.properties      |   1 +
 .../sis/feature/internal/Resources_fr.properties   |   1 +
 .../feature/privy/FeatureProjectionBuilder.java    |  51 +-
 .../main/org/apache/sis/xml/XML.java               |   2 +-
 ...g.opengis.referencing.operation.OperationMethod |   2 +
 .../main/module-info.java                          |   2 +
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   2 +-
 .../org/apache/sis/parameter/ParameterFormat.java  |   2 +-
 .../org/apache/sis/parameter/Parameterized.java    |   3 +
 .../sis/referencing/cs/CoordinateSystems.java      |  63 +-
 .../sis/referencing/cs/DefaultCompoundCS.java      |   7 +-
 .../sis/referencing/datum/BursaWolfParameters.java |   2 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |  55 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |   2 +-
 .../org/apache/sis/referencing/datum/Sphere.java   |  15 +-
 .../internal/ParameterizedTransformBuilder.java    | 239 ++++---
 .../operation/CoordinateOperationFinder.java       | 210 ++----
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../referencing/operation/DefaultConversion.java   |   2 +-
 .../DefaultCoordinateOperationFactory.java         |  11 +-
 .../operation/MathTransformContext.java            |  90 ++-
 .../operation/matrix/GeneralMatrix.java            |  22 +-
 .../sis/referencing/operation/matrix/Matrices.java |   3 +
 .../operation/provider/AbstractProvider.java       |  52 +-
 .../GeocentricAffineBetweenGeographic.java         |  53 +-
 .../operation/provider/GeocentricToGeographic.java |   4 +-
 .../provider/GeocentricToTopocentric.java          |  16 +-
 .../provider/GeocentricTranslation3D.java          |   1 +
 .../operation/provider/Geographic2Dto3D.java       |  26 +-
 .../operation/provider/Geographic3Dto2D.java       |  19 +-
 .../operation/provider/GeographicToGeocentric.java |  40 +-
 .../operation/provider/MapProjection.java          |  28 +-
 ...{Geographic2Dto3D.java => Spherical2Dto3D.java} |  59 +-
 ...{Geographic2Dto3D.java => Spherical3Dto2D.java} |  63 +-
 .../operation/transform/AbstractMathTransform.java | 183 ++++-
 .../operation/transform/CartesianToPolar.java      |   6 +-
 .../operation/transform/CartesianToSpherical.java  |   6 +-
 .../operation/transform/ConcatenatedTransform.java |  24 +-
 .../operation/transform/ContextualParameters.java  |  80 ++-
 .../transform/CoordinateSystemTransform.java       |  34 +-
 .../CoordinateSystemTransformBuilder.java          | 349 ++++++---
 .../operation/transform/CopyTransform.java         |  25 +-
 .../operation/transform/DatumShiftTransform.java   |   3 +-
 .../transform/DefaultMathTransformFactory.java     |   8 +-
 .../transform/EllipsoidToCentricTransform.java     | 787 ++++++++++++---------
 .../transform/EllipsoidToRadiusTransform.java      | 505 +++++++++++++
 .../transform/InterpolatedGeocentricTransform.java |   9 +-
 .../operation/transform/LinearTransform1D.java     |   5 +-
 .../operation/transform/MathTransforms.java        |  20 +-
 .../operation/transform/MolodenskyTransform.java   |   1 +
 .../operation/transform/OnewayLinearTransform.java | 212 ++++++
 .../operation/transform/PolarToCartesian.java      |   6 +-
 .../operation/transform/PoleRotation.java          |  13 +-
 .../operation/transform/SphericalToCartesian.java  |   8 +-
 .../operation/transform/TransformSeparator.java    |   6 +-
 .../org/apache/sis/referencing/privy/Formulas.java |  26 +-
 .../referencing/privy/ReferencingUtilities.java    |  27 +
 .../ParameterizedTransformBuilderTest.java         |   2 +-
 .../operation/CoordinateOperationFinderTest.java   |  64 ++
 .../provider/GeocentricTranslationTest.java        |  10 +-
 .../operation/provider/Geographic3Dto2DTest.java   |   5 +-
 .../operation/provider/ProvidersTest.java          |   2 +
 .../transform/EllipsoidToCentricTransformTest.java | 135 ++--
 .../transform/EllipsoidToRadiusTransformTest.java  | 162 +++++
 .../EllipsoidToSphericalTransformTest.java         | 198 ++++++
 .../operation/transform/MathTransformTestCase.java |   4 +-
 .../operation/transform/MathTransformWrapper.java  |   4 +-
 .../transform/TransformSeparatorTest.java          |   4 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |   2 +-
 .../apache/sis/storage/sql/feature/Relation.java   |   2 +-
 .../main/org/apache/sis/storage/gpx/Store.java     |  17 -
 .../main/org/apache/sis/storage/gpx/Types.java     |  26 +-
 .../apache/sis/io/stream/FileCacheByteChannel.java |  24 +-
 .../main/org/apache/sis/storage/FeatureQuery.java  |  13 +-
 .../main/org/apache/sis/storage/FeatureSet.java    |   1 -
 .../main/org/apache/sis/storage/FeatureSubset.java |   4 +-
 .../org/apache/sis/storage/StorageConnector.java   |   2 +-
 .../sis/storage/UnsupportedQueryException.java     |  12 +
 .../sis/storage/base/FeatureCatalogBuilder.java    |  81 ---
 .../apache/sis/storage/base/MetadataBuilder.java   |   3 -
 .../org/apache/sis/storage/FeatureQueryTest.java   |   2 +-
 .../sis/storage/base/MetadataBuilderTest.java      |   4 +-
 .../main/org/apache/sis/pending/jdk/JDK21.java     |  24 +-
 .../org/apache/sis/util/privy/CollectionsExt.java  |   8 +-
 netbeans-project/nbproject/project.xml             |   2 +
 optional/src/org.apache.sis.gui/bundle/README      |   2 +-
 settings.gradle.kts                                |   2 +-
 108 files changed, 3578 insertions(+), 1354 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
index 13cdbacc5b,4b9d9ef158..775e23c0ad
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
@@@ -744,48 -770,36 +771,34 @@@ public class ParameterizedTransformBuil
              if (numTrailingCoordinates > 0) {
                  step2 = factory.createPassThroughTransform(0, step2, 
numTrailingCoordinates);
              } else {
-                 var select = Matrices.createDimensionSelect(kernelDim, 
ArraysExt.range(0, resultDim));
-                 step2 = factory.createConcatenatedTransform(step2, 
factory.createAffineTransform(select));
+                 step2 = factory.createConcatenatedTransform(step2, 
addOrRemoveDimensions(kernelDim, resultDim));
              }
+             neededDim = step2.getSourceDimensions();
+             kernelDim = step2.getTargetDimensions();
          }
          /*
-          * If the source CS has a height but the target CS doesn't, drops the 
extra coordinates.
-          * Conversely if the source CS is missing a height, add a height with 
NaN values.
-          * After this block, the dimensions of `step1` and `step2` should 
match.
-          *
-          * When adding an ellipsoidal height, there are two scenarios: the 
ellipsoidal height may be used by the
-          * parameterized operation, or it may be passed through (in which 
case the operation ignores the height).
-          * If the height is expected as operation input, set the height to 0. 
Otherwise (the pass through case),
-          * set the height to NaN. We do that way because the given 
`parameterized` transform may be a Molodensky
-          * transform or anything else that could use the height in its 
calculation. If we have to add a height as
-          * a pass through dimension, maybe the parameterized transform is a 
2D Molodensky instead of a 3D Molodensky.
-          * The result of passing through the height is not the same as if a 
3D Molodensky was used in the first place.
-          * A NaN value avoid to give a false sense of accuracy.
+          * Make the number of target dimensions of `step1` compatible with 
the number of source dimensions of `step2`.
+          * If dimensions must be added, their values will be NaN. Note that 
the vertical dimension (height or radius)
+          * has already been added with a non-NaN value before to reach this 
point if that value was required by `step2`.
           */
-         final int sourceDim = step1.getTargetDimensions();
-         final int targetDim = step2.getSourceDimensions();
-         int insertCount = targetDim - sourceDim;
-         if (insertCount != 0) {
-             ensureDimensionChangeAllowed(normalized, insertCount, targetDim);
-             final Matrix resize = Matrices.createZero(targetDim+1, 
sourceDim+1);
-             for (int j=0; j<targetDim; j++) {
-                 resize.setElement(j, Math.min(j, sourceDim), (j < sourceDim) 
? 1 :
-                         ((--insertCount >= numTrailingCoordinates) ? 0 : 
Double.NaN));        // See above note.
-             }
-             resize.setElement(targetDim, sourceDim, 1);     // Element in the 
lower-right corner.
-             step1 = factory.createConcatenatedTransform(step1, 
factory.createAffineTransform(resize));
+         if (sourceDim != neededDim) {
+             ensureDimensionChangeAllowed(neededDim - sourceDim, neededDim, 
normalized);
+             step1 = factory.createConcatenatedTransform(step1, 
addOrRemoveDimensions(sourceDim, neededDim));
+         }
+         if (kernelDim != resultDim) {
+             ensureDimensionChangeAllowed(resultDim - kernelDim, resultDim, 
normalized);
+             step3 = 
factory.createConcatenatedTransform(addOrRemoveDimensions(kernelDim, 
resultDim), step3);
          }
-         MathTransform mt = 
factory.createConcatenatedTransform(factory.createConcatenatedTransform(step1, 
step2), step3);
          /*
-          * At this point we finished to create the transform.  But before to 
return it, verify if the
-          * parameterized transform given in argument had some custom 
parameters. This happen with the
-          * Equirectangular projection, which can be simplified as an 
AffineTransform while we want to
-          * continue to describe it with the "semi_major", "semi_minor", etc. 
parameters  instead of
-          * "elt_0_0", "elt_0_1", etc.  The following code just forwards those 
parameters to the newly
-          * created transform; it does not change the operation.
+          * Create the transform.
+          *
+          * Special case: if the parameterized transform was a map projection 
but the result, after simplification,
+          * is an affine transform (it can happen with the Equirectangular 
projection), wraps the affine transform
+          * for continuing to show "semi_major", "semi_minor", etc. parameters 
instead of "elt_0_0", "elt_0_1", etc.
           */
+         MathTransform mt = 
factory.createConcatenatedTransform(factory.createConcatenatedTransform(step1, 
step2), step3);
          if (normalized instanceof ParameterizedAffine && !(mt instanceof 
ParameterizedAffine)) {
 -            if (mt != (mt = ((ParameterizedAffine) 
normalized).newTransform(mt))) {
 -                mt = unique(mt);
 -            }
 +            return ((ParameterizedAffine) normalized).newTransform(mt);
          }
          return mt;
      }
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MapProjection.java
index 0afd5b45d1,12431785d6..1dc7260107
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MapProjection.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MapProjection.java
@@@ -46,11 -47,9 +47,12 @@@ import org.apache.sis.metadata.iso.cita
  import org.apache.sis.parameter.DefaultParameterDescriptor;
  import org.apache.sis.parameter.ParameterBuilder;
  import org.apache.sis.parameter.Parameters;
+ import org.apache.sis.util.privy.Constants;
  import org.apache.sis.util.resources.Errors;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.ReferenceIdentifier;
 +
  
  /**
   * Base class for most two-dimensional map projection providers defined in 
this package.

Reply via email to