Author: desruisseaux
Date: Mon Mar 21 21:59:03 2016
New Revision: 1736104

URL: http://svn.apache.org/viewvc?rev=1736104&view=rev
Log:
Modify DefaultMathTransformFactory.Context API for making clearer that the 
factory does not deal with datum.
In particular, change of prime meridian is caller's responsibility. Added a 
Context.getMatrix(MatrixRole)
method for making easier to handle prime meridian outside 
DefaultMathTransformFactory.
Those changes are needed for continuing CoordinateOperationInference 
implementation.

Modified:
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1736104&r1=1736103&r2=1736104&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
 [UTF-8] Mon Mar 21 21:59:03 2016
@@ -37,6 +37,7 @@ import org.apache.sis.referencing.Identi
 import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.cs.AxesConvention;
+import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.Context;
 
 import static java.util.Collections.singletonMap;
 
@@ -321,4 +322,36 @@ public final class ReferencingUtilities
         }
         return null;
     }
+
+    /**
+     * 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).
+     *
+     * @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.
+     *
+     * @since 0.7
+     */
+    public static Context createTransformContext(final 
CoordinateReferenceSystem sourceCRS,
+            final CoordinateReferenceSystem targetCRS, Context context)
+    {
+        if (context == null) {
+            context = new Context();
+        }
+        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);
+        }
+        return context;
+    }
 }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1736104&r1=1736103&r2=1736104&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
 [UTF-8] Mon Mar 21 21:59:03 2016
@@ -70,6 +70,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.metadata.sql.SQLUtilities;
 import org.apache.sis.internal.referencing.DeprecatedCode;
 import org.apache.sis.internal.referencing.EPSGParameterDomain;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Semaphores;
@@ -2845,10 +2846,8 @@ next:               while (r.next()) {
                         final MathTransform mt;
                         final MathTransformFactory mtFactory = owner.mtFactory;
                         if (mtFactory instanceof DefaultMathTransformFactory) {
-                            DefaultMathTransformFactory.Context context = new 
DefaultMathTransformFactory.Context();
-                            context.setSource(sourceCRS);
-                            context.setTarget(targetCRS);
-                            mt = ((DefaultMathTransformFactory) 
mtFactory).createParameterizedTransform(parameters, context);
+                            mt = ((DefaultMathTransformFactory) 
mtFactory).createParameterizedTransform(parameters,
+                                    
ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
                         } else {
                             // Fallback for non-SIS implementations. Work for 
map projections but not for Molodensky.
                             mt = mtFactory.createBaseToDerived(sourceCRS, 
parameters, targetCRS.getCoordinateSystem());

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java?rev=1736104&r1=1736103&r2=1736104&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
 [UTF-8] Mon Mar 21 21:59:03 2016
@@ -254,12 +254,12 @@ public class DefaultConversion extends A
                  * CoordinateReferenceSystem because the targetCRS is 
typically under construction when this
                  * method in invoked, and attempts to use it can cause 
NullPointerException.
                  */
-                final DefaultMathTransformFactory.Context context = new 
DefaultMathTransformFactory.Context();
-                context.setSource(source);
+                final DefaultMathTransformFactory.Context context;
                 if (target instanceof GeneralDerivedCRS) {
+                    context = 
ReferencingUtilities.createTransformContext(source, null, null);
                     context.setTarget(target.getCoordinateSystem());    // 
Using 'target' would be unsafe here.
                 } else {
-                    context.setTarget(target);
+                    context = 
ReferencingUtilities.createTransformContext(source, target, null);
                 }
                 transform = ((DefaultMathTransformFactory) 
factory).createParameterizedTransform(parameters, context);
                 parameters = 
Parameters.unmodifiable(context.getCompletedParameters());

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1736104&r1=1736103&r2=1736104&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
 [UTF-8] Mon Mar 21 21:59:03 2016
@@ -68,7 +68,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.parameter.TensorParameters
@@ -776,7 +776,6 @@ public final class Matrices extends Stat
      * @return {@code true} if the matrix represents an affine transform.
      *
      * @see MatrixSIS#isAffine()
-     * @see AffineTransforms2D#castOrCopy(Matrix)
      */
     public static boolean isAffine(final Matrix matrix) {
         if (matrix instanceof MatrixSIS) {
@@ -787,6 +786,32 @@ public final class Matrices extends Stat
     }
 
     /**
+     * Returns {@code true} if the given matrix represents a translation.
+     * This method returns {@code true} if the given matrix {@linkplain 
#isAffine(Matrix) is affine}
+     * and differs from the identity matrix only in the last column.
+     *
+     * @param matrix The matrix to test.
+     * @return {@code true} if the matrix represents a translation.
+     *
+     * @since 0.7
+     */
+    public static boolean isTranslation(final Matrix matrix) {
+        if (!isAffine(matrix)) {
+            return false;
+        }
+        final int numRow = matrix.getNumRow() - 1;      // Excluding 
translation column.
+        final int numCol = matrix.getNumCol() - 1;      // Excluding last row 
in affine transform.
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                if (matrix.getElement(j,i) != ((i == j) ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
      * Returns {@code true} if the given matrix is close to an identity 
matrix, given a tolerance threshold.
      * This method is equivalent to computing the difference between the given 
matrix and an identity matrix
      * of identical size, and returning {@code true} if and only if all 
differences are smaller than or equal

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1736104&r1=1736103&r2=1736104&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
 [UTF-8] Mon Mar 21 21:59:03 2016
@@ -71,6 +71,7 @@ import org.apache.sis.referencing.cs.Coo
 import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.referencing.operation.DefaultOperationMethod;
 import org.apache.sis.referencing.operation.matrix.Matrices;
+import 
org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Classes;
@@ -450,13 +451,18 @@ public class DefaultMathTransformFactory
      * {@link DefaultMathTransformFactory} uses this information for:
      *
      * <ul>
-     *   <li>Complete some parameters if they were not provided. In 
particular, the {@linkplain #getSourceEllipsoid()
+     *   <li>Completing some parameters if they were not provided. In 
particular, the {@linkplain #getSourceEllipsoid()
      *       source ellipsoid} can be used for providing values for the {@code 
"semi_major"} and {@code "semi_minor"}
      *       parameters in map projections.</li>
-     *   <li>{@linkplain CoordinateSystems#swapAndScaleAxes Swap and scale 
axes} if the source or the target
+     *   <li>{@linkplain CoordinateSystems#swapAndScaleAxes Swapping and 
scaling axes} if the source or the target
      *       coordinate systems are not {@linkplain AxesConvention#NORMALIZED 
normalized}.</li>
      * </ul>
      *
+     * By default 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
      * @since   0.7
@@ -502,17 +508,6 @@ public class DefaultMathTransformFactory
         }
 
         /**
-         * Sets the source ellipsoid to the given value.
-         * The source coordinate system is unconditionally set to {@code null}.
-         *
-         * @param ellipsoid The ellipsoid to set as the source (can be {@code 
null}).
-         */
-        public void setSource(final Ellipsoid ellipsoid) {
-            sourceEllipsoid = ellipsoid;
-            sourceCS = null;
-        }
-
-        /**
          * Sets the source coordinate system to the given value.
          * The source ellipsoid is unconditionally set to {@code null}.
          *
@@ -524,26 +519,23 @@ public class DefaultMathTransformFactory
         }
 
         /**
-         * Sets the source ellipsoid and coordinate system to values inferred 
from the given CRS.
-         * The source ellipsoid will be non-null only if the given CRS is 
geographic (not geocentric).
+         * Sets the source coordinate system and its associated ellipsoid to 
the given value.
          *
-         * @param crs The source coordinate reference system (can be {@code 
null}).
-         */
-        public void setSource(final CoordinateReferenceSystem crs) {
-            sourceCS = (crs != null) ? crs.getCoordinateSystem() : null;
-            sourceEllipsoid = 
ReferencingUtilities.getEllipsoidOfGeographicCRS(crs);
-            // Ellipsoid is intentionally null for GeocentricCRS.
-        }
-
-        /**
-         * Sets the target ellipsoid to the given value.
-         * The target coordinate system is unconditionally set to {@code null}.
+         * <div class="note"><b>Design note:</b>
+         * ellipsoidal coordinate systems and ellipsoids are associated 
indirectly, through a geodetic CRS.
+         * However this method expects those two components to be given 
explicitely instead than inferring
+         * them from a {@code CoordinateReferenceSystem} for making clear that 
{@code MathTransformFactory}
+         * does not perform any {@linkplain 
org.apache.sis.referencing.datum.DefaultGeodeticDatum geodetic
+         * datum} analysis. For coordinate operations that take datum changes 
in account (including change
+         * of prime meridian), see {@link 
org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory}.
+         * This policy helps to enforce a separation of concerns.</div>
          *
-         * @param ellipsoid The ellipsoid to set as the target (can be {@code 
null}).
+         * @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}.
          */
-        public void setTarget(final Ellipsoid ellipsoid) {
-            targetEllipsoid = ellipsoid;
-            targetCS = null;
+        public void setSource(final EllipsoidalCS cs, final Ellipsoid 
ellipsoid) {
+            sourceCS = cs;
+            sourceEllipsoid = ellipsoid;
         }
 
         /**
@@ -558,15 +550,17 @@ public class DefaultMathTransformFactory
         }
 
         /**
-         * Sets the target ellipsoid and coordinate system to values inferred 
from the given CRS.
-         * The target ellipsoid will be non-null only if the given CRS is 
geographic (not geocentric).
+         * Sets the target coordinate system and its associated ellipsoid to 
the given value.
+         *
+         * <div class="note"><b>Design note:</b>
+         * see {@link #setSource(EllipsoidalCS, Ellipsoid)}.</div>
          *
-         * @param crs The target coordinate reference system (can be {@code 
null}).
+         * @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}.
          */
-        public void setTarget(final CoordinateReferenceSystem crs) {
-            targetCS = (crs != null) ? crs.getCoordinateSystem() : null;
-            targetEllipsoid = 
ReferencingUtilities.getEllipsoidOfGeographicCRS(crs);
-            // Ellipsoid is intentionally null for GeocentricCRS.
+        public void setTarget(final EllipsoidalCS cs, final Ellipsoid 
ellipsoid) {
+            targetCS = cs;
+            targetEllipsoid = ellipsoid;
         }
 
         /**
@@ -608,6 +602,70 @@ public class DefaultMathTransformFactory
         }
 
         /**
+         * Returns the matrix that represent the affine transform to 
concatenate before or after
+         * the parameterized transform. The {@code role} argument specifies 
which matrix is desired:
+         *
+         * <ul class="verbose">
+         *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#NORMALIZATION
+         *       NORMALIZATION} for the conversion from the {@linkplain 
#getSourceCS() source coordinate system} to
+         *       a {@linkplain AxesConvention#NORMALIZED normalized} 
coordinate system, usually with
+         *       (<var>longitude</var>, <var>latitude</var>) axis order in 
degrees or
+         *       (<var>easting</var>, <var>northing</var>) in metres.
+         *       This normalization needs to be applied <em>before</em> the 
parameterized transform.</li>
+         *
+         *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#DENORMALIZATION
+         *       DENORMALIZATION} for the conversion from a normalized 
coordinate system to the
+         *       {@linkplain #getTargetCS() target coordinate system}, for 
example with
+         *       (<var>latitude</var>, <var>longitude</var>) axis order.
+         *       This denormalization needs to be applied <em>after</em> the 
parameterized transform.</li>
+         *
+         *   <li>{@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#INVERSE_NORMALIZATION
 INVERSE_NORMALIZATION} and
+         *       {@link 
org.apache.sis.referencing.operation.transform.ContextualParameters.MatrixRole#INVERSE_DENORMALIZATION
 INVERSE_DENORMALIZATION}
+         *       are also supported but rarely used.</li>
+         * </ul>
+         *
+         * This method is invoked by {@link 
DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, Context)}.
+         * Users an override this method if they need to customize the 
normalization process.
+         *
+         * @param  role Whether the normalization or denormalization matrix is 
desired.
+         * @return The requested matrix, or {@code null} if this {@code 
Context} has no information about the coordinate system.
+         * @throws FactoryException if an error occurred while computing the 
matrix.
+         *
+         * @see DefaultMathTransformFactory#createAffineTransform(Matrix)
+         * @see 
DefaultMathTransformFactory#createParameterizedTransform(ParameterValueGroup, 
Context)
+         */
+        @SuppressWarnings("fallthrough")
+        public Matrix getMatrix(final ContextualParameters.MatrixRole role) 
throws FactoryException {
+            final CoordinateSystem source, target;
+            boolean inverse = false;
+            switch (role) {
+                case INVERSE_NORMALIZATION: inverse = true;         // Fall 
through
+                case NORMALIZATION: {
+                    source = getSourceCS(); if (source == null) return null;
+                    target = CoordinateSystems.replaceAxes(source, 
AxesConvention.NORMALIZED);
+                    break;
+                }
+                case INVERSE_DENORMALIZATION: inverse = true;       // Fall 
through
+                case DENORMALIZATION: {
+                    target = getTargetCS(); if (target == null) return null;
+                    source = CoordinateSystems.replaceAxes(target, 
AxesConvention.NORMALIZED);
+                    break;
+                }
+                default: throw new 
IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, 
"role", role));
+            }
+            Matrix matrix;
+            try {
+                matrix = CoordinateSystems.swapAndScaleAxes(source, target);
+                if (inverse) {
+                    matrix = Matrices.inverse(matrix);
+                }
+            } catch (IllegalArgumentException | ConversionException | 
NoninvertibleMatrixException cause) {
+                throw new 
InvalidGeodeticParameterException(cause.getLocalizedMessage(), cause);
+            }
+            return matrix;
+        }
+
+        /**
          * Returns the parameter values used for the math transform creation, 
including the parameters completed
          * by the factory.
          *
@@ -965,7 +1023,7 @@ public class DefaultMathTransformFactory
 
     /**
      * Given a transform between normalized spaces,
-     * creates a transform taking in account axis directions and units of 
measurement.
+     * creates a transform taking in account axis directions, units of 
measurement and longitude rotation.
      * This method {@linkplain #createConcatenatedTransform concatenates} the 
given parameterized transform
      * with any other transform required for performing units changes and 
ordinates swapping.
      *
@@ -981,6 +1039,10 @@ public class DefaultMathTransformFactory
      * both of them with ({@linkplain 
org.opengis.referencing.cs.AxisDirection#EAST East},
      * {@linkplain org.opengis.referencing.cs.AxisDirection#NORTH North}) axis 
orientations.</div>
      *
+     * <div class="section">Controlling the normalization process</div>
+     * Users who need a different normalized space than the default one way 
find more convenient to
+     * override the {@link Context#getMatrix 
Context.getMatrix(ContextualParameters.MatrixRole)} method.
+     *
      * @param  parameterized A transform for normalized input and output 
coordinates.
      * @param  context Source and target coordinate systems in which the 
transform is going to be used.
      * @return A transform taking in account unit conversions and axis 
swapping.
@@ -988,25 +1050,20 @@ public class DefaultMathTransformFactory
      *
      * @see org.apache.sis.referencing.cs.AxesConvention#NORMALIZED
      * @see 
org.apache.sis.referencing.operation.DefaultConversion#DefaultConversion(Map, 
OperationMethod, MathTransform, ParameterValueGroup)
+     *
+     * @since 0.7
      */
     public MathTransform swapAndScaleAxes(final MathTransform parameterized, 
final Context context) throws FactoryException {
         ArgumentChecks.ensureNonNull("parameterized", parameterized);
         ArgumentChecks.ensureNonNull("context", context);
-        final CoordinateSystem sourceCS = context.getSourceCS();
-        final CoordinateSystem targetCS = context.getTargetCS();
         /*
          * Computes matrix for swapping axis and performing units conversion.
          * There is one matrix to apply before projection on 
(longitude,latitude)
          * coordinates, and one matrix to apply after projection on 
(easting,northing)
          * coordinates.
          */
-        final Matrix swap1, swap3;
-        try {
-            swap1 = (sourceCS != null) ? 
CoordinateSystems.swapAndScaleAxes(sourceCS, 
CoordinateSystems.replaceAxes(sourceCS, AxesConvention.NORMALIZED)) : null;
-            swap3 = (targetCS != null) ? 
CoordinateSystems.swapAndScaleAxes(CoordinateSystems.replaceAxes(targetCS, 
AxesConvention.NORMALIZED), targetCS) : null;
-        } catch (IllegalArgumentException | ConversionException cause) {
-            throw new 
InvalidGeodeticParameterException(cause.getLocalizedMessage(), cause);
-        }
+        final Matrix swap1 = 
context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
+        final Matrix swap3 = 
context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         /*
          * Prepares the concatenation of the matrices computed above and the 
projection.
          * Note that at this stage, the dimensions between each step may not 
be compatible.
@@ -1086,8 +1143,7 @@ public class DefaultMathTransformFactory
         ArgumentChecks.ensureNonNull("baseCRS",    baseCRS);
         ArgumentChecks.ensureNonNull("parameters", parameters);
         ArgumentChecks.ensureNonNull("derivedCS",  derivedCS);
-        final Context context = new Context();
-        context.setSource(baseCRS);
+        final Context context = 
ReferencingUtilities.createTransformContext(baseCRS, null, null);
         context.setTarget(derivedCS);
         return createParameterizedTransform(parameters, context);
     }


Reply via email to