sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1690767 - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ core/sis-referencing/src/main/java/org/apache/sis/referencing/opera...
Date Mon, 13 Jul 2015 17:26:57 GMT
Author: desruisseaux
Date: Mon Jul 13 17:26:56 2015
New Revision: 1690767

URL: http://svn.apache.org/r1690767
Log:
Merge the map projection reviews from the JDK7 branch.

Added:
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertConformalMichigan.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertConformalMichigan.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertConformalWest.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertConformalWest.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AbstractLambertConformal.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AbstractLambertConformal.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AbstractLambertConformalTest.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AbstractLambertConformalTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Predicate.java
      - copied unchanged from r1690762, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Predicate.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
    sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/EquirectangularTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
    sis/branches/JDK6/ide-project/NetBeans/nbproject/genfiles.properties
    sis/branches/JDK6/ide-project/NetBeans/nbproject/project.xml

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 13 17:26:56 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK7:1394913-1690102
-/sis/branches/JDK8:1584960-1690098
+/sis/branches/JDK7:1394913-1690762
+/sis/branches/JDK8:1584960-1690754
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -558,6 +558,15 @@ public class WKTFormat extends CompoundF
      */
     public <T extends Factory> T getFactory(final Class<T> type) {
         ensureValidFactoryType(type);
+        if (type == CoordinateOperationFactory.class) {
+            /*
+             * HACK: we have a special way to get the CoordinateOperationFactory because of its dependency
+             * toward MathTransformFactory.  A lazy (but costly) way to ensure a consistent behavior is to
+             * let the GeodeticObjectParser constructor do its job.  This is costly, but should not happen
+             * often.
+             */
+            parser();
+        }
         return GeodeticObjectParser.getFactory(type, factories());
     }
 
@@ -573,6 +582,11 @@ public class WKTFormat extends CompoundF
      *   <li><code>{@linkplain CoordinateOperationFactory}.class</code></li>
      * </ul>
      *
+     * <div class="section">Limitation</div>
+     * The current implementation does not serialize the given factories, because they are usually not
+     * {@link java.io.Serializable}. The factories used by {@code WKTFormat} instances after deserialization
+     * are the default ones.
+     *
      * @param  <T>     The compile-time type of the {@code type} argument.
      * @param  type    The factory type.
      * @param  factory The factory to be used by this {@code WKTFormat} for the given type.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -29,7 +29,9 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.internal.referencing.provider.LambertConformal1SP;
 import org.apache.sis.internal.referencing.provider.LambertConformal2SP;
+import org.apache.sis.internal.referencing.provider.LambertConformalWest;
 import org.apache.sis.internal.referencing.provider.LambertConformalBelgium;
+import org.apache.sis.internal.referencing.provider.LambertConformalMichigan;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.util.Constants;
@@ -41,10 +43,11 @@ import org.apache.sis.util.Debug;
 
 import static java.lang.Math.*;
 import static java.lang.Double.*;
+import static org.apache.sis.math.MathFunctions.isPositive;
 
 
 /**
- * <cite>Lambert Conical Conformal</cite> projection (EPSG codes 9801, 9802, 9803).
+ * <cite>Lambert Conical Conformal</cite> projection (EPSG codes 9801, 9802, 9803, 9826, 1051).
  * See the <a href="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert conformal
  * conic projection on MathWorld</a> for an overview.
  *
@@ -61,7 +64,7 @@ import static java.lang.Double.*;
  * @version 0.6
  * @module
  */
-public class LambertConformal extends NormalizedProjection {
+public class LambertConformal extends AbstractLambertConformal {
     /**
      * For cross-version compatibility.
      */
@@ -71,9 +74,13 @@ public class LambertConformal extends No
      * Codes for special kinds of Lambert projection. We do not provide such codes in public API because
      * they duplicate the functionality of {@link OperationMethod} instances. We use them only for convenience.
      *
+     * <p>Codes for SP1 case must be odd, and codes for SP2 case must be even.</p>
+     *
      * @see #getType(ParameterDescriptorGroup)
      */
-    static final byte SP1 = 1, SP2 = 2, BELGIUM = 3;
+    private static final byte SP1  = 1,   SP2      = 2,
+                              WEST = 3,   BELGIUM  = 4,
+                                          MICHIGAN = 6;
 
     /**
      * Constant for the Belgium 2SP case. This is 29.2985 seconds, given here in radians.
@@ -82,15 +89,18 @@ public class LambertConformal extends No
 
     /**
      * Internal coefficients for computation, depending only on values of standards parallels.
+     * This is defined as {@literal n = (ln m₁ – ln m₂) / (ln t₁ – ln t₂)} in §1.3.1.1 of
+     * IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015.
      */
     final double n;
 
     /**
      * Returns the (<var>role</var> → <var>parameter</var>) associations for a Lambert projection of the given type.
      *
-     * @param  type One of {@link #SP1}, {@link #SP2} or {@link #BELGIUM} constants.
+     * @param  type One of {@link #SP1}, {@link #SP2}, {@link #WEST}, {@link #BELGIUM} and {@link #MICHIGAN} constants.
      * @return The roles map to give to super-class constructor.
      */
+    @SuppressWarnings("fallthrough")
     private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final byte type) {
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles =
                 new EnumMap<ParameterRole, ParameterDescriptor<Double>>(ParameterRole.class);
@@ -98,21 +108,37 @@ public class LambertConformal extends No
          * "Scale factor" is not formally a "Lambert Conformal (2SP)" argument, but we accept it
          * anyway for all Lambert projections since it may be used in some Well Known Text (WKT).
          */
-        roles.put(ParameterRole.SCALE_FACTOR, LambertConformal1SP.SCALE_FACTOR);
+        ParameterDescriptor<Double> scaleFactor = LambertConformal1SP.SCALE_FACTOR;
+        ParameterRole eastingDirection = ParameterRole.FALSE_EASTING;
         switch (type) {
+            case WEST: {
+                /*
+                 * For "Lambert Conic Conformal (West Orientated)" projection, the "false easting" parameter is
+                 * effectively a "false westing" (Geomatics Guidance Note number 7, part 2 – April 2015, §1.3.1.3)
+                 */
+                eastingDirection = ParameterRole.FALSE_WESTING;
+                // Fallthrough
+            }
             case SP1: {
-                roles.put(ParameterRole.CENTRAL_MERIDIAN, LambertConformal1SP.CENTRAL_MERIDIAN);
-                roles.put(ParameterRole.FALSE_EASTING,    LambertConformal1SP.FALSE_EASTING);
+                roles.put(eastingDirection,               LambertConformal1SP.FALSE_EASTING);
                 roles.put(ParameterRole.FALSE_NORTHING,   LambertConformal1SP.FALSE_NORTHING);
+                roles.put(ParameterRole.CENTRAL_MERIDIAN, LambertConformal1SP.CENTRAL_MERIDIAN);
                 break;
             }
-            default: {
-                roles.put(ParameterRole.CENTRAL_MERIDIAN, LambertConformal2SP.LONGITUDE_OF_FALSE_ORIGIN);
-                roles.put(ParameterRole.FALSE_EASTING,    LambertConformal2SP.EASTING_AT_FALSE_ORIGIN);
+            case MICHIGAN: {
+                scaleFactor = LambertConformalMichigan.SCALE_FACTOR;    // Ellipsoid scaling factor (EPSG:1038)
+                // Fallthrough
+            }
+            case BELGIUM:
+            case SP2: {
+                roles.put(eastingDirection,               LambertConformal2SP.EASTING_AT_FALSE_ORIGIN);
                 roles.put(ParameterRole.FALSE_NORTHING,   LambertConformal2SP.NORTHING_AT_FALSE_ORIGIN);
+                roles.put(ParameterRole.CENTRAL_MERIDIAN, LambertConformal2SP.LONGITUDE_OF_FALSE_ORIGIN);
                 break;
             }
+            default: throw new AssertionError(type);
         }
+        roles.put(ParameterRole.SCALE_FACTOR, scaleFactor);
         return roles;
     }
 
@@ -122,8 +148,10 @@ public class LambertConformal extends No
      *
      * <ul>
      *   <li><cite>"Lambert Conic Conformal (1SP)"</cite>.</li>
+     *   <li><cite>"Lambert Conic Conformal (West Orientated)"</cite>.</li>
      *   <li><cite>"Lambert Conic Conformal (2SP)"</cite>.</li>
      *   <li><cite>"Lambert Conic Conformal (2SP Belgium)"</cite>.</li>
+     *   <li><cite>"Lambert Conic Conformal (2SP Michigan)"</cite>.</li>
      * </ul>
      *
      * @param method     Description of the projection parameters.
@@ -140,7 +168,7 @@ public class LambertConformal extends No
     @Workaround(library="JDK", version="1.7")
     private LambertConformal(final OperationMethod method, final Parameters parameters, final byte type) {
         super(method, parameters, roles(type));
-        double φ0 = getAndStore(parameters, (type == SP1) ?
+        double φ0 = getAndStore(parameters, ((type & 1) != 0) ?  // Odd 'type' are SP1, even 'type' are SP2.
                 LambertConformal1SP.LATITUDE_OF_ORIGIN : LambertConformal2SP.LATITUDE_OF_FALSE_ORIGIN);
         /*
          * Standard parallels (SP) are defined only for the 2SP case, but we look for them unconditionally
@@ -153,6 +181,33 @@ public class LambertConformal extends No
             throw new IllegalArgumentException(Errors.format(Errors.Keys.LatitudesAreOpposite_2,
                     new Latitude(φ1), new Latitude(φ2)));
         }
+        /*
+         * Whether to favorize precision in the North hemisphere (true) or in the South hemisphere (false).
+         * The IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015 uses the
+         * following formula:
+         *
+         *     t = tan(π/4 – φ/2) / [(1 – ℯ⋅sinφ)/(1 + ℯ⋅sinφ)] ^ (ℯ/2)
+         *
+         * while our 'expOfNorthing' function is defined like above, but with   tan(π/4 + φ/2)   instead of
+         * tan(π/4 - φ/2). Those two expressions are the reciprocal of each other if we reverse the sign of
+         * φ (see 'expOfNorthing' for trigonometric identities), but their accuracies are not equivalent:
+         * the hemisphere having values closer to zero is favorized. The EPSG formulas favorize the North
+         * hemisphere.
+         *
+         * Since Apache SIS's formula uses the + operator instead of -, we need to reverse the sign of φ
+         * values in order to match the EPSG formulas, but we will do that only if the map projection is
+         * for the North hemisphere.
+         *
+         * TEST: whether 'isNorth' is true of false does not change the formulas "correctness": it is only
+         * a small accuracy improvement. One can safely force this boolean value to 'true' or 'false' for
+         * testing purpose.
+         */
+        final boolean isNorth = isPositive(φ0);
+        if (isNorth) {
+            φ0 = -φ0;
+            φ1 = -φ1;
+            φ2 = -φ2;
+        }
         φ0 = toRadians(φ0);
         φ1 = toRadians(φ1);
         φ2 = toRadians(φ2);
@@ -165,6 +220,11 @@ public class LambertConformal extends No
         final double sinφ1 = sin(φ1);
         final double m1    = cos(φ1) / rν(sinφ1);
         final double t1    = expOfNorthing(φ1, excentricity*sinφ1);
+        /*
+         * Computes n = (ln m₁ – ln m₂) / (ln t₁ – ln t₂), which we rewrite as ln(m₁/m₂) / ln(t₁/t₂)
+         * since division is less at risk of precision lost than subtraction. Note that this equation
+         * tends toward 0/0 if φ₁ ≈ φ₂, which force us to do a special check for the SP1 case.
+         */
         if (abs(φ1 - φ2) >= ANGULAR_TOLERANCE) {  // Should be 'true' for 2SP case.
             final double sinφ2 = sin(φ2);
             final double m2 = cos(φ2) / rν(sinφ2);
@@ -174,18 +234,26 @@ public class LambertConformal extends No
             n = -sinφ1;
         }
         /*
+         * Computes F = m₁/(n⋅t₁ⁿ) from Geomatics Guidance Note number 7.
          * Following constants will be stored in the denormalization matrix, to be applied after
          * the non-linear formulas implemented by this LambertConformal class. Opportunistically
          * use double-double arithmetic since we the matrix coefficients will be stored in this
          * format anyway. This makes a change in the 2 or 3 last digits.
          */
-        final DoubleDouble F = new DoubleDouble(-pow(t1, -n), 0);
-        F.multiply(m1, 0);
-        F.divide(n, 0);
-        final DoubleDouble ρ0 = new DoubleDouble();    // Initialized to zero.
+        final DoubleDouble F = new DoubleDouble(n, 0);
+        F.multiply(pow(t1, n), 0);
+        F.inverseDivide(m1, 0);
+        if (!isNorth) {
+            F.negate();
+        }
+        /*
+         * Compute  r = a⋅F⋅tⁿ  from EPSG notes where (in our case) a=1 and t is our 'expOfNorthing' function.
+         * Note that Snyder calls this term "ρ0".
+         */
+        final DoubleDouble r0 = new DoubleDouble();    // Initialized to zero.
         if (φ0 != copySign(PI/2, -n)) {    // For avoiding the rounding error documented in expOfNorthing(+π/2).
-            ρ0.value = pow(expOfNorthing(φ0, excentricity*sin(φ0)), n);
-            ρ0.multiply(F);
+            r0.value = pow(expOfNorthing(φ0, excentricity*sin(φ0)), n);
+            r0.multiply(F);
         }
         /*
          * At this point, all parameters have been processed. Now store
@@ -202,15 +270,18 @@ public class LambertConformal extends No
          *   - Scale x and y by F.
          *   - Translate y by ρ0.
          *   - Multiply by the scale factor (done by the super-class constructor).
-         *   - Add false easting and fasle northing (done by the super-class constructor).
+         *   - Add false easting and false northing (done by the super-class constructor).
          */
-        context.getMatrix(true).convertAfter(0, new DoubleDouble(-n, 0),    // Multiplication factor for longitudes.
+        final MatrixSIS normalize = context.getMatrix(true);
+        normalize.convertAfter(0, new DoubleDouble(isNorth ? n : -n, 0),    // Multiplication factor for longitudes.
                 (type == BELGIUM) ? new DoubleDouble(-BELGE_A, 0) : null);  // Longitude translation for Belgium.
-
+        if (isNorth) {
+            normalize.convertAfter(1, new DoubleDouble(-1, 0), null);
+        }
         final MatrixSIS denormalize = context.getMatrix(false);
         denormalize.convertBefore(0, F, null);
         F.negate();
-        denormalize.convertBefore(1, F, ρ0);
+        denormalize.convertBefore(1, F, r0);
     }
 
     /**
@@ -226,9 +297,11 @@ public class LambertConformal extends No
      * If this method can not identify the type, then the parameters should be considered as a 2SP case.
      */
     private static byte getType(final ParameterDescriptorGroup parameters) {
-        if (identMatch(parameters, "(?i).*\\bBelgium\\b.*", LambertConformalBelgium.IDENTIFIER)) return BELGIUM;
-        if (identMatch(parameters, "(?i).*\\b2SP\\b.*",     LambertConformal2SP    .IDENTIFIER)) return SP2;
-        if (identMatch(parameters, "(?i).*\\b1SP\\b.*",     LambertConformal1SP    .IDENTIFIER)) return SP1;
+        if (identMatch(parameters, "(?i).*\\bBelgium\\b.*",  LambertConformalBelgium .IDENTIFIER)) return BELGIUM;
+        if (identMatch(parameters, "(?i).*\\bMichigan\\b.*", LambertConformalMichigan.IDENTIFIER)) return MICHIGAN;
+        if (identMatch(parameters, "(?i).*\\bWest\\b.*",     LambertConformalWest    .IDENTIFIER)) return WEST;
+        if (identMatch(parameters, "(?i).*\\b2SP\\b.*",      LambertConformal2SP     .IDENTIFIER)) return SP2;
+        if (identMatch(parameters, "(?i).*\\b1SP\\b.*",      LambertConformal1SP     .IDENTIFIER)) return SP1;
         return 0; // Unidentified case, to be considered as 2SP.
     }
 
@@ -275,7 +348,7 @@ public class LambertConformal extends No
     }
 
     /**
-     * Converts the specified (λ,φ) coordinate (units in radians) and stores the result in {@code dstPts}
+     * Converts the specified (θ,φ) coordinate (units in radians) and stores the result in {@code dstPts}
      * (linear distance on a unit sphere). In addition, opportunistically computes the projection derivative
      * if {@code derivate} is {@code true}.
      *
@@ -293,27 +366,27 @@ public class LambertConformal extends No
          * the first non-linear one moved to the "normalize" affine transform, and the linear operations
          * applied after the last non-linear one moved to the "denormalize" affine transform.
          */
-        final double λ    = srcPts[srcOff];
-        final double φ    = srcPts[srcOff + 1];
+        final double θ    = srcPts[srcOff];         // θ = λ⋅n
+        final double φ    = srcPts[srcOff + 1];     // Sign may be reversed
         final double absφ = abs(φ);
-        final double sinλ = sin(λ);
-        final double cosλ = cos(λ);
+        final double sinθ = sin(θ);
+        final double cosθ = cos(θ);
         final double sinφ;
-        final double ρ;     // Snyder p. 108
+        final double r;     // From EPSG guide. Note that Snyder p. 108 calls this term "ρ".
         if (absφ < PI/2) {
             sinφ = sin(φ);
-            ρ = pow(expOfNorthing(φ, excentricity*sinφ), n);
+            r = pow(expOfNorthing(φ, excentricity*sinφ), n);
         } else if (absφ < PI/2 + ANGULAR_TOLERANCE) {
             sinφ = 1;
-            ρ = (φ*n >= 0) ? POSITIVE_INFINITY : 0;
+            r = (φ*n >= 0) ? POSITIVE_INFINITY : 0;
         } else {
-            ρ = sinφ = NaN;
+            r = sinφ = NaN;
         }
-        final double x = ρ * sinλ;
-        final double y = ρ * cosλ;
+        final double x = r * sinθ;
+        final double y = r * cosθ;
         if (dstPts != null) {
-            dstPts[dstOff]   = x;
-            dstPts[dstOff+1] = y;
+            dstPts[dstOff    ] = x;
+            dstPts[dstOff + 1] = y;
         }
         if (!derivate) {
             return null;
@@ -323,12 +396,12 @@ public class LambertConformal extends No
         //
         final double dρ;
         if (sinφ != 1) {
-            dρ = n * dy_dφ(sinφ, cos(φ)) * ρ;
+            dρ = n * dy_dφ(sinφ, cos(φ)) * r;
         } else {
-            dρ = ρ;
+            dρ = r;
         }
-        return new Matrix2(y, dρ*sinλ,      // ∂x/∂λ , ∂x/∂φ
-                          -x, dρ*cosλ);     // ∂y/∂λ , ∂y/∂φ
+        return new Matrix2(y, dρ*sinθ,      // ∂x/∂λ , ∂x/∂φ
+                          -x, dρ*cosθ);     // ∂y/∂λ , ∂y/∂φ
     }
 
     /**
@@ -342,8 +415,8 @@ public class LambertConformal extends No
                                     final double[] dstPts, final int dstOff)
             throws ProjectionException
     {
-        final double x = srcPts[srcOff  ];
-        final double y = srcPts[srcOff+1];
+        final double x = srcPts[srcOff    ];
+        final double y = srcPts[srcOff + 1];
         /*
          * NOTE: If some equation terms seem missing (e.g. "y = ρ0 - y"), this is because the linear operations
          * applied before the first non-linear one moved to the inverse of the "denormalize" transform, and the
@@ -405,38 +478,38 @@ public class LambertConformal extends No
                                 final double[] dstPts, final int dstOff,
                                 final boolean derivate) throws ProjectionException
         {
-            final double λ    = srcPts[srcOff];
-            final double φ    = srcPts[srcOff + 1];
+            final double θ    = srcPts[srcOff];         // θ = λ⋅n
+            final double φ    = srcPts[srcOff + 1];     // Sign may be reversed
             final double absφ = abs(φ);
-            final double sinλ = sin(λ);
-            final double cosλ = cos(λ);
-            final double ρ;
+            final double sinθ = sin(θ);
+            final double cosθ = cos(θ);
+            final double r;   // Snyder p. 108 calls this term "ρ", but we use "r" for consistency with EPSG guide.
             if (absφ < PI/2) {
-                ρ = pow(tan(PI/4 + 0.5*φ), n);
+                r = pow(tan(PI/4 + 0.5*φ), n);
             } else if (absφ < PI/2 + ANGULAR_TOLERANCE) {
-                ρ = (φ*n >= 0) ? POSITIVE_INFINITY : 0;
+                r = (φ*n >= 0) ? POSITIVE_INFINITY : 0;
             } else {
-                ρ = NaN;
+                r = NaN;
             }
-            final double x = ρ * sinλ;
-            final double y = ρ * cosλ;
+            final double x = r * sinθ;
+            final double y = r * cosθ;
             Matrix derivative = null;
             if (derivate) {
                 final double dρ;
                 if (absφ < PI/2) {
-                    dρ = n*ρ / cos(φ);
+                    dρ = n*r / cos(φ);
                 } else {
                     dρ = NaN;
                 }
-                derivative = new Matrix2(y, dρ*sinλ,    // ∂x/∂λ , ∂x/∂φ
-                                        -x, dρ*cosλ);   // ∂y/∂λ , ∂y/∂φ
+                derivative = new Matrix2(y, dρ*sinθ,    // ∂x/∂λ , ∂x/∂φ
+                                        -x, dρ*cosθ);   // ∂y/∂λ , ∂y/∂φ
             }
             // Following part is common to all spherical projections: verify, store and return.
             assert Assertions.checkDerivative(derivative, super.transform(srcPts, srcOff, dstPts, dstOff, derivate))
                 && Assertions.checkTransform(dstPts, dstOff, x, y);     // dstPts = result from ellipsoidal formulas.
             if (dstPts != null) {
-                dstPts[dstOff  ] = x;
-                dstPts[dstOff+1] = y;
+                dstPts[dstOff    ] = x;
+                dstPts[dstOff + 1] = y;
             }
             return derivative;
         }
@@ -453,10 +526,10 @@ public class LambertConformal extends No
             double y = srcPts[srcOff+1];
             final double ρ = hypot(x, y);
             x = atan2(x, y);  // Really (x,y), not (y,x)
-            y = 2 * atan(pow(1/ρ, -1/n)) - PI/2;
+            y = 2*atan(pow(1/ρ, -1/n)) - PI/2;
             assert checkInverseTransform(srcPts, srcOff, dstPts, dstOff, x, y);
-            dstPts[dstOff  ] = x;
-            dstPts[dstOff+1] = y;
+            dstPts[dstOff    ] = x;
+            dstPts[dstOff + 1] = y;
         }
 
         /**
@@ -465,11 +538,11 @@ public class LambertConformal extends No
          */
         private boolean checkInverseTransform(final double[] srcPts, final int srcOff,
                                               final double[] dstPts, final int dstOff,
-                                              final double λ, final double φ)
+                                              final double θ, final double φ)
                 throws ProjectionException
         {
             super.inverseTransform(srcPts, srcOff, dstPts, dstOff);
-            return Assertions.checkInverseTransform(dstPts, dstOff, λ, φ);
+            return Assertions.checkInverseTransform(dstPts, dstOff, θ, φ);
         }
     }
 

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -39,6 +39,7 @@ import org.apache.sis.util.Workaround;
 
 import static java.lang.Math.*;
 import static java.lang.Double.*;
+import static org.apache.sis.math.MathFunctions.isPositive;
 
 
 /**
@@ -75,7 +76,7 @@ import static java.lang.Double.*;
  * @see TransverseMercator
  * @see ObliqueMercator
  */
-public class Mercator extends NormalizedProjection {
+public class Mercator extends AbstractLambertConformal {
     /**
      * For cross-version compatibility.
      */
@@ -228,6 +229,7 @@ public class Mercator extends Normalized
          * 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);
         denormalize.convertBefore(0, k0, null);
         denormalize.convertBefore(1, k0, null);
@@ -240,9 +242,37 @@ public class Mercator extends Normalized
             denormalize.convertBefore(1, null, new DoubleDouble(-log(expOfNorthing(φ0, excentricity * sin(φ0)))));
         }
         if (type == MILLER) {
-            context.getMatrix(true).convertBefore(1, new DoubleDouble(0.8), null);
+              normalize.convertBefore(1, new DoubleDouble(0.80), null);
             denormalize.convertBefore(1, new DoubleDouble(1.25), null);
         }
+        /*
+         * At this point we are done, but we add here a little bit a maniac precision hunting.
+         * The Mercator equations have naturally a very slight better precision in the South
+         * hemisphere, because of the following term:
+         *
+         *     tan(π/4 + φ/2)        which implies        tan( 0 )   when   φ = -90°    (south pole)
+         *                                                tan(π/2)   when   φ = +90°    (north pole)
+         *
+         * The case for the North pole has no exact representation. Furthermore IEEE 754 arithmetic has
+         * better precision for values close to zero, which favors the South hemisphere in the above term.
+         * The code below reverses the sign of latitudes before the map projection, then reverses the sign
+         * of results after the projection. This has the effect of interchanging the favorized hemisphere.
+         * But we do that only if the latitude given in parameter is positive. In other words, we favor the
+         * hemisphere of the latitude given in parameters.
+         *
+         * Other libraries do something equivalent by rewriting the equations, e.g. using  tan(π/4 - φ/2)
+         * and modifying the other equations accordingly. This favors the North hemisphere instead of the
+         * South one, but this favoritism is hard-coded. The Apache SIS design with normalization matrices
+         * allows a more dynamic approach, which we apply here.
+         *
+         * This "precision hunting" is optional. If something seems to go wrong, it is safe to comment all
+         * those remaning lines of code.
+         */
+        if (φ0 == 0 && isPositive(φ1 != 0 ? φ1 : φ0)) {
+            final DoubleDouble revert = new DoubleDouble(-1, 0);
+              normalize.convertBefore(1, revert, null);
+            denormalize.convertBefore(1, revert, null);  // Must be before false easting/northing.
+        }
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -35,7 +35,6 @@ import org.opengis.referencing.operation
 import org.opengis.util.FactoryException;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.resources.Errors;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -50,7 +49,6 @@ import org.apache.sis.internal.util.Cons
 import org.apache.sis.internal.util.Numerics;
 
 import static java.lang.Math.*;
-import static java.lang.Double.*;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
 // Branch-dependent imports
@@ -145,7 +143,7 @@ public abstract class NormalizedProjecti
 
     /**
      * Desired accuracy for the result of iterative computations, in radians.
-     * This constant defines the desired accuracy of methods like {@link #φ(double)}.
+     * This constant defines the desired accuracy of methods like {@link AbstractLambertConformal#φ(double)}.
      *
      * <p>The current value is 0.25 time the accuracy derived from {@link Formulas#LINEAR_TOLERANCE}.
      * So if the linear tolerance is 1 cm, then the accuracy that we will seek for is 0.25 cm (about
@@ -155,6 +153,9 @@ 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.
      */
     static final int MAXIMUM_ITERATIONS = 15;
 
@@ -168,7 +169,7 @@ public abstract class NormalizedProjecti
     final ContextualParameters context;
 
     /**
-     * Ellipsoid excentricity, equal to <code>sqrt({@linkplain #excentricitySquared})</code>.
+     * Ellipsoid excentricity, equals to <code>sqrt({@linkplain #excentricitySquared})</code>.
      * Value 0 means that the ellipsoid is spherical.
      */
     protected final double excentricity;
@@ -281,6 +282,17 @@ public abstract class NormalizedProjecti
         FALSE_EASTING,
 
         /**
+         * Maps the <cite>false westing</cite> parameter (symbol: <var>FW</var>).
+         * This is the same <var>x</var> translation than {@link #FALSE_EASTING}, but of opposite sign.
+         *
+         * <p>Actually, there is usually no parameter named "false westing" in a map projection.
+         * But some projections like <cite>"Lambert Conic Conformal (West Orientated)"</cite> are
+         * defined in such a way that their "false easting" parameter is effectively a "false westing".
+         * This enumeration value can be used for informing {@link NormalizedProjection} about that fact.</p>
+         */
+        FALSE_WESTING,
+
+        /**
          * Maps the <cite>false northing</cite> parameter (symbol: <var>FN</var>).
          * This is a translation term for the <var>y</var> values obtained after map projections.
          *
@@ -291,7 +303,18 @@ public abstract class NormalizedProjecti
          *   <li>Northing at projection centre</li>
          * </ul>
          */
-        FALSE_NORTHING
+        FALSE_NORTHING,
+
+        /**
+         * Maps the <cite>false southing</cite> parameter (symbol: <var>FS</var>).
+         * This is the same <var>y</var> translation than {@link #FALSE_NORTHING}, but of opposite sign.
+         *
+         * <p>Actually, there is usually no parameter named "false southing" in a map projection.
+         * But some projections like <cite>"Transverse Mercator (South Orientated)"</cite> are
+         * defined in such a way that their "false northing" parameter is effectively a "false southing".
+         * This enumeration value can be used for informing {@link NormalizedProjection} about that fact.</p>
+         */
+        FALSE_SOUTHING
     }
 
     /**
@@ -379,8 +402,10 @@ public abstract class NormalizedProjecti
               double a  = getAndStore(parameters, semiMajor);
         final double b  = getAndStore(parameters, semiMinor);
         final double λ0 = getAndStore(parameters, roles.get(ParameterRole.CENTRAL_MERIDIAN));
-        final double fe = getAndStore(parameters, roles.get(ParameterRole.FALSE_EASTING));
-        final double fn = getAndStore(parameters, roles.get(ParameterRole.FALSE_NORTHING));
+        final double fe = getAndStore(parameters, roles.get(ParameterRole.FALSE_EASTING))
+                        - getAndStore(parameters, roles.get(ParameterRole.FALSE_WESTING));
+        final double fn = getAndStore(parameters, roles.get(ParameterRole.FALSE_NORTHING))
+                        - getAndStore(parameters, roles.get(ParameterRole.FALSE_SOUTHING));
         final double rs = b / a;
         excentricitySquared = 1 - (rs * rs);
         excentricity = sqrt(excentricitySquared);
@@ -842,8 +867,12 @@ public abstract class NormalizedProjecti
      * Lambert Conic Conformal projection, since Mercator can be considered as a special case of that
      * Lambert projection with the equator as the single standard parallel.
      *
-     * <p>The Mercator projection is given by the {@linkplain Math#log(double) natural logarithm} of the
-     * value returned by this method. This function is <em>almost</em> the converse of {@link #φ(double)}.
+     * <p>The Mercator projection is given by the {@linkplain Math#log(double) natural logarithm}
+     * of the value returned by this method. This function is <em>almost</em> the converse of
+     * {@link AbstractLambertConformal#φ(double)}.
+     *
+     * <p>In IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015,
+     * a function closely related to this one has the letter <var>t</var>.</p>
      *
      *
      * <div class="section">Properties</div>
@@ -888,57 +917,21 @@ public abstract class NormalizedProjecti
      * @param  ℯsinφ The sine of the φ argument multiplied by {@link #excentricity}.
      * @return {@code Math.exp} of the Mercator projection of the given latitude.
      *
-     * @see #φ(double)
+     * @see AbstractLambertConformal#φ(double)
      * @see #dy_dφ(double, double)
      */
     final double expOfNorthing(final double φ, final double ℯsinφ) {
         /*
          * Note:   tan(π/4 - φ/2)  =  1 / tan(π/4 + φ/2)
+         *
+         * A + sign in the equation favorises slightly the accuracy in South hemisphere, while a - sign
+         * 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);
     }
 
     /**
-     * Computes the latitude for a value closely related to the <var>y</var> value of a Mercator projection.
-     * This formula is also part of other projections, since Mercator can be considered as a special case of
-     * Lambert Conic Conformal for instance.
-     *
-     * <p>This function is <em>almost</em> the converse of the above {@link #expOfNorthing(double, double)} function.
-     * In a Mercator inverse projection, the value of the {@code expOfSouthing} argument is {@code exp(-y)}.</p>
-     *
-     * <p>The input should be a positive number, otherwise the result will be either outside
-     * the [-π/2 … π/2] range, or will be NaN. Its behavior at some particular points is:</p>
-     *
-     * <ul>
-     *   <li>φ(0)   =   π/2</li>
-     *   <li>φ(1)   =   0</li>
-     *   <li>φ(∞)   =  -π/2.</li>
-     * </ul>
-     *
-     * @param  expOfSouthing The <em>reciprocal</em> of the value returned by {@link #expOfNorthing}.
-     * @return The latitude in radians.
-     * @throws ProjectionException if the iteration does not converge.
-     *
-     * @see #expOfNorthing(double, double)
-     * @see #dy_dφ(double, double)
-     */
-    final double φ(final double expOfSouthing) throws ProjectionException {
-        final double hℯ = 0.5 * excentricity;
-        double φ = (PI/2) - 2*atan(expOfSouthing);          // Snyder (7-11)
-        for (int i=0; i<MAXIMUM_ITERATIONS; i++) {          // Iteratively solve equation (7-9) from Snyder
-            final double ℯsinφ = excentricity * sin(φ);
-            final double Δφ = abs(φ - (φ = PI/2 - 2*atan(expOfSouthing * pow((1 - ℯsinφ)/(1 + ℯsinφ), hℯ))));
-            if (Δφ <= ITERATION_TOLERANCE) {
-                return φ;
-            }
-        }
-        if (isNaN(expOfSouthing)) {
-            return NaN;
-        }
-        throw new ProjectionException(Errors.Keys.NoConvergence);
-    }
-
-    /**
      * Computes the partial derivative of a Mercator projection at the given latitude. This formula is also part of
      * other projections, since Mercator can be considered as a special case of Lambert Conic Conformal for instance.
      *
@@ -950,7 +943,7 @@ public abstract class NormalizedProjecti
      * @return The partial derivative of a Mercator projection at the given latitude.
      *
      * @see #expOfNorthing(double, double)
-     * @see #φ(double)
+     * @see AbstractLambertConformal#φ(double)
      */
     final double dy_dφ(final double sinφ, final double cosφ) {
         return (1 / cosφ)  -  excentricitySquared * cosφ / (1 - excentricitySquared * (sinφ*sinφ));

Modified: sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Mon Jul 13 17:26:56 2015
@@ -11,4 +11,6 @@ org.apache.sis.internal.referencing.prov
 org.apache.sis.internal.referencing.provider.MillerCylindrical
 org.apache.sis.internal.referencing.provider.LambertConformal1SP
 org.apache.sis.internal.referencing.provider.LambertConformal2SP
+org.apache.sis.internal.referencing.provider.LambertConformalWest
 org.apache.sis.internal.referencing.provider.LambertConformalBelgium
+org.apache.sis.internal.referencing.provider.LambertConformalMichigan

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -78,11 +78,18 @@ public final class CoordinateOperationMe
     public static void main(final String[] args) throws IOException {
         final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
         final List<OperationMethod> methods = new ArrayList<OperationMethod>(factory.getAvailableMethods(SingleOperation.class));
+        JDK8.removeIf(methods, new org.apache.sis.internal.jdk8.Predicate<OperationMethod>() {
+            @Override public boolean test(OperationMethod method) {
+                return method.getClass().getName().endsWith("Mock");
+            }
+        });
         Collections.sort(methods, new java.util.Comparator<OperationMethod>() {
             @Override public int compare(OperationMethod o1, OperationMethod o2) {
                 int c = category(o1) - category(o2);
                 if (c == 0) {  // If the two methods are in the same category, sort by name.
-                    c = o1.getName().getCode().compareTo(o2.getName().getCode());
+                    final String n1 = o1.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
+                    final String n2 = o2.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
+                    c = n1.compareTo(n2);
                 }
                 return c;
             }
@@ -338,7 +345,17 @@ public final class CoordinateOperationMe
                 if (index == null) {
                     index = footnotes.size();
                 }
-                remarks = ((param.getMinimumOccurs() != 0) ? "Unmodifiable " : "Optional ") + toSuperScript(index);
+                if (param.getMinimumOccurs() == 0) {
+                    remarks = "Optional ";
+                } else {
+                    final Comparable<?> min = param.getMinimumValue();
+                    if (min != null && min.equals(param.getMaximumValue())) {
+                        remarks = "Unmodifiable ";
+                    } else {
+                        remarks = "See note ";
+                    }
+                }
+                remarks += toSuperScript(index);
             }
             println("td class=\"sep\"", escape(remarks));
             final String domain = toLocalizedString(Parameters.getValueDomain(param));
@@ -483,16 +500,32 @@ public final class CoordinateOperationMe
     private static String getUnit(final ParameterDescriptor<?> param) {
         final String unit = PatchedUnitFormat.toString(param.getUnit());
         if (unit != null && !unit.isEmpty()) {
+            if (unit.equals("°")) {
+                return unit;
+            }
             return " " + unit;
         }
         return "";
     }
 
     /**
+     * Returns the operation type of the given method.
+     */
+    private static Class<?> getOperationType(final DefaultOperationMethod method) {
+        Class<?> type = method.getOperationType();
+        if (type == SingleOperation.class) {
+            if (method instanceof Affine) {     // EPSG:9624 - Affine parametric transformation
+                type = Transformation.class;
+            }
+        }
+        return type;
+    }
+
+    /**
      * Returns a code for sorting methods in categories.
      */
     private static int category(final OperationMethod method) {
-        final Class<?> c = ((DefaultOperationMethod) method).getOperationType();
+        final Class<?> c = getOperationType((DefaultOperationMethod) method);
         if (CylindricalProjection.class.isAssignableFrom(c)) return CYLINDRICAL_PROJECTION;
         if (ConicProjection      .class.isAssignableFrom(c)) return CONIC_PROJECTION;
         if (PlanarProjection     .class.isAssignableFrom(c)) return PLANAR_PROJECTION;

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/EquirectangularTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/EquirectangularTest.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/EquirectangularTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/EquirectangularTest.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -118,7 +118,13 @@ public final strictfp class Equirectangu
      */
     @Test
     public void testRandomPoints() throws FactoryException, TransformException {
-        initialize(new Equirectangular(), true, false, true, false);
+        initialize(new Equirectangular(), true,
+                  0.5,  // Central meridian
+                  0,    // Latitude of origin (none)
+                 20,    // Standard parallel
+                  1,    // Scale factor (none)
+                200,    // False easting
+                100);   // False northing
         tolerance = Formulas.LINEAR_TOLERANCE;  // Not NORMALIZED_TOLERANCE since this is not a NormalizedProjection.
         derivativeDeltas = new double[] {100, 100};
         verifyInDomain(CoordinateDomain.GEOGRAPHIC, 0);

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -16,16 +16,21 @@
  */
 package org.apache.sis.referencing.operation.projection;
 
+import java.util.Random;
 import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.provider.LambertConformal1SP;
 import org.apache.sis.internal.referencing.provider.LambertConformal2SP;
+import org.apache.sis.internal.referencing.provider.LambertConformalWest;
 import org.apache.sis.internal.referencing.provider.LambertConformalBelgium;
+import org.apache.sis.internal.referencing.provider.LambertConformalMichigan;
 import org.apache.sis.referencing.operation.transform.CoordinateDomain;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestUtilities;
 import org.junit.Test;
 
 import static java.lang.StrictMath.*;
@@ -45,7 +50,7 @@ import static org.junit.Assert.*;
  * @version 0.6
  * @module
  */
-@DependsOn(NormalizedProjectionTest.class)
+@DependsOn(AbstractLambertConformalTest.class)
 public final strictfp class LambertConformalTest extends MapProjectionTestCase {
     /**
      * Creates a new instance of {@link LambertConformal}. See the class javadoc for an explanation
@@ -88,25 +93,25 @@ public final strictfp class LambertConfo
     @Test
     public void testSpecialLatitudes() throws ProjectionException {
         if (transform == null) {    // May have been initialized by 'testSphericalCase'.
-            initialize(true, 40);   // Elliptical case
+            initialize(true, 40);  // Elliptical case
         }
         final double INF = POSITIVE_INFINITY;
         assertEquals ("Not a number",     NaN, transform(NaN),            NORMALIZED_TOLERANCE);
         assertEquals ("Out of range",     NaN, transform(+2),             NORMALIZED_TOLERANCE);
         assertEquals ("Out of range",     NaN, transform(-2),             NORMALIZED_TOLERANCE);
         assertEquals ("Forward 0°N",      1,   transform(0),              NORMALIZED_TOLERANCE);
-        assertEquals ("Forward 90°N",     0,   transform(+PI/2),          NORMALIZED_TOLERANCE);
-        assertEquals ("Forward 90°S",     INF, transform(-PI/2),          NORMALIZED_TOLERANCE);
-        assertEquals ("Forward (90+ε)°N", 0,   transform(+nextUp(+PI/2)), NORMALIZED_TOLERANCE);
-        assertEquals ("Forward (90+ε)°S", INF, transform(-nextUp( PI/2)), NORMALIZED_TOLERANCE);
-        assertEquals ("Forward (90-ε)°N", 0,   transform(-nextUp(-PI/2)), 1E-10);
+        assertEquals ("Forward 90°S",     0,   transform(-PI/2),          NORMALIZED_TOLERANCE);
+        assertEquals ("Forward 90°N",     INF, transform(+PI/2),          NORMALIZED_TOLERANCE);
+        assertEquals ("Forward (90+ε)°S", 0,   transform(-nextUp( PI/2)), NORMALIZED_TOLERANCE);
+        assertEquals ("Forward (90+ε)°N", INF, transform(+nextUp(+PI/2)), NORMALIZED_TOLERANCE);
+        assertEquals ("Forward (90-ε)°S", 0,   transform(+nextUp(-PI/2)), 1E-10);
 
         assertEquals ("Not a number", NaN, inverseTransform(NaN),  NORMALIZED_TOLERANCE);
-        assertEquals ("Inverse 0",  +PI/2, inverseTransform( 0),   NORMALIZED_TOLERANCE);
+        assertEquals ("Inverse 0",  -PI/2, inverseTransform( 0),   NORMALIZED_TOLERANCE);
         assertEquals ("Inverse +1",     0, inverseTransform(+1),   NORMALIZED_TOLERANCE);
         assertEquals ("Inverse -1",     0, inverseTransform(-1),   NORMALIZED_TOLERANCE);
-        assertEquals ("Inverse +∞", -PI/2, inverseTransform(INF),  NORMALIZED_TOLERANCE);
-        assertEquals ("Inverse -∞", -PI/2, inverseTransform(-INF), NORMALIZED_TOLERANCE);
+        assertEquals ("Inverse +∞", +PI/2, inverseTransform(INF),  NORMALIZED_TOLERANCE);
+        assertEquals ("Inverse -∞", +PI/2, inverseTransform(-INF), NORMALIZED_TOLERANCE);
 
         // Like the north case, but with sign inversed.
         initialize(((LambertConformal) transform).excentricity != 0, -40);
@@ -194,6 +199,81 @@ public final strictfp class LambertConfo
     }
 
     /**
+     * Tests the <cite>"Lambert Conic Conformal (2SP Michigan)"</cite> case (EPSG:1051).
+     * This test is defined in GeoAPI conformance test suite.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     *
+     * @see org.opengis.test.referencing.ParameterizedTransformTest#testLambertConicConformalMichigan()
+     */
+    @Test
+    @DependsOnMethod("testLambertConicConformal2SP")
+    public void testLambertConicConformalMichigan() throws FactoryException, TransformException {
+        createGeoApiTest(new LambertConformalMichigan()).testLambertConicConformalMichigan();
+    }
+
+    /**
+     * Tests the <cite>"Lambert Conic Conformal (1SP West Orientated)"</cite> case (EPSG:9826)).
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    @DependsOnMethod("testLambertConicConformal1SP")
+    public void testLambertConicConformalWestOrientated() throws FactoryException, TransformException {
+        initialize(new LambertConformal1SP(), false,
+                  0.5,    // Central meridian
+                 40,      // Latitude of origin
+                  0,      // Standard parallel (none)
+                  0.997,  // Scale factor
+                200,      // False easting
+                100);     // False northing
+        final MathTransform reference = transform;
+
+        initialize(new LambertConformalWest(), false,
+                  0.5,    // Central meridian
+                 40,      // Latitude of origin
+                  0,      // Standard parallel (none)
+                  0.997,  // Scale factor
+                200,      // False easting
+                100);     // False northing
+
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        final double[] sources = new double[20];
+        for (int i=0; i<sources.length;) {
+            sources[i++] = 20 * random.nextDouble();      // Longitude
+            sources[i++] = 10 * random.nextDouble() + 35; // Latitude
+        }
+        final double[] expected = new double[sources.length];
+        reference.transform(sources, 0, expected, 0, sources.length/2);
+        /*
+         * At this point, we have the source coordinates and the expected projected coordinates calculated
+         * by the "Lambert Conic Conformal (1SP)" method. Now convert those projected coordinates into the
+         * coordinates that we expect from the "Lambert Conic Conformal (1SP West Orientated)".  If we had
+         * no false easting, we would just revert the sign of 'x' values. But because of the false easting,
+         * we expect an additional offset of two time that easting. This is because (quoting the EPSG guide):
+         *
+         *    the term FE retains its definition, i.e. in the Lambert Conic Conformal (West Orientated)
+         *    method it increases the Westing value at the natural origin.
+         *    In this method it is effectively false westing (FW).
+         *
+         * So the conversion for this test case should be:     W = 400 - E
+         *
+         * However our map projection "kernel" implementation does not reverse the sign of 'x' values,
+         * because this reversal is the job of a separated method (CoordinateSystems.swapAndScaleAxes)
+         * which does is work by examining the axis directions. So we the values that we expect are:
+         *
+         *     expected  =  -W  =  E - 400
+         */
+        for (int i=0; i<sources.length; i += 2) {
+            expected[i] -= 400;
+        }
+        tolerance = Formulas.LINEAR_TOLERANCE;
+        verifyTransform(sources, expected);
+    }
+
+    /**
      * Verifies the consistency of spherical formulas with the elliptical formulas.
      *
      * @throws FactoryException if an error occurred while creating the map projection.
@@ -212,7 +292,13 @@ public final strictfp class LambertConfo
         /*
          * For some random points, compare the result of spherical formulas with the ellipsoidal ones.
          */
-        initialize(new LambertConformal1SP(), false, true, false, true);
+        initialize(new LambertConformal1SP(), false,
+                  0.5,    // Central meridian
+                 40,      // Latitude of origin
+                  0,      // Standard parallel (none)
+                  0.997,  // Scale factor
+                200,      // False easting
+                100);     // False northing
         tolerance = Formulas.LINEAR_TOLERANCE;
         verifyInDomain(CoordinateDomain.GEOGRAPHIC_SAFE, 268617081);
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -83,24 +83,20 @@ strictfp class MapProjectionTestCase ext
      * the chances to detect a mismatch.
      */
     final void initialize(final DefaultOperationMethod provider, final boolean ellipse,
-            final boolean hasLatitudeOfOrigin,
-            final boolean hasStandardParallel,
-            final boolean hasScaleFactor)
-            throws FactoryException
+            final double centralMeridian,
+            final double latitudeOfOrigin,
+            final double standardParallel,
+            final double scaleFactor,
+            final double falseEasting,
+            final double falseNorthing) throws FactoryException
     {
         final Parameters parameters = parameters(provider, ellipse);
-        parameters.parameter(Constants.CENTRAL_MERIDIAN).setValue(0.5, NonSI.DEGREE_ANGLE);
-        parameters.parameter(Constants.FALSE_EASTING)   .setValue(200);
-        parameters.parameter(Constants.FALSE_NORTHING)  .setValue(100);
-        if (hasLatitudeOfOrigin) {
-            parameters.parameter("latitude_of_origin").setValue(40);
-        }
-        if (hasStandardParallel) {
-            parameters.parameter(Constants.STANDARD_PARALLEL_1).setValue(20);
-        }
-        if (hasScaleFactor) {
-            parameters.parameter(Constants.SCALE_FACTOR).setValue(0.997);
-        }
+        if (centralMeridian  != 0) parameters.parameter(Constants.CENTRAL_MERIDIAN)   .setValue(centralMeridian, NonSI.DEGREE_ANGLE);
+        if (latitudeOfOrigin != 0) parameters.parameter("latitude_of_origin")         .setValue(latitudeOfOrigin);
+        if (standardParallel != 0) parameters.parameter(Constants.STANDARD_PARALLEL_1).setValue(standardParallel);
+        if (scaleFactor      != 1) parameters.parameter(Constants.SCALE_FACTOR)       .setValue(scaleFactor);
+        if (falseEasting     != 0) parameters.parameter(Constants.FALSE_EASTING)      .setValue(falseEasting);
+        if (falseNorthing    != 0) parameters.parameter(Constants.FALSE_NORTHING)     .setValue(falseNorthing);
         transform = new MathTransformFactoryMock(provider).createParameterizedTransform(parameters);
         validate();
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -46,7 +46,7 @@ import static org.apache.sis.referencing
  * @version 0.6
  * @module
  */
-@DependsOn(NormalizedProjectionTest.class)
+@DependsOn(AbstractLambertConformalTest.class)
 public final strictfp class MercatorTest extends MapProjectionTestCase {
     /**
      * Creates a new instance of {@link Mercator} for a sphere or an ellipsoid.
@@ -234,7 +234,13 @@ public final strictfp class MercatorTest
         /*
          * For some random points, compare the result of spherical formulas with the ellipsoidal ones.
          */
-        initialize(new Mercator1SP(), false, false, false, true);
+        initialize(new Mercator1SP(), false,
+                  0.5,    // Central meridian
+                  0,      // Latitude of origin (none)
+                  0,      // Standard parallel (none)
+                  0.997,  // Scale factor
+                200,      // False easting
+                100);     // False northing
         tolerance = Formulas.LINEAR_TOLERANCE;
         verifyInDomain(CoordinateDomain.GEOGRAPHIC_SAFE, 84018710);
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -39,14 +39,21 @@ import org.apache.sis.util.Workaround;
  * @module
  */
 @SuppressWarnings("serial")
-final strictfp class NoOp extends NormalizedProjection {
+final strictfp class NoOp extends AbstractLambertConformal {
     /**
      * Creates a new "no-operation".
      *
      * @param ellipsoidal {@code true} for an ellipsoidal case, or {@code false} for a spherical case.
      */
     NoOp(final boolean ellipsoidal) {
-        this(parameters(ellipsoidal));
+        this(parameters((ellipsoidal ? GeodeticDatumMock.WGS84 : GeodeticDatumMock.SPHERE).getEllipsoid()));
+    }
+
+    /**
+     * Creates a new "no-operation" for the given axis lengths.
+     */
+    NoOp(final double semiMajor, final double semiMinor) {
+        this(parameters(semiMajor, semiMinor));
     }
 
     /**
@@ -66,12 +73,21 @@ final strictfp class NoOp extends Normal
      * ("Relax constraint on placement of this()/super() call in constructors").
      */
     @Workaround(library="JDK", version="1.7")
-    private static Parameters parameters(final boolean ellipse) {
+    private static Parameters parameters(final Ellipsoid ellipsoid) {
+        return parameters(ellipsoid.getSemiMajorAxis(),
+                          ellipsoid.getSemiMinorAxis());
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    @Workaround(library="JDK", version="1.7")
+    private static Parameters parameters(final double semiMajor, final double semiMinor) {
         final ParameterValueGroup group = new ParameterBuilder()
                 .addName("No-operation").createGroupForMapProjection().createValue();
-        final Ellipsoid ellipsoid = (ellipse ? GeodeticDatumMock.WGS84 : GeodeticDatumMock.SPHERE).getEllipsoid();
-        group.parameter(Constants.SEMI_MAJOR).setValue(ellipsoid.getSemiMajorAxis());
-        group.parameter(Constants.SEMI_MINOR).setValue(ellipsoid.getSemiMinorAxis());
+        group.parameter(Constants.SEMI_MAJOR).setValue(semiMajor);
+        group.parameter(Constants.SEMI_MINOR).setValue(semiMinor);
         return (Parameters) group;
     }
 

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -51,7 +51,7 @@ public final strictfp class NormalizedPr
     /**
      * Tolerance level for comparing floating point numbers.
      */
-    private static final double TOLERANCE = 1E-12;
+    static final double TOLERANCE = 1E-12;
 
     /**
      * Natural logarithm of the pseudo-infinity as returned by Mercator formulas in the spherical
@@ -82,17 +82,6 @@ public final strictfp class NormalizedPr
     }
 
     /**
-     * Computes {@link NormalizedProjection#φ(double)}.
-     *
-     * @param  expOfSouthing The reciprocal of the value returned by {@link #expOfNorthing(double)}.
-     * @return The latitude in radians.
-     * @throws ProjectionException if the iteration does not converge.
-     */
-    private double φ(final double expOfSouthing) throws ProjectionException {
-        return ((NormalizedProjection) transform).φ(expOfSouthing);
-    }
-
-    /**
      * Tests the value documented in the javadoc. Those value may be freely changed;
      * those tests exist only to increase the chances that the documented values are right.
      */
@@ -220,56 +209,6 @@ public final strictfp class NormalizedPr
     }
 
     /**
-     * Tests the {@link NormalizedProjection#φ(double)} function. We expect it to be the converse of the
-     * {@link NormalizedProjection#t(double, double)} function. In theory only the [-90° … +90°] range needs
-     * to be tested. However the function still consistent in the [-90° … +270°] range so we test that range
-     * for tracking this fact.
-     *
-     * @throws ProjectionException Should never happen.
-     */
-    @Test
-    @DependsOnMethod("testExpOfNorthing")
-    public void test_φ() throws ProjectionException {
-        transform = new NoOp(false);   // Spherical case
-        tolerance = TOLERANCE;
-        doTest_φ();
-        transform = new NoOp(true);    // Ellipsoidal case
-        tolerance = NormalizedProjection.ITERATION_TOLERANCE;
-        doTest_φ();
-    }
-
-    /**
-     * Implementation of {@link #test_φ()}.
-     * The {@link #projection} field must have been set before this method is called.
-     */
-    private void doTest_φ() throws ProjectionException {
-        assertEquals("φ(NaN) = NaN",    NaN,   φ(NaN),               tolerance);
-        assertEquals("φ( ∞)  = -90°", -PI/2,   φ(POSITIVE_INFINITY), tolerance);
-        assertEquals("φ( ∞)  = -90°", -PI/2,   φ(MAX_VALUE),         tolerance);
-        assertEquals("φ( 1)  =   0°",    0,    φ(1),                 tolerance);
-        assertEquals("φ( ε)  →  90°",  PI/2,   φ(MIN_VALUE),         tolerance);
-        assertEquals("φ( 0)  =  90°",  PI/2,   φ(0),                 tolerance);
-        assertEquals("φ(-ε)  →  90°",  PI/2,   φ(-MIN_VALUE),        tolerance);
-        assertEquals("φ(-1)  = 180°",  PI,     φ(-1),                tolerance);
-        assertEquals("φ(-∞)  = 270°",  PI*1.5, φ(-MAX_VALUE),        tolerance);
-        assertEquals("φ(-∞)  = 270°",  PI*1.5, φ(NEGATIVE_INFINITY), tolerance);
-        /*
-         * Using t(φ) as a reference.
-         */
-        for (int i=-90; i<=270; i+=5) {
-            final double φ   = toRadians(i);
-            final double t    = 1 / expOfNorthing(φ);
-            final double back = toDegrees(φ(t));
-            if (i <= 90) {
-                assertTrue("φ(t) in valid range should be positive.", t >= 0);
-            } else {
-                assertTrue("φ(t) in invalid range should be negative.", t < 0);
-            }
-            assertEquals("Inverse function doesn't match.", i, back, tolerance);
-        }
-    }
-
-    /**
      * Tests the {@link NormalizedProjection#dy_dφ(double, double)} method.
      *
      * @throws TransformException Should never happen.

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -101,6 +101,7 @@ import org.junit.BeforeClass;
     // Test map projections. Those tests need the providers tested above.
     org.apache.sis.referencing.operation.projection.NormalizedProjectionTest.class,
     org.apache.sis.referencing.operation.projection.EquirectangularTest.class,
+    org.apache.sis.referencing.operation.projection.AbstractLambertConformalTest.class,
     org.apache.sis.referencing.operation.projection.MercatorTest.class,
     org.apache.sis.referencing.operation.projection.LambertConformalTest.class,
 

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -19,7 +19,9 @@ package org.apache.sis.internal.jdk8;
 import java.util.Map;
 import java.util.Date;
 import java.util.Calendar;
+import java.util.Collection;
 import java.util.GregorianCalendar;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentMap;
@@ -100,6 +102,25 @@ public final class JDK8 {
     }
 
     /**
+     * Removes all elements for which the given filter returns {@code true}.
+     *
+     * @param  <E>        The type of elements in the given collection.
+     * @param  collection The collection from which to remove element.
+     * @param  filter     The condition for elements to remove.
+     * @return {@code true} if at least one element has been removed.
+     */
+    public static <E> boolean removeIf(final Collection<E> collection, final Predicate<? super E> filter) {
+        boolean changed = false;
+        for (final Iterator<E> it = collection.iterator(); it.hasNext();) {
+            if (filter.test(it.next())) {
+                it.remove();
+                changed = true;
+            }
+        }
+        return changed;
+    }
+
+    /**
      * Atomically computes and stores the value for the given key. This is a substitute for
      * {@link ConcurrentMap#compute(java.lang.Object, java.util.function.BiFunction)}
      * on pre-JDK8 branches.

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] Mon Jul 13 17:26:56 2015
@@ -119,6 +119,11 @@ public final class Messages extends Inde
         public static final short MismatchedEllipsoidAxisLength_3 = 9;
 
         /**
+         * Despite its name, this parameter is effectively “{0}”.
+         */
+        public static final short MisnamedParameter_1 = 18;
+
+        /**
          * Formatting of “{0}” is not conform to the format standard.
          */
         public static final short NonConformFormatting_1 = 15;

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] Mon Jul 13 17:26:56 2015
@@ -28,6 +28,7 @@ LocalesDiscarded                = Text w
 OptionalModuleNotFound_1        = Optional module \u201c{0}\u201d requested but not found.
 PropertyHiddenBy_2              = Property \u201c{0}\u201d is hidden by \u201c{1}\u201d.
 MismatchedEllipsoidAxisLength_3 = The \u201c{1}\u201d parameter could have been omitted. But it has been given a value of {2} which does not match the definition of the \u201c{0}\u201d ellipsoid.
+MisnamedParameter_1             = Despite its name, this parameter is effectively \u201c{0}\u201d.
 NonConformFormatting_1          = Formatting of \u201c{0}\u201d is not conform to the format standard.
 NotFormalProjectionParameter_1  = This parameter borrowed from the \u201c{0}\u201d projection is not formally a parameter of this projection.
 UnknownElementsInText           = The text contains unknown elements:

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] Mon Jul 13 17:26:56 2015
@@ -35,6 +35,7 @@ LocalesDiscarded                = Des te
 OptionalModuleNotFound_1        = Le module optionnel \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 demand\u00e9 mais n\u2019a pas \u00e9t\u00e9 trouv\u00e9.
 PropertyHiddenBy_2              = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb est masqu\u00e9e par \u00ab\u202f{1}\u202f\u00bb.
 MismatchedEllipsoidAxisLength_3 = Le param\u00e8tre \u00ab\u202f{1}\u202f\u00bb aurait pu \u00eatre omis. Mais il lui a \u00e9t\u00e9 donn\u00e9 la valeur {2} qui ne correspond pas \u00e0 la d\u00e9finition de l\u2019ellipso\u00efde \u00ab\u202f{0}\u202f\u00bb.
+MisnamedParameter_1             = Malgr\u00e9 son nom, ce param\u00e8tre produit en r\u00e9alit\u00e9 l\u2019effet d\u2019un \u00ab\u202f{0}\u202f\u00bb.
 NonConformFormatting_1          = L\u2019\u00e9criture de \u00ab\u202f{0}\u202f\u00bb n\u2019est pas conforme au format standard.
 NotFormalProjectionParameter_1  = Ce param\u00e8tre emprunt\u00e9 \u00e0 la projection \u00ab\u202f{0}\u202f\u00bb n\u2019est pas formellement un param\u00e8tre de cette projection.
 UnknownElementsInText           = Le texte contient des \u00e9l\u00e9ments inconnus\u00a0:

Modified: sis/branches/JDK6/ide-project/NetBeans/nbproject/genfiles.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/ide-project/NetBeans/nbproject/genfiles.properties?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] Mon Jul 13 17:26:56 2015
@@ -3,6 +3,6 @@
 build.xml.data.CRC32=58e6b21c
 build.xml.script.CRC32=462eaba0
 build.xml.stylesheet.CRC32=28e38971@1.53.1.46
-nbproject/build-impl.xml.data.CRC32=21ae62d4
+nbproject/build-impl.xml.data.CRC32=8bd6b764
 nbproject/build-impl.xml.script.CRC32=fc0a5456
 nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48

Modified: sis/branches/JDK6/ide-project/NetBeans/nbproject/project.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/ide-project/NetBeans/nbproject/project.xml?rev=1690767&r1=1690766&r2=1690767&view=diff
==============================================================================
--- sis/branches/JDK6/ide-project/NetBeans/nbproject/project.xml (original)
+++ sis/branches/JDK6/ide-project/NetBeans/nbproject/project.xml Mon Jul 13 17:26:56 2015
@@ -66,6 +66,7 @@
             <word>deserialization</word>
             <word>deserialized</word>
             <word>endianness</word>
+            <word>excentricity</word>
             <word>geoidal</word>
             <word>hectopascals</word>
             <word>initially</word>



Mime
View raw message