sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1825688 - in /sis/branches/JDK8: application/sis-console/src/main/java/org/apache/sis/console/ core/sis-referencing/src/main/java/org/apache/sis/geometry/ core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ core/sis-ref...
Date Thu, 01 Mar 2018 22:28:30 GMT
Author: desruisseaux
Date: Thu Mar  1 22:28:30 2018
New Revision: 1825688

URL: http://svn.apache.org/viewvc?rev=1825688&view=rev
Log:
Avoid OutOfMemoryException when tie points in a GeoTIFF images are not distributed on a regular grid.
https://issues.apache.org/jira/browse/SIS-407

Initial version of a SpecializableTransform for handling the case where a localization grid needs to be splitted in two parts.
https://issues.apache.org/jira/browse/SIS-408

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java   (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java   (with props)
Modified:
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DirectPositionView.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IterationStrategy.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/PassThroughTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/PseudoTransform.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -586,7 +586,7 @@ final class TransformCommand extends For
         if (toDomainOfValidity != null && (bbox = CRS.getGeographicBoundingBox(operation)) != null) {
             domainOfValidity = new ImmutableEnvelope(bbox);
             domainCoordinate = new double[toDomainOfValidity.getTargetDimensions()];
-            positionInDomain = new DirectPositionView(domainCoordinate, 0, domainCoordinate.length);
+            positionInDomain = new DirectPositionView.Double(domainCoordinate, 0, domainCoordinate.length);
         } else {
             domainOfValidity = null;
             domainCoordinate = null;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -131,7 +131,8 @@ public final class Envelopes extends Sta
             return ((AbstractMathTransform) transform).transform(srcPts, 0, dstPts, dstOff, derivate);
         }
         // Derivative must be calculated before to transform the coordinate.
-        final Matrix derivative = derivate ? transform.derivative(new DirectPositionView(srcPts, 0, transform.getSourceDimensions())) : null;
+        final Matrix derivative = derivate ? transform.derivative(
+                new DirectPositionView.Double(srcPts, 0, transform.getSourceDimensions())) : null;
         transform.transform(srcPts, 0, dstPts, dstOff, 1);
         return derivative;
     }
@@ -265,7 +266,7 @@ public final class Envelopes extends Sta
             sourcePt[i] = envelope.getMinimum(i);
         }
         // A window over a single coordinate in the 'ordinates' array.
-        final DirectPositionView ordinatesView = new DirectPositionView(ordinates, 0, targetDim);
+        final DirectPositionView ordinatesView = new DirectPositionView.Double(ordinates, 0, targetDim);
         /*
          * Iterates over every minimal, maximal and median ordinate values (3 points) along each
          * dimension. The total number of iterations is 3 ^ (number of source dimensions).
@@ -339,7 +340,7 @@ public final class Envelopes extends Sta
          * to avoid the need for storage.
          */
         DirectPosition temporary = null;
-        final DirectPositionView sourceView = new DirectPositionView(sourcePt, 0, sourceDim);
+        final DirectPositionView sourceView = new DirectPositionView.Double(sourcePt, 0, sourceDim);
         final CurveExtremum extremum = new CurveExtremum();
         for (pointIndex=0; pointIndex < derivatives.length; pointIndex++) {
             final Matrix D1 = derivatives[pointIndex];

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DirectPositionView.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DirectPositionView.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DirectPositionView.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DirectPositionView.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -17,8 +17,8 @@
 package org.apache.sis.internal.referencing;
 
 import java.util.Arrays;
-import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometry.AbstractDirectPosition;
 
 // Branch-dependent imports
 import org.opengis.geometry.UnmodifiableGeometryException;
@@ -29,19 +29,13 @@ import org.opengis.geometry.Unmodifiable
  * This class shall be used for temporary objects only (it is not serializable for this reason).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 1.0
  * @since   0.5
  * @module
  */
-public final class DirectPositionView implements DirectPosition {
+public abstract class DirectPositionView extends AbstractDirectPosition {
     /**
-     * The ordinate values. This is a direct reference to the array given to the constructor.
-     * The length of this array may be greater then the number of dimensions.
-     */
-    private final double[] ordinates;
-
-    /**
-     * The index of the first value in the {@linkplain #ordinates} array.
+     * The index of the first value in the ordinates array.
      * This field is non-final in order to allow the caller to move the view over an array of coordinates.
      */
     public int offset;
@@ -49,70 +43,129 @@ public final class DirectPositionView im
     /**
      * The number of valid ordinate values.
      */
-    private final int dimension;
+    final int dimension;
 
     /**
      * Creates a new direct position wrapping the given array.
      *
-     * @param  ordinates  the ordinate values.
      * @param  offset     the first value index in the ordinates array.
      * @param  dimension  the number of valid ordinate values.
      */
-    public DirectPositionView(final double[] ordinates, final int offset, final int dimension) {
-        this.ordinates = ordinates;
+    DirectPositionView(final int offset, final int dimension) {
         this.offset    = offset;
         this.dimension = dimension;
     }
 
     /**
      * Returns {@code null} since there is no CRS associated with this position.
+     *
+     * @return {@code null}.
      */
     @Override
-    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+    public final CoordinateReferenceSystem getCoordinateReferenceSystem() {
         return null;
     }
 
     /**
      * Returns the dimension given at construction time.
-     */
-    @Override
-    public int getDimension() {
-        return dimension;
-    }
-
-    /**
-     * Returns all ordinate values.
-     */
-    @Override
-    public double[] getCoordinate() {
-        return Arrays.copyOfRange(ordinates, offset, offset + dimension);
-    }
-
-    /**
-     * Returns the ordinate at the given index.
-     * <strong>This implementation does not check index validity</strong>, unless assertions are enabled.
      *
-     * @param  dim  the dimension of the ordinate to get fetch.
+     * @return number of dimensions.
      */
     @Override
-    public double getOrdinate(final int dim) {
-        assert dim >= 0 && dim < dimension : dim;
-        return ordinates[offset + dim];
+    public final int getDimension() {
+        return dimension;
     }
 
     /**
      * Do not allow any change.
+     *
+     * @param  dimension  ignored.
+     * @param  value      ignored.
      */
     @Override
-    public void setOrdinate(final int dimension, final double value) {
+    public final void setOrdinate(final int dimension, final double value) {
         throw new UnmodifiableGeometryException();
     }
 
     /**
-     * Returns the direct position, which is {@code this}.
+     * The double-precision version of {@link DirectPositionView}.
      */
-    @Override
-    public DirectPosition getDirectPosition() {
-        return this;
+    public static final class Double extends DirectPositionView {
+        /**
+         * The ordinate values. This is a direct reference to the array given to the constructor.
+         * The length of this array may be greater then the number of dimensions.
+         */
+        private final double[] ordinates;
+
+        /**
+         * Creates a new direct position wrapping the given array.
+         *
+         * @param  ordinates  the ordinate values.
+         * @param  offset     the first value index in the ordinates array.
+         * @param  dimension  the number of valid ordinate values.
+         */
+        public Double(final double[] ordinates, final int offset, final int dimension) {
+            super(offset, dimension);
+            this.ordinates = ordinates;
+        }
+
+        /**
+         * Returns the ordinate at the given index.
+         * <strong>This implementation does not check index validity</strong>, unless assertions are enabled.
+         *
+         * @param  dim  the dimension of the ordinate to get fetch.
+         * @return the coordinate value at the given dimension.
+         */
+        @Override
+        public double getOrdinate(final int dim) {
+            assert dim >= 0 && dim < dimension : dim;
+            return ordinates[offset + dim];
+        }
+
+        /**
+         * Returns all ordinate values.
+         *
+         * @return all coordinate values.
+         */
+        @Override
+        public double[] getCoordinate() {
+            return Arrays.copyOfRange(ordinates, offset, offset + dimension);
+        }
+    }
+
+    /**
+     * The single-precision version of {@link DirectPositionView}.
+     */
+    public static final class Float extends DirectPositionView {
+        /**
+         * The ordinate values. This is a direct reference to the array given to the constructor.
+         * The length of this array may be greater then the number of dimensions.
+         */
+        private final float[] ordinates;
+
+        /**
+         * Creates a new direct position wrapping the given array.
+         *
+         * @param  ordinates  the ordinate values.
+         * @param  offset     the first value index in the ordinates array.
+         * @param  dimension  the number of valid ordinate values.
+         */
+        public Float(final float[] ordinates, final int offset, final int dimension) {
+            super(offset, dimension);
+            this.ordinates = ordinates;
+        }
+
+        /**
+         * Returns the ordinate at the given index.
+         * <strong>This implementation does not check index validity</strong>, unless assertions are enabled.
+         *
+         * @param  dim  the dimension of the ordinate to get fetch.
+         * @return the coordinate value at the given dimension.
+         */
+        @Override
+        public double getOrdinate(final int dim) {
+            assert dim >= 0 && dim < dimension : dim;
+            return ordinates[offset + dim];
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -322,6 +322,11 @@ public final class Resources extends Ind
         public static final short MissingValueForParameter_1 = 44;
 
         /**
+         * The localization grid still have some undefined source or target coordinates.
+         */
+        public static final short MissingValuesInLocalizationGrid = 81;
+
+        /**
          * No vertical dimension found in “{0}”
          */
         public static final short MissingVerticalDimension_1 = 45;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] Thu Mar  1 22:28:30 2018
@@ -80,6 +80,7 @@ MissingTemporalDimension_1        = No t
 MissingSpatioTemporalDimension_1  = No spatial or temporal dimension found in \u201c{0}\u201d
 MissingParameterValues_1          = Missing parameter values for \u201c{0}\u201d coordinate operation.
 MissingValueForParameter_1        = Missing value for \u201c{0}\u201d parameter.
+MissingValuesInLocalizationGrid   = The localization grid still have some undefined source or target coordinates.
 NoConvergence                     = No convergence.
 NoConvergenceForPoints_2          = No convergence for points {0} and {1}.
 NonHorizontalCRS_1                = No horizontal component found in the \u201c{0}\u201d coordinate reference system.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] Thu Mar  1 22:28:30 2018
@@ -85,6 +85,7 @@ MissingTemporalDimension_1        = Aucu
 MissingSpatioTemporalDimension_1  = Aucune dimension spatiale ou temporelle n\u2019a \u00e9t\u00e9 trouv\u00e9e dans \u00ab\u202f{0}\u202f\u00bb.
 MissingParameterValues_1          = Il manque les valeurs des param\u00e8tres pour l\u2019op\u00e9ration \u00ab\u202f{0}\u202f\u00bb.
 MissingValueForParameter_1        = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb.
+MissingValuesInLocalizationGrid   = Il manque encore des coordonn\u00e9es sources ou destinations dans la grille de localisation.
 NoConvergence                     = Le calcul ne converge pas.
 NoConvergenceForPoints_2          = Le calcul ne converge pas pour les points {0} et {1}.
 NonHorizontalCRS_1                = Aucune composante horizontale n\u2019a \u00e9t\u00e9 trouv\u00e9e dans le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es \u00ab\u202f{0}\u202f\u00bb.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/package-info.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/package-info.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -24,7 +24,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 1.0
  * @since   0.3
  * @module
  */

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -32,7 +32,9 @@ import org.apache.sis.math.Vector;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
+import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
+import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
@@ -53,7 +55,7 @@ import org.apache.sis.util.Debug;
  * with the assumption that source positions are exact and all the uncertainty is in the target positions.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  *
  * @see LocalizationGridBuilder
  * @see LinearTransform
@@ -302,7 +304,7 @@ search: for (int j=0; j<numPoints; j++)
      * Returns the error message to be given to {@link IllegalStateException} when there is no data.
      */
     private static String noData() {
-        return Errors.format(Errors.Keys.MissingValueForProperty_1, "sourceToTarget");
+        return Resources.format(Resources.Keys.MissingValuesInLocalizationGrid);
     }
 
     /**
@@ -610,7 +612,7 @@ search: for (int j=0; j<numPoints; j++)
                             c = plan.fit(gridSize[0], gridSize[1], Vector.create(targets[j], false));
                         } catch (IllegalArgumentException e) {
                             // This may happen if the z vector still contain some "NaN" values.
-                            throw new FactoryException(noData(), e);
+                            throw new InvalidGeodeticParameterException(noData(), e);
                         }
                         break;
                     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -27,7 +27,7 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
-import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.referencing.datum.DatumShiftGrid;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.geometry.DirectPosition2D;
@@ -58,7 +58,7 @@ import org.apache.sis.math.Vector;
  * </ol>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  *
  * @see InterpolatedTransform
  * @see LinearTransform
@@ -128,7 +128,7 @@ public class LocalizationGridBuilder ext
      * @throws ArithmeticException if this constructor can not infer a reasonable grid size from the given vectors.
      */
     public LocalizationGridBuilder(final Vector sourceX, final Vector sourceY) {
-        final Matrix fromGrid = Matrices.createDiagonal(3,3);
+        final Matrix fromGrid = new Matrix3();
         linear = new LinearTransformBuilder(infer(sourceX, fromGrid, 0), infer(sourceY, fromGrid, 1));
         try {
             sourceToGrid = MathTransforms.linear(fromGrid).inverse();
@@ -171,10 +171,16 @@ public class LocalizationGridBuilder ext
                 }
             }
         }
+        /*
+         * Compute the size from the increment that we found. If the size is larger than the vector length,
+         * consider as too large. The rational is that attempt to create a localization grid with that size
+         * would fail anyway, because it would contain holes where no value is defined. A limit is important
+         * for preventing useless allocation of large arrays - https://issues.apache.org/jira/browse/SIS-407
+         */
         fromGrid.setElement(dim, dim, inc);
         fromGrid.setElement(dim,   2, min);
         final double n = span / inc;
-        if (n > 0.5 && n < 0.5 + Short.MAX_VALUE) {
+        if (n >= 0.5 && n < source.size() - 0.5) {          // Compare as 'double' in case the value is large.
             return ((int) Math.round(n)) + 1;
         }
         throw new ArithmeticException(Resources.format(Resources.Keys.CanNotInferGridSizeFromValues_1, range));

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -30,8 +30,8 @@
  * convenience.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
- * @since   0.8
+ * @version 1.0
+ * @since   0.5
  * @module
  */
 package org.apache.sis.referencing.operation.builder;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -876,7 +876,7 @@ next:   while (--numPts >= 0) {
                 dstPts[dstOff+1] = point[1];
             }
             // We need to keep h during matrix inversion because (λ,φ,h) values are not independent.
-            Matrix matrix = EllipsoidToCentricTransform.this.derivative(new DirectPositionView(point, offset, 3));
+            Matrix matrix = EllipsoidToCentricTransform.this.derivative(new DirectPositionView.Double(point, offset, 3));
             matrix = Matrices.inverse(matrix);
             if (!withHeight) {
                 matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3);     // Drop height only after matrix inversion is done.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -488,7 +488,7 @@ public class InterpolatedTransform exten
                     dstPts[dstOff+1] = yi;
                     if (derivate) {
                         return Matrices.inverse(InterpolatedTransform.this.derivative(
-                                new DirectPositionView(dstPts, dstOff, dimension)));
+                                new DirectPositionView.Double(dstPts, dstOff, dimension)));
                     }
                     return null;
                 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IterationStrategy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IterationStrategy.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IterationStrategy.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IterationStrategy.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -95,7 +95,7 @@ public enum IterationStrategy {
     DESCENDING(false),
 
     /**
-     * Copies the points to transform in a temporary array before to apply the transform.
+     * Copy the points to transform in a temporary array before to apply the transform.
      * The temporary array will be used for fetching the source ordinates.
      *
      * <p>This algorithm can be used as a fallback for any unknown enumeration.</p>
@@ -103,7 +103,7 @@ public enum IterationStrategy {
     BUFFER_SOURCE(true),
 
     /**
-     * Writes the transformed points in a temporary array and copies them to the
+     * Write the transformed points in a temporary array and copies them to the
      * destination subarray when the transformation is finished.
      *
      * <p>Developers are allowed to ignore this value and fallback on the same algorithm

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=1825688&r1=1825687&r2=1825688&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 Mar  1 22:28:30 2018
@@ -445,7 +445,8 @@ public final class MathTransforms extend
             return ((AbstractMathTransform) transform).transform(srcPts, srcOff, dstPts, dstOff, true);
         }
         // Must be calculated before to transform the coordinate.
-        final Matrix derivative = transform.derivative(new DirectPositionView(srcPts, srcOff, transform.getSourceDimensions()));
+        final Matrix derivative = transform.derivative(
+                new DirectPositionView.Double(srcPts, srcOff, transform.getSourceDimensions()));
         if (dstPts != null) {
             transform.transform(srcPts, srcOff, dstPts, dstOff, 1);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -318,7 +318,7 @@ public class PassThroughTransform extend
     {
         Matrix derivative = null;
         if (derivate) {
-            derivative = derivative(new DirectPositionView(srcPts, srcOff, getSourceDimensions()));
+            derivative = derivative(new DirectPositionView.Double(srcPts, srcOff, getSourceDimensions()));
         }
         if (dstPts != null) {
             transform(srcPts, srcOff, dstPts, dstOff, 1);

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java?rev=1825688&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -0,0 +1,497 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Map;
+import java.util.Arrays;
+import java.util.Objects;
+import org.opengis.geometry.Envelope;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
+import org.apache.sis.internal.referencing.DirectPositionView;
+import org.apache.sis.internal.referencing.Resources;
+import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.Utilities;
+import org.apache.sis.util.ArraysExt;
+
+
+/**
+ * A transform having sub-areas where more accurate transforms can be used.
+ * The general transform must be a reasonable approximation of the specialized transforms.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since   1.0
+ * @module
+ */
+class SpecializableTransform extends AbstractMathTransform {
+    /**
+     * The generic transform to use if there is no suitable specialization.
+     */
+    private final MathTransform generic;
+
+    /**
+     * The region where a transform is valid, together with the transform.
+     * Contains also a chain of {@code SubArea}s fully included in this area.
+     * Shall be unmodified after {@link SpecializableTransform} construction.
+     */
+    private static final class SubArea extends GeneralEnvelope {
+        /**
+         * The transform to apply in this area.
+         */
+        final MathTransform transform;
+
+        /**
+         * Specialization, or {@code null} if none. If non-null, that sub-area shall be fully included
+         * in this {@code SubArea}. The specialization may itself contain another specialization. This
+         * form a chain from this wider area to smallest area, where each step is a smaller area.
+         *
+         * <p>Note that this is note a substitute for an R-Tree. This is an optimization for the common
+         * case where coordinates are close to each other (e.g. when iterating in a geometry), in which
+         * case we can check immediately for inclusion in smaller areas before to check the wider area.</p>
+         */
+        private SubArea specialization;
+
+        /**
+         * Creates a new area where a transform is valid.
+         */
+        SubArea(final Envelope area, final MathTransform transform) {
+            super(area);
+            this.transform = transform;
+        }
+
+        /**
+         * Tries to add a nested sub-area (a specialization of a specialization).
+         *
+         * @return whether the given area has been added.
+         */
+        boolean addSpecialization(final SubArea candidate) {
+            if (specialization == null) {
+                if (!contains(candidate)) {
+                    return false;
+                }
+            } else if (!candidate.addSpecialization(specialization)) {
+                return specialization.addSpecialization(candidate);
+            }
+            specialization = candidate;
+            return true;
+        }
+
+        /**
+         * Sets the CRS of all given ares to a common value. An exception is thrown if incompatible CRS are found.
+         * This method does not verify the number of dimensions; this check should have been done by the caller.
+         */
+        static void uniformize(final SubArea[] domains) throws InvalidGeodeticParameterException {
+            CoordinateReferenceSystem common = null;
+            for (SubArea area : domains) {
+                do {
+                    final CoordinateReferenceSystem crs = area.getCoordinateReferenceSystem();
+                    if (common == null) {
+                        common = crs;
+                    } else if (crs != null && !Utilities.equalsIgnoreMetadata(common, crs)) {
+                        throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.MismatchedCRS));
+                    }
+                } while ((area = area.specialization) != null);
+            }
+            for (SubArea area : domains) {
+                do area.setCoordinateReferenceSystem(common);
+                while ((area = area.specialization) != null);
+            }
+        }
+
+        /**
+         * Returns the area that contains the given position, or {@code null} if none.
+         * This method may be replaced by an R-Tree in a future Apache SIS version.
+         */
+        static SubArea find(final SubArea[] domains, final DirectPosition pos) {
+            for (SubArea area : domains) {
+                if (area.contains(pos)) {
+                    SubArea next = area.specialization;
+                    while (next != null && next.contains(pos)) {
+                        area = next;
+                        next = next.specialization;
+                    }
+                    return area;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Returns the area that contains the given position, looking only in the given area or its specializations.
+         * Returns {@code null} if no area has been found.
+         */
+        static SubArea find(SubArea area, final DirectPosition pos) {
+            SubArea found = null;
+            while (area.contains(pos)) {
+                found = area;
+                area = area.specialization;
+            }
+            return found;
+        }
+
+        /**
+         * For {@link SpecializableTransform#computeHashCode()} implementation.
+         */
+        @Override
+        public int hashCode() {
+            int code = super.hashCode() ^ transform.hashCode();
+            if (specialization != null) {
+                code += 37 * specialization.hashCode();
+            }
+            return code;
+        }
+
+        /**
+         * For {@link SpecializableTransform#equals(Object)} implementation.
+         */
+        @Override
+        public boolean equals(final Object obj) {
+            if (super.equals(obj)) {
+                final SubArea other = (SubArea) obj;
+                return transform.equals(other.transform) && Objects.equals(specialization, other.specialization);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Domains where specialized transforms are valid. The array should be very small.
+     * In current implementation, elements in this array shall not overlap.
+     * This array may be replaced by an R-Tree in a future Apache SIS version.
+     */
+    private final SubArea[] domains;
+
+    /**
+     * Creates a new transform with the given generic transform and some amount of specializations.
+     */
+    SpecializableTransform(final MathTransform generic, final Map<Envelope,MathTransform> specializations)
+            throws InvalidGeodeticParameterException
+    {
+        this.generic = generic;
+        final int sourceDim = generic.getSourceDimensions();
+        final int targetDim = generic.getTargetDimensions();
+        int n = 0;
+        final SubArea[] areas = new SubArea[specializations.size()];
+next:   for (final Map.Entry<Envelope,MathTransform> e : specializations.entrySet()) {
+            final MathTransform tr = e.getValue();
+            ensureDimensionMatches(0, sourceDim, tr.getSourceDimensions());
+            ensureDimensionMatches(1, targetDim, tr.getTargetDimensions());
+            final SubArea area = new SubArea(e.getKey(), tr);
+            if (area.getDimension() != sourceDim) {
+                throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.MismatchedDimension_3,
+                            "envelope", sourceDim, area.getDimension()));
+            }
+            for (int i=0; i<n; i++) {
+                if (areas[i].addSpecialization(area)) {
+                    continue next;
+                }
+            }
+            for (int i=0; i<n; i++) {
+                if (area.intersects(areas[n])) {
+                    // Pending implementation of R-Tree in Apache SIS.
+                    throw new InvalidGeodeticParameterException("Current implementation does not accept overlapping envelopes.");
+                }
+            }
+            areas[n++] = area;
+        }
+        domains = ArraysExt.resize(areas, n);
+        SubArea.uniformize(domains);
+    }
+
+    /**
+     * Helper method for verifying transform dimension consistency.
+     *
+     * @param  type  0 if verifying source dimension, or 1 if verifying target dimension.
+     */
+    private static void ensureDimensionMatches(final int type, final int expected, final int actual)
+            throws InvalidGeodeticParameterException
+    {
+        if (expected != actual) {
+            throw new InvalidGeodeticParameterException(Resources.format(
+                    Resources.Keys.MismatchedTransformDimension_3, type, expected, actual));
+        }
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    @Override
+    public final int getSourceDimensions() {
+        return generic.getSourceDimensions();
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    @Override
+    public final int getTargetDimensions() {
+        return generic.getTargetDimensions();
+    }
+
+    /**
+     * Returns the transform to use for the given domain.
+     */
+    private MathTransform forDomain(final SubArea domain) {
+        return (domain != null) ? domain.transform : generic;
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     * This method delegates to the most specialized transform.
+     */
+    @Override
+    public final DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst) throws TransformException {
+        return forDomain(SubArea.find(domains, ptSrc)).transform(ptSrc, ptDst);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     * This method delegates to the most specialized transform.
+     */
+    @Override
+    public final Matrix derivative(final DirectPosition point) throws TransformException {
+        return forDomain(SubArea.find(domains, point)).derivative(point);
+    }
+
+    /**
+     * Transforms a single coordinate point in an array, and optionally computes the transform
+     * derivative at that location. This method delegates to the most specialized transform.
+     */
+    @Override
+    public final Matrix transform(final double[] srcPts, final int srcOff,
+                                  final double[] dstPts, final int dstOff,
+                                  boolean derivate) throws TransformException
+    {
+        final DirectPositionView pos = new DirectPositionView.Double(srcPts, srcOff, generic.getSourceDimensions());
+        final MathTransform tr = forDomain(SubArea.find(domains, pos));
+        if (tr instanceof AbstractMathTransform) {
+            return ((AbstractMathTransform) tr).transform(srcPts, srcOff, dstPts, dstOff, derivate);
+        } else {
+            tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
+            return derivate ? tr.derivative(pos) : null;
+        }
+    }
+
+    /**
+     * Call of a {@code MathTransform.transform(…)} method with source and target arrays fixed at
+     * {@code TransformCall} creation time. This is used for allowing the same implementation to
+     * be shared by most {@code transform(…)} methods in {@link SpecializableTransform}.
+     */
+    @FunctionalInterface
+    private interface TransformCall {
+        /** Performs the transform at the given offsets. */
+        void apply(MathTransform tr, int srcOff, int dstOff, int numPts) throws TransformException;
+    }
+
+    /**
+     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
+     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
+     *
+     * @param  transform  caller for a {@code MathTransform.transform(…)} method.
+     * @param  src        a window over the source points. May be backed by a {@code float[]} or {@code double[]} array.
+     * @param  dstOff     where to write the first coordinate in the target array.
+     * @param  srcInc     the source dimension, negative if we must iterate backward.
+     * @param  dstInc     the target dimension, negative if we must iterate backward.
+     * @param  numPts     number of points to transform.
+     */
+    private void transform(final TransformCall transform, final DirectPositionView src,
+            int dstOff, int srcInc, int dstInc, int numPts) throws TransformException
+    {
+        final boolean downard = (srcInc < 0);
+        SubArea domain = SubArea.find(domains, src);
+        while (numPts > 0) {
+            int srcOff = src.offset;
+            final MathTransform tr;
+            if (domain == null) {
+                tr = generic;                               // The transform to apply when no specialization is found.
+                do {                                        // Count how many points will use that transform.
+                    src.offset += srcInc;
+                    if (--numPts <= 0) break;
+                    domain = SubArea.find(domains, src);    // More expansive check than the case where domain is non-null.
+                } while (domain == null);
+            } else {
+                final SubArea previous = domain;
+                tr = domain.transform;                      // The specialized transform to apply.
+                do {                                        // Count how many points will use that transform.
+                    src.offset += srcInc;
+                    if (--numPts <= 0) break;
+                    domain = SubArea.find(domain, src);     // Cheaper check compared to the case where domain is null.
+                } while (domain == previous);
+                if (domain == null) {
+                    domain = SubArea.find(domains, src);    // Need to update with the more expansive check.
+                }
+            }
+            final int num = (src.offset - srcOff) / srcInc;
+            int dstLow = dstOff;
+            dstOff += dstInc * num;
+            if (downard) {
+                srcOff = src.offset - srcInc;
+                dstLow = dstOff     - dstInc;
+            }
+            transform.apply(tr, srcOff, dstLow, num);
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate points.
+     * This method delegates to the most specialized transform.
+     */
+    @Override
+    public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts)
+            throws TransformException
+    {
+        int srcInc = getSourceDimensions();
+        int dstInc = getTargetDimensions();
+        if (srcPts == dstPts) {
+            switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) {
+                case ASCENDING: {
+                    break;
+                }
+                case DESCENDING: {
+                    srcOff += (numPts-1) * srcInc; srcInc = -srcInc;
+                    dstOff += (numPts-1) * dstInc; dstInc = -dstInc;
+                    break;
+                }
+                default: {
+                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc);
+                    srcOff = 0;
+                    break;
+                }
+            }
+        }
+        final double[] refPts = srcPts;
+        transform((tr, src, dst, num) -> tr.transform(refPts, src, dstPts, dst, num),
+                  new DirectPositionView.Double(srcPts, srcOff, Math.abs(srcInc)),
+                  dstOff, srcInc, dstInc, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate points.
+     * This method delegates to the most specialized transform.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts)
+            throws TransformException
+    {
+        int srcInc = getSourceDimensions();
+        int dstInc = getTargetDimensions();
+        if (srcPts == dstPts) {
+            switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) {
+                case ASCENDING: {
+                    break;
+                }
+                case DESCENDING: {
+                    srcOff += (numPts-1) * srcInc; srcInc = -srcInc;
+                    dstOff += (numPts-1) * dstInc; dstInc = -dstInc;
+                    break;
+                }
+                default: {
+                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc);
+                    srcOff = 0;
+                    break;
+                }
+            }
+        }
+        final float[] refPts = srcPts;
+        transform((tr, src, dst, num) -> tr.transform(refPts, src, dstPts, dst, num),
+                  new DirectPositionView.Float(srcPts, srcOff, Math.abs(srcInc)),
+                  dstOff, srcInc, dstInc, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
+     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
+     */
+    @Override
+    public void transform(final double[] srcPts, int srcOff,
+                          final float [] dstPts, int dstOff, int numPts) throws TransformException
+    {
+        final int srcDim = getSourceDimensions();
+        final int dstDim = getTargetDimensions();
+        transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts, dst, num),
+                  new DirectPositionView.Double(srcPts, srcOff, srcDim),
+                  dstOff, srcDim, dstDim, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
+     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
+     */
+    @Override
+    public void transform(final float [] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+            throws TransformException
+    {
+        final int srcDim = getSourceDimensions();
+        final int dstDim = getTargetDimensions();
+        transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts, dst, num),
+                  new DirectPositionView.Float(srcPts, srcOff, srcDim),
+                  dstOff, srcDim, dstDim, numPts);
+    }
+
+    /**
+     * Computes a hash value for this transform.
+     * This method is invoked by {@link #hashCode()} when first needed.
+     */
+    @Override
+    protected int computeHashCode() {
+        return super.computeHashCode() + 7*generic.hashCode() ^ Arrays.hashCode(domains);
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object, final ComparisonMode mode) {
+        if (super.equals(object, mode)) {
+            final SpecializableTransform other = (SpecializableTransform) object;
+            return Utilities.deepEquals(generic, other.generic, mode) &&
+                   Utilities.deepEquals(domains, other.domains, mode);
+        }
+        return false;
+    }
+
+    /**
+     * Formats the inner part of a <cite>Well Known Text</cite> version 1 (WKT 1) element.
+     *
+     * <div class="note"><b>Compatibility note:</b>
+     * The {@code SPECIALIZABLE_MT} element formatted here is an Apache SIS-specific extension.</div>
+     *
+     * @param  formatter  the formatter to use.
+     * @return the WKT element name, which is {@code "Specializable_MT"}.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        for (final SubArea domain : domains) {
+            formatter.newLine();
+            formatter.append(generic);
+            formatter.newLine();
+            // TODO: format BBOX.
+            formatter.append(domain.transform);
+        }
+        formatter.setInvalidWKT(SpecializableTransform.class, null);
+        return "Specializable_MT";
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/package-info.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/package-info.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -61,7 +61,7 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Adrian Custer (Geomatys)
- * @version 0.7
+ * @version 1.0
  * @since   0.5
  * @module
  */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/PseudoTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/PseudoTransform.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/PseudoTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/PseudoTransform.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -96,7 +96,7 @@ strictfp class PseudoTransform extends A
                             final boolean derivate) throws TransformException
     {
         final Matrix derivative = derivate ? derivative(
-                new DirectPositionView(srcPts, srcOff, getSourceDimensions())) : null;
+                new DirectPositionView.Double(srcPts, srcOff, getSourceDimensions())) : null;
         System.arraycopy(srcPts, srcOff, buffer, 0, sourceDimension);
         for (int i=0; i<targetDimension; i++) {
             double v = buffer[i % sourceDimension];

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java?rev=1825688&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Map;
+import java.util.HashMap;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
+import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
+import org.apache.sis.geometry.Envelope2D;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link SpecializableTransform}. This test use a simple affine transform that multiply
+ * coordinate values by 10, except in specialized sub-areas in which case a small translation is added.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since   1.0
+ * @module
+ */
+public final strictfp class SpecializableTransformTest extends MathTransformTestCase {
+    /**
+     * Creates a transform scaling the coordinate values by 10, then applying the given translation.
+     */
+    private static MathTransform translation(final double t) {
+        return new AffineTransform2D(10, 0, 0, 10, t, t);
+    }
+
+    /**
+     * Creates a transform to test.
+     *
+     * @throws InvalidGeodeticParameterException if {@link SpecializableTransform} constructor reject a parameter.
+     */
+    private static SpecializableTransform create() throws InvalidGeodeticParameterException {
+        final Map<Envelope,MathTransform> specializations = new HashMap<>(4);
+        assertNull(specializations.put(new Envelope2D(null, -5, -4, 10, 7), translation(0.1)));
+        assertNull(specializations.put(new Envelope2D(null, -3, -1,  5, 2), translation(0.2)));
+        return new SpecializableTransform(translation(0), specializations);
+    }
+
+    /**
+     * Tests consistency between different {@code transform(…)} methods.
+     *
+     * @throws InvalidGeodeticParameterException if {@link SpecializableTransform} constructor reject a parameter.
+     * @throws TransformException if a transformation failed.
+     */
+    @Test
+    public void testConsistency() throws InvalidGeodeticParameterException, TransformException {
+        transform = create();
+        isDerivativeSupported = false;          // Actually supported, but our test transform has discontinuities.
+        isInverseTransformSupported = false;
+        verifyInDomain(CoordinateDomain.RANGE_10, -672445632505596619L);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -25,7 +25,7 @@ import org.junit.BeforeClass;
  * All tests from the {@code sis-referencing} module, in approximative dependency order.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */
@@ -131,6 +131,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.transform.PolarToCartesianTest.class,
     org.apache.sis.referencing.operation.transform.CartesianToPolarTest.class,
     org.apache.sis.referencing.operation.transform.CoordinateSystemTransformTest.class,
+    org.apache.sis.referencing.operation.transform.SpecializableTransformTest.class,
     org.apache.sis.referencing.operation.DefaultFormulaTest.class,
     org.apache.sis.referencing.operation.DefaultOperationMethodTest.class,
     org.apache.sis.referencing.operation.AbstractSingleOperationTest.class,

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java?rev=1825688&r1=1825687&r2=1825688&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java [UTF-8] Thu Mar  1 22:28:30 2018
@@ -41,6 +41,8 @@ import org.apache.sis.util.CharSequences
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.MetadataServices;
+import org.apache.sis.measure.RangeFormat;
+import org.apache.sis.measure.Range;
 
 
 /**
@@ -69,7 +71,7 @@ import org.apache.sis.internal.util.Meta
  * multiple threads.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */
@@ -419,6 +421,9 @@ public class IndexedResourceBundle exten
                 replacement = Classes.getShortName(getPublicType((Class<?>) element));
             } else if (element instanceof ControlledVocabulary) {
                 replacement = MetadataServices.getInstance().getCodeTitle((ControlledVocabulary) element, getLocale());
+            } else if (element instanceof Range<?>) {
+                final Range<?> range = (Range<?>) element;
+                replacement = new RangeFormat(getLocale(), range.getElementType()).format(range);
             }
             /*
              * No need to check for Numbers or Dates instances, since they are



Mime
View raw message