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

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

commit 6a5584c4867a595b524a5b42a5f1f9e83a5acd04
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Aug 9 13:04:30 2022 +0200

    Replace `Context.setSource(EllipsoidalCS, Ellipsoid)` method by 
`setSource(GeodeticCRS)`.
    The rational which was in previous method is actually inexact:
    we may need the ellipsoid even with non-ellipsoidal CS, if the CRS is 
geocentric.
---
 .../internal/referencing/ReferencingUtilities.java | 39 +++++------
 .../operation/CoordinateOperationFinder.java       |  5 +-
 .../operation/CoordinateOperationRegistry.java     |  4 +-
 .../referencing/operation/DefaultConversion.java   |  4 +-
 .../transform/DefaultMathTransformFactory.java     | 76 +++++++++++++++++++---
 5 files changed, 90 insertions(+), 38 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
index 3df50b8c34..c3825e8b0d 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
@@ -509,38 +509,33 @@ public final class ReferencingUtilities extends Static {
     }
 
     /**
-     * Sets the source and target ellipsoids and coordinate systems to values 
inferred from the given CRS.
-     * The ellipsoids will be non-null only if the given CRS is geographic 
(not geocentric).
+     * Creates a context with source and target ellipsoids and coordinate 
systems inferred from the given CRS.
+     * The ellipsoids will be non-null only if the given CRS is geodetic 
(geographic or geocentric).
      *
-     * @param  sourceCRS  the CRS from which to get the source coordinate 
system and ellipsoid.
-     * @param  targetCRS  the CRS from which to get the target coordinate 
system and ellipsoid.
-     * @param  context    a pre-allocated context, or {@code null} for 
creating a new one.
-     * @return the given context if it was non-null, or a new context 
otherwise.
+     * @param  sourceCRS  the CRS from which to get the source coordinate 
system and ellipsoid, or {@code null}.
+     * @param  targetCRS  the CRS from which to get the target coordinate 
system and ellipsoid, or {@code null}.
+     * @return the context to provides to math transform factory.
      */
     public static Context createTransformContext(final 
CoordinateReferenceSystem sourceCRS,
-            final CoordinateReferenceSystem targetCRS, Context context)
+                                                 final 
CoordinateReferenceSystem targetCRS)
     {
-        if (context == null) {
-            context = new Context();
+        final Context context = new Context();
+        if (sourceCRS instanceof GeodeticCRS) {
+            context.setSource((GeodeticCRS) sourceCRS);
+        } else if (sourceCRS != null) {
+            context.setSource(sourceCRS.getCoordinateSystem());
         }
-        final CoordinateSystem sourceCS = (sourceCRS != null) ? 
sourceCRS.getCoordinateSystem() : null;
-        final CoordinateSystem targetCS = (targetCRS != null) ? 
targetCRS.getCoordinateSystem() : null;
-        if (sourceCRS instanceof GeodeticCRS && sourceCS instanceof 
EllipsoidalCS) {
-            context.setSource((EllipsoidalCS) sourceCS, ((GeodeticCRS) 
sourceCRS).getDatum().getEllipsoid());
-        } else {
-            context.setSource(sourceCS);
-        }
-        if (targetCRS instanceof GeodeticCRS && targetCS instanceof 
EllipsoidalCS) {
-            context.setTarget((EllipsoidalCS) targetCS, ((GeodeticCRS) 
targetCRS).getDatum().getEllipsoid());
-        } else {
-            context.setTarget(targetCS);
+        if (targetCRS instanceof GeodeticCRS) {
+            context.setTarget((GeodeticCRS) targetCRS);
+        } else if (targetCRS != null) {
+            context.setTarget(targetCRS.getCoordinateSystem());
         }
         return context;
     }
 
     /**
      * Substitute for the deprecated {@link 
MathTransformFactory#createBaseToDerived createBaseToDerived(…)} method.
-     * This substitute use the full {@code targetCRS} instead of only the 
coordinate system of the target.
+     * This substitute uses the full {@code targetCRS} instead of only the 
coordinate system of the target.
      * This is needed for setting the {@code "tgt_semi_minor"} and {@code 
"tgt_semi_major"} parameters of
      * Molodensky transformation for example.
      *
@@ -561,7 +556,7 @@ public final class ReferencingUtilities extends Static {
     {
         if (factory instanceof DefaultMathTransformFactory) {
             return ((DefaultMathTransformFactory) 
factory).createParameterizedTransform(
-                    parameters, createTransformContext(sourceCRS, targetCRS, 
null));
+                    parameters, createTransformContext(sourceCRS, targetCRS));
         } else {
             // Fallback for non-SIS implementations. Work for map projections 
but not for Molodensky.
             return factory.createBaseToDerived(sourceCRS, parameters, 
targetCRS.getCoordinateSystem());
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index 94f949561e..f61f85df2b 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -524,8 +524,9 @@ public class CoordinateOperationFinder extends 
CoordinateOperationRegistry {
          * set to Greenwich in EPSG dataset 8.9.  For safety, the SIS's 
DefaultGeodeticDatum class ensures that if the
          * prime meridians are not the same, then the target meridian must be 
Greenwich.
          */
-        final DefaultMathTransformFactory.Context context = 
ReferencingUtilities.createTransformContext(
-                sourceCRS, targetCRS, new MathTransformContext(sourceDatum, 
targetDatum));
+        final DefaultMathTransformFactory.Context context = new 
MathTransformContext(sourceDatum, targetDatum);
+        context.setSource(sourceCRS);
+        context.setTarget(targetCRS);
         /*
          * If both CRS use the same datum and the same prime meridian, then 
the coordinate operation is only axis
          * swapping, unit conversion or change of coordinate system type 
(Ellipsoidal ↔ Cartesian ↔ Spherical).
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index 3991cc6240..52a76c2844 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@ -982,7 +982,7 @@ class CoordinateOperationRegistry {
             final MathTransformFactory mtFactory = 
factorySIS.getMathTransformFactory();
             if (mtFactory instanceof DefaultMathTransformFactory) {
                 MathTransform mt = ((DefaultMathTransformFactory) 
mtFactory).createParameterizedTransform(
-                        parameters, 
ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
+                        parameters, 
ReferencingUtilities.createTransformContext(sourceCRS, targetCRS));
                 return 
factorySIS.createSingleOperation(IdentifiedObjects.getProperties(operation),
                         sourceCRS, targetCRS, null, operation.getMethod(), mt);
             }
@@ -1104,7 +1104,7 @@ class CoordinateOperationRegistry {
                         try {
                             mt = ((DefaultMathTransformFactory) 
mtFactory).createParameterizedTransform(
                                     ((SingleOperation) 
op).getParameterValues(),
-                                    
ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
+                                    
ReferencingUtilities.createTransformContext(sourceCRS, targetCRS));
                         } catch (InvalidGeodeticParameterException e) {
                             log(null, e);
                             break;
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
index 92ac8c9899..8cec2a3414 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
@@ -256,10 +256,10 @@ public class DefaultConversion extends 
AbstractSingleOperation implements Conver
                  */
                 final DefaultMathTransformFactory.Context context;
                 if (target instanceof GeneralDerivedCRS) {
-                    context = 
ReferencingUtilities.createTransformContext(source, null, null);
+                    context = 
ReferencingUtilities.createTransformContext(source, null);
                     context.setTarget(target.getCoordinateSystem());    // 
Using `target` would be unsafe here.
                 } else {
-                    context = 
ReferencingUtilities.createTransformContext(source, target, null);
+                    context = 
ReferencingUtilities.createTransformContext(source, target);
                 }
                 transform = ((DefaultMathTransformFactory) 
factory).createParameterizedTransform(parameters, context);
                 parameters = 
Parameters.unmodifiable(context.getCompletedParameters());
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
index ff5ce4ac11..b863524fa5 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
@@ -38,6 +38,7 @@ import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.parameter.InvalidParameterNameException;
 import org.opengis.parameter.InvalidParameterValueException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.CartesianCS;
@@ -165,7 +166,7 @@ import static java.util.logging.Logger.getLogger;
  * There is typically only one {@code MathTransformFactory} instance for the 
whole application.
  *
  * @author  Martin Desruisseaux (Geomatys, IRD)
- * @version 1.1
+ * @version 1.3
  *
  * @see MathTransformProvider
  * @see AbstractMathTransform
@@ -541,16 +542,17 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
      *       coordinate systems are not {@linkplain AxesConvention#NORMALIZED 
normalized}.</li>
      * </ul>
      *
-     * By default this class does <strong>not</strong> handle change of
+     * This class does <strong>not</strong> handle change of
      * {@linkplain 
org.apache.sis.referencing.datum.DefaultGeodeticDatum#getPrimeMeridian() prime 
meridian}
      * or anything else related to datum. Datum changes have dedicated {@link 
OperationMethod},
      * for example <cite>"Longitude rotation"</cite> (EPSG:9601) for changing 
the prime meridian.
      *
      * @author  Martin Desruisseaux (Geomatys)
-     * @version 0.7
+     * @version 1.3
      * @since   0.7
      * @module
      */
+    @SuppressWarnings("serial")         // Fields are not statically typed as 
Serializable.
     public static class Context implements Serializable {
         /**
          * For cross-version compatibility.
@@ -575,14 +577,14 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
          *
          * @todo We could make this information public as a replacement of 
{@link #getLastMethodUsed()}.
          */
-        OperationMethod provider;
+        private OperationMethod provider;
 
         /**
          * The parameters actually used.
          *
          * @see #getCompletedParameters()
          */
-        ParameterValueGroup parameters;
+        private ParameterValueGroup parameters;
 
         /**
          * Creates a new context with all properties initialized to {@code 
null}.
@@ -615,12 +617,38 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
          *
          * @param  cs         the coordinate system to set as the source, or 
{@code null}.
          * @param  ellipsoid  the ellipsoid associated to the given coordinate 
system, or {@code null}.
+         *
+         * @deprecated Replaced by {@link #setSource(GeodeticCRS)}.
          */
+        @Deprecated
         public void setSource(final EllipsoidalCS cs, final Ellipsoid 
ellipsoid) {
             sourceCS = cs;
             sourceEllipsoid = ellipsoid;
         }
 
+        /**
+         * Sets the source coordinate system and related ellipsoid to the 
components of given CRS.
+         * The {@link Ellipsoid}, fetched from the geodetic datum, is often 
used together with an {@link EllipsoidalCS},
+         * but not necessarily. The geodetic CRS may also be associated with a 
spherical or Cartesian coordinate system,
+         * and the ellipsoid information may still be needed even with those 
non-ellipsoidal coordinate systems.
+         *
+         * <p><strong>This method is not for datum shifts.</strong>
+         * All datum information other than the ellipsoid are ignored.</p>
+         *
+         * @param  crs  the coordinate system and ellipsoid to set as the 
source, or {@code null}.
+         *
+         * @since 1.3
+         */
+        public void setSource(final GeodeticCRS crs) {
+            if (crs != null) {
+                sourceCS = crs.getCoordinateSystem();
+                sourceEllipsoid = crs.getDatum().getEllipsoid();
+            } else {
+                sourceCS = null;
+                sourceEllipsoid = null;
+            }
+        }
+
         /**
          * Sets the target coordinate system to the given value.
          * The target ellipsoid is unconditionally set to {@code null}.
@@ -640,12 +668,38 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
          *
          * @param  cs         the coordinate system to set as the source, or 
{@code null}.
          * @param  ellipsoid  the ellipsoid associated to the given coordinate 
system, or {@code null}.
+         *
+         * @deprecated Replaced by {@link #setTarget(GeodeticCRS)}.
          */
+        @Deprecated
         public void setTarget(final EllipsoidalCS cs, final Ellipsoid 
ellipsoid) {
             targetCS = cs;
             targetEllipsoid = ellipsoid;
         }
 
+        /**
+         * Sets the target coordinate system and related ellipsoid to the 
components of given CRS.
+         * The {@link Ellipsoid}, fetched from the geodetic datum, is often 
used together with an {@link EllipsoidalCS},
+         * but not necessarily. The geodetic CRS may also be associated with a 
spherical or Cartesian coordinate system,
+         * and the ellipsoid information may still be needed even with those 
non-ellipsoidal coordinate systems.
+         *
+         * <p><strong>This method is not for datum shifts.</strong>
+         * All datum information other than the ellipsoid are ignored.</p>
+         *
+         * @param  crs  the coordinate system and ellipsoid to set as the 
target, or {@code null}.
+         *
+         * @since 1.3
+         */
+        public void setTarget(final GeodeticCRS crs) {
+            if (crs != null) {
+                targetCS = crs.getCoordinateSystem();
+                targetEllipsoid = crs.getDatum().getEllipsoid();
+            } else {
+                targetCS = null;
+                targetEllipsoid = null;
+            }
+        }
+
         /**
          * Returns the source coordinate system, or {@code null} if 
unspecified.
          *
@@ -986,8 +1040,8 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
                 n = ((AbstractProvider) provider).getEllipsoidsMask();
             } else {
                 n = 0;
-                if (sourceEllipsoid != null) n  = 1;
-                if (targetEllipsoid != null) n |= 2;
+                if (getSourceEllipsoid() != null) n  = 1;
+                if (getTargetEllipsoid() != null) n |= 2;
             }
             /*
              * Set the ellipsoid axis-length parameter values. Those 
parameters may appear in the source ellipsoid,
@@ -1356,7 +1410,7 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
         ArgumentChecks.ensureNonNull("baseCRS",    baseCRS);
         ArgumentChecks.ensureNonNull("parameters", parameters);
         ArgumentChecks.ensureNonNull("derivedCS",  derivedCS);
-        final Context context = 
ReferencingUtilities.createTransformContext(baseCRS, null, null);
+        final Context context = 
ReferencingUtilities.createTransformContext(baseCRS, null);
         context.setTarget(derivedCS);
         return createParameterizedTransform(parameters, context);
     }
@@ -1403,12 +1457,14 @@ public class DefaultMathTransformFactory extends 
AbstractFactory implements Math
                     final String operation;
                     if (isEllipsoidalSource) {
                         operation = GeographicToGeocentric.NAME;
-                        context.setSource(cs = (EllipsoidalCS) source, 
ellipsoid);
+                        context.setSource(cs = (EllipsoidalCS) source);
                         context.setTarget(target);
+                        context.sourceEllipsoid = ellipsoid;
                     } else {
                         operation = GeocentricToGeographic.NAME;
                         context.setSource(source);
-                        context.setTarget(cs = (EllipsoidalCS) target, 
ellipsoid);
+                        context.setTarget(cs = (EllipsoidalCS) target);
+                        context.targetEllipsoid = ellipsoid;
                     }
                     final ParameterValueGroup pg = 
getDefaultParameters(operation);
                     if (cs.getDimension() < 3) 
pg.parameter("dim").setValue(2);       // Apache SIS specific parameter.

Reply via email to