sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1713527 [2/4] - in /sis/branches/JDK7: ./ core/sis-build-helper/src/main/java/org/apache/sis/internal/book/ core/sis-build-helper/src/main/resources/org/apache/sis/internal/book/ core/sis-feature/src/main/java/org/apache/sis/feature/ core/...
Date Mon, 09 Nov 2015 19:57:42 GMT
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercatorSouth.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercatorSouth.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercatorSouth.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercatorSouth.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -62,17 +62,17 @@ public final class TransverseMercatorSou
                 .setRemarks(Messages.formatInternational(Messages.Keys.MisnamedParameter_1, "False southing")));
 
         PARAMETERS = builder
-            .addIdentifier(IDENTIFIER)
-            .addName(                    "Transverse Mercator (South Orientated)")
-            .addName(Citations.OGC,      "Transverse_Mercator_South_Orientated")
-            .addName(Citations.GEOTIFF,  "CT_TransvMercator_SouthOriented")
-            .addIdentifier(Citations.GEOTIFF,  "27")
-            .createGroupForMapProjection(
-                    TransverseMercator.LATITUDE_OF_ORIGIN,
-                    TransverseMercator.LONGITUDE_OF_ORIGIN,
-                    TransverseMercator.SCALE_FACTOR,
-                    LambertConformalWest.FALSE_WESTING,
-                    falseSouthing);
+                .addIdentifier(IDENTIFIER)
+                .addName(                    "Transverse Mercator (South Orientated)")
+                .addName(Citations.OGC,      "Transverse_Mercator_South_Orientated")
+                .addName(Citations.GEOTIFF,  "CT_TransvMercator_SouthOriented")
+                .addIdentifier(Citations.GEOTIFF,  "27")
+                .createGroupForMapProjection(
+                        TransverseMercator.LATITUDE_OF_ORIGIN,
+                        TransverseMercator.LONGITUDE_OF_ORIGIN,
+                        TransverseMercator.SCALE_FACTOR,
+                        LambertConformalWest.FALSE_WESTING,
+                        falseSouthing);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -148,7 +148,7 @@ public class DefaultParameterDescriptorG
      *   </tr>
      * </table>
      *
-     * @param properties    The properties to be given to the identified object.
+     * @param properties    The properties to be given to the new parameter group.
      * @param minimumOccurs The {@linkplain #getMinimumOccurs() minimum number of times} that values
      *                      for this parameter group are required, or 0 if no restriction.
      * @param maximumOccurs The {@linkplain #getMaximumOccurs() maximum number of times} that values
@@ -167,12 +167,39 @@ public class DefaultParameterDescriptorG
     }
 
     /**
+     * Constructs a group with the same parameters than another group. This is a convenience constructor for
+     * operations that expect the same parameters than another operation, but perform a different process.
+     *
+     * <div class="note"><b>Example:</b>
+     * the various <cite>"Coordinate Frame Rotation"</cite> variants (EPSG codes 1032, 1038 and 9607)
+     * expect the same parameters than their <cite>"Position Vector transformation"</cite> counterpart
+     * (EPSG codes 1033, 1037 and 9606) but perform the rotation in the opposite direction.</div>
+     *
+     * @param properties The properties to be given to the new parameter group.
+     * @param parameters The existing group from which to copy the {@linkplain #descriptors() parameter descriptors}.
+     *
+     * @since 0.7
+     */
+    public DefaultParameterDescriptorGroup(final Map<String,?> properties, final ParameterDescriptorGroup parameters) {
+        super(properties, parameters.getMinimumOccurs(), parameters.getMaximumOccurs());
+        descriptors = parameters.descriptors();    // We will share the same instance if it is safe.
+        if (!(parameters instanceof DefaultParameterDescriptorGroup)
+            || ((DefaultParameterDescriptorGroup) parameters).descriptors != descriptors)
+        {
+            // Note sure where the list come from, we are better to copy its content.
+            final GeneralParameterDescriptor[] p = descriptors.toArray(new GeneralParameterDescriptor[descriptors.size()]);
+            verifyNames(properties, p);
+            descriptors = asList(p);
+        }
+    }
+
+    /**
      * Creates a mandatory parameter group without cloning the given array. This constructor shall
      * be used only when we know that the given array is already a copy of the user-provided array.
      */
     DefaultParameterDescriptorGroup(final Map<String,?> properties, final GeneralParameterDescriptor[] parameters) {
         super(properties, 1, 1);
-        verifyNames(properties, parameters.clone());
+        verifyNames(properties, parameters);
         descriptors = asList(parameters);
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -957,9 +957,14 @@ public class DefaultParameterValue<T> ex
              * is identical in both units (typically the 0 value).
              */
             if (!ignoreUnits && !Double.isNaN(value)) {
+                // Test equivalent to unit.equals(contextualUnit) but more aggressive.
                 ignoreUnits = Numerics.equals(value, doubleValue(contextualUnit));
             }
-            if (!ignoreUnits || !convention.isSimplified() || !hasContextualUnit(formatter)) {
+            if (ignoreUnits && convention != Convention.INTERNAL) {
+                // One last check about if we are really allowed to ignore units.
+                ignoreUnits = convention.isSimplified() && hasContextualUnit(formatter);
+            }
+            if (!ignoreUnits) {
                 if (!isWKT1) {
                     formatter.append(unit);
                 } else if (!ignoreUnits) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -38,7 +38,6 @@ import org.apache.sis.util.LenientCompar
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.Debug;
 
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.referencing.IdentifiedObjects.isHeuristicMatchForName;
@@ -473,31 +472,6 @@ public class DefaultParameterValueGroup
         return copy;
     }
 
-    /**
-     * Returns a string representation of this group.
-     * The default implementation delegates to {@link ParameterFormat}.
-     *
-     * <p>This method is for information purpose only and may change in future SIS version.</p>
-     */
-    @Debug
-    @Override
-    public String toString() {
-        return ParameterFormat.sharedFormat(this);
-    }
-
-    /**
-     * Prints a string representation of this group to the {@linkplain System#out standard output stream}.
-     * If a {@linkplain java.io.Console console} is attached to the running JVM (i.e. if the application
-     * is run from the command-line and the output is not redirected to a file) and if Apache SIS thinks
-     * that the console supports the ANSI escape codes (a.k.a. X3.64), then a syntax coloring will be applied.
-     *
-     * <p>This is a convenience method for debugging purpose and for console applications.</p>
-     */
-    @Debug
-    public void print() {
-        ParameterFormat.print(this);
-    }
-
 
 
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -368,6 +368,31 @@ public class ParameterBuilder extends Bu
     }
 
     /**
+     * Creates a descriptor group with the same parameters than another group. This is a convenience constructor
+     * for operations that expect the same parameters than another operation, but perform a different process.
+     *
+     * <div class="note"><b>Example:</b>
+     * the various <cite>"Coordinate Frame Rotation"</cite> variants (EPSG codes 1032, 1038 and 9607)
+     * expect the same parameters than their <cite>"Position Vector transformation"</cite> counterpart
+     * (EPSG codes 1033, 1037 and 9606) but perform the rotation in the opposite direction.</div>
+     *
+     * @param parameters The existing group from which to copy the parameters.
+     * @return The parameter descriptor group.
+     *
+     * @since 0.7
+     */
+    public ParameterDescriptorGroup createGroupWithSameParameters(final ParameterDescriptorGroup parameters) {
+        final ParameterDescriptorGroup group;
+        onCreate(false);
+        try {
+            group = new DefaultParameterDescriptorGroup(properties, parameters);
+        } finally {
+            onCreate(true);
+        }
+        return group;
+    }
+
+    /**
      * Creates a descriptor group for a map projection. This method automatically adds mandatory parameters
      * for the <cite>semi-major</cite> and <cite>semi-minor axis length</cite>. Those parameters are usually
      * not explicitely included in parameter definitions since the axis lengths can be inferred from the

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -34,6 +34,7 @@ import org.apache.sis.referencing.Identi
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ObjectConverters;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Debug;
 
 import static org.apache.sis.referencing.IdentifiedObjects.isHeuristicMatchForName;
 
@@ -111,7 +112,7 @@ import org.apache.sis.internal.jdk8.JDK8
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @XmlTransient
@@ -760,4 +761,33 @@ public abstract class Parameters impleme
             throw new IndexOutOfBoundsException(name);
         }
     }
+
+    /**
+     * Returns a string representation of this group.
+     * The default implementation delegates to {@link ParameterFormat}.
+     *
+     * <p>This method is for information purpose only and may change in future SIS version.</p>
+     *
+     * @since 0.7
+     */
+    @Debug
+    @Override
+    public String toString() {
+        return ParameterFormat.sharedFormat(this);
+    }
+
+    /**
+     * Prints a string representation of this group to the {@linkplain System#out standard output stream}.
+     * If a {@linkplain java.io.Console console} is attached to the running JVM (i.e. if the application
+     * is run from the command-line and the output is not redirected to a file) and if Apache SIS thinks
+     * that the console supports the ANSI escape codes (a.k.a. X3.64), then a syntax coloring will be applied.
+     *
+     * <p>This is a convenience method for debugging purpose and for console applications.</p>
+     *
+     * @since 0.7
+     */
+    @Debug
+    public void print() {
+        ParameterFormat.print(this);
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -31,6 +31,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.internal.util.Numerics;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.jaxb.gml.Measure;
 import org.apache.sis.internal.jaxb.referencing.SecondDefiningParameter;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
@@ -399,15 +400,76 @@ public class DefaultEllipsoid extends Ab
     }
 
     /**
-     * The ratio of the distance between the center and a focus of the ellipse
-     * to the length of its semi-major axis. The eccentricity can alternately be
-     * computed from the equation: <code>e = sqrt(2f - f²)</code>.
+     * The ratio of the distance between the center and a focus of the ellipse to the length of its semi-major axis.
+     * The eccentricity can alternately be computed from the equation: ℯ = √(2f - f²) where <var>f</var> is the
+     * flattening factor (not inverse).
      *
-     * @return The eccentricity of this ellipsoid.
+     * @return ℯ, the eccentricity of this ellipsoid.
      */
     public double getEccentricity() {
-        final double f = 1 - getSemiMinorAxis() / getSemiMajorAxis();
-        return sqrt(2*f - f*f);
+        final DoubleDouble e = eccentricitySquared();
+        e.sqrt();
+        return e.value;
+    }
+
+    /**
+     * Returns the square of the {@link #getEccentricity() eccentricity} value.
+     *
+     * <div class="note"><b>Purpose:</b>
+     * this convenience method is provided because ℯ² is frequently used in coordinate operations,
+     * actually more often than ℯ. This convenience method avoids the cost of computing the square
+     * root when not needed.</div>
+     *
+     * @return ℯ², the square of the eccentricity value.
+     *
+     * @since 0.7
+     */
+    public double getEccentricitySquared() {
+        return eccentricitySquared().value;
+    }
+
+    /**
+     * Computes the square of the eccentricity value with ℯ² = 2f - f².
+     *
+     * <div class="note"><b>Implementation note:</b>
+     * we use the flattening factor for this computation because the inverse flattening factor is usually the
+     * second defining parameter.  But even if the second defining parameter of this ellipsoid was rather the
+     * semi-minor axis, the fact that we use double-double arithmetic should give the same result anyway.</div>
+     */
+    private DoubleDouble eccentricitySquared() {
+        final DoubleDouble f = flattening(this);
+        final DoubleDouble eccentricitySquared = new DoubleDouble(f);
+        eccentricitySquared.multiply(2, 0);
+        f.square();
+        eccentricitySquared.subtract(f);
+        return eccentricitySquared;
+    }
+
+    /**
+     * Computes the flattening factor (not inverse) of the given ellipsoid.
+     * This method chooses the formula depending on whether the defining parameter is the inverse flattening factor
+     * or the semi-minor axis length. The defining parameters are presumed fully accurate in base 10 (even if this
+     * is of course not possible in the reality), because those parameters are definitions given by authorities.
+     *
+     * <div class="note"><b>Analogy:</b>
+     * the conversion factor from inches to centimetres is 2.54 <em>by definition</em>. Even if we could find a more
+     * accurate value matching historical measurements, the 2.54 value is the internationally agreed value for all
+     * conversions. This value is (by convention) defined in base 10 and has no exact {@code double} representation.
+     * </div>
+     */
+    private static DoubleDouble flattening(final Ellipsoid e) {
+        final DoubleDouble f;
+        if (e.isIvfDefinitive()) {
+            f = new DoubleDouble(e.getInverseFlattening());   // Presumed accurate in base 10 (not 2) by definition.
+            f.inverseDivide(1, 0);
+        } else {
+            f = new DoubleDouble(e.getSemiMajorAxis());       // Presumed accurate in base 10 (not 2) by definition.
+            final double value = f.value;
+            final double error = f.error;
+            f.subtract(e.getSemiMinorAxis());                 // Presumed accurate in base 10 (not 2) by definition.
+            f.divide(value, error);
+        }
+        return f;
     }
 
     /**
@@ -553,6 +615,47 @@ public class DefaultEllipsoid extends Ab
     }
 
     /**
+     * Returns the difference between the semi-major axis length of two ellipsoids.
+     * If the two ellipsoid does not use the same unit of measurement, than the axis
+     * length of the other ellipsoid is converted into the units of this ellipsoid axis.
+     *
+     * <div class="note"><b>Example:</b>
+     * {@code WGS84.semiMajorAxisDifference(ED50)} returns 251 metres. This information is a parameter of
+     * {@linkplain org.apache.sis.referencing.operation.transform.MolodenskyTransform Molodensky transformations}.</div>
+     *
+     * @param  other The other ellipsoid from which to get semi-major axis length difference.
+     * @return (<var>other</var> ellipsoid semi-major axis) - (<var>this</var> ellipsoid semi-major axis).
+     *
+     * @since 0.7
+     */
+    public double semiMajorAxisDifference(final Ellipsoid other) {
+        double semiMajor = other.getSemiMajorAxis();
+        semiMajor = other.getAxisUnit().getConverterTo(getAxisUnit()).convert(semiMajor);   // Often a no-op.
+        final DoubleDouble a = new DoubleDouble(semiMajor);     // Presumed accurate in base 10 if no unit conversion.
+        a.subtract(getSemiMajorAxis());                         // Presumed accurate in base 10 (not 2) by definition.
+        return a.value;
+    }
+
+    /**
+     * Returns the difference between the flattening factor of two ellipsoids.
+     * This method returns 0 if the two ellipsoids are equal.
+     *
+     * <div class="note"><b>Example:</b>
+     * {@code WGS84.flatteningDifference(ED50)} returns approximatively 1.41927E-05. This information is a parameter of
+     * {@linkplain org.apache.sis.referencing.operation.transform.MolodenskyTransform Molodensky transformations}.</div>
+     *
+     * @param  other The other ellipsoid from which to get flattening difference.
+     * @return (<var>other</var> ellipsoid flattening) - (<var>this</var> ellipsoid flattening).
+     *
+     * @since 0.7
+     */
+    public double flatteningDifference(final Ellipsoid other) {
+        final DoubleDouble f = flattening(other);
+        f.subtract(flattening(this));
+        return f.value;
+    }
+
+    /**
      * Compares this ellipsoid with the specified object for equality.
      *
      * @param  object The object to compare to {@code this}.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -20,6 +20,7 @@ import java.util.Map;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
 import javax.xml.bind.annotation.XmlTransient;
+import org.opengis.referencing.datum.Ellipsoid;
 
 import static java.lang.Math.*;
 
@@ -35,7 +36,7 @@ import static java.lang.Math.*;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlTransient
@@ -82,6 +83,22 @@ final class Sphere extends DefaultEllips
     }
 
     /**
+     * Eccentricity of a sphere is always zero.
+     */
+    @Override
+    public double getEccentricitySquared() {
+        return 0;
+    }
+
+    /**
+     * Returns the flattening factor of the other ellipsoid, since the flattening factor of {@code this} is zero.
+     */
+    @Override
+    public double flatteningDifference(final Ellipsoid other) {
+        return 1 / other.getInverseFlattening();
+    }
+
+    /**
      * Returns the orthodromic distance between two geographic coordinates.
      * The orthodromic distance is the shortest distance between two points
      * on a sphere's surface. The orthodromic path is always on a great circle.

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=1713527&r1=1713526&r2=1713527&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] Mon Nov  9 19:57:39 2015
@@ -377,8 +377,8 @@ public final class Matrices extends Stat
      * </ul>
      *
      * <div class="note"><b>Example:</b>
-     * It is legal to transform from (<i>easting</i>, <i>northing</i>, <i>up</i>) to
-     * (<i>easting</i>, <i>northing</i>) - this is the first above case, but illegal
+     * it is legal to transform from (<i>easting</i>, <i>northing</i>, <i>up</i>) to
+     * (<i>easting</i>, <i>northing</i>) — this is the first above case — but illegal
      * to transform (<i>easting</i>, <i>northing</i>) to (<i>easting</i>, <i>up</i>).</div>
      *
      * <div class="section">Example</div>
@@ -487,7 +487,7 @@ public final class Matrices extends Stat
 
     /**
      * Creates a matrix for a transform that keep only a subset of source ordinate values.
-     * The matrix size will be ({@code selectedDimensions.length}+1) × ({@code sourceDimensions}+1).
+     * The matrix size will be ({@code selectedDimensions.length} + 1) × ({@code sourceDimensions} + 1).
      * The matrix will contain only zero elements, except for the following cells which will contain 1:
      *
      * <ul>
@@ -541,7 +541,7 @@ public final class Matrices extends Stat
     }
 
     /**
-     * Creates a matrix which converts a subset of ordinates with another matrix.
+     * Creates a matrix which converts a subset of ordinates using the transform given by another matrix.
      * For example giving (<var>latitude</var>, <var>longitude</var>, <var>height</var>) coordinates,
      * a pass through operation can convert the height values from feet to metres without affecting
      * the (<var>latitude</var>, <var>longitude</var>) values.
@@ -650,6 +650,75 @@ 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;
+    }
+
+    /**
      * Creates a new matrix which is a copy of the given matrix.
      *
      * <div class="note"><b>Implementation note:</b>

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -126,6 +126,7 @@ final class UnmodifiableMatrix extends M
      * Returns a copy of this matrix that users can modify.
      */
     @Override
+    @SuppressWarnings("CloneDoesntCallSuperClone")
     public MatrixSIS clone() {
         return castOrCopy(matrix.clone());
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -100,7 +100,7 @@ abstract class ConformalProjection exten
     static final boolean ALLOW_TRIGONOMETRIC_IDENTITIES = true;
 
     /**
-     * The threshold value of {@link #excentricity} at which we consider the accuracy of the
+     * The threshold value of {@link #eccentricity} at which we consider the accuracy of the
      * series expansion insufficient. This threshold is determined empirically with the help
      * of the {@code MercatorMethodComparison} class in the test directory.
      * We choose the value where:
@@ -110,20 +110,22 @@ abstract class ConformalProjection exten
      *   <li>the maximal error of series expansion become greater than {@link NormalizedProjection#ANGULAR_TOLERANCE}.</li>
      * </ul>
      */
-    static final double EXCENTRICITY_THRESHOLD = 0.16;
+    static final double ECCENTRICITY_THRESHOLD = 0.16;
 
     /**
-     * {@code true} if the {@link #excentricity} value is greater than or equals to {@link #EXCENTRICITY_THRESHOLD},
+     * {@code true} if the {@link #eccentricity} value is greater than or equals to {@link #ECCENTRICITY_THRESHOLD},
      * in which case the {@link #φ(double)} method will need to use an iterative method.
      *
      * <p><strong>Consider this field as final!</strong>
-     * It is not final only for the purpose of {@link #readObject(ObjectInputStream)}.</p>
+     * It is not final only for the purpose of {@link #readObject(ObjectInputStream)}.
+     * This field is not serialized because its value may depend on the version of this
+     * {@code ConformalProjection} class.</p>
      */
     private transient boolean useIterations;
 
     /**
      * Coefficients in the series expansion of the inverse projection,
-     * depending only on {@linkplain #excentricity excentricity} value.
+     * depending only on {@linkplain #eccentricity eccentricity} value.
      * The series expansion is of the following form, where f(θ) is typically sin(θ):
      *
      *     <blockquote>ci₂⋅f(2θ) + ci₄⋅f(4θ) + ci₆⋅f(6θ) + ci₈⋅f(8θ)</blockquote>
@@ -152,18 +154,18 @@ abstract class ConformalProjection exten
     }
 
     /**
-     * Computes the coefficients in the series expansions from the {@link #excentricitySquared} value.
+     * Computes the coefficients in the series expansions from the {@link #eccentricitySquared} value.
      * This method shall be invoked after {@code ConformalProjection} construction or deserialization.
      */
     void computeCoefficients() {
-        useIterations = (excentricity >= EXCENTRICITY_THRESHOLD);
-        final double e2 = excentricitySquared;
+        useIterations = (eccentricity >= ECCENTRICITY_THRESHOLD);
+        final double e2 = eccentricitySquared;
         final double e4 = e2 * e2;
         final double e6 = e2 * e4;
         final double e8 = e4 * e4;
         /*
          * For each line below, add the smallest values first in order to reduce rounding errors.
-         * The smallest values are the one using the excentricity raised to the highest power.
+         * The smallest values are the one using the eccentricity raised to the highest power.
          */
         ci2  =    13/   360.* e8  +   1/ 12.* e6  +  5/24.* e4  +  e2/2;
         ci4  =   811/ 11520.* e8  +  29/240.* e6  +  7/48.* e4;
@@ -222,7 +224,7 @@ abstract class ConformalProjection exten
      *
      * <b>Note:</b> §1.3.3 in Geomatics Guidance Note number 7 part 2 (April 2015) uses a series expansion
      * while USGS used an iterative method. The series expansion is twice faster than the iterative method
-     * for the same precision, but this precision is achieved "only" for relatively small excentricity like
+     * for the same precision, but this precision is achieved "only" for relatively small eccentricity like
      * the Earth's one. See the {@code MercatorMethodComparison} class in the test package for more discussion.
      *
      * @param  expOfSouthing The <em>reciprocal</em> of the value returned by {@link #expOfNorthing}.
@@ -235,7 +237,7 @@ abstract class ConformalProjection exten
     final double φ(final double expOfSouthing) throws ProjectionException {
         /*
          * Get a first approximation of φ from Snyder (7-11). The result below would be exact if the
-         * ellipsoid was actually a sphere. But if the excentricity is different than 0, then we will
+         * ellipsoid was actually a sphere. But if the eccentricity is different than 0, then we will
          * need to add a correction.
          *
          * Note that the φ value computed by the line below is called χ in EPSG guide.
@@ -273,23 +275,20 @@ abstract class ConformalProjection exten
         }
         /*
          * We should never reach this point for map projections on Earth. But if the ellipsoid is for some
-         * other planet having a high excentricity, then the above series expansion may not be sufficient.
+         * other planet having a high eccentricity, then the above series expansion may not be sufficient.
          * Try to improve by iteratively solving equation (7-9) from Snyder. However instead than using
          * Snyder (7-11) as the starting point, we take the result of above calculation as the initial φ.
          * Assuming that it is closer to the real φ value, this save us some iteration loops and usually
          * gives us more accurate results (according MercatorMethodComparison tests).
          */
-        final double hℯ = 0.5 * excentricity;
-        for (int i=0; i<MAXIMUM_ITERATIONS; i++) {
-            final double ℯsinφ = excentricity * sin(φ);
-            double ε = abs(φ - (φ = PI/2 - 2*atan(expOfSouthing * pow((1 - ℯsinφ)/(1 + ℯsinφ), hℯ))));
-            if (ε <= ITERATION_TOLERANCE) {
+        final double hℯ = 0.5 * eccentricity;
+        for (int it=0; it<MAXIMUM_ITERATIONS; it++) {
+            final double ℯsinφ = eccentricity * sin(φ);
+            final double Δφ = φ - (φ = PI/2 - 2*atan(expOfSouthing * pow((1 - ℯsinφ)/(1 + ℯsinφ), hℯ)));
+            if (!(abs(Δφ) > ITERATION_TOLERANCE)) {     // Use '!' for accepting NaN.
                 return φ;
             }
         }
-        if (Double.isNaN(expOfSouthing)) {
-            return Double.NaN;
-        }
         throw new ProjectionException(Errors.Keys.NoConvergence);
     }
 
@@ -345,7 +344,7 @@ abstract class ConformalProjection exten
      * </ul>
      *
      * @param  φ     The latitude in radians.
-     * @param  ℯsinφ The sine of the φ argument multiplied by {@link #excentricity}.
+     * @param  ℯsinφ The sine of the φ argument multiplied by {@link #eccentricity}.
      * @return {@code Math.exp} of the Mercator projection of the given latitude.
      *
      * @see #φ(double)
@@ -359,7 +358,7 @@ abstract class ConformalProjection exten
          * favorises slightly the North hemisphere (but the differences are very small). In Apache SIS,
          * we handle that by changing the sign of some terms in the (de)normalisation matrices.
          */
-        return tan(PI/4 + 0.5*φ) * pow((1 - ℯsinφ) / (1 + ℯsinφ), 0.5*excentricity);
+        return tan(PI/4 + 0.5*φ) * pow((1 - ℯsinφ) / (1 + ℯsinφ), 0.5*eccentricity);
     }
 
     /**
@@ -377,7 +376,7 @@ abstract class ConformalProjection exten
      * @see #φ(double)
      */
     final double dy_dφ(final double sinφ, final double cosφ) {
-        return (1 / cosφ)  -  excentricitySquared * cosφ / (1 - excentricitySquared * (sinφ*sinφ));
+        return (1 / cosφ)  -  eccentricitySquared * cosφ / (1 - eccentricitySquared * (sinφ*sinφ));
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -42,7 +42,7 @@ import static org.apache.sis.internal.ut
  *
  * <ul>
  *   <li>To convert degrees to radians, than back to degrees and find the original value.</li>
- *   <li>To convert axis length (optionally with flattening factor) to excentricity, then back
+ *   <li>To convert axis length (optionally with flattening factor) to eccentricity, then back
  *       to axis length and find the original value.</li>
  * </ul>
  *
@@ -75,8 +75,8 @@ final class Initializer {
     final Parameters parameters;
 
     /**
-     * The square of excentricity: ℯ² = (a²-b²)/a² where
-     * <var>ℯ</var> is the {@linkplain #excentricity excentricity},
+     * The square of eccentricity: ℯ² = (a²-b²)/a² where
+     * <var>ℯ</var> is the {@linkplain #eccentricity eccentricity},
      * <var>a</var> is the <cite>semi-major</cite> axis length and
      * <var>b</var> is the <cite>semi-minor</cite> axis length.
      *
@@ -85,7 +85,7 @@ final class Initializer {
      * {@code double} parameter value without rounding errors. This wish usually do not apply to other internal
      * {@link NormalizedProjection} parameters.</p>
      */
-    final DoubleDouble excentricitySquared;
+    final DoubleDouble eccentricitySquared;
 
     /**
      * Map projection variant. This is a convenience field left at
@@ -130,7 +130,7 @@ final class Initializer {
         final double fn = getAndStore(roles.get(ParameterRole.FALSE_NORTHING))
                         - getAndStore(roles.get(ParameterRole.FALSE_SOUTHING));
 
-        excentricitySquared = new DoubleDouble();
+        eccentricitySquared = new DoubleDouble();
         DoubleDouble k = new DoubleDouble(a);  // The value by which to multiply all results of normalized projection.
         if (a != b) {
             /*
@@ -161,16 +161,16 @@ final class Initializer {
             if (isIvfDefinitive) {
                 final DoubleDouble f = new DoubleDouble(parameters.parameter(Constants.INVERSE_FLATTENING).doubleValue());
                 f.inverseDivide(1,0);
-                excentricitySquared.setFrom(f);
-                excentricitySquared.multiply(2,0);
+                eccentricitySquared.setFrom(f);
+                eccentricitySquared.multiply(2,0);
                 f.square();
-                excentricitySquared.subtract(f);
+                eccentricitySquared.subtract(f);
             } else {
                 final DoubleDouble rs = new DoubleDouble(b);
                 rs.divide(k);    // rs = b/a
                 rs.square();
-                excentricitySquared.value = 1;
-                excentricitySquared.subtract(rs);
+                eccentricitySquared.value = 1;
+                eccentricitySquared.subtract(rs);
             }
             final ParameterDescriptor<? extends Number> radius = roles.get(ParameterRole.LATITUDE_OF_CONFORMAL_SPHERE_RADIUS);
             if (radius != null) {
@@ -188,7 +188,7 @@ final class Initializer {
                  * Equivalent Java code:
                  *
                  *     final double sinφ = sin(toRadians(parameters.doubleValue(radius)));
-                 *     k = b / (1 - excentricitySquared * (sinφ*sinφ));
+                 *     k = b / (1 - eccentricitySquared * (sinφ*sinφ));
                  */
                 k = rν2(sin(toRadians(parameters.doubleValue(radius))));
                 k.inverseDivide(b, 0);
@@ -208,7 +208,7 @@ final class Initializer {
          * in the (de)normalization matrices.
          */
         context.normalizeGeographicInputs(λ0);
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         denormalize.convertAfter(0, k, new DoubleDouble(fe));
         denormalize.convertAfter(1, k, new DoubleDouble(fn));
     }
@@ -255,11 +255,11 @@ final class Initializer {
 
     /**
      * Returns {@code b/a} where {@code a} is the semi-major axis length and {@code b} the semi-minor axis length.
-     * We retrieve this value from the excentricity with {@code b/a = sqrt(1-ℯ²)}.
+     * We retrieve this value from the eccentricity with {@code b/a = sqrt(1-ℯ²)}.
      */
     final DoubleDouble axisLengthRatio() {
         final DoubleDouble b = new DoubleDouble(1,0);
-        b.subtract(excentricitySquared);
+        b.subtract(eccentricitySquared);
         b.sqrt();
         return b;
     }
@@ -291,11 +291,11 @@ final class Initializer {
      */
     private DoubleDouble rν2(final double sinφ) {
         if (DoubleDouble.DISABLED) {
-            return verbatim(1 - excentricitySquared.value * (sinφ*sinφ));
+            return verbatim(1 - eccentricitySquared.value * (sinφ*sinφ));
         }
         final DoubleDouble t = verbatim(sinφ);
         t.square();
-        t.multiply(excentricitySquared);
+        t.multiply(eccentricitySquared);
 
         // Compute 1 - ℯ²⋅sin²φ.  Since  ℯ²⋅sin²φ  may be small,
         // this is where double-double arithmetic has more value.
@@ -320,7 +320,7 @@ final class Initializer {
      */
     final double radiusOfConformalSphere(final double sinφ) {
         final DoubleDouble Rc = verbatim(1);
-        Rc.subtract(excentricitySquared);       //  1 - ℯ²
+        Rc.subtract(eccentricitySquared);       //  1 - ℯ²
         Rc.sqrt();                              //  √(1 - ℯ²)
         Rc.divide(rν2(sinφ));                   //  √(1 - ℯ²) / (1 - ℯ²sin²φ)
         return Rc.value;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -27,6 +27,7 @@ import org.apache.sis.measure.Latitude;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.internal.referencing.provider.LambertConformal1SP;
 import org.apache.sis.internal.referencing.provider.LambertConformal2SP;
 import org.apache.sis.internal.referencing.provider.LambertConformalWest;
@@ -261,13 +262,13 @@ public class LambertConicConformal exten
         φ2 = toRadians(φ2);
         /*
          * Compute constants. We do not need to use special formulas for the spherical case below,
-         * since rν(sinφ) = 1 and expOfNorthing(φ) = tan(π/4 + φ/2) when the excentricity is zero.
+         * since rν(sinφ) = 1 and expOfNorthing(φ) = tan(π/4 + φ/2) when the eccentricity is zero.
          * However we need special formulas for φ1 ≈ φ2 in the calculation of n, otherwise we got
          * a 0/0 indetermination.
          */
         final double sinφ1 = sin(φ1);
         final double m1 = initializer.scaleAtφ(sinφ1, cos(φ1));
-        final double t1 = expOfNorthing(φ1, excentricity*sinφ1);
+        final double t1 = expOfNorthing(φ1, eccentricity*sinφ1);
         /*
          * Compute n = (ln m₁ – ln m₂) / (ln t₁ – ln t₂), which we rewrite as ln(m₁/m₂) / ln(t₁/t₂)
          * for reducing the amount of calls to the logarithmic function. Note that this equation
@@ -276,7 +277,7 @@ public class LambertConicConformal exten
         if (abs(φ1 - φ2) >= ANGULAR_TOLERANCE) {  // Should be 'true' for 2SP case.
             final double sinφ2 = sin(φ2);
             final double m2 = initializer.scaleAtφ(sinφ2, cos(φ2));
-            final double t2 = expOfNorthing(φ2, excentricity*sinφ2);
+            final double t2 = expOfNorthing(φ2, eccentricity*sinφ2);
             n = log(m1/m2) / log(t1/t2);    // Tend toward 0/0 if φ1 ≈ φ2.
         } else {
             n = -sinφ1;
@@ -305,7 +306,7 @@ public class LambertConicConformal exten
         DoubleDouble rF = null;
         if (φ0 != copySign(PI/2, -n)) {    // For reducing the rounding error documented in expOfNorthing(+π/2).
             rF = new DoubleDouble(F);
-            rF.multiply(pow(expOfNorthing(φ0, excentricity*sin(φ0)), n), 0);
+            rF.multiply(pow(expOfNorthing(φ0, eccentricity*sin(φ0)), n), 0);
         }
         /*
          * At this point, all parameters have been processed. Now store
@@ -332,8 +333,8 @@ public class LambertConicConformal exten
         } else {
             sλ.negate();
         }
-        final MatrixSIS normalize   = context.getMatrix(true);
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS normalize   = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         normalize  .convertAfter(0, sλ, (initializer.variant == BELGIUM) ? belgeA() : null);
         normalize  .convertAfter(1, sφ, null);
         denormalize.convertBefore(0, F, null); F.negate();
@@ -381,7 +382,7 @@ public class LambertConicConformal exten
     @Override
     public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
         LambertConicConformal kernel = this;
-        if (excentricity == 0) {
+        if (eccentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -414,7 +415,7 @@ public class LambertConicConformal exten
         final double ρ;     // EPSG guide uses "r", but we keep the symbol from Snyder p. 108 for consistency with PolarStereographic.
         if (absφ < PI/2) {
             sinφ = sin(φ);
-            ρ = pow(expOfNorthing(φ, excentricity*sinφ), n);
+            ρ = pow(expOfNorthing(φ, eccentricity*sinφ), n);
         } else if (absφ < PI/2 + ANGULAR_TOLERANCE) {
             sinφ = 1;
             ρ = (φ*n >= 0) ? POSITIVE_INFINITY : 0;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -30,8 +30,9 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.referencing.provider.RegionalMercator;
 import org.apache.sis.internal.referencing.provider.PseudoMercator;
 import org.apache.sis.internal.util.DoubleDouble;
-import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.Workaround;
 
@@ -242,8 +243,8 @@ public class Mercator extends ConformalP
          * simple as possible, we increase the chances of efficient concatenation of an inverse with a forward
          * projection.
          */
-        final MatrixSIS   normalize = context.getMatrix(true);
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS normalize   = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         denormalize.convertBefore(0, k0, null);
         denormalize.convertBefore(1, k0, null);
         if (λ0 != 0) {
@@ -257,7 +258,7 @@ public class Mercator extends ConformalP
             denormalize.convertBefore(0, null, offset);
         }
         if (φ0 != 0) {
-            denormalize.convertBefore(1, null, verbatim(-log(expOfNorthing(φ0, excentricity * sin(φ0)))));
+            denormalize.convertBefore(1, null, verbatim(-log(expOfNorthing(φ0, eccentricity * sin(φ0)))));
         }
         if (variant == MILLER) {
             normalize  .convertBefore(1, 0.80, null);
@@ -316,7 +317,7 @@ public class Mercator extends ConformalP
     @Override
     public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
         Mercator kernel = this;
-        if ((variant & SPHERICAL) != 0 || excentricity == 0) {
+        if ((variant & SPHERICAL) != 0 || eccentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -352,7 +353,7 @@ public class Mercator extends ConformalP
                 // about why we perform explicit checks for the pole cases.
                 final double a = abs(φ);
                 if (a < PI/2) {
-                    y = log(expOfNorthing(φ, excentricity * sinφ));     // Snyder (7-7)
+                    y = log(expOfNorthing(φ, eccentricity * sinφ));     // Snyder (7-7)
                 } else {
                     y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY : NaN, φ);
                 }
@@ -393,7 +394,7 @@ public class Mercator extends ConformalP
                     final double a = abs(φ);
                     final double y;
                     if (a < PI/2) {
-                        y = log(expOfNorthing(φ, excentricity * sin(φ)));
+                        y = log(expOfNorthing(φ, eccentricity * sin(φ)));
                     } else {
                         y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY : NaN, φ);
                     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -44,9 +44,9 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.referencing.operation.transform.MathTransformProvider;
+import org.apache.sis.internal.referencing.provider.MapProjection;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.Utilities;
 import org.apache.sis.internal.util.Numerics;
@@ -162,14 +162,14 @@ public abstract class NormalizedProjecti
     /**
      * Maximum number of iterations for iterative computations.
      * The iterative methods used in subclasses should converge quickly (in 3 or 4 iterations)
-     * when used for a planet with an excentricity similar to Earth. But we allow a high limit
-     * in case someone uses SIS for some planet with higher excentricity.
+     * when used for a planet with an eccentricity similar to Earth. But we allow a high limit
+     * in case someone uses SIS for some planet with higher eccentricity.
      */
-    static final int MAXIMUM_ITERATIONS = 15;
+    static final int MAXIMUM_ITERATIONS = Formulas.MAXIMUM_ITERATIONS;
 
     /**
      * The internal parameter descriptors. Keys are implementation classes.  Values are parameter descriptor groups
-     * containing at least a parameter for the {@link #excentricity} value, and optionally other internal parameter
+     * containing at least a parameter for the {@link #eccentricity} value, and optionally other internal parameter
      * added by some subclasses.
      *
      * <p>Entries are created only when first needed. Those descriptors are usually never created since they are
@@ -188,27 +188,33 @@ public abstract class NormalizedProjecti
     final ContextualParameters context;
 
     /**
-     * Ellipsoid excentricity, equals to <code>sqrt({@linkplain #excentricitySquared})</code>.
+     * Ellipsoid eccentricity, equals to <code>sqrt({@linkplain #eccentricitySquared})</code>.
      * Value 0 means that the ellipsoid is spherical.
      */
-    protected final double excentricity;
+    protected final double eccentricity;
 
     /**
-     * The square of excentricity: ℯ² = (a²-b²)/a² where
-     * <var>ℯ</var> is the {@linkplain #excentricity excentricity},
+     * The square of eccentricity: ℯ² = (a²-b²)/a² where
+     * <var>ℯ</var> is the {@linkplain #eccentricity eccentricity},
      * <var>a</var> is the <cite>semi-major</cite> axis length and
      * <var>b</var> is the <cite>semi-minor</cite> axis length.
      */
-    protected final double excentricitySquared;
+    protected final double eccentricitySquared;
 
     /**
      * The inverse of this map projection.
+     *
+     * <div class="note"><b>Note:</b>
+     * creation of this object is not deferred to the first call to the {@link #inverse()} method because this
+     * object is lightweight and typically needed soon anyway (may be as soon as {@code ConcatenatedTransform}
+     * construction time). In addition this field is part of serialization form in order to preserve the
+     * references graph.</div>
      */
     private final MathTransform2D inverse;
 
     /**
      * Maps the parameters to be used for initializing {@link NormalizedProjection} and its
-     * {@linkplain ContextualParameters#getMatrix(boolean) normalization / denormalization} matrices.
+     * {@linkplain ContextualParameters#getMatrix normalization / denormalization} matrices.
      * This is an enumeration of parameters found in almost every map projections, but under different names.
      * This enumeration allows {@code NormalizedProjection} subclasses to specify which parameter names, ranges
      * and default values should be used by the
@@ -227,7 +233,7 @@ public abstract class NormalizedProjecti
     protected static enum ParameterRole {
         /**
          * Maps the <cite>semi-major axis length</cite> parameter (symbol: <var>a</var>).
-         * This value is used for computing {@link NormalizedProjection#excentricity},
+         * This value is used for computing {@link NormalizedProjection#eccentricity},
          * and is also a multiplication factor for the denormalization matrix.
          *
          * <p>Unless specified otherwise, this is always mapped to a parameter named {@code "semi_major"}.
@@ -237,7 +243,7 @@ public abstract class NormalizedProjecti
 
         /**
          * Maps the <cite>semi-minor axis length</cite> parameter (symbol: <var>b</var>).
-         * This value is used for computing {@link NormalizedProjection#excentricity}.
+         * This value is used for computing {@link NormalizedProjection#eccentricity}.
          *
          * <p>Unless specified otherwise, this is always mapped to a parameter named {@code "semi_minor"}.
          * {@code NormalizedProjection} subclasses typically do not need to provide a value for this key.</p>
@@ -414,8 +420,8 @@ public abstract class NormalizedProjecti
      */
     NormalizedProjection(final Initializer initializer) {
         context             = initializer.context;
-        excentricitySquared = initializer.excentricitySquared.value;
-        excentricity        = sqrt(excentricitySquared);  // DoubleDouble.sqrt() does not make any difference here.
+        eccentricitySquared = initializer.eccentricitySquared.value;
+        eccentricity        = sqrt(eccentricitySquared);  // DoubleDouble.sqrt() does not make any difference here.
         inverse             = new Inverse();
     }
 
@@ -427,8 +433,8 @@ public abstract class NormalizedProjecti
      */
     NormalizedProjection(final NormalizedProjection other) {
         context             = other.context;
-        excentricity        = other.excentricity;
-        excentricitySquared = other.excentricitySquared;
+        eccentricity        = other.eccentricity;
+        eccentricitySquared = other.eccentricitySquared;
         inverse             = new Inverse();
     }
 
@@ -540,10 +546,10 @@ public abstract class NormalizedProjecti
 
     /**
      * Returns a copy of non-linear internal parameter values of this {@code NormalizedProjection}.
-     * The returned group contained at least the {@link #excentricity} parameter value.
+     * The returned group contains at least the {@link #eccentricity} parameter value.
      * Some subclasses add more non-linear parameters, but most of them do not because many parameters
      * like the <cite>scale factor</cite> or the <cite>false easting/northing</cite> are handled by the
-     * {@linkplain ContextualParameters#getMatrix(boolean) (de)normalization affine transforms} instead.
+     * {@linkplain ContextualParameters#getMatrix (de)normalization affine transforms} instead.
      *
      * <div class="note"><b>Note:</b>
      * This method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
@@ -557,7 +563,7 @@ public abstract class NormalizedProjecti
     @Override
     public ParameterValueGroup getParameterValues() {
         final ParameterValueGroup group = getParameterDescriptors().createValue();
-        group.parameter("excentricity").setValue(excentricity);
+        group.parameter("eccentricity").setValue(eccentricity);
         final String[] names  = getInternalParameterNames();
         final double[] values = getInternalParameterValues();
         for (int i=0; i<names.length; i++) {
@@ -568,7 +574,7 @@ public abstract class NormalizedProjecti
 
     /**
      * Returns a description of the non-linear internal parameters of this {@code NormalizedProjection}.
-     * The returned group contained at least a descriptor for the {@link #excentricity} parameter.
+     * The returned group contains at least a descriptor for the {@link #eccentricity} parameter.
      * Subclasses may add more parameters.
      *
      * <p>This method is for inspecting the parameter values of this non-linear kernel only,
@@ -590,23 +596,13 @@ public abstract class NormalizedProjecti
             if (group == null) {
                 final ParameterBuilder builder = new ParameterBuilder().setRequired(true);
                 if (Utilities.isSIS(type)) {
-                    builder.setCodeSpace(Citations.SIS, "SIS");
+                    builder.setCodeSpace(Citations.SIS, Constants.SIS);
                 }
                 final String[] names = getInternalParameterNames();
                 final ParameterDescriptor<?>[] parameters = new ParameterDescriptor<?>[names.length + 1];
-                for (int i=0; i<parameters.length; i++) {
-                    final ParameterDescriptor<?> p;
-                    if (i == 0) {
-                        final ParameterDescriptorGroup existing = CollectionsExt.first(DESCRIPTORS.values());
-                        if (existing != null) {
-                            p = (ParameterDescriptor<?>) existing.descriptor("excentricity");
-                        } else {
-                            p = builder.addName(Citations.SIS, "excentricity").createBounded(0, 1, Double.NaN, null);
-                        }
-                    } else {
-                        p = builder.addName(names[i-1]).create(Double.class, null);
-                    }
-                    parameters[i] = p;
+                parameters[0] = MapProjection.ECCENTRICITY;
+                for (int i=1; i<parameters.length; i++) {
+                    parameters[i] = builder.addName(names[i-1]).create(Double.class, null);
                 }
                 group = builder.addName(CharSequences.camelCaseToSentence(type.getSimpleName())).createGroup(1, 1, parameters);
                 DESCRIPTORS.put(type, group);
@@ -616,7 +612,7 @@ public abstract class NormalizedProjecti
     }
 
     /**
-     * Returns the names of any additional internal parameters (other than {@link #excentricity})
+     * Returns the names of any additional internal parameters (other than {@link #eccentricity})
      * that this projection has. The length of this array must be the same than the length of the
      * {@link #getInternalParameterValues()} array, if the later is non-null.
      */
@@ -625,7 +621,7 @@ public abstract class NormalizedProjecti
     }
 
     /**
-     * Returns the values of any additional internal parameters (other than {@link #excentricity}) that
+     * Returns the values of any additional internal parameters (other than {@link #eccentricity}) that
      * this projection has. Those values are also compared by {@link #equals(Object, ComparisonMode)}.
      */
     double[] getInternalParameterValues() {
@@ -761,7 +757,7 @@ public abstract class NormalizedProjecti
      */
     @Override
     protected int computeHashCode() {
-        long c = Double.doubleToLongBits(excentricity);
+        long c = Double.doubleToLongBits(eccentricity);
         final double[] parameters = getInternalParameterValues();
         if (parameters != null) {
             for (int i=0; i<parameters.length; i++) {
@@ -773,7 +769,7 @@ public abstract class NormalizedProjecti
 
     /**
      * Compares the given object with this transform for equivalence. The default implementation checks if
-     * {@code object} is an instance of the same class than {@code this}, then compares the excentricity.
+     * {@code object} is an instance of the same class than {@code this}, then compares the eccentricity.
      *
      * <p>If this method returns {@code true}, then for any given identical source position, the two compared map
      * projections shall compute the same target position. Many of the {@linkplain #getContextualParameters()
@@ -808,23 +804,23 @@ public abstract class NormalizedProjecti
                 if (!Objects.equals(context, that.context)) {
                     return false;
                 }
-                // Fall through for comparing the excentricity.
+                // Fall through for comparing the eccentricity.
             }
             case IGNORE_METADATA: {
                 /*
-                 * There is no need to compare both 'excentricity' and 'excentricitySquared' since the former
-                 * is computed from the later. We are better to compare 'excentricitySquared' since it is the
+                 * There is no need to compare both 'eccentricity' and 'eccentricitySquared' since the former
+                 * is computed from the later. We are better to compare 'eccentricitySquared' since it is the
                  * original value from which the other value is derived.
                  */
-                if (!Numerics.equals(excentricitySquared, that.excentricitySquared)) {
+                if (!Numerics.equals(eccentricitySquared, that.eccentricitySquared)) {
                     return false;
                 }
                 break;
             }
             default: {
                 /*
-                 * We want to compare the excentricity with a tolerance threshold corresponding approximatively
-                 * to an error of 1 cm on Earth. The excentricity for an ellipsoid of semi-major axis a=1 is:
+                 * We want to compare the eccentricity with a tolerance threshold corresponding approximatively
+                 * to an error of 1 cm on Earth. The eccentricity for an ellipsoid of semi-major axis a=1 is:
                  *
                  *     ℯ² = 1 - b²
                  *
@@ -842,12 +838,12 @@ public abstract class NormalizedProjecti
                  *     ε′  ≈   ε⋅(ℯ - 1/ℯ)
                  *
                  * Note that  ε′  is negative for  ℯ < 1  so we actually need to compute  ε⋅(1/ℯ - ℯ)  instead.
-                 * The result is less than 2E-8 for the excentricity of the Earth.
+                 * The result is less than 2E-8 for the eccentricity of the Earth.
                  */
-                final double e = max(excentricity, that.excentricity);
-                if (!Numerics.epsilonEqual(excentricity, that.excentricity, ANGULAR_TOLERANCE * (1/e - e))) {
+                final double e = max(eccentricity, that.eccentricity);
+                if (!Numerics.epsilonEqual(eccentricity, that.eccentricity, ANGULAR_TOLERANCE * (1/e - e))) {
                     assert (mode != ComparisonMode.DEBUG) : Numerics.messageForDifference(
-                            "excentricity", excentricity, that.excentricity);
+                            "eccentricity", eccentricity, that.eccentricity);
                     return false;
                 }
                 break;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -26,6 +26,7 @@ import org.opengis.util.FactoryException
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.internal.referencing.provider.PolarStereographicA;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.util.resources.Errors;
@@ -125,14 +126,14 @@ public class ObliqueStereographic extend
         super(initializer);
         final double φ0     = toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));
         final double sinφ0  = sin(φ0);
-        final double ℯsinφ0 = excentricity * sinφ0;
-        n = sqrt(1 + ((excentricitySquared * pow(cos(φ0), 4)) / (1 - excentricitySquared)));
+        final double ℯsinφ0 = eccentricity * sinφ0;
+        n = sqrt(1 + ((eccentricitySquared * pow(cos(φ0), 4)) / (1 - eccentricitySquared)));
         /*
          * Following variables use upper-case because they are written that way in the EPSG guide.
          */
         final double S1 = (1 +  sinφ0) / (1 -  sinφ0);
         final double S2 = (1 - ℯsinφ0) / (1 + ℯsinφ0);
-        final double w1 = pow(S1 * pow(S2, excentricity), n);
+        final double w1 = pow(S1 * pow(S2, eccentricity), n);
         /*
          * The χ₁ variable below was named χ₀ in the EPSG guide. We use the χ₁ name in order to avoid confusion with
          * the conformal latitude of origin, which is also named χ₀ in the EPSG guide. Mathematically, χ₀ and χ₁ are
@@ -158,8 +159,8 @@ public class ObliqueStereographic extend
          * Since this is a linear operation, we can combine it with other linear operations performed by the
          * normalization matrix.
          */
-        final MatrixSIS normalize   = context.getMatrix(true);
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS normalize   = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         normalize.convertAfter(0, n, null);
         /*
          * One of the last steps performed by the stereographic projection is to multiply the easting and northing
@@ -190,7 +191,7 @@ public class ObliqueStereographic extend
      * comparing two {@code ObliqueStereographic} projections or formatting them in debug mode.
      *
      * <p>We could report any of the internal parameters. But since they are all derived from φ₀ and
-     * the {@linkplain #excentricity excentricity} and since the excentricity is already reported by
+     * the {@linkplain #eccentricity eccentricity} and since the eccentricity is already reported by
      * the super-class, we report only χ₀ is a representative of the internal parameters.</p>
      */
     @Override
@@ -233,7 +234,7 @@ public class ObliqueStereographic extend
             }
         }
         ObliqueStereographic kernel = this;
-        if (excentricity == 0) {
+        if (eccentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -255,10 +256,10 @@ public class ObliqueStereographic extend
         final double Λ     = srcPts[srcOff  ];      // Λ = λ⋅n  (see below), ignoring longitude of origin.
         final double φ     = srcPts[srcOff+1];
         final double sinφ  = sin(φ);
-        final double ℯsinφ = excentricity * sinφ;
+        final double ℯsinφ = eccentricity * sinφ;
         final double Sa    = (1 +  sinφ) / (1 -  sinφ);
         final double Sb    = (1 - ℯsinφ) / (1 + ℯsinφ);
-        final double w     = c * pow(Sa * pow(Sb, excentricity), n);
+        final double w     = c * pow(Sa * pow(Sb, eccentricity), n);
         /*
          * Convert the geodetic coordinates (φ,λ) to conformal coordinates (χ,Λ) before to apply the
          * actual stereographic projection.  The geodetic and conformal coordinates will be the same
@@ -304,7 +305,7 @@ public class ObliqueStereographic extend
          *      ∂w/∂φ =  2⋅n⋅w⋅(1/cosφ - ℯ²⋅cosφ/(1 - ℯ²⋅sin²φ));
          */
         final double cosφ = cos(φ);
-        final double dχ_dφ = (1/cosφ - cosφ*excentricitySquared/(1 - ℯsinφ*ℯsinφ)) * 2*n*sqrt(w) / (w + 1);
+        final double dχ_dφ = (1/cosφ - cosφ*eccentricitySquared/(1 - ℯsinφ*ℯsinφ)) * 2*n*sqrt(w) / (w + 1);
         /*
          * Above ∂χ/∂φ is equals to 1 in the spherical case.
          * Remaining formulas below are the same than in the spherical case.
@@ -350,11 +351,10 @@ public class ObliqueStereographic extend
         final double sinχ = sin(χ0 + 2*atan(y - x*tan(j/2)));
         final double ψ = log((1 + sinχ) / ((1 - sinχ)*c)) / (2*n);
         double φ = 2*atan(exp(ψ)) - PI/2;                               // First approximation
-        final double he = excentricity/2;
-        final double me = 1 - excentricitySquared;
-        int r = MAXIMUM_ITERATIONS;
-        do {
-            final double ℯsinφ = excentricity * sin(φ);
+        final double he = eccentricity/2;
+        final double me = 1 - eccentricitySquared;
+        for (int it=0; it<MAXIMUM_ITERATIONS; it++) {
+            final double ℯsinφ = eccentricity * sin(φ);
             final double ψi = log(tan(φ/2 + PI/4) * pow((1 - ℯsinφ) / (1 + ℯsinφ), he));
             final double Δφ = (ψ - ψi) * cos(φ) * (1 - ℯsinφ*ℯsinφ) / me;
             φ += Δφ;
@@ -363,13 +363,16 @@ public class ObliqueStereographic extend
                 dstPts[dstOff+1] = φ;
                 return;
             }
-        } while (--r != 0);
+        }
         throw new ProjectionException(Errors.Keys.NoConvergence);
     }
 
+
+
+
     /**
      * Provides the transform equations for the spherical case of the Oblique Stereographic projection.
-     * This implementation can be used when {@link #excentricity} = 0.
+     * This implementation can be used when {@link #eccentricity} = 0.
      *
      * @author  Rémi Maréchal (Geomatys)
      * @author  Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -25,6 +25,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.internal.referencing.provider.PolarStereographicA;
 import org.apache.sis.internal.referencing.provider.PolarStereographicB;
 import org.apache.sis.internal.referencing.provider.PolarStereographicC;
@@ -206,7 +207,7 @@ public class PolarStereographic extends
              *
              * In the spherical case, should give ρ == 2.
              */
-            ρ = verbatim(2 / sqrt(pow(1+excentricity, 1+excentricity) * pow(1-excentricity, 1-excentricity)));
+            ρ = verbatim(2 / sqrt(pow(1+eccentricity, 1+eccentricity) * pow(1-eccentricity, 1-eccentricity)));
             ρF = null;
         } else {
             /*
@@ -228,19 +229,19 @@ public class PolarStereographic extends
              */
             final double sinφ1 = sin(φ1);
             final double mF = initializer.scaleAtφ(sinφ1, cos(φ1));
-            ρ = verbatim(mF / expOfNorthing(φ1, excentricity*sinφ1));
+            ρ = verbatim(mF / expOfNorthing(φ1, eccentricity*sinφ1));
             ρF = (variant == C) ? verbatim(-mF) : null;
         }
         /*
          * At this point, all parameters have been processed. Now process to their
          * validation and the initialization of (de)normalize affine transforms.
          */
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         denormalize.convertBefore(0, ρ, null);
         denormalize.convertBefore(1, ρ, ρF);
         if (isNorth) {
             final Number reverseSign = verbatim(-1);
-            final MatrixSIS normalize = context.getMatrix(true);
+            final MatrixSIS normalize = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
             normalize  .convertAfter (1, reverseSign, null);
             denormalize.convertBefore(1, reverseSign, null);
         }
@@ -268,7 +269,7 @@ public class PolarStereographic extends
     @Override
     public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
         PolarStereographic kernel = this;
-        if (excentricity == 0) {
+        if (eccentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -303,7 +304,7 @@ public class PolarStereographic extends
          * The next step is to compute ρ = 2⋅a⋅k₀⋅t / …, but those steps are
          * applied by the denormalization matrix and shall not be done here.
          */
-        final double t = expOfNorthing(φ, excentricity*sinφ);
+        final double t = expOfNorthing(φ, eccentricity*sinφ);
         final double x = t * sinθ;
         final double y = t * cosθ;
         if (dstPts != null) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1713527&r1=1713526&r2=1713527&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] Mon Nov  9 19:57:39 2015
@@ -25,6 +25,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
 import org.apache.sis.internal.referencing.provider.TransverseMercatorSouth;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.parameter.Parameters;
@@ -72,7 +73,7 @@ public class TransverseMercator extends
 
     /**
      * Coefficients in the series expansion of the forward projection,
-     * depending only on {@linkplain #excentricity excentricity} value.
+     * depending only on {@linkplain #eccentricity eccentricity} value.
      * The series expansion is of the following form:
      *
      *     <blockquote>cf₂⋅f(2θ) + cf₄⋅f(4θ) + cf₆⋅f(6θ) + cf₈⋅f(8θ)</blockquote>
@@ -163,7 +164,7 @@ public class TransverseMercator extends
          * NOTE: the EPSG documentation makes special cases for φ₀ = 0 or ±π/2. This is not
          * needed here; we verified that the code below produces naturally the expected values.
          */
-        final double Q = asinh(tan(φ0)) - excentricity * atanh(excentricity * sin(φ0));
+        final double Q = asinh(tan(φ0)) - eccentricity * atanh(eccentricity * sin(φ0));
         final double β = atan(sinh(Q));
         final DoubleDouble M0 = new DoubleDouble();
         M0.value = cf8 * sin(8*β)
@@ -187,7 +188,7 @@ public class TransverseMercator extends
          *   - Multiply by the scale factor (done by the super-class constructor).
          *   - Add false easting and false northing (done by the super-class constructor).
          */
-        final MatrixSIS denormalize = context.getMatrix(false);
+        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
         denormalize.convertBefore(0, B, null);
         denormalize.convertBefore(1, B, M0);
         /*
@@ -215,7 +216,7 @@ public class TransverseMercator extends
          * 'n' value at serialization time.
          */
         final DoubleDouble t = new DoubleDouble(1, 0);
-        t.subtract(excentricitySquared, 0);
+        t.subtract(eccentricitySquared, 0);
         t.sqrt();
         t.ratio_1m_1p();
         computeCoefficients(t.doubleValue());
@@ -239,7 +240,7 @@ public class TransverseMercator extends
      *
      * As much as possible, b/a should be computed from the map projection parameters.
      * However if those parameters are not available anymore, then they can be computed
-     * from the excentricity as:
+     * from the eccentricity as:
      *
      *     <blockquote>b/a = √(1 - ℯ²)</blockquote>
      *
@@ -293,7 +294,7 @@ public class TransverseMercator extends
     @Override
     public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
         TransverseMercator kernel = this;
-        if (excentricity == 0) {
+        if (eccentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -315,8 +316,8 @@ public class TransverseMercator extends
         final double λ     = srcPts[srcOff  ];
         final double φ     = srcPts[srcOff+1];
         final double sinλ  = sin(λ);
-        final double ℯsinφ = sin(φ) * excentricity;
-        final double Q     = asinh(tan(φ)) - atanh(ℯsinφ) * excentricity;
+        final double ℯsinφ = sin(φ) * eccentricity;
+        final double Q     = asinh(tan(φ)) - atanh(ℯsinφ) * eccentricity;
         final double coshQ = cosh(Q);
         final double η0    = atanh(sinλ / coshQ);
         /*
@@ -417,7 +418,7 @@ public class TransverseMercator extends
         final double sqrt1_thQchη0 = sqrt(1 - (tanhQ * tanhQ) * (coshη0 * coshη0)); //-- Qη0
 
         //-- dQ_dλ = 0;
-        final double dQ_dφ  = 1 / cosφ - excentricitySquared * cosφ / (1 - ℯsinφ * ℯsinφ);
+        final double dQ_dφ  = 1 / cosφ - eccentricitySquared * cosφ / (1 - ℯsinφ * ℯsinφ);
 
         final double dη0_dλ =   cosλ * coshQ         / cosh2Q_sin2λ;
         final double dη0_dφ = - dQ_dφ * sinλ * sinhQ / cosh2Q_sin2λ;
@@ -541,10 +542,12 @@ public class TransverseMercator extends
         final double Q = asinh(tan(β));
         /*
          * Following usually converges in 4 iterations.
+         * The first iteration is unrolled.
          */
-        double Qp = Q, p = 0;
-        for (int i=0; i<MAXIMUM_ITERATIONS; i++) {
-            final double c = excentricity * atanh(excentricity * tanh(Qp));
+        double p = eccentricity * atanh(eccentricity * tanh(Q));
+        double Qp = Q + p;
+        for (int it=0; it<MAXIMUM_ITERATIONS; it++) {
+            final double c = eccentricity * atanh(eccentricity * tanh(Qp));
             Qp = Q + c;
             if (abs(c - p) <= ITERATION_TOLERANCE) {
                 dstPts[dstOff  ] = asin(tanh(η0) / cos(β));
@@ -557,6 +560,8 @@ public class TransverseMercator extends
     }
 
 
+
+
     /**
      * Provides the transform equations for the spherical case of the Transverse Mercator projection.
      *

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=1713527&r1=1713526&r2=1713527&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] Mon Nov  9 19:57:39 2015
@@ -16,8 +16,10 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
+import java.io.Serializable;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.provider.Affine;
@@ -37,13 +39,23 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
-@SuppressWarnings("CloneInNonCloneableClass")
-abstract class AbstractLinearTransform extends AbstractMathTransform
-        implements LinearTransform, Matrix // Not Cloneable, despite the clone() method.
-{
+@SuppressWarnings("CloneInNonCloneableClass")   // Intentionally not Cloneable despite the clone() method.
+abstract class AbstractLinearTransform extends AbstractMathTransform implements LinearTransform, Matrix, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -4649708313541868599L;
+
+    /**
+     * The inverse transform, or {@code null} if not yet created.
+     * This field is part of the serialization form in order to avoid rounding errors if a user
+     * asks for the inverse of the inverse (i.e. the original transform) after deserialization.
+     */
+    MathTransform inverse;
+
     /**
      * Constructs a transform.
      */



Mime
View raw message