sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1737648 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ sis-referencing/src/test/java/org/apache/sis/re...
Date Mon, 04 Apr 2016 10:17:20 GMT
Author: desruisseaux
Date: Mon Apr  4 10:17:20 2016
New Revision: 1737648

URL: http://svn.apache.org/viewvc?rev=1737648&view=rev
Log:
Fix support for geographic 3D to 2D + datum shift transform.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -22,10 +22,8 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.Parameters;
-import org.apache.sis.util.ArgumentChecks;
 
 
 /**
@@ -70,22 +68,11 @@ public final class AbridgedMolodensky ex
     }
 
     /**
-     * The providers for all combinations between 2D and 3D cases.
-     * Array length is 4. Index is build with following rule:
-     * <ul>
-     *   <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li>
-     *   <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li>
-     * </ul>
-     */
-    private final AbridgedMolodensky[] redimensioned;
-
-    /**
      * Constructs a new provider.
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
     public AbridgedMolodensky() {
-        super(3, 3, PARAMETERS);
-        redimensioned = new AbridgedMolodensky[4];
+        this(3, 3, new AbridgedMolodensky[4]);
         redimensioned[0] = new AbridgedMolodensky(2, 2, redimensioned);
         redimensioned[1] = new AbridgedMolodensky(2, 3, redimensioned);
         redimensioned[2] = new AbridgedMolodensky(3, 2, redimensioned);
@@ -99,23 +86,8 @@ public final class AbridgedMolodensky ex
      * @param targetDimension Number of dimensions in the target CRS of this operation method.
      * @param redimensioned   Providers for all combinations between 2D and 3D cases.
      */
-    private AbridgedMolodensky(final int sourceDimension, final int targetDimension, final
AbridgedMolodensky[] redimensioned) {
-        super(sourceDimension, targetDimension, PARAMETERS);
-        this.redimensioned = redimensioned;
-    }
-
-    /**
-     * Returns the same operation method, but for different number of dimensions.
-     *
-     * @param  sourceDimensions The desired number of input dimensions.
-     * @param  targetDimensions The desired number of output dimensions.
-     * @return The redimensioned operation method, or {@code this} if no change is needed.
-     */
-    @Override
-    public OperationMethod redimension(final int sourceDimensions, final int targetDimensions)
{
-        ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions);
-        ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions);
-        return redimensioned[((sourceDimensions & 1) << 1) | (targetDimensions
& 1)];
+    private AbridgedMolodensky(int sourceDimension, int targetDimension, GeocentricAffineBetweenGeographic[]
redimensioned) {
+        super(sourceDimension, targetDimension, PARAMETERS, redimensioned);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -76,15 +76,15 @@ public abstract class AbstractProvider e
      * Constructs a math transform provider from a set of parameters. The provider name and
      * {@linkplain #getIdentifiers() identifiers} will be the same than the parameter ones.
      *
-     * @param sourceDimension Number of dimensions in the source CRS of this operation method.
-     * @param targetDimension Number of dimensions in the target CRS of this operation method.
-     * @param parameters      The set of parameters (never {@code null}).
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters       Description of parameters expected by this operation.
      */
-    AbstractProvider(final int sourceDimension,
-                     final int targetDimension,
+    AbstractProvider(final int sourceDimensions,
+                     final int targetDimensions,
                      final ParameterDescriptorGroup parameters)
     {
-        super(toMap(parameters), sourceDimension, targetDimension, parameters);
+        super(toMap(parameters), sourceDimensions, targetDimensions, parameters);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -57,7 +57,7 @@ public final class CoordinateFrameRotati
      * Constructs the provider.
      */
     public CoordinateFrameRotation2D() {
-        super(2, 2, PARAMETERS);
+        super(2, 2, PARAMETERS, null);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -56,8 +56,23 @@ public final class CoordinateFrameRotati
     /**
      * Constructs the provider.
      */
+    @SuppressWarnings("ThisEscapedInObjectConstruction")
     public CoordinateFrameRotation3D() {
-        super(3, 3, PARAMETERS);
+        this(3, 3, new CoordinateFrameRotation3D[4]);
+        redimensioned[1] = new CoordinateFrameRotation3D(2, 3, redimensioned);
+        redimensioned[2] = new CoordinateFrameRotation3D(3, 2, redimensioned);
+        redimensioned[3] = this;
+    }
+
+    /**
+     * Constructs a provider for the given dimensions.
+     *
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param redimensioned    Providers for all combinations between 2D and 3D cases.
+     */
+    private CoordinateFrameRotation3D(int sourceDimensions, int targetDimensions, GeocentricAffineBetweenGeographic[]
redimensioned) {
+        super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -155,6 +155,7 @@ public abstract class GeocentricAffine e
      *
      * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
      * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters       Description of parameters expected by this operation.
      */
     GeocentricAffine(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup
parameters) {
         super(sourceDimensions, targetDimensions, parameters);
@@ -275,7 +276,7 @@ public abstract class GeocentricAffine e
         @SuppressWarnings("null")
         int dimension  = sourceCS.getDimension();
         if (dimension != targetCS.getDimension()) {
-            dimension  = 0;                             // Sentinal value for mismatched
dimensions.
+            dimension  = 4;     // Any value greater than 3 means "mismatched dimensions"
for this method.
         }
         /*
          * Try to convert the matrix into (tX, tY, tZ, rX, rY, rZ, dS) parameters.
@@ -312,7 +313,7 @@ public abstract class GeocentricAffine e
             }
         }
         final Parameters values = createParameters(descriptor, parameters, isTranslation);
-        if (useMolodensky && dimension != 0) {
+        if (useMolodensky && dimension <= 3) {
             values.getOrCreate(Molodensky.DIMENSION).setValue(dimension);
         }
         return values;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -25,11 +25,13 @@ import org.opengis.parameter.ParameterDe
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.referencing.operation.transform.EllipsoidToCentricTransform;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.parameter.Parameters;
+import org.apache.sis.util.ArgumentChecks;
 
 
 /**
@@ -99,13 +101,52 @@ public abstract class GeocentricAffineBe
     }
 
     /**
+     * The providers for all combinations between 2D and 3D cases, or {@code null} if none.
+     * If non-null, then array length shall be 4. Indices are built with following rules:
+     *
+     * <ul>
+     *   <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li>
+     *   <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li>
+     * </ul>
+     *
+     * <strong>Do not modify this array after construction</strong>, since the
same array is shared by many
+     * objects and there is no synchronization.
+     */
+    final GeocentricAffineBetweenGeographic[] redimensioned;
+
+    /**
      * Constructs a provider with the specified parameters.
      *
      * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
      * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters       Description of parameters expected by this operation.
+     * @param redimensioned    The providers for all combinations between 2D and 3D cases,
or {@code null}.
      */
-    GeocentricAffineBetweenGeographic(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup
parameters) {
+    GeocentricAffineBetweenGeographic(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup
parameters,
+            final GeocentricAffineBetweenGeographic[] redimensioned)
+    {
         super(sourceDimensions, targetDimensions, parameters);
+        this.redimensioned = redimensioned;
+    }
+
+    /**
+     * Returns the same operation method, but for different number of dimensions.
+     *
+     * @param  sourceDimensions The desired number of input dimensions.
+     * @param  targetDimensions The desired number of output dimensions.
+     * @return The redimensioned operation method, or {@code this} if no change is needed.
+     */
+    @Override
+    public final OperationMethod redimension(final int sourceDimensions, final int targetDimensions)
{
+        if (redimensioned != null) {
+            ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions);
+            ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions);
+            final OperationMethod m = redimensioned[((sourceDimensions & 1) <<
1) | (targetDimensions & 1)];
+            if (m != null) {
+                return m;
+            }
+        }
+        return super.redimension(sourceDimensions, targetDimensions);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -56,7 +56,7 @@ public final class GeocentricTranslation
      * Constructs the provider.
      */
     public GeocentricTranslation2D() {
-        super(2, 2, PARAMETERS);
+        super(2, 2, PARAMETERS, null);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -51,8 +51,23 @@ public final class GeocentricTranslation
     /**
      * Constructs the provider.
      */
+    @SuppressWarnings("ThisEscapedInObjectConstruction")
     public GeocentricTranslation3D() {
-        super(3, 3, PARAMETERS);
+        this(3, 3, new GeocentricTranslation3D[4]);
+        redimensioned[1] = new GeocentricTranslation3D(2, 3, redimensioned);
+        redimensioned[2] = new GeocentricTranslation3D(3, 2, redimensioned);
+        redimensioned[3] = this;
+    }
+
+    /**
+     * Constructs a provider for the given dimensions.
+     *
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param redimensioned    Providers for all combinations between 2D and 3D cases.
+     */
+    private GeocentricTranslation3D(int sourceDimensions, int targetDimensions, GeocentricAffineBetweenGeographic[]
redimensioned) {
+        super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -29,7 +29,6 @@ import org.opengis.parameter.ParameterNo
 import org.opengis.parameter.InvalidParameterValueException;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
@@ -39,7 +38,6 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Debug;
 
 
@@ -134,22 +132,11 @@ public final class Molodensky extends Ge
     }
 
     /**
-     * The providers for all combinations between 2D and 3D cases.
-     * Array length is 4. Index is built with following rule:
-     * <ul>
-     *   <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li>
-     *   <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li>
-     * </ul>
-     */
-    private final Molodensky[] redimensioned;
-
-    /**
      * Constructs a new provider.
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
     public Molodensky() {
-        super(3, 3, PARAMETERS);
-        redimensioned = new Molodensky[4];
+        this(3, 3, new Molodensky[4]);
         redimensioned[0] = new Molodensky(2, 2, redimensioned);
         redimensioned[1] = new Molodensky(2, 3, redimensioned);
         redimensioned[2] = new Molodensky(3, 2, redimensioned);
@@ -163,23 +150,8 @@ public final class Molodensky extends Ge
      * @param targetDimensions Number of dimensions in the target CRS of this operation method.
      * @param redimensioned    Providers for all combinations between 2D and 3D cases.
      */
-    private Molodensky(final int sourceDimensions, final int targetDimensions, final Molodensky[]
redimensioned) {
-        super(sourceDimensions, targetDimensions, PARAMETERS);
-        this.redimensioned = redimensioned;
-    }
-
-    /**
-     * Returns the same operation method, but for different number of dimensions.
-     *
-     * @param  sourceDimensions The desired number of input dimensions.
-     * @param  targetDimensions The desired number of output dimensions.
-     * @return The redimensioned operation method, or {@code this} if no change is needed.
-     */
-    @Override
-    public OperationMethod redimension(final int sourceDimensions, final int targetDimensions)
{
-        ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions);
-        ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions);
-        return redimensioned[((sourceDimensions & 1) << 1) | (targetDimensions
& 1)];
+    private Molodensky(int sourceDimensions, int targetDimensions, GeocentricAffineBetweenGeographic[]
redimensioned) {
+        super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -59,7 +59,7 @@ public final class PositionVector7Param2
      * Constructs the provider.
      */
     public PositionVector7Param2D() {
-        super(2, 2, PARAMETERS);
+        super(2, 2, PARAMETERS, null);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -54,8 +54,23 @@ public final class PositionVector7Param3
     /**
      * Constructs the provider.
      */
+    @SuppressWarnings("ThisEscapedInObjectConstruction")
     public PositionVector7Param3D() {
-        super(3, 3, PARAMETERS);
+        this(3, 3, new PositionVector7Param3D[4]);
+        redimensioned[1] = new PositionVector7Param3D(2, 3, redimensioned);
+        redimensioned[2] = new PositionVector7Param3D(3, 2, redimensioned);
+        redimensioned[3] = this;
+    }
+
+    /**
+     * Constructs a provider for the given dimensions.
+     *
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param redimensioned    Providers for all combinations between 2D and 3D cases.
+     */
+    private PositionVector7Param3D(int sourceDimensions, int targetDimensions, GeocentricAffineBetweenGeographic[]
redimensioned) {
+        super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned);
     }
 
     /**

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=1737648&r1=1737647&r2=1737648&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 Apr  4 10:17:20 2016
@@ -840,25 +840,60 @@ public class DefaultMathTransformFactory
          * if available. This method writes semi-major and semi-minor parameter values only
if they do not
          * already exists in the given parameters.
          *
+         * <p>The given method and parameters are stored in the {@link #provider} and
{@link #parameters}
+         * fields respectively. The actual stored values may differ from the values given
to this method.</p>
+         *
          * @param  method Description of the transform to be created, or {@code null} if
unknown.
          * @return The exception if the operation failed, or {@code null} if none. This exception
is not thrown now
          *         because the caller may succeed in creating the transform anyway, or otherwise
may produce a more
          *         informative exception.
          * @throws IllegalArgumentException if the operation fails because a parameter has
a unrecognized name or an
          *         illegal value.
+         *
+         * @see #getCompletedParameters()
          */
-        final RuntimeException setEllipsoids(final OperationMethod method) throws IllegalArgumentException
{
-            ensureCompatibleParameters(false);
+        @SuppressWarnings("null")
+        final RuntimeException completeParameters(OperationMethod method, final ParameterValueGroup
userParams)
+                throws IllegalArgumentException
+        {
+            provider   = method;
+            parameters = userParams;
+            /*
+             * Get the operation method for the appropriate number of dimensions. For example
the default Molodensky
+             * operation expects two-dimensional source and target CRS. If a given CRS is
three-dimensional, we need
+             * a provider variant which will not concatenate a "geographic 3D to 2D" operation
before the Molodensky
+             * one. It is worth to perform this check only if the provider is a subclass
of DefaultOperationMethod,
+             * since it needs to override the 'redimension(int, int)' method.
+             */
+            if (method instanceof DefaultOperationMethod && method.getClass() !=
DefaultOperationMethod.class) {
+                final Integer sourceDim = (sourceCS != null) ? sourceCS.getDimension() :
method.getSourceDimensions();
+                final Integer targetDim = (targetCS != null) ? targetCS.getDimension() :
method.getTargetDimensions();
+                if (sourceDim != null && targetDim != null) {
+                    method = ((DefaultOperationMethod) method).redimension(sourceDim, targetDim);
+                    if (method instanceof MathTransformProvider) {
+                        provider = method;
+                    }
+                }
+            }
+            ensureCompatibleParameters(false);      // Invoke only after we set 'provider'
to its final instance.
+            /*
+             * Get a mask telling us if we need to set parameters for the source and/or target
ellipsoid.
+             * This information should preferably be given by the provider. But if the given
provider is
+             * not a SIS implementation, use as a fallback whether ellipsoids are provided.
This fallback
+             * may be less reliable.
+             */
             int n;
-            if (method instanceof AbstractProvider) {
-                n = ((AbstractProvider) method).getEllipsoidsMask();
+            if (provider instanceof AbstractProvider) {
+                n = ((AbstractProvider) provider).getEllipsoidsMask();
             } else {
-                // Fallback used only when the information is not available in
-                // a more reliable way from AbstractProvider.getEllipsoidsMask().
                 n = 0;
                 if (sourceEllipsoid != null) n  = 1;
                 if (targetEllipsoid != null) n |= 2;
             }
+            /*
+             * Set the ellipsoid axis-length parameter values. Those parameters may appear
in the source
+             * ellipsoid, in the target ellipsoid or in both ellipsoids.
+             */
             switch (n) {
                 case 0: return null;
                 case 1: return setEllipsoid(getSourceEllipsoid(), Constants.SEMI_MAJOR, Constants.SEMI_MINOR,
true, null);
@@ -867,7 +902,7 @@ public class DefaultMathTransformFactory
                     RuntimeException failure = null;
                     if (sourceCS != null) try {
                         ensureCompatibleParameters(true);
-                        final ParameterValue<?> p = parameters.parameter("dim");
+                        final ParameterValue<?> p = parameters.parameter("dim");  
 // Really 'parameters', not 'userParams'.
                         if (p.getValue() == null) {
                             p.setValue(sourceCS.getDimension());
                         }
@@ -980,10 +1015,9 @@ public class DefaultMathTransformFactory
                  * since the standard place where to provide this information is in the ellipsoid
object.
                  */
                 if (context != null) {
-                    context.provider   = method;
-                    context.parameters = parameters;
-                    failure = context.setEllipsoids(method);
+                    failure = context.completeParameters(method, parameters);
                     parameters = context.parameters;
+                    method     = context.provider;
                 }
                 transform = ((MathTransformProvider) method).createMathTransform(this, parameters);
             } catch (IllegalArgumentException | IllegalStateException exception) {

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -17,13 +17,16 @@
 package org.apache.sis.referencing.operation;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.text.ParseException;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.SingleOperation;
@@ -34,6 +37,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.OperationNotFoundException;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.io.wkt.WKTFormat;
 
@@ -43,6 +47,7 @@ import static org.apache.sis.internal.re
 
 // Test dependencies
 import org.apache.sis.referencing.operation.transform.MathTransformTestCase;
+import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.junit.BeforeClass;
@@ -106,7 +111,7 @@ public final strictfp class CoordinateOp
                 "GEOGCS[“Sphere”,\n" +
                 "  Datum[“Sphere”, Ellipsoid[“Sphere”, 6370997, 0]],\n" +
                 "  CS[ellipsoidal, 2],\n" +
-                "    Axis[“Longitude (λ)”, EAST],\n" +
+                "    Axis[“Longitude (λ)”, EAST],\n" +          // Use of non-ASCII
letters is departure from WKT 2.
                 "    Axis[“Latitude (φ)”, NORTH],\n" +
                 "    Unit[“degree”, 0.017453292519943295]]");
         /*
@@ -217,6 +222,72 @@ public final strictfp class CoordinateOp
     }
 
     /**
+     * Tests a transformation using the <cite>"Geocentric translations (geog3D domain)"</cite>
method.
+     * This method verifies with both a three-dimensional and a two-dimensional target CRS.
+     *
+     * @throws ParseException if a CRS used in this test can not be parsed.
+     * @throws FactoryException if the operation can not be created.
+     * @throws TransformException if an error occurred while converting the test points.
+     */
+    @Test
+    @DependsOnMethod("testGeocentricTranslationInGeographicDomain")
+    public void testGeocentricTranslationInGeographic3D() throws ParseException, FactoryException,
TransformException {
+        final GeographicCRS sourceCRS = (GeographicCRS) parse(
+                "GeodeticCRS[“NAD27”,\n" +
+                "  Datum[“North American Datum 1927”,\n" +
+                "    Ellipsoid[“Clarke 1866”, 6378206.4, 294.9786982138982],\n" +
+                "    ToWGS84[-8, 160, 176]]," +                                     // See
comment in above test.
+                "  CS[ellipsoidal, 3],\n" +
+                "    Axis[“Latitude (φ)”, NORTH, Unit[“degree”, 0.017453292519943295]],\n"
+
+                "    Axis[“Longitude (λ)”, EAST, Unit[“degree”, 0.017453292519943295]],\n"
+
+                "    Axis[“Height (h)”, UP, Unit[“m”, 1]]]");
+
+        testGeocentricTranslationInGeographic3D(sourceCRS, CommonCRS.WGS84.geographic3D());
+
+        isInverseTransformSupported = false;
+        testGeocentricTranslationInGeographic3D(sourceCRS, CommonCRS.WGS84.geographic());
+    }
+
+    /**
+     * Implementation of {@link #testGeocentricTranslationInGeographic3D()}.
+     *
+     * @param sourceCRS The NAD27 geographic CRS.
+     * @param targetCRS Either the two-dimensional or the three-dimensional geographic CRS
using WGS84 datum.
+     */
+    private void testGeocentricTranslationInGeographic3D(final GeographicCRS sourceCRS, final
GeographicCRS targetCRS)
+            throws ParseException, FactoryException, TransformException
+    {
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        assertSame  ("sourceCRS",  sourceCRS,  operation.getSourceCRS());
+        assertSame  ("targetCRS",  targetCRS,  operation.getTargetCRS());
+        assertFalse ("isIdentity", operation.getMathTransform().isIdentity());
+        assertEquals("name", "Datum shift", operation.getName().getCode());
+        assertSetEquals(Arrays.asList(DATUM_SHIFT_APPLIED), operation.getCoordinateOperationAccuracy());
+        assertInstanceOf("operation", Transformation.class, operation);
+        assertEquals("method", "Geocentric translations (geog3D domain)",
+                ((SingleOperation) operation).getMethod().getName().getCode());
+
+        transform  = operation.getMathTransform();
+        tolerance  = ANGULAR_TOLERANCE;
+        zTolerance = 0.01;
+        λDimension = new int[] {1};
+        zDimension = new int[] {2};
+        double[] source = {
+            39.00,       -85.00,       -10000.00,   // The intend of those large height values
is to cause a shift in (φ,λ)
+            38.26,       -80.58,       +10000.00    // large enough for being detected if
we fail to use h in calculations.
+        };
+        double[] target = {
+            39.00004487, -84.99993091, -10038.28,
+            38.26005011, -80.57979129,   9962.38
+        };
+        if (targetCRS.getCoordinateSystem().getDimension() == 2) {
+            target = TestUtilities.dropLastDimensions(target, 3, 2);
+        }
+        verifyTransform(source, target);
+        validate();
+    }
+
+    /**
      * Tests a transformation using the <cite>"Geocentric translations (geog2D domain)"</cite>
method
      * together with a longitude rotation and unit conversion. The CRS and sample point are
taken from
      * the GR3DF97A – <cite>Grille de paramètres de transformation de coordonnées</cite>
document.
@@ -507,4 +578,42 @@ public final strictfp class CoordinateOp
         });
         validate();
     }
+
+    /**
+     * Convenience method for creating a compound CRS.
+     */
+    private static CompoundCRS compound(final String name, final SingleCRS... components)
{
+        return new DefaultCompoundCRS(Collections.singletonMap(CompoundCRS.NAME_KEY, name),
components);
+    }
+
+    /**
+     * Tests transformation from three-dimensional geographic CRS to four-dimensional compound
CRS
+     * where the last dimension is time.
+     *
+     * @throws FactoryException if the operation can not be created.
+     * @throws TransformException if an error occurred while converting the test points.
+     */
+//  @Test
+    public void testGeographic3D_to_4D() throws FactoryException, TransformException {
+        final CompoundCRS sourceCRS = compound("Test3D", CommonCRS.WGS84.geographic(),  
CommonCRS.Temporal.UNIX.crs());
+        final CompoundCRS targetCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(),
CommonCRS.Temporal.MODIFIED_JULIAN.crs());
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
+        assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
+        assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
+        assertInstanceOf("operation", Conversion.class, operation);
+
+        transform = operation.getMathTransform();
+        assertInstanceOf("transform", LinearTransform.class, transform);
+        assertEquals(3, transform.getSourceDimensions());
+        assertEquals(4, transform.getTargetDimensions());
+        assertTrue(Matrices.create(5, 4, new double[] {
+            1, 0, 0, 0,
+            0, 1, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 1./(24*60*60), 40587,
+            0, 0, 0, 1
+        }).equals(((LinearTransform) transform).getMatrix(), 1E-12));
+        validate();
+    }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java?rev=1737648&r1=1737647&r2=1737648&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
[UTF-8] Mon Apr  4 10:17:20 2016
@@ -45,7 +45,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 public final strictfp class TestUtilities extends Static {
@@ -285,7 +285,7 @@ public final strictfp class TestUtilitie
      *   "      └─"
      * }
      *
-     * This method is used for comparing two tree having string representation in different
locales.
+     * This method is used for comparing two trees having string representation in different
locales.
      * In such case, we can not compare the actual text content. The best we can do is to
compare
      * the tree structure.
      *
@@ -341,6 +341,26 @@ public final strictfp class TestUtilitie
     }
 
     /**
+     * Returns a copy of the given array with the last ordinate values dropped for each coordinates.
+     *
+     * @param  coordinates The source coordinates from which to drop the last ordinate values.
+     * @param  sourceDim   Number of dimensions of each point in the {@code coordinates}
array.
+     * @param  targetDim   Number of dimensions to retain.
+     * @return Copy of the given {@code coordinates} array with only the {@code targetDim}
first dimension for each point.
+     *
+     * @since 0.7
+     */
+    public static double[] dropLastDimensions(final double[] coordinates, final int sourceDim,
final int targetDim) {
+        assertEquals("Unexpected array length.", 0, coordinates.length % sourceDim);
+        final int numPts = coordinates.length / sourceDim;
+        final double[] reduced = new double[numPts * targetDim];
+        for (int i=0; i<numPts; i++) {
+            System.arraycopy(coordinates, i*sourceDim, reduced, i*targetDim, targetDim);
+        }
+        return reduced;
+    }
+
+    /**
      * If the given failure is not null, re-thrown it as an {@link Error} or
      * {@link RuntimeException}. Otherwise do nothing.
      *




Mime
View raw message