sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1713951 - 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/matrix/ sis-referencing/src/main/java/org/apache/sis/refer...
Date Thu, 12 Nov 2015 00:18:37 GMT
Author: desruisseaux
Date: Thu Nov 12 00:18:37 2015
New Revision: 1713951

URL: http://svn.apache.org/viewvc?rev=1713951&view=rev
Log:
Avoid the use of the non-standard "DIMENSION" parameters in "Geographic/Geocentric conversions".
This force us to improve the concatenation of EllipsoidToCartesianTransform with affine transforms
in order to detect if an affine transform is actually a "Geographic 3D to 2D" conversion or conversely.
As a side effect, we had to refactor the 'removeRows' and 'removeColumns' matrix operations in order to
preserve the double-double precision when it exists.

Modified:
    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/GeocentricToGeographic.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.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/matrix/MatrixSIS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.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/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

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=1713951&r1=1713950&r2=1713951&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] Thu Nov 12 00:18:37 2015
@@ -25,6 +25,7 @@ import org.opengis.parameter.ParameterDe
 import org.opengis.parameter.InvalidParameterValueException;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.internal.util.Constants;
@@ -53,7 +54,7 @@ public abstract class GeocentricAffineBe
     /**
      * The operation parameter descriptor for the number of source and target geographic dimensions (2 or 3).
      * This is an OGC-specific parameter for the {@link Molodensky} and {@link AbridgedMolodensky} operations,
-     * but Apache SIS uses it also for Geographic/Geocentric conversions.
+     * but Apache SIS uses it also for internal parameters of Geographic/Geocentric.
      *
      * <p>We do not provide default value for this parameter (neither we do for other OGC-specific parameters
      * in this class) because this parameter is used with both two- and three-dimensional operation methods.
@@ -144,7 +145,6 @@ public abstract class GeocentricAffineBe
     {
         final Parameters pv = Parameters.castOrWrap(values);
         final MathTransform affine = super.createMathTransform(factory, pv);
-        final int dimension = getDimension(pv);
         /*
          * Create a "Geographic to Geocentric" conversion with ellipsoid axis length units converted to metres
          * (the unit implied by SRC_SEMI_MAJOR) because it is the unit of Bursa-Wolf param. that we created above.
@@ -152,8 +152,14 @@ public abstract class GeocentricAffineBe
         Parameters step = Parameters.castOrWrap(factory.getDefaultParameters(GeographicToGeocentric.NAME));
         step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(SRC_SEMI_MAJOR));
         step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(SRC_SEMI_MINOR));
-        step.getOrCreate(DIMENSION).setValue(dimension != 0 ? dimension : getSourceDimensions());
-        final MathTransform toGeocentric = factory.createParameterizedTransform(step);
+        MathTransform toGeocentric = factory.createParameterizedTransform(step);
+        MathTransform reduce = null;
+        if (getSourceDimensions() == 2) try {
+            reduce = factory.createParameterizedTransform(factory.getDefaultParameters(Geographic3Dto2D.NAME));
+            toGeocentric = factory.createConcatenatedTransform(reduce.inverse(), toGeocentric);
+        } catch (NoninvertibleTransformException e) {
+            throw new FactoryException(e);
+        }
         /*
          * Create a "Geocentric to Geographic" conversion with ellipsoid axis length units converted to metres
          * because this is the unit of the Geocentric CRS used above.
@@ -161,8 +167,11 @@ public abstract class GeocentricAffineBe
         step = Parameters.castOrWrap(factory.getDefaultParameters(GeocentricToGeographic.NAME));
         step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(TGT_SEMI_MAJOR));
         step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(TGT_SEMI_MINOR));
-        step.getOrCreate(DIMENSION).setValue(dimension != 0 ? dimension : getTargetDimensions());
-        final MathTransform toGeographic = factory.createParameterizedTransform(step);
+        MathTransform toGeographic = factory.createParameterizedTransform(step);
+        if (getTargetDimensions() == 2) {
+            // 'reduce' should not be null since we provide only "2 to 2" or "3 to 3" dimensions.
+            toGeographic = factory.createConcatenatedTransform(toGeographic, reduce);
+        }
         /*
          * The  Geocentric → Affine → Geographic  chain.
          */

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -61,7 +61,7 @@ public final class GeocentricToGeographi
     static {
         PARAMETERS = builder()
                 .addName(Citations.OGC, NAME)
-                .createGroupForMapProjection(GeocentricAffineBetweenGeographic.DIMENSION);
+                .createGroupForMapProjection();
                 // Not really a map projection, but we leverage the same axis parameters.
     }
 
@@ -110,7 +110,7 @@ public final class GeocentricToGeographi
     public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup values)
             throws FactoryException
     {
-        MathTransform tr = GeographicToGeocentric.createMathTransform(GeocentricToGeographic.class, factory, values);
+        MathTransform tr = GeographicToGeocentric.create(factory, values);
         try {
             tr = tr.inverse();
         } catch (NoninvertibleTransformException e) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -52,10 +52,14 @@ public final class Geographic3Dto2D exte
     private static final long serialVersionUID = -9103595336196565505L;
 
     /**
+     * The EPSG name used for this operation method.
+     */
+    static final String NAME = "Geographic3D to 2D conversion";
+
+    /**
      * The group of all parameters expected by this coordinate operation (in this case, none).
      */
-    static final ParameterDescriptorGroup PARAMETERS =
-            builder().addIdentifier("9659").addName("Geographic3D to 2D conversion").createGroup();
+    static final ParameterDescriptorGroup PARAMETERS = builder().addIdentifier("9659").addName(NAME).createGroup();
 
     /**
      * The unique instance, created when first needed.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -21,19 +21,15 @@ import javax.measure.quantity.Length;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.parameter.ParameterValue;
 import org.opengis.referencing.operation.Conversion;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.MathTransformFactory;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.referencing.operation.transform.EllipsoidalToCartesianTransform;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.logging.Logging;
 
 
 /**
@@ -72,7 +68,7 @@ public final class GeographicToGeocentri
                 .addIdentifier("9602")
                 .addName("Geographic/geocentric conversions")
                 .addName(Citations.OGC, NAME)
-                .createGroupForMapProjection(GeocentricAffineBetweenGeographic.DIMENSION);
+                .createGroupForMapProjection();
                 // Not really a map projection, but we leverage the same axis parameters.
     }
 
@@ -121,36 +117,20 @@ public final class GeographicToGeocentri
     public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup values)
             throws FactoryException
     {
-        return createMathTransform(GeographicToGeocentric.class, factory, values);
+        return create(factory, values);
     }
 
     /**
      * Implementation of {@link #createMathTransform(MathTransformFactory, ParameterValueGroup)}
      * shared with {@link GeocentricToGeographic}.
      */
-    static MathTransform createMathTransform(final Class<?> caller, final MathTransformFactory factory,
-            final ParameterValueGroup values) throws FactoryException
+    static MathTransform create(final MathTransformFactory factory, final ParameterValueGroup values)
+            throws FactoryException
     {
-        boolean is3D;
-        try {
-            /*
-             * Set 'is3D' to false if the given parameter group contains a "DIM" parameter having value 2.
-             * If the parameter value is 3 or if there is no parameter value, then 'is3D' is set to true,
-             * which is consistent with the default value.
-             */
-            is3D = GeocentricAffineBetweenGeographic.getDimension(Parameters.castOrWrap(values)) != 2;
-        } catch (ParameterNotFoundException e) {
-            /*
-             * Should never happen with the parameter descriptors provided by SIS, but could happen
-             * if the user provided its own descriptor. Default to three-dimensional case.
-             */
-            Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION), caller, "createMathTransform", e);
-            is3D = true;
-        }
         final ParameterValue<?> semiMajor = values.parameter(Constants.SEMI_MAJOR);
         final Unit<Length> unit = semiMajor.getUnit().asType(Length.class);
         return EllipsoidalToCartesianTransform.createGeodeticConversion(factory, semiMajor.doubleValue(),
-                values.parameter(Constants.SEMI_MINOR).doubleValue(unit), unit, is3D);
+                values.parameter(Constants.SEMI_MINOR).doubleValue(unit), unit, true);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -240,6 +240,14 @@ class GeneralMatrix extends MatrixSIS im
     }
 
     /**
+     * Returns {@code true} if this matrix uses extended precision.
+     */
+    @Override
+    final boolean isExtendedPrecision() {
+        return elements.length > numRow * numCol;
+    }
+
+    /**
      * Stores the value at the specified row and column in the given {@code dd} object.
      * This method does not need to verify argument validity.
      */

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=1713951&r1=1713950&r2=1713951&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] Thu Nov 12 00:18:37 2015
@@ -158,6 +158,13 @@ public final class Matrices extends Stat
     }
 
     /**
+     * Creates a matrix filled with zero values, using double-double precision if {@code precision} is {@code true}.
+     */
+    static MatrixSIS createZero(final int numRow, final int numCol, final boolean precision) {
+        return precision ? GeneralMatrix.createExtendedPrecision(numRow, numCol, false) : createZero(numRow, numCol);
+    }
+
+    /**
      * Creates a matrix of size {@code numRow} × {@code numCol} initialized to the given elements.
      * The elements array size must be equals to {@code numRow*numCol}. Column indices vary fastest.
      *
@@ -653,72 +660,13 @@ public final class Matrices extends Stat
     }
 
     /**
-     * Returns a new matrix with the same elements than the given matrix except for the specified rows.
-     * This method is useful for removing a range of <em>target</em> dimensions in an affine transform.
-     *
-     * @param  matrix The matrix where to remove rows, or {@code null}.
-     * @param  lower  Index of the first row to remove (inclusive).
-     * @param  upper  Index after the last row to remove (exclusive).
-     * @return A copy of the given matrix with the specified rows removed,
-     *         or {@code null} if the given matrix was null.
-     *
-     * @since 0.7
-     */
-    public static Matrix removeRows(final Matrix matrix, final int lower, final int upper) {
-        if (matrix == null) {
-            return null;
-        }
-        final int numRow = matrix.getNumRow();
-        final int numCol = matrix.getNumCol();
-        ArgumentChecks.ensureValidIndexRange(numRow, lower, upper);
-        final Matrix reduced = createZero(numRow - (upper - lower), numCol);
-        int dest = 0;
-        for (int j=0; j<numRow; j++) {
-            if (j == lower) {
-                j = upper;
-                if (j == numRow) break;
-            }
-            for (int i=0; i<numCol; i++) {
-                reduced.setElement(dest, i, matrix.getElement(j, i));
-            }
-            dest++;
-        }
-        return reduced;
-    }
-
-    /**
-     * Returns a new matrix with the same elements than the given matrix except for the specified columns.
-     * This method is useful for removing a range of <em>source</em> dimensions in an affine transform.
-     * Coordinates will be converted as if the values in the removed dimensions were zeros.
-     *
-     * @param  matrix The matrix where to remove columns, or {@code null}.
-     * @param  lower  Index of the first column to remove (inclusive).
-     * @param  upper  Index after the last column to remove (exclusive).
-     * @return A copy of the given matrix with the specified columns removed,
-     *         or {@code null} if the given matrix was null.
-     *
-     * @since 0.7
-     */
-    public static Matrix removeColumns(final Matrix matrix, final int lower, final int upper) {
-        if (matrix == null) {
-            return null;
-        }
-        final int numRow = matrix.getNumRow();
-        final int numCol = matrix.getNumCol();
-        ArgumentChecks.ensureValidIndexRange(numCol, lower, upper);
-        final Matrix reduced = createZero(numRow, numCol - (upper - lower));
-        int dest = 0;
-        for (int i=0; i<numCol; i++) {
-            if (i == lower) {
-                i = upper;
-                if (i == numCol) break;
-            }
-            for (int j=0; j<numRow; j++) {
-                reduced.setElement(j, dest, matrix.getElement(j, i));
-            }
-            dest++;
-        }
-        return reduced;
+     * Returns {@code true} if the given matrix is likely to use extended precision.
+     * A value of {@code true} is not a guarantee that the matrix uses extended precision,
+     * but a value of {@code false} is a guarantee that it does not.
+     */
+    private static boolean isExtendedPrecision(final Matrix matrix) {
+        return (matrix instanceof MatrixSIS) ? ((MatrixSIS) matrix).isExtendedPrecision() :
+               (matrix instanceof ExtendedPrecisionMatrix);  // Not guarantee that the matrix really uses double-double.
     }
 
     /**
@@ -727,7 +675,7 @@ public final class Matrices extends Stat
      * <div class="note"><b>Implementation note:</b>
      * For square matrix with a size between {@value org.apache.sis.referencing.operation.matrix.Matrix1#SIZE}
      * and {@value org.apache.sis.referencing.operation.matrix.Matrix4#SIZE} inclusive, the returned matrix is
-     * guaranteed to be an instance of one of {@link Matrix1} … {@link Matrix4} subtypes.</div>
+     * usually an instance of one of {@link Matrix1} … {@link Matrix4} subtypes.</div>
      *
      * @param matrix The matrix to copy, or {@code null}.
      * @return A copy of the given matrix, or {@code null} if the given matrix was null.
@@ -743,7 +691,7 @@ public final class Matrices extends Stat
         if (size != matrix.getNumCol()) {
             return new NonSquareMatrix(matrix);
         }
-        if (!(matrix instanceof ExtendedPrecisionMatrix)) {
+        if (!isExtendedPrecision(matrix)) {
             switch (size) {
                 case 1: return new Matrix1(matrix);
                 case 2: return new Matrix2(matrix);

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -55,7 +55,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see Matrices
@@ -226,6 +226,13 @@ public abstract class MatrixSIS implemen
     public abstract void setElements(final double[] elements);
 
     /**
+     * Returns {@code true} if this matrix uses extended precision.
+     */
+    boolean isExtendedPrecision() {
+        return false;
+    }
+
+    /**
      * Returns {@code true} if this matrix represents an affine transform.
      * A transform is affine if the matrix is square and its last row contains
      * only zeros, except in the last column which contains 1.
@@ -455,6 +462,77 @@ public abstract class MatrixSIS implemen
     }
 
     /**
+     * Returns a new matrix with the same elements than this matrix except for the specified rows.
+     * This method is useful for removing a range of <em>target</em> dimensions in an affine transform.
+     *
+     * @param  lower Index of the first row to remove (inclusive).
+     * @param  upper Index after the last row to remove (exclusive).
+     * @return A copy of this matrix with the specified rows removed.
+     *
+     * @since 0.7
+     */
+    public MatrixSIS removeRows(final int lower, final int upper) {
+        final int numRow = getNumRow();
+        final int numCol = getNumCol();
+        ArgumentChecks.ensureValidIndexRange(numRow, lower, upper);
+        final DoubleDouble dd = isExtendedPrecision() ? new DoubleDouble() : null;
+        final MatrixSIS reduced = Matrices.createZero(numRow - (upper - lower), numCol, dd != null);
+        int dest = 0;
+        for (int j=0; j<numRow; j++) {
+            if (j == lower) {
+                j = upper;
+                if (j == numRow) break;
+            }
+            for (int i=0; i<numCol; i++) {
+                if (dd != null) {
+                    get(j, i, dd);
+                    reduced.set(dest, i, dd);
+                } else {
+                    reduced.setElement(dest, i, getElement(j, i));
+                }
+            }
+            dest++;
+        }
+        return reduced;
+    }
+
+    /**
+     * Returns a new matrix with the same elements than this matrix except for the specified columns.
+     * This method is useful for removing a range of <em>source</em> dimensions in an affine transform.
+     * Coordinates will be converted as if the values in the removed dimensions were zeros.
+     *
+     * @param  lower  Index of the first column to remove (inclusive).
+     * @param  upper  Index after the last column to remove (exclusive).
+     * @return A copy of this matrix with the specified columns removed.
+     *
+     * @since 0.7
+     */
+    public MatrixSIS removeColumns(final int lower, final int upper) {
+        final int numRow = getNumRow();
+        final int numCol = getNumCol();
+        ArgumentChecks.ensureValidIndexRange(numCol, lower, upper);
+        final DoubleDouble dd = isExtendedPrecision() ? new DoubleDouble() : null;
+        final MatrixSIS reduced = Matrices.createZero(numRow, numCol - (upper - lower), dd != null);
+        int dest = 0;
+        for (int i=0; i<numCol; i++) {
+            if (i == lower) {
+                i = upper;
+                if (i == numCol) break;
+            }
+            for (int j=0; j<numRow; j++) {
+                if (dd != null) {
+                    get(j, i, dd);
+                    reduced.set(j, dest, dd);
+                } else {
+                    reduced.setElement(j, dest, getElement(j, i));
+                }
+            }
+            dest++;
+        }
+        return reduced;
+    }
+
+    /**
      * Returns a hash code value based on the data values in this matrix.
      *
      * @return A hash code value for this matrix.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -21,12 +21,14 @@ import java.util.Arrays;
 import java.io.Serializable;
 import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
+import org.opengis.util.FactoryException;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.opengis.referencing.operation.OperationMethod;
@@ -79,7 +81,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.5
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see DefaultMathTransformFactory
@@ -785,9 +787,9 @@ public abstract class AbstractMathTransf
     }
 
     /**
-     * Concatenates in an optimized way this math transform with the given one. A new math transform
-     * is created to perform the combined transformation. The {@code applyOtherFirst} value determines
-     * the transformation order as bellow:
+     * Concatenates in an optimized way this math transform with the given one.
+     * A new math transform is created to perform the combined transformation.
+     * The {@code applyOtherFirst} value determines the transformation order as bellow:
      *
      * <ul>
      *   <li>If {@code applyOtherFirst} is {@code true}, then transforming a point
@@ -809,9 +811,12 @@ public abstract class AbstractMathTransf
      * @param  other The math transform to apply.
      * @param  applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
      *         or {@code false} if the transformation order is {@code this} followed by {@code other}.
+     * @param  factory The factory which is (indirectly) invoking this method, or {@code null} if none.
      * @return The combined math transform, or {@code null} if no optimized combined transform is available.
      */
-    MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+    MathTransform concatenate(MathTransform other, boolean applyOtherFirst, MathTransformFactory factory)
+            throws FactoryException
+    {
         return null;
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
 import java.util.List;
 import java.util.ArrayList;
 import java.io.Serializable;
+import org.opengis.util.FactoryException;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.parameter.ParameterValueGroup;
@@ -27,6 +28,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.parameter.Parameterized;
@@ -145,18 +147,21 @@ class ConcatenatedTransform extends Abst
      *
      * @param tr1 The first math transform.
      * @param tr2 The second math transform.
-     * @return    The concatenated transform.
+     * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
+     * @return The concatenated transform.
      *
      * @see MathTransforms#concatenate(MathTransform, MathTransform)
      */
-    public static MathTransform create(MathTransform tr1, MathTransform tr2) throws MismatchedDimensionException {
+    public static MathTransform create(MathTransform tr1, MathTransform tr2, final MathTransformFactory factory)
+            throws FactoryException, MismatchedDimensionException
+    {
         final int dim1 = tr1.getTargetDimensions();
         final int dim2 = tr2.getSourceDimensions();
         if (dim1 != dim2) {
             throw new MismatchedDimensionException(Errors.format(Errors.Keys.CanNotConcatenateTransforms_2, getName(tr1),
                     getName(tr2)) + ' ' + Errors.format(Errors.Keys.MismatchedDimension_2, dim1, dim2));
         }
-        MathTransform mt = createOptimized(tr1, tr2);
+        MathTransform mt = createOptimized(tr1, tr2, factory);
         if (mt != null) {
             return mt;
         }
@@ -189,9 +194,9 @@ class ConcatenatedTransform extends Abst
                 final ConcatenatedTransform ctr = (ConcatenatedTransform) candidate;
                 if (first) {
                     c1 = candidate = ctr.transform1;
-                    c2 = create(ctr.transform2, c2);
+                    c2 = create(ctr.transform2, c2, factory);
                 } else {
-                    c1 = create(c1, ctr.transform1);
+                    c1 = create(c1, ctr.transform1, factory);
                     c2 = candidate = ctr.transform2;
                 }
                 final int c = getStepCount(c1) + getStepCount(c2);
@@ -209,7 +214,7 @@ class ConcatenatedTransform extends Abst
          * Tries again the check for optimized cases (identity, etc.), because a
          * transform may have been simplified to identity as a result of the above.
          */
-        mt = createOptimized(tr1, tr2);
+        mt = createOptimized(tr1, tr2, factory);
         if (mt != null) {
             return mt;
         }
@@ -252,8 +257,12 @@ class ConcatenatedTransform extends Abst
      * Tries to returns an optimized concatenation, for example by merging two affine transforms
      * into a single one. If no optimized cases has been found, returns {@code null}. In the later
      * case, the caller will need to create a more heavy {@link ConcatenatedTransform} instance.
+     *
+     * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
      */
-    private static MathTransform createOptimized(final MathTransform tr1, final MathTransform tr2) {
+    private static MathTransform createOptimized(final MathTransform tr1, final MathTransform tr2,
+            final MathTransformFactory factory) throws FactoryException
+    {
         /*
          * Trivial - but actually essential!! - check for the identity cases.
          */
@@ -269,7 +278,7 @@ class ConcatenatedTransform extends Abst
             if (matrix2 != null) {
                 final Matrix matrix = Matrices.multiply(matrix2, matrix1);
                 if (Matrices.isIdentity(matrix, IDENTITY_TOLERANCE)) {
-                    return MathTransforms.identity(matrix.getNumRow() - 1);
+                    return MathTransforms.identity(matrix.getNumRow() - 1);     // Returns a cached instance.
                 }
                 /*
                  * NOTE: It is quite tempting to "fix rounding errors" in the matrix before to create the transform.
@@ -278,7 +287,11 @@ class ConcatenatedTransform extends Abst
                  * Apache SIS performs matrix operations using double-double arithmetic in the hope to get exact
                  * results at the 'double' accuracy, which avoid the need for a tolerance threshold.
                  */
-                return MathTransforms.linear(matrix);
+                if (factory != null) {
+                    return factory.createAffineTransform(matrix);
+                } else {
+                    return MathTransforms.linear(matrix);
+                }
             }
             /*
              * If the second transform is a passthrough transform and all passthrough ordinates
@@ -288,9 +301,17 @@ class ConcatenatedTransform extends Abst
                 final PassThroughTransform candidate = (PassThroughTransform) tr2;
                 final Matrix sub = candidate.toSubMatrix(matrix1);
                 if (sub != null) {
-                    return PassThroughTransform.create(candidate.firstAffectedOrdinate,
-                            create(MathTransforms.linear(sub), candidate.subTransform),
-                            candidate.numTrailingOrdinates);
+                    if (factory != null) {
+                        return factory.createPassThroughTransform(
+                                candidate.firstAffectedOrdinate,
+                                factory.createConcatenatedTransform(factory.createAffineTransform(sub), candidate.subTransform),
+                                candidate.numTrailingOrdinates);
+                    } else {
+                        return PassThroughTransform.create(
+                                candidate.firstAffectedOrdinate,
+                                create(MathTransforms.linear(sub), candidate.subTransform, factory),
+                                candidate.numTrailingOrdinates);
+                    }
                 }
             }
         }
@@ -301,20 +322,20 @@ class ConcatenatedTransform extends Abst
         if (areInverse(tr1, tr2) || areInverse(tr2, tr1)) {
             assert tr1.getSourceDimensions() == tr2.getTargetDimensions();
             assert tr1.getTargetDimensions() == tr2.getSourceDimensions();
-            return MathTransforms.identity(tr1.getSourceDimensions());
+            return MathTransforms.identity(tr1.getSourceDimensions());      // Returns a cached instance.
         }
         /*
          * Gives a chance to AbstractMathTransform to returns an optimized object.
          * The main use case is Logarithmic vs Exponential transforms.
          */
         if (tr1 instanceof AbstractMathTransform) {
-            final MathTransform optimized = ((AbstractMathTransform) tr1).concatenate(tr2, false);
+            final MathTransform optimized = ((AbstractMathTransform) tr1).concatenate(tr2, false, factory);
             if (optimized != null) {
                 return optimized;
             }
         }
         if (tr2 instanceof AbstractMathTransform) {
-            final MathTransform optimized = ((AbstractMathTransform) tr2).concatenate(tr1, true);
+            final MathTransform optimized = ((AbstractMathTransform) tr2).concatenate(tr1, true, factory);
             if (optimized != null) {
                 return optimized;
             }
@@ -847,11 +868,13 @@ class ConcatenatedTransform extends Abst
     @Override
     public synchronized MathTransform inverse() throws NoninvertibleTransformException {
         assert isValid();
-        if (inverse == null) {
-            inverse = create(transform2.inverse(), transform1.inverse());
+        if (inverse == null) try {
+            inverse = create(transform2.inverse(), transform1.inverse(), null);
             if (inverse instanceof ConcatenatedTransform) {
                 ((ConcatenatedTransform) inverse).inverse = this;
             }
+        } catch (FactoryException e) {
+            throw new NoninvertibleTransformException(Errors.format(Errors.Keys.NonInvertibleTransform), e);
         }
         return inverse;
     }

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=1713951&r1=1713950&r2=1713951&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] Thu Nov 12 00:18:37 2015
@@ -149,7 +149,7 @@ import org.apache.sis.util.resources.Mes
  *
  * @author  Martin Desruisseaux (Geomatys, IRD)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see MathTransformProvider
@@ -773,12 +773,15 @@ public class DefaultMathTransformFactory
             throws FactoryException
     {
         lastMethod.remove();
+        ArgumentChecks.ensureNonNull("tr1", tr1);
+        ArgumentChecks.ensureNonNull("tr2", tr2);
         final MathTransform tr;
         try {
-            tr = MathTransforms.concatenate(tr1, tr2);
+            tr = ConcatenatedTransform.create(tr1, tr2, this);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
+        assert MathTransforms.isValid(MathTransforms.getSteps(tr)) : tr;
         return unique(tr);
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -26,6 +26,7 @@ import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.DirectPosition;
+import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.Matrix;
@@ -782,7 +783,7 @@ next:   while (--numPts >= 0) {
             Matrix matrix = EllipsoidalToCartesianTransform.this.derivative(new DirectPositionView(point, offset, 3));
             matrix = Matrices.inverse(matrix);
             if (!withHeight) {
-                matrix = Matrices.removeRows(matrix, 2, 3);     // Drop height only after matrix inversion is done.
+                matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3);     // Drop height only after matrix inversion is done.
             }
             return matrix;
         }
@@ -799,6 +800,51 @@ next:   while (--numPts >= 0) {
         }
 
         /**
+         * If this transform returns three-dimensional outputs, and if the transform just after this one
+         * just drops the height values, then replaces this transform by a two-dimensional one.
+         * The intend is to handle the following sequence of operations defined in the EPSG database:
+         *
+         * <ol>
+         *   <li>Inverse of <cite>Geographic/geocentric conversions</cite> (EPSG:9602)</li>
+         *   <li><cite>Geographic 3D to 2D conversion</cite> (EPSG:9659)</li>
+         * </ol>
+         *
+         * Replacing the above sequence by a two-dimensional {@code EllipsoidalToCartesianTransform} instance
+         * allow the following optimizations:
+         *
+         * <ul>
+         *   <li>Avoid computation of <var>h</var> value.</li>
+         *   <li>Allow use of the more efficient {@link java.awt.geom.AffineTransform} after this transform
+         *       instead than a transform based on a matrix of size 3×4.</li>
+         * </ul>
+         */
+        @Override
+        final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+                final MathTransformFactory factory) throws FactoryException
+        {
+            if (!applyOtherFirst && withHeight && other instanceof LinearTransform && other.getTargetDimensions() == 2) {
+                /*
+                 * Found a 3×4 matrix after this transform. We can reduce to a 3×3 matrix only if no dimension
+                 * use the column that we are about to drop (i.e. all coefficients in that column are zero).
+                 */
+                Matrix matrix = ((LinearTransform) other).getMatrix();
+                if (matrix.getElement(0,2) == 0 &&
+                    matrix.getElement(1,2) == 0 &&
+                    matrix.getElement(2,2) == 0)
+                {
+                    matrix = MatrixSIS.castOrCopy(matrix).removeColumns(2, 3);
+                    final MathTransform tr2D = create2D().inverse();
+                    if (factory != null) {
+                        return factory.createConcatenatedTransform(tr2D, factory.createAffineTransform(matrix));
+                    } else {
+                        return ConcatenatedTransform.create(tr2D, MathTransforms.linear(matrix), factory);
+                    }
+                }
+            }
+            return super.concatenate(other, applyOtherFirst, factory);
+        }
+
+        /**
          * Given a transformation chain to format in WKT, inserts a "Geographic 3D to 2D" pseudo-conversion
          * after this transform (normally {@code transforms.get(index)}) if this conversion computes no height.
          *
@@ -832,4 +878,60 @@ next:   while (--numPts >= 0) {
         }
         return index;
     }
+
+    /**
+     * If this transform expects three-dimensional inputs, and if the transform just before this one
+     * unconditionally sets the height to zero, then replaces this transform by a two-dimensional one.
+     * The intend is to handle the following sequence of operations defined in the EPSG database:
+     *
+     * <ol>
+     *   <li>Inverse of <cite>Geographic 3D to 2D conversion</cite> (EPSG:9659)</li>
+     *   <li><cite>Geographic/geocentric conversions</cite> (EPSG:9602)</li>
+     * </ol>
+     *
+     * Replacing the above sequence by a two-dimensional {@code EllipsoidalToCartesianTransform} instance
+     * allow the following optimizations:
+     *
+     * <ul>
+     *   <li>Avoid computation of <var>h</var> value.</li>
+     *   <li>Allow use of the more efficient {@link java.awt.geom.AffineTransform} before this transform
+     *       instead than a transform based on a matrix of size 4×3.</li>
+     * </ul>
+     */
+    @Override
+    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+            final MathTransformFactory factory) throws FactoryException
+    {
+        if (applyOtherFirst && withHeight && other instanceof LinearTransform && other.getSourceDimensions() == 2) {
+            /*
+             * Found a 4×3 matrix before this transform. We can reduce to a 3×3 matrix only if the row that we are
+             * about to drop unconditionnaly set the height to zero (i.e. all coefficients in that row are zero).
+             */
+            Matrix matrix = ((LinearTransform) other).getMatrix();
+            if (matrix.getElement(2,0) == 0 &&
+                matrix.getElement(2,1) == 0 &&
+                matrix.getElement(2,2) == 0)
+            {
+                matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3);
+                final MathTransform tr2D = create2D();
+                if (factory != null) {
+                    return factory.createConcatenatedTransform(factory.createAffineTransform(matrix), tr2D);
+                } else {
+                    return ConcatenatedTransform.create(MathTransforms.linear(matrix), tr2D, factory);
+                }
+            }
+        }
+        return super.concatenate(other, applyOtherFirst, factory);
+    }
+
+    /**
+     * Creates a transform with the same parameters than this transform,
+     * but expecting two-dimensional inputs instead than three-dimensional.
+     */
+    final EllipsoidalToCartesianTransform create2D() {
+        final ParameterValue<Double> p = context.getOrCreate(SEMI_MAJOR);
+        final Unit<Length> unit = p.getUnit().asType(Length.class);
+        return new EllipsoidalToCartesianTransform(p.doubleValue(),
+                context.getOrCreate(SEMI_MINOR).doubleValue(unit), unit, false);
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
 import java.io.Serializable;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.ComparisonMode;
 
@@ -219,11 +221,13 @@ final class ExponentialTransform1D exten
      * @param  applyOtherFirst {@code true} if the transformation order is {@code other}
      *         followed by {@code this}, or {@code false} if the transformation order is
      *         {@code this} followed by {@code other}.
-     * @return The combined math transform, or {@code null} if no optimized combined
-     *         transform is available.
+     * @param  factory The factory which is (indirectly) invoking this method, or {@code null} if none.
+     * @return The combined math transform, or {@code null} if no optimized combined transform is available.
      */
     @Override
-    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+            final MathTransformFactory factory) throws FactoryException
+    {
         if (other instanceof LinearTransform) {
             final LinearTransform1D linear = (LinearTransform1D) other;
             if (applyOtherFirst) {
@@ -240,7 +244,7 @@ final class ExponentialTransform1D exten
         } else if (other instanceof LogarithmicTransform1D) {
             return concatenateLog((LogarithmicTransform1D) other, applyOtherFirst);
         }
-        return super.concatenate(other, applyOtherFirst);
+        return super.concatenate(other, applyOtherFirst, factory);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
 import java.io.Serializable;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.util.ArgumentChecks;
@@ -114,10 +116,13 @@ class LogarithmicTransform1D extends Abs
      * @param  other The math transform to apply.
      * @param  applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
      *         or {@code false} if the transformation order is {@code this} followed by {@code other}.
+     * @param  factory The factory which is (indirectly) invoking this method, or {@code null} if none.
      * @return The combined math transform, or {@code null} if no optimized combined transform is available.
      */
     @Override
-    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+            final MathTransformFactory factory) throws FactoryException
+    {
         if (other instanceof LinearTransform1D) {
             final LinearTransform1D linear = (LinearTransform1D) other;
             if (applyOtherFirst) {
@@ -133,7 +138,7 @@ class LogarithmicTransform1D extends Abs
         } else if (other instanceof ExponentialTransform1D) {
             return ((ExponentialTransform1D) other).concatenateLog(this, !applyOtherFirst);
         }
-        return super.concatenate(other, applyOtherFirst);
+        return super.concatenate(other, applyOtherFirst, factory);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
 import java.util.List;
 import java.util.Collections;
 import java.awt.geom.AffineTransform;
+import org.opengis.util.FactoryException;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
@@ -52,7 +53,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see MathTransformFactory
@@ -185,7 +186,7 @@ public final class MathTransforms extend
             if (compound == null) {
                 compound = tr;
             } else {
-                compound = ConcatenatedTransform.create(compound, tr);
+                compound = concatenate(compound, tr);
             }
         }
         assert isValid(getSteps(compound)) : compound;
@@ -210,7 +211,12 @@ public final class MathTransforms extend
     {
         ensureNonNull("tr1", tr1);
         ensureNonNull("tr2", tr2);
-        final MathTransform tr = ConcatenatedTransform.create(tr1, tr2);
+        final MathTransform tr;
+        try {
+            tr = ConcatenatedTransform.create(tr1, tr2, null);
+        } catch (FactoryException e) {
+            throw new IllegalArgumentException(e);      // Should never happen actually.
+        }
         assert isValid(getSteps(tr)) : tr;
         return tr;
     }
@@ -310,7 +316,7 @@ public final class MathTransforms extend
      * (because their matrices should have been multiplied together).
      * This is used for assertion purposes only.
      */
-    private static boolean isValid(final List<MathTransform> steps) {
+    static boolean isValid(final List<MathTransform> steps) {
         boolean wasLinear = false;
         for (final MathTransform step : steps) {
             if (step instanceof LinearTransform) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
 import java.io.Serializable;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.ComparisonMode;
 
@@ -172,15 +174,18 @@ final class PowerTransform1D extends Abs
      * @param  other The math transform to apply.
      * @param  applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
      *         or {@code false} if the transformation order is {@code this} followed by {@code other}.
+     * @param  factory The factory which is (indirectly) invoking this method, or {@code null} if none.
      * @return The combined math transform, or {@code null} if no optimized combined transform is available.
      */
     @Override
-    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+    final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+            final MathTransformFactory factory) throws FactoryException
+    {
         if (other instanceof PowerTransform1D) {
             return create(power + ((PowerTransform1D) other).power);
         }
         // TODO: more optimization could go here for logarithmic and exponential cases.
-        return super.concatenate(other, applyOtherFirst);
+        return super.concatenate(other, applyOtherFirst, factory);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -201,8 +201,7 @@ public class TransferFunction implements
             } else if (TransferFunctionType.EXPONENTIAL.equals(type)) {
                 transform = ExponentialTransform1D.create(base, scale);
                 if (offset != 0) {  // Rarely occurs in practice.
-                    transform = (MathTransform1D) ConcatenatedTransform.create(
-                            transform, LinearTransform1D.create(0, offset));
+                    transform = MathTransforms.concatenate(transform, LinearTransform1D.create(0, offset));
                 }
             } else if (TransferFunctionType.LOGARITHMIC.equals(type)) {
                 if (scale == 1) {
@@ -213,7 +212,7 @@ public class TransferFunction implements
                      * The ExponentialTransform1D.concatenate(…) method will rewrite the equation using
                      * mathematical identities. The result will be a function with a different base.
                      */
-                    transform = (MathTransform1D) ConcatenatedTransform.create(
+                    transform = MathTransforms.concatenate(
                             LogarithmicTransform1D.create(base, 0),
                             LinearTransform1D.create(scale, offset));
                 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -364,17 +364,17 @@ public final strictfp class MatricesTest
     }
 
     /**
-     * Tests {@link Matrices#removeRows(Matrix, int, int)}
+     * Tests {@link MatrixSIS#removeRows(int, int)}
      */
     @Test
     public void testRemoveRows() {
-        Matrix matrix = Matrices.create(4, 5, new double[] {
+        MatrixSIS matrix = Matrices.create(4, 5, new double[] {
             1, 2, 7, 8, 9,
             3, 4, 6, 7, 8,
             9, 8, 7, 6, 5,
             4, 3, 2, 1, 0
         });
-        matrix = Matrices.removeRows(matrix, 3, 4);
+        matrix = matrix.removeRows(3, 4);
         assertEquals(Matrices.create(3, 5, new double[] {
             1, 2, 7, 8, 9,
             3, 4, 6, 7, 8,
@@ -383,17 +383,17 @@ public final strictfp class MatricesTest
     }
 
     /**
-     * Tests {@link Matrices#removeColumns(Matrix, int, int)}
+     * Tests {@link MatrixSIS#removeColumns(int, int)}
      */
     @Test
     public void testRemoveColumns() {
-        Matrix matrix = Matrices.create(4, 5, new double[] {
+        MatrixSIS matrix = Matrices.create(4, 5, new double[] {
             1, 2, 7, 8, 9,
             3, 4, 6, 7, 8,
             9, 8, 7, 6, 5,
             4, 3, 2, 1, 0
         });
-        matrix = Matrices.removeColumns(matrix, 2, 4);
+        matrix = matrix.removeColumns(2, 4);
         assertEquals(Matrices.create(4, 3, new double[] {
             1, 2, 9,
             3, 4, 8,

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java [UTF-8] Thu Nov 12 00:18:37 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
+import org.opengis.util.FactoryException;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
@@ -31,7 +32,7 @@ import static org.opengis.test.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @DependsOn(ProjectiveTransformTest.class)
@@ -81,11 +82,12 @@ public final strictfp class Concatenated
      * Tests the concatenation of two affine transforms than can not be represented as a
      * {@link ConcatenatedTransformDirect}. The slower {@link ConcatenatedTransform} shall be used.
      *
+     * @throws FactoryException Should never happen.
      * @throws TransformException Should never happen.
      */
     @Test
     @org.junit.Ignore("Missing implementation of DimensionFilter.")
-    public void testGeneric() throws TransformException {
+    public void testGeneric() throws FactoryException, TransformException {
         final MathTransform first = null; //MathTransforms.dimensionFilter(4, new int[] {1,3});
 
         final AffineTransform2D second = new AffineTransform2D(0.5, 0, 0, 0.25, 0, 0);  // scale(0.5, 0.25);
@@ -100,7 +102,7 @@ public final strictfp class Concatenated
         verifyTransform(source, target);
 
         // Optimized case.
-        transform = ConcatenatedTransform.create(first, second);
+        transform = ConcatenatedTransform.create(first, second, null);
         assertInstanceOf("Expected optimized concatenation through matrix multiplication.", ProjectiveTransform.class, transform);
         validate();
         verifyTransform(source, target);
@@ -110,13 +112,15 @@ public final strictfp class Concatenated
      * Tests the concatenation of a 3D affine transform with a pass-through transform.
      * The {@link ConcatenatedTransform#create(MathTransform, MathTransform)} method
      * should optimize this case.
+     *
+     * @throws FactoryException Should never happen.
      */
     @Test
-    public void testPassthrough() {
+    public void testPassthrough() throws FactoryException {
         final MathTransform kernel = new PseudoTransform(2, 3); // Any non-linear transform.
         final MathTransform passth = PassThroughTransform.create(0, kernel, 1);
         final Matrix4 matrix = new Matrix4();
-        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth);
+        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth, null);
         assertSame("Identity transform should be ignored.", passth, transform);
         assertEquals("Source dimensions", 3, transform.getSourceDimensions());
         assertEquals("Target dimensions", 4, transform.getTargetDimensions());
@@ -127,7 +131,7 @@ public final strictfp class Concatenated
          */
         matrix.m00 = 3;
         matrix.m13 = 2;
-        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth);
+        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth, null);
         assertInstanceOf("Expected a new passthrough transform.", PassThroughTransform.class, transform);
         final MathTransform subTransform = ((PassThroughTransform) transform).subTransform;
         assertInstanceOf("Expected a new concatenated transform.", ConcatenatedTransform.class, subTransform);
@@ -139,7 +143,7 @@ public final strictfp class Concatenated
          * can not anymore be concatenated with the sub-transform.
          */
         matrix.m22 = 4;
-        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth);
+        transform = ConcatenatedTransform.create(MathTransforms.linear(matrix), passth, null);
         assertInstanceOf("Expected a new concatenated transform.", ConcatenatedTransform.class, transform);
         assertSame(passth, ((ConcatenatedTransform) transform).transform2);
         assertEquals("Source dimensions", 3, transform.getSourceDimensions());

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1713951&r1=1713950&r2=1713951&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu Nov 12 00:18:37 2015
@@ -112,7 +112,7 @@ MismatchedArrayLengths            = Les
 MismatchedCRS                     = Le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es doit \u00eatre le m\u00eame pour tous les objets.
 MismatchedDimension_2             = Les dimensions des objets ({0}D et {1}D) ne concordent pas.
 MismatchedDimension_3             = L\u2019argument \u2018{0}\u2019 a {2} dimension{2,choice,1#|2#s}, alors qu\u2019on en attendait {1}.
-MismatchedMatrixSize_4            = Une matrice de taille de {0}\u00d7{1} \u00e9tait attendue mais la matrice donn\u00e9es est de taille {2}\u00d7{3}.
+MismatchedMatrixSize_4            = Une matrice de taille de {0}\u00d7{1} \u00e9tait attendue mais la matrice donn\u00e9e est de taille {2}\u00d7{3}.
 MismatchedParameterDescriptor_1   = Le descripteur du param\u00e8tre \u00ab\u202f{0}\u202f\u00bb ne correspond pas.
 MismatchedPropertyType_1          = Le type de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb ne correspond pas.
 MismatchedTransformDimension_3    = La {0,choice,0#source|1#destination} de la transformation a {2} dimension{2,choice,1#|2#s}, alors qu\u2019on en attendait {1}.



Mime
View raw message