sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1714052 [1/2] - in /sis/branches/JDK7: ./ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ core/sis-referencing/src/main/java/org/apache/sis/referencing...
Date Thu, 12 Nov 2015 14:24:25 GMT
Author: desruisseaux
Date: Thu Nov 12 14:24:24 2015
New Revision: 1714052

URL: http://svn.apache.org/viewvc?rev=1714052&view=rev
Log:
Merge from the JDK8 branch.

Added:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java
      - copied unchanged from r1714051, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java
Removed:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.java
Modified:
    sis/branches/JDK7/   (props changed)
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
    sis/branches/JDK7/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeocentricTranslationTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties
    sis/branches/JDK7/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/InputFeatureStream.java
    sis/branches/JDK7/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
    sis/branches/JDK7/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java

Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Nov 12 14:24:24 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1584960-1713526
+/sis/branches/JDK8:1584960-1714051
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -493,7 +493,6 @@ public class Formatter implements Locali
      *
      * <p>This method has no effect in any of the following cases:</p>
      * <ul>
-     *   <li>WKT formatting has not yet started.</li>
      *   <li>This method has already been invoked before the next {@code append(…)}.</li>
      *   <li>The indentation is {@link WKTFormat#SINGLE_LINE}.</li>
      * </ul>
@@ -546,6 +545,8 @@ public class Formatter implements Locali
             } else {
                 buffer.append(symbols.getSeparator());
             }
+        } else if (requestNewLine) {
+            buffer.append(System.lineSeparator()).append(CharSequences.spaces(margin));
         }
         requestNewLine = false;
     }
@@ -557,7 +558,7 @@ public class Formatter implements Locali
      * @param keyword The element keyword (e.g. {@code "DATUM"}, {@code "AXIS"}, <i>etc</i>).
      */
     private void openElement(final boolean newLine, String keyword) {
-        if (newLine) {
+        if (newLine && buffer.length() != elementStart) {
             newLine();
         }
         appendSeparator();

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -207,8 +207,7 @@ public abstract class GeocentricAffine e
      * <p>This method is invoked only by {@code ConcatenatedTransform.getPseudoSteps()} for the need of WKT formatting.
      * The purpose of this method is very similar to the purpose of {@code AbstractMathTransform.beforeFormat(List, int,
      * boolean)} except that we need to perform the {@code forDatumShift(…)} work only after {@code beforeFormat(…)}
-     * finished its work for all {@code ContextualParameters}, including the {@code EllipsoidalToCartesianTransform}'s
-     * one.</p>
+     * finished its work for all {@code ContextualParameters}, including the {@code EllipsoidToCentricTransform}'s one.</p>
      *
      * @param transforms The full chain of concatenated transforms.
      */

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -22,14 +22,14 @@ import org.opengis.util.FactoryException
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
-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.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.resources.Errors;
 
 
 /**
@@ -53,7 +53,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.
@@ -109,27 +109,6 @@ public abstract class GeocentricAffineBe
     }
 
     /**
-     * Returns the number of dimensions declared in the given parameter group, or 0 if none.
-     * If this method returns a non-zero value, then it is guaranteed to be either 2 or 3.
-     *
-     * @param  values The values from which to get the dimension.
-     * @return The dimension, or 0 if none.
-     * @throws InvalidParameterValueException if the dimension parameter has an invalid value.
-     */
-    static int getDimension(final Parameters values) throws InvalidParameterValueException {
-        final Integer value = values.getValue(DIMENSION);
-        if (value == null) {
-            return 0;
-        }
-        final int dimension = value;  // Unboxing.
-        if (dimension != 2 && dimension != 3) {
-            throw new InvalidParameterValueException(Errors.format(
-                    Errors.Keys.IllegalArgumentValue_2, "dim", value), "dim", value);
-        }
-        return dimension;
-    }
-
-    /**
      * Creates a math transform from the specified group of parameter values.
      * This method wraps the affine operation into Geographic/Geocentric conversions.
      *
@@ -144,25 +123,29 @@ 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.
+         * (the unit implied by SRC_SEMI_MAJOR) because it is the unit of Bursa-Wolf parameters that we created above.
          */
-        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 = EllipsoidToCentricTransform.createGeodeticConversion(factory,
+                pv.doubleValue(SRC_SEMI_MAJOR),
+                pv.doubleValue(SRC_SEMI_MINOR),
+                SI.METRE, getSourceDimensions() >= 3,
+                EllipsoidToCentricTransform.TargetType.CARTESIAN);
         /*
          * 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.
          */
-        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 = EllipsoidToCentricTransform.createGeodeticConversion(factory,
+                pv.doubleValue(TGT_SEMI_MAJOR),
+                pv.doubleValue(TGT_SEMI_MINOR),
+                SI.METRE, getTargetDimensions() >= 3,
+                EllipsoidToCentricTransform.TargetType.CARTESIAN);
+        try {
+            toGeographic = toGeographic.inverse();
+        } catch (NoninvertibleTransformException e) {
+            throw new FactoryException(e);  // Should never happen with SIS implementation.
+        }
         /*
          * The  Geocentric → Affine → Geographic  chain.
          */

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricToGeographic.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -22,9 +22,7 @@ import org.opengis.referencing.operation
 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.opengis.util.FactoryException;
-import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.metadata.iso.citation.Citations;
 
 
@@ -32,10 +30,6 @@ import org.apache.sis.metadata.iso.citat
  * The provider for the <strong>inverse</strong> of "<cite>Geographic/geocentric conversions</cite>" (EPSG:9602).
  * This provider creates transforms from geocentric to geographic coordinate reference systems.
  *
- * <p>By default, this provider creates a transform to a three-dimensional ellipsoidal coordinate system,
- * which is the behavior implied in OGC's WKT. However a SIS-specific {@code "dim"} parameter allows to
- * transform to a two-dimensional ellipsoidal coordinate system instead.</p>
- *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.7
  * @version 0.7
@@ -61,31 +55,15 @@ 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.
     }
 
     /**
-     * The provider for the other number of dimensions (2D or 3D).
-     */
-    private final GeocentricToGeographic redimensioned;
-
-    /**
      * Constructs a provider for the 3-dimensional case.
      */
     public GeocentricToGeographic() {
         super(3, 3, PARAMETERS);
-        redimensioned = new GeocentricToGeographic(this);
-    }
-
-    /**
-     * Constructs a provider for the 2-dimensional case.
-     *
-     * @param redimensioned The three-dimensional case.
-     */
-    private GeocentricToGeographic(final GeocentricToGeographic redimensioned) {
-        super(3, 2, PARAMETERS);
-        this.redimensioned = redimensioned;
     }
 
     /**
@@ -110,7 +88,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) {
@@ -118,18 +96,4 @@ public final class GeocentricToGeographi
         }
         return tr;
     }
-
-    /**
-     * 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", 3, 3, sourceDimensions);
-        ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions);
-        return (targetDimensions == getTargetDimensions()) ? this : redimensioned;
-    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -21,29 +21,19 @@ 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.referencing.operation.transform.EllipsoidToCentricTransform;
 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;
 
 
 /**
  * The provider for <cite>"Geographic/geocentric conversions"</cite> (EPSG:9602).
  * This provider creates transforms from geographic to geocentric coordinate reference systems.
  *
- * <p>By default, this provider creates a transform from a three-dimensional ellipsoidal coordinate system,
- * which is the behavior implied in OGC's WKT. However a SIS-specific {@code "dim"} parameter allows to transform
- * from a two-dimensional ellipsoidal coordinate system instead.</p>
- *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.7
  * @version 0.7
@@ -72,31 +62,15 @@ 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.
     }
 
     /**
-     * The provider for the other number of dimensions (2D or 3D).
-     */
-    private final GeographicToGeocentric redimensioned;
-
-    /**
      * Constructs a provider for the 3-dimensional case.
      */
     public GeographicToGeocentric() {
         super(3, 3, PARAMETERS);
-        redimensioned = new GeographicToGeocentric(this);
-    }
-
-    /**
-     * Constructs a provider for the 2-dimensional case.
-     *
-     * @param redimensioned The three-dimensional case.
-     */
-    private GeographicToGeocentric(final GeographicToGeocentric redimensioned) {
-        super(2, 3, PARAMETERS);
-        this.redimensioned = redimensioned;
     }
 
     /**
@@ -121,49 +95,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);
-    }
-
-    /**
-     * 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", 3, 3, targetDimensions);
-        return (sourceDimensions == getSourceDimensions()) ? this : redimensioned;
+        return EllipsoidToCentricTransform.createGeodeticConversion(factory, semiMajor.doubleValue(),
+                values.parameter(Constants.SEMI_MINOR).doubleValue(unit), unit, true,
+                EllipsoidToCentricTransform.TargetType.CARTESIAN);
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -26,6 +26,7 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.InvalidParameterValueException;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.OperationMethod;
@@ -37,6 +38,7 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.internal.referencing.NilReferencingObject;
 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;
 
@@ -222,9 +224,14 @@ public final class Molodensky extends Ge
     static MathTransform createMathTransform(final MathTransformFactory factory, final Parameters values,
             int sourceDimensions, int targetDimensions, final boolean isAbridged) throws FactoryException
     {
-        int dimension = getDimension(values);
-        if (dimension != 0) {
-            sourceDimensions = targetDimensions = dimension;
+        final Integer dim = values.getValue(DIMENSION);
+        if (dim != null) {
+            final int n = dim;  // Unboxing.
+            if (n != 2 && n != 3) {
+                throw new InvalidParameterValueException(Errors.format(
+                        Errors.Keys.IllegalArgumentValue_2, "dim", dim), "dim", dim);
+            }
+            sourceDimensions = targetDimensions = n;
         }
         /*
          * Following method calls implicitly convert parameter values to metres.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Thu Nov 12 14:24:24 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.
      *
@@ -519,6 +526,9 @@ public final class Matrices extends Stat
      * }
      * </div>
      *
+     * The inverse of the matrix created by this method will put {@link Double#NaN} values in the extra dimensions.
+     * Other dimensions will work as expected.
+     *
      * @param  sourceDimensions The number of dimensions in source coordinates.
      * @param  selectedDimensions The 0-based indices of source ordinate values to keep.
      *         The length of this array will be the number of dimensions in target coordinates.
@@ -650,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.
     }
 
     /**
@@ -724,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.
@@ -740,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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -21,6 +21,7 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.util.ComparisonMode;
@@ -106,6 +107,29 @@ abstract class AbstractLinearTransform e
     }
 
     /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            /*
+             * Should never be the identity transform at this point (except during tests) because
+             * MathTransforms.linear(…) should never instantiate this class in the identity case.
+             * But we check anyway as a paranoiac safety.
+             */
+            if (isIdentity()) {
+                inverse = this;
+            } else {
+                inverse = MathTransforms.linear(Matrices.inverse(this));
+                if (inverse instanceof AbstractLinearTransform) {
+                    ((AbstractLinearTransform) inverse).inverse = this;
+                }
+            }
+        }
+        return inverse;
+    }
+
+    /**
      * Returns the parameter descriptors for this math transform.
      *
      * @return {@inheritDoc}

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Thu Nov 12 14:24:24 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;
     }
 
@@ -932,7 +937,7 @@ public abstract class AbstractMathTransf
      * @param  transforms The full chain of concatenated transforms.
      * @param  index      The index of this transform in the {@code transforms} chain.
      * @param  inverse    Always {@code false}, except if we are formatting the inverse transform.
-     * @return Index of the last transform processed. Iteration should continue at that index + 1.
+     * @return Index of this transform in the {@code transforms} chain after processing.
      *
      * @see ConcatenatedTransform#getPseudoSteps()
      */
@@ -1098,7 +1103,7 @@ public abstract class AbstractMathTransf
          * but with the knowledge that this transform is an inverse transform.
          */
         @Override
-        final int beforeFormat(final List<Object> transforms, final int index, final boolean inverse) {
+        int beforeFormat(final List<Object> transforms, final int index, final boolean inverse) {
             final ContextualParameters parameters = getContextualParameters();
             if (parameters != null) {
                 return parameters.beforeFormat(transforms, index, inverse);
@@ -1127,6 +1132,7 @@ public abstract class AbstractMathTransf
                 WKTUtilities.appendParamMT(parameters, formatter);
                 return WKTKeywords.Param_MT;
             } else {
+                formatter.newLine();
                 formatter.append((FormattableObject) AbstractMathTransform.this);
                 return WKTKeywords.Inverse_MT;
             }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -323,7 +323,7 @@ public class ContextualParameters extend
      * The definition of "kernel" is left to implementors.
      * In the particular case of Apache SIS implementation of map projections,
      * kernels are instances of {@link org.apache.sis.referencing.operation.projection.NormalizedProjection}.
-     * Other "kernels" in SIS are {@link EllipsoidalToCartesianTransform} and {@link MolodenskyTransform}.</div>
+     * Other "kernels" in SIS are {@link EllipsoidToCentricTransform} and {@link MolodenskyTransform}.</div>
      *
      * @return The description of the parameters.
      */
@@ -511,7 +511,6 @@ public class ContextualParameters extend
      * @throws FactoryException if an error occurred while creating a math transform instance.
      *
      * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#createMapProjection(MathTransformFactory)
-     * @see EllipsoidalToCartesianTransform#createGeodeticConversion(MathTransformFactory, double, double, Unit, boolean)
      */
     @SuppressWarnings("AssignmentToForLoopParameter")
     public synchronized MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
@@ -784,6 +783,7 @@ public class ContextualParameters extend
         @Override
         protected String formatTo(final Formatter formatter) {
             if (inverse) {
+                formatter.newLine();
                 formatter.append(new WKT(false));
                 return WKTKeywords.Inverse_MT;
             } else {
@@ -807,7 +807,7 @@ public class ContextualParameters extend
      * @param  transforms The full chain of concatenated transforms.
      * @param  index      The index of this transform in the {@code transforms} chain.
      * @param  inverse    Always {@code false}, except if we are formatting the inverse transform.
-     * @return Index of the last transform processed. Iteration should continue at that index + 1.
+     * @return Index of this transform in the {@code transforms} chain after processing.
      *
      * @see ConcatenatedTransform#getPseudoSteps()
      * @see AbstractMathTransform#beforeFormat(List, int, boolean)
@@ -888,7 +888,7 @@ public class ContextualParameters extend
          * Note that if this operation fails, we will cancel everything we would have done
          * in this method (i.e. we do not touch the transforms list at all).
          */
-        if (!inverse) try {
+        try {
             userDefined = getMatrix(inverse ? MatrixRole.NORMALIZATION : MatrixRole.INVERSE_DENORMALIZATION);
         } catch (IllegalStateException e) {
             unexpectedException(e);
@@ -941,12 +941,11 @@ public class ContextualParameters extend
                 assert (old instanceof LinearTransform);
             }
         } else {
-            index++;
             if (hasAfter) {
-                final Object old = transforms.set(index, after);
+                final Object old = transforms.set(index + 1, after);
                 assert (old instanceof LinearTransform);
             } else {
-                transforms.add(index, after);
+                transforms.add(index + 1, after);
             }
         }
         return index;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -79,9 +79,9 @@ final class CopyTransform extends Abstra
     static CopyTransform create(final Matrix matrix) {
         final int srcDim = matrix.getNumCol() - 1;
         final int dstDim = matrix.getNumRow() - 1;
-        for (int i=0; i<=srcDim; i++) {
+        for (int i=0; i <= srcDim; i++) {
             if (matrix.getElement(dstDim, i) != (i == srcDim ? 1 : 0)) {
-                // Not an affine transform.
+                // Not an affine transform (ignoring if square or not).
                 return null;
             }
         }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -152,7 +152,7 @@ import org.apache.sis.internal.jdk8.JDK8
  *
  * @author  Martin Desruisseaux (Geomatys, IRD)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see MathTransformProvider
@@ -776,12 +776,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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Thu Nov 12 14:24:24 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
@@ -143,7 +144,7 @@ public final class MathTransforms extend
         if (candidate != null) {
             return candidate;
         }
-        return new ProjectiveTransform(matrix);
+        return new ProjectiveTransform(matrix).optimize();
     }
 
     /**
@@ -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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -701,8 +701,8 @@ public class MolodenskyTransform extends
      * NOTE: we do not bother to override the methods expecting a 'float' array because those methods should
      *       be rarely invoked. Since there is usually LinearTransforms before and after this transform, the
      *       conversion between float and double will be handle by those LinearTransforms.   If nevertheless
-     *       this EllipsoidalToCartesianTransform is at the beginning or the end of a transformation chain,
-     *       the method inherited from the subclass will work (even if slightly slower).
+     *       this MolodenskyTransform is at the beginning or the end of a transformation chain,  the methods
+     *       inherited from the subclass will work (but may be slightly slower).
      */
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -19,8 +19,6 @@ package org.apache.sis.referencing.opera
 import java.util.Arrays;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
@@ -90,6 +88,30 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
+     * If a more efficient implementation of this math transform can be used, returns it.
+     * Otherwise returns {@code this} unchanged.
+     */
+    final LinearTransform optimize() {
+        final int n = (numRow - 1) * numCol;
+        for (int i = 0; i != numCol;) {
+            if (elt[n + i] != (++i == numCol ? 1 : 0)) {
+                return this;    // Transform is not affine (ignoring if square or not).
+            }
+        }
+        /*
+         * Note: we could check for CopyTransform case here, but this check is rather done in
+         * MathTransforms.linear(Matrix) in order to avoid ProjectiveTransform instantiation.
+         */
+        for (int i=0; i<n; i++) {
+            // Non-zero elements are allowed to appear only on the diagonal.
+            if (elt[i] != 0 && (i / numCol) != (i % numCol)) {
+                return this;
+            }
+        }
+        return new ScaleTransform(numRow, numCol, elt);
+    }
+
+    /**
      * Gets the dimension of input points.
      */
     @Override
@@ -195,7 +217,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
+    public final void transform(double[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         final int srcDim, dstDim;
         int srcInc = srcDim = numCol - 1; // The last ordinate will be assumed equal to 1.
         int dstInc = dstDim = numRow - 1;
@@ -266,7 +288,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
+    public final void transform(float[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         final int srcDim, dstDim;
         int srcInc = srcDim = numCol-1;
         int dstInc = dstDim = numRow-1;
@@ -322,7 +344,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
+    public final void transform(final double[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         final int srcDim = numCol-1;
         final int dstDim = numRow-1;
         final double[] buffer = new double[numRow];
@@ -357,7 +379,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
+    public final void transform(final float[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         final int srcDim = numCol - 1;
         final int dstDim = numRow - 1;
         final double[] buffer = new double[numRow];
@@ -404,29 +426,6 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Creates the inverse transform of this object.
-     */
-    @Override
-    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
-        if (inverse == null) {
-            /*
-             * Should never be the identity transform at this point (except during tests) because
-             * MathTransforms.linear(…) should never instantiate this class in the identity case.
-             * But we check anyway as a paranoiac safety.
-             */
-            if (isIdentity()) {
-                inverse = this;
-            } else {
-                inverse = MathTransforms.linear(Matrices.inverse(this));
-                if (inverse instanceof AbstractLinearTransform) {
-                    ((AbstractLinearTransform) inverse).inverse = this;
-                }
-            }
-        }
-        return inverse;
-    }
-
-    /**
      * {@inheritDoc}
      *
      * @return {@inheritDoc}

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -26,6 +26,9 @@ import org.opengis.referencing.operation
 
 /**
  * Projective transform in 2D case.
+ * This class is used only if the transform is not affine, i.e. the last row in the 3×3 matrix is not [0 0 1].
+ * Otherwise {@link org.apache.sis.internal.referencing.j2d.AffineTransform2D} should be used instead
+ * (unless {@link java.awt.geom.AffineTransform} is not available on the target platform).
  *
  * @author  Jan Jezek (UWB)
  * @author  Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java [UTF-8] Thu Nov 12 14:24:24 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/JDK7/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Thu Nov 12 14:24:24 2015
@@ -1,6 +1,7 @@
 # Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
 # Heavier classes (e.g. having more dependencies) or classes less likely to be used, should be last.
 org.apache.sis.internal.referencing.provider.Affine
+org.apache.sis.internal.referencing.provider.Geographic3Dto2D
 org.apache.sis.internal.referencing.provider.LongitudeRotation
 org.apache.sis.internal.referencing.provider.GeocentricTranslation
 org.apache.sis.internal.referencing.provider.PositionVector7Param

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java?rev=1714052&r1=1714051&r2=1714052&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] Thu Nov 12 14:24:24 2015
@@ -64,6 +64,7 @@ public final strictfp class AllProviders
             GeocentricTranslation3D.class,
             GeographicToGeocentric.class,
             GeocentricToGeographic.class,
+            Geographic3Dto2D.class,
             Molodensky.class,
             AbridgedMolodensky.class,
             Equirectangular.class,




Mime
View raw message