sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1691751 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/operation/projection/ test/java/org/apache/sis/referencing/operation/projection/ test/ja...
Date Sat, 18 Jul 2015 16:35:55 GMT
Author: desruisseaux
Date: Sat Jul 18 16:35:54 2015
New Revision: 1691751

URL: http://svn.apache.org/r1691751
Log:
Fix the PolarStereographic projection (tests pass).
Rearrange Mercator and LambertConformal code in order to have a consistent pattern accross all our projection implementations.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/PolarStereographicTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -45,6 +45,12 @@ public final class PolarStereographicB e
     public static final String IDENTIFIER = "9829";
 
     /**
+     * The operation parameter descriptor for the <cite>Longitude of origin</cite> (λ₀) parameter value.
+     * Valid values range is [-180 … 180]° and default value is 0°.
+     */
+    public static final ParameterDescriptor<Double> LONGITUDE_OF_ORIGIN;
+
+    /**
      * The operation parameter descriptor for the <cite>Latitude of standard parallel</cite> (φ₁) parameter value.
      * Valid values are -90° or 90°.
      */
@@ -67,6 +73,10 @@ public final class PolarStereographicB e
     static final ParameterDescriptorGroup PARAMETERS;
     static {
         final ParameterBuilder builder = builder();
+        LONGITUDE_OF_ORIGIN = createLongitude(
+                exceptEPSG(PolarStereographicA.LONGITUDE_OF_ORIGIN,
+                builder.addIdentifier("8833").addName("Longitude of origin").setDeprecated(false)));
+
         STANDARD_PARALLEL = createMandatoryLatitude(builder
                 .addIdentifier("8832").addName("Latitude of standard parallel")
                 .addName(sameNameAs(Citations.OGC, Mercator2SP.STANDARD_PARALLEL)));
@@ -75,10 +85,6 @@ public final class PolarStereographicB e
                 .addNamesAndIdentifiers(Mercator2SP.SCALE_FACTOR)
                 .setRemarks(notFormalParameter("Polar Stereographic (variant A)")).setDeprecated(true));
 
-        final ParameterDescriptor<Double> longitudeOfOrigin = createLongitude(
-                exceptEPSG(PolarStereographicA.LONGITUDE_OF_ORIGIN,
-                builder.addIdentifier("8833").addName("Longitude of origin").setDeprecated(false)));
-
         PARAMETERS = builder
             .addIdentifier(IDENTIFIER)
             .addName("Polar Stereographic (variant B)")
@@ -89,7 +95,7 @@ public final class PolarStereographicB e
             .addIdentifier(Citations.S57, "11")
             .createGroupForMapProjection(
                     STANDARD_PARALLEL,
-                    longitudeOfOrigin,
+                    LONGITUDE_OF_ORIGIN,
                     SCALE_FACTOR,       // Not formally a parameter of this projection.
                     FALSE_EASTING,
                     FALSE_NORTHING);

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -185,10 +185,14 @@ abstract class ConformalProjection exten
      */
     final double φ(final double expOfSouthing) throws ProjectionException {
         /*
-         * Get a first approximation of φ. The result below is exact if the ellipsoid is actually a sphere.
-         * But if the excentricity is different than 0, then we will need to add a correction.
+         * 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
+         * need to add a correction.
+         *
+         * Note that the φ value computed by the line below is called χ in EPSG guide.
+         * We name it φ in our code because we will modify that value in-place in order to get φ.
          */
-        double φ = (PI/2) - 2*atan(expOfSouthing);          // Snyder (7-11)
+        double φ = (PI/2) - 2*atan(expOfSouthing);          // at this point == χ
         /*
          * Add a correction for the flattened shape of the Earth. The correction can be represented by an
          * infinite series. Here, we apply only the first 4 terms. Those terms are given by §1.3.3 in the

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -18,9 +18,12 @@ package org.apache.sis.referencing.opera
 
 import java.util.Map;
 import java.util.EnumMap;
+import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.measure.Latitude;
@@ -71,16 +74,32 @@ public class LambertConformal extends Co
     private static final long serialVersionUID = 2067358524298002016L;
 
     /**
-     * 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.
+     * Codes for variants of Lambert Conical Conformal projection. Those variants modify the way the projections are
+     * constructed (e.g. in the way parameters are interpreted), but formulas are basically the same after construction.
+     * Those variants are not exactly the same than variants 1SP and 2SP used by EPSG, but they are closely related.
      *
-     * <p>Codes for SP1 case must be odd, and codes for SP2 case must be even.</p>
+     * <p>We do not provide such codes in public API because they duplicate the functionality of
+     * {@link OperationMethod} instances. We use them only for constructors convenience.</p>
      *
-     * @see #getType(ParameterDescriptorGroup)
+     * <p><b>CONVENTION:</b> Codes for SP1 case must be odd, and codes for SP2 case must be even.
+     *
+     * @see #getVariant(ParameterDescriptorGroup)
      */
-    private static final byte SP1  = 1,   SP2      = 2,
-                              WEST = 3,   BELGIUM  = 4,
-                                          MICHIGAN = 6;
+    private static final byte SP1  = 1,  WEST    = 3,                   // Must be odd
+                              SP2  = 2,  BELGIUM = 4,  MICHIGAN = 6;    // Must be even
+
+    /**
+     * Returns the type of the projection based on the name and identifier of the given parameter group.
+     * If this method can not identify the type, then the parameters should be considered as a 2SP case.
+     */
+    private static byte getVariant(final ParameterDescriptorGroup parameters) {
+        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.
+    }
 
     /**
      * Constant for the Belgium 2SP case. This is 29.2985 seconds, given here in radians.
@@ -95,13 +114,13 @@ public class LambertConformal extends Co
     final double n;
 
     /**
-     * Returns the (<var>role</var> → <var>parameter</var>) associations for a Lambert projection of the given type.
+     * Returns the (<var>role</var> → <var>parameter</var>) associations for a Lambert projection of the given variant.
      *
-     * @param  type One of {@link #SP1}, {@link #SP2}, {@link #WEST}, {@link #BELGIUM} and {@link #MICHIGAN} constants.
+     * @param  variant 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) {
+    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final byte variant) {
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(ParameterRole.class);
         /*
          * "Scale factor" is not formally a "Lambert Conformal (2SP)" argument, but we accept it
@@ -109,7 +128,7 @@ public class LambertConformal extends Co
          */
         ParameterDescriptor<Double> scaleFactor = LambertConformal1SP.SCALE_FACTOR;
         ParameterRole eastingDirection = ParameterRole.FALSE_EASTING;
-        switch (type) {
+        switch (variant) {
             case WEST: {
                 /*
                  * For "Lambert Conic Conformal (West Orientated)" projection, the "false easting" parameter is
@@ -135,7 +154,7 @@ public class LambertConformal extends Co
                 roles.put(ParameterRole.CENTRAL_MERIDIAN, LambertConformal2SP.LONGITUDE_OF_FALSE_ORIGIN);
                 break;
             }
-            default: throw new AssertionError(type);
+            default: throw new AssertionError(variant);
         }
         roles.put(ParameterRole.SCALE_FACTOR, scaleFactor);
         return roles;
@@ -157,7 +176,7 @@ public class LambertConformal extends Co
      * @param parameters The parameter values of the projection to create.
      */
     public LambertConformal(final OperationMethod method, final Parameters parameters) {
-        this(method, parameters, getType(parameters.getDescriptor()));
+        this(method, parameters, getVariant(parameters.getDescriptor()));
     }
 
     /**
@@ -246,13 +265,17 @@ public class LambertConformal extends Co
             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".
+         * Compute the radius of the parallel of latitude of the false origin.
+         * This is related to the "ρ0" term in Snyder. From EPG guide:
+         *
+         *    r = a⋅F⋅tⁿ     where (in our case) a=1 and t is our 'expOfNorthing' function.
+         *
+         * EPSG uses this term in the computation of  y = FN + rF – r⋅cos(θ).
          */
-        final DoubleDouble r0 = new DoubleDouble();    // Initialized to zero.
+        final DoubleDouble rF = new DoubleDouble();    // Initialized to zero.
         if (φ0 != copySign(PI/2, -n)) {    // For avoiding the rounding error documented in expOfNorthing(+π/2).
-            r0.value = pow(expOfNorthing(φ0, excentricity*sin(φ0)), n);
-            r0.multiply(F);
+            rF.value = pow(expOfNorthing(φ0, excentricity*sin(φ0)), n);
+            rF.multiply(F);
         }
         /*
          * At this point, all parameters have been processed. Now store
@@ -280,7 +303,7 @@ public class LambertConformal extends Co
         final MatrixSIS denormalize = context.getMatrix(false);
         denormalize.convertBefore(0, F, null);
         F.negate();
-        denormalize.convertBefore(1, F, r0);
+        denormalize.convertBefore(1, F, rF);
     }
 
     /**
@@ -292,16 +315,24 @@ public class LambertConformal extends Co
     }
 
     /**
-     * Returns the type of the projection based on the name and identifier of the given parameter group.
-     * If this method can not identify the type, then the parameters should be considered as a 2SP case.
+     * Returns the sequence of <cite>normalization</cite> → {@code this} → <cite>denormalization</cite> transforms
+     * as a whole. The transform returned by this method except (<var>longitude</var>, <var>latitude</var>)
+     * coordinates in <em>degrees</em> and returns (<var>x</var>,<var>y</var>) coordinates in <em>metres</em>.
+     *
+     * <p>The non-linear part of the returned transform will be {@code this} transform, except if the ellipsoid
+     * is spherical. In the later case, {@code this} transform will be replaced by a simplified implementation.</p>
+     *
+     * @param  factory The factory to use for creating the transform.
+     * @return The map projection from (λ,φ) to (<var>x</var>,<var>y</var>) coordinates.
+     * @throws FactoryException if an error occurred while creating a transform.
      */
-    private static byte getType(final ParameterDescriptorGroup parameters) {
-        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.
+    @Override
+    public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
+        LambertConformal kernel = this;
+        if (excentricity == 0) {
+            kernel = new Spherical(this);
+        }
+        return context.completeTransform(factory, kernel);
     }
 
     /**
@@ -383,8 +414,8 @@ public class LambertConformal extends Co
         final double x = ρ * sinθ;
         final double y = ρ * cosθ;
         if (dstPts != null) {
-            dstPts[dstOff    ] = x;
-            dstPts[dstOff + 1] = y;
+            dstPts[dstOff  ] = x;
+            dstPts[dstOff+1] = y;
         }
         if (!derivate) {
             return null;
@@ -412,15 +443,15 @@ public class LambertConformal extends Co
                                     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
          * linear operations applied after the last non-linear one moved to the inverse of the "normalize" transform.
          */
-        dstPts[dstOff  ] = atan2(x, y);  // Really (x,y), not (y,x)
-        dstPts[dstOff+1] = φ(pow(hypot(x, y), -1/n));
+        dstPts[dstOff  ] = atan2(x, y);                 // Really (x,y), not (y,x)
+        dstPts[dstOff+1] = -φ(pow(hypot(x, y), 1/n));   // Equivalent to φ(pow(hypot(x,y), -1/n)) but more accurate for n>0.
     }
 
 
@@ -475,8 +506,8 @@ public class LambertConformal extends Co
                                 final double[] dstPts, final int dstOff,
                                 final boolean derivate) throws ProjectionException
         {
-            final double θ    = srcPts[srcOff];         // θ = λ⋅n
-            final double φ    = srcPts[srcOff + 1];     // Sign may be reversed
+            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(θ);
@@ -505,8 +536,8 @@ public class LambertConformal extends Co
             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;
         }
@@ -523,10 +554,10 @@ public class LambertConformal extends Co
             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 = PI/2 - 2*atan(pow(1/ρ, 1/n));
             assert checkInverseTransform(srcPts, srcOff, dstPts, dstOff, x, y);
-            dstPts[dstOff    ] = x;
-            dstPts[dstOff + 1] = y;
+            dstPts[dstOff  ] = x;
+            dstPts[dstOff+1] = y;
         }
 
         /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -83,16 +83,31 @@ public class Mercator extends ConformalP
     private static final long serialVersionUID = 2564172914329253286L;
 
     /**
-     * Codes for special kinds of Mercator 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.
+     * Codes for variants of Mercator projection. Those variants modify the way the projections are constructed
+     * (e.g. in the way parameters are interpreted), but formulas are basically the same after construction.
+     * Those variants are not exactly the same than variants A, B and C used by EPSG, but they are related.
      *
-     * <p><b>CONVENTION:</b> Spherical cases must be odd, all other cases must be even. This allow us to perform
-     * quick checks for all spherical cases using {@code if ((type & SPHERICAL) != 0)}.</p>
+     * <p>We do not provide such codes in public API because they duplicate the functionality of
+     * {@link OperationMethod} instances. We use them only for constructors convenience.</p>
      *
-     * @see #getType(ParameterDescriptorGroup)
+     * <p><b>CONVENTION:</b> <strong>Spherical cases must be odd, all other cases must be even.</strong>
+     * This allow us to perform quick checks for all spherical cases using {@code if ((type & SPHERICAL) != 0)}.</p>
+     *
+     * @see #getVariant(ParameterDescriptorGroup)
      */
-    static final byte SPHERICAL = 1, PSEUDO = 3,    // Must be odd and SPHERICAL must be 1.
-                      REGIONAL  = 2, MILLER = 4;    // Must be even.
+    private static final byte SPHERICAL = 1, PSEUDO = 3,    // Must be odd and SPHERICAL must be 1.
+                              REGIONAL  = 2, MILLER = 4;    // Must be even.
+
+    /**
+     * Returns the variant of the projection based on the name and identifier of the given parameter group.
+     */
+    private static byte getVariant(final ParameterDescriptorGroup parameters) {
+        if (identMatch(parameters, "(?i).*\\bvariant\\s*C\\b.*", RegionalMercator .IDENTIFIER)) return REGIONAL;
+        if (identMatch(parameters, "(?i).*\\bSpherical\\b.*",    MercatorSpherical.IDENTIFIER)) return SPHERICAL;
+        if (identMatch(parameters, "(?i).*\\bPseudo.*",          PseudoMercator   .IDENTIFIER)) return PSEUDO;
+        if (identMatch(parameters, "(?i).*\\bMiller.*",          null))                         return MILLER;
+        return 0;
+    }
 
     /**
      * The type of Mercator projection. Possible values are:
@@ -106,18 +121,18 @@ public class Mercator extends ConformalP
      *
      * Other cases may be added in the future.
      *
-     * @see #getType(ParameterDescriptorGroup)
+     * @see #getVariant(ParameterDescriptorGroup)
      */
-    final byte type;
+    private final byte variant;
 
     /**
-     * Returns the (<var>role</var> → <var>parameter</var>) associations for a Mercator projection of the given type.
+     * Returns the (<var>role</var> → <var>parameter</var>) associations for a Mercator projection of the given variant.
      *
-     * @param  type One of {@link #REGIONAL}, {@link #SPHERICAL}, {@link #PSEUDO} or {@link #MILLER} constants.
+     * @param  variant One of {@link #REGIONAL}, {@link #SPHERICAL}, {@link #PSEUDO} or {@link #MILLER} constants.
      * @return The roles map to give to super-class constructor.
      */
     @SuppressWarnings("fallthrough")
-    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final byte type) {
+    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final byte variant) {
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(ParameterRole.class);
         /*
          * "Longitude of origin" is a parameter of all Mercator projections, but is intentionally omitted from
@@ -126,7 +141,7 @@ public class Mercator extends ConformalP
          * since it may be used in some Well Known Text (WKT).
          */
         roles.put(ParameterRole.SCALE_FACTOR, Mercator1SP.SCALE_FACTOR);
-        switch (type) {
+        switch (variant) {
             case REGIONAL: {
                 roles.put(ParameterRole.FALSE_EASTING,  RegionalMercator.EASTING_AT_FALSE_ORIGIN);
                 roles.put(ParameterRole.FALSE_NORTHING, RegionalMercator.NORTHING_AT_FALSE_ORIGIN);
@@ -177,7 +192,7 @@ public class Mercator extends ConformalP
      * @param parameters The parameter values of the projection to create.
      */
     public Mercator(final OperationMethod method, final Parameters parameters) {
-        this(method, parameters, getType(parameters.getDescriptor()));
+        this(method, parameters, getVariant(parameters.getDescriptor()));
     }
 
     /**
@@ -185,9 +200,9 @@ public class Mercator extends ConformalP
      * ("Relax constraint on placement of this()/super() call in constructors").
      */
     @Workaround(library="JDK", version="1.7")
-    private Mercator(final OperationMethod method, final Parameters parameters, final byte type) {
-        super(method, parameters, roles(type));
-        this.type = type;
+    private Mercator(final OperationMethod method, final Parameters parameters, final byte variant) {
+        super(method, parameters, roles(variant));
+        this.variant = variant;
         /*
          * The "Longitude of natural origin" parameter is found in all Mercator projections and is mandatory.
          * Since this is usually the Greenwich meridian, the default value is 0°. We keep the value in degrees
@@ -206,7 +221,7 @@ public class Mercator extends ConformalP
          * "Latitude of origin" can not have a non-zero value, if it still have non-zero value we will process as
          * for "Latitude of false origin".
          */
-        final double φ0 = toRadians(getAndStore(parameters, (type == REGIONAL)
+        final double φ0 = toRadians(getAndStore(parameters, (variant == REGIONAL)
                 ? RegionalMercator.LATITUDE_OF_FALSE_ORIGIN : Mercator1SP.LATITUDE_OF_ORIGIN));
         /*
          * In theory, the "Latitude of 1st standard parallel" and the "Scale factor at natural origin" parameters
@@ -240,7 +255,7 @@ public class Mercator extends ConformalP
         if (φ0 != 0) {
             denormalize.convertBefore(1, null, new DoubleDouble(-log(expOfNorthing(φ0, excentricity * sin(φ0)))));
         }
-        if (type == MILLER) {
+        if (variant == MILLER) {
               normalize.convertBefore(1, new DoubleDouble(0.80), null);
             denormalize.convertBefore(1, new DoubleDouble(1.25), null);
         }
@@ -279,18 +294,7 @@ public class Mercator extends ConformalP
      */
     Mercator(final Mercator other) {
         super(other);
-        type = other.type;
-    }
-
-    /**
-     * Returns the type of the projection based on the name and identifier of the given parameter group.
-     */
-    private static byte getType(final ParameterDescriptorGroup parameters) {
-        if (identMatch(parameters, "(?i).*\\bvariant\\s*C\\b.*", RegionalMercator .IDENTIFIER)) return REGIONAL;
-        if (identMatch(parameters, "(?i).*\\bSpherical\\b.*",    MercatorSpherical.IDENTIFIER)) return SPHERICAL;
-        if (identMatch(parameters, "(?i).*\\bPseudo.*",          PseudoMercator   .IDENTIFIER)) return PSEUDO;
-        if (identMatch(parameters, "(?i).*\\bMiller.*",          null))                         return MILLER;
-        return 0;
+        variant = other.variant;
     }
 
     /**
@@ -308,7 +312,7 @@ public class Mercator extends ConformalP
     @Override
     public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
         Mercator kernel = this;
-        if ((type & SPHERICAL) != 0 || excentricity == 0) {
+        if ((variant & SPHERICAL) != 0 || excentricity == 0) {
             kernel = new Spherical(this);
         }
         return context.completeTransform(factory, kernel);
@@ -328,8 +332,8 @@ public class Mercator extends ConformalP
                             final double[] dstPts, final int dstOff,
                             final boolean derivate) throws ProjectionException
     {
-        final double λ    = srcPts[srcOff];
-        final double φ    = srcPts[srcOff + 1];
+        final double λ    = srcPts[srcOff  ];
+        final double φ    = srcPts[srcOff+1];
         final double sinφ = sin(φ);
         if (dstPts != null) {
             /*
@@ -350,7 +354,7 @@ public class Mercator extends ConformalP
                     y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY : NaN, φ);
                 }
             }
-            dstPts[dstOff]   = λ;
+            dstPts[dstOff  ] = λ;   // Scale will be applied by the denormalization matrix.
             dstPts[dstOff+1] = y;
         }
         /*

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -18,10 +18,13 @@ package org.apache.sis.referencing.opera
 
 import java.util.Map;
 import java.util.EnumMap;
+import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.OperationMethod;
+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.internal.referencing.provider.PolarStereographicA;
@@ -29,6 +32,7 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Workaround;
 import org.apache.sis.measure.Latitude;
 
 import static java.lang.Math.*;
@@ -56,40 +60,48 @@ public class PolarStereographic extends
     private static final long serialVersionUID = -6635298308431138524L;
 
     /**
-     * Codes for variants.
+     * Codes for variants of Polar Stereographic projection. Those variants modify the way the projections are
+     * constructed (e.g. in the way parameters are interpreted), but formulas are basically the same after construction.
+     * Those variants are not exactly the same than variants A, B and C used by EPSG, but they are closely related.
+     *
+     * <p>We do not provide such codes in public API because they duplicate the functionality of
+     * {@link OperationMethod} instances. We use them only for constructors convenience.</p>
      *
      * @see #getVariant(ParameterDescriptorGroup)
      */
     private static final byte A = 1, B = 2, C = 3, NORTH = 4, SOUTH = 5;
 
     /**
+     * Returns the type of the projection based on the name and identifier of the given parameter group.
+     * If this method can not identify the type, then the parameters should be considered as a 2SP case.
+     */
+    private static byte getVariant(final ParameterDescriptorGroup parameters) {
+        if (identMatch(parameters, "(?i).*\\bvariant\\s*A\\b.*",  PolarStereographicA.IDENTIFIER)) return A;
+        if (identMatch(parameters, "(?i).*\\bvariant\\s*B\\b.*",  PolarStereographicB.IDENTIFIER)) return B;
+//      if (identMatch(parameters, "(?i).*\\bvariant\\s*C\\b.*",  PolarStereographicC.IDENTIFIER)) return C;
+        if (identMatch(parameters, "(?i).*\\bNorth\\b.*",         null)) return NORTH;
+        if (identMatch(parameters, "(?i).*\\bSouth\\b.*",         null)) return SOUTH;
+        return 0; // Unidentified case, to be considered as variant A.
+    }
+
+    /**
      * Returns the (<var>role</var> → <var>parameter</var>) associations for a Polar Stereographic projection.
      *
+     * @param  variant One of {@link #A}, {@link #B}, {@link #C}, {@link #NORTH} or {@link #SOUTH} constants.
      * @return The roles map to give to super-class constructor.
      */
-    private static Map<ParameterRole, ParameterDescriptor<Double>> roles() {
+    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final byte variant) {
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(ParameterRole.class);
-        roles.put(ParameterRole.CENTRAL_MERIDIAN, PolarStereographicA.LONGITUDE_OF_ORIGIN);
         roles.put(ParameterRole.SCALE_FACTOR,     PolarStereographicA.SCALE_FACTOR);
         roles.put(ParameterRole.FALSE_EASTING,    PolarStereographicA.FALSE_EASTING);
         roles.put(ParameterRole.FALSE_NORTHING,   PolarStereographicA.FALSE_NORTHING);
+        roles.put(ParameterRole.CENTRAL_MERIDIAN, (variant == B)
+                ? PolarStereographicB.LONGITUDE_OF_ORIGIN
+                : PolarStereographicA.LONGITUDE_OF_ORIGIN);
         return roles;
     }
 
     /**
-     * Returns the type of the projection based on the name and identifier of the given parameter group.
-     * If this method can not identify the type, then the parameters should be considered as a 2SP case.
-     */
-    private static byte getVariant(final ParameterDescriptorGroup parameters) {
-        if (identMatch(parameters, "(?i).*\\bA\\b.*",  PolarStereographicA.IDENTIFIER)) return A;
-        if (identMatch(parameters, "(?i).*\\bB\\b.*",  PolarStereographicB.IDENTIFIER)) return B;
-//      if (identMatch(parameters, "(?i).*\\bC\\b.*",  PolarStereographicC.IDENTIFIER)) return C;
-        if (identMatch(parameters, "(?i).*\\bNorth\\b.*",  null)) return NORTH;
-        if (identMatch(parameters, "(?i).*\\bSouth\\b.*",  null)) return SOUTH;
-        return 0; // Unidentified case, to be considered as variant A.
-    }
-
-    /**
      * Creates a Polar Stereographic projection from the given parameters.
      * The {@code method} argument can be the description of one of the following:
      *
@@ -103,8 +115,16 @@ public class PolarStereographic extends
      * @param parameters The parameter values of the projection to create.
      */
     public PolarStereographic(final OperationMethod method, final Parameters parameters) {
-        super(method, parameters, roles());
-        final byte variant = getVariant(parameters.getDescriptor());
+        this(method, parameters, getVariant(parameters.getDescriptor()));
+    }
+
+    /**
+     * 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 PolarStereographic(final OperationMethod method, final Parameters parameters, final byte variant) {
+        super(method, parameters, roles(variant));
         /*
          * "Standard parallel" and "Latitude of origin" should be mutually exclusive,
          * but this is not a strict requirement for the constructor.
@@ -145,9 +165,10 @@ public class PolarStereographic extends
          * It may be possible to specify φ0 and φ1 if the caller used his own parameter descriptor,
          * in which case maybe he really wanted different sign (e.g. for testing purpose).
          */
-        φ1 = toRadians(abs(φ1));  // May be anything in [0 … π/2] range.
+        φ1 = toRadians(φ1);  // May be anything in [-π/2 … π/2] range.
         final double ρ;
-        if (abs(φ1 - PI/2) < ANGULAR_TOLERANCE) {
+        Double ρF = null;    // Actually -ρF (compared to EPSG guide).
+        if (abs(abs(φ1) - PI/2) < ANGULAR_TOLERANCE) {
             /*
              * Polar Stereographic (variant A)
              * True scale at pole (part of Synder 21-33). From EPSG guide (April 2015) §1.3.7.2:
@@ -163,11 +184,28 @@ public class PolarStereographic extends
             ρ = 2 / sqrt(pow(1+excentricity, 1+excentricity) * pow(1-excentricity, 1-excentricity));
         } else {
             /*
-             * Derived from Synder 21-32 and 21-33.
+             * Polar Stereographic (variant B or C)
+             * Derived from Synder 21-32 and 21-33. From EPSG guide (April 2015) §1.3.7.2:
+             *
+             *   tF = tan(π/4 + φ1/2) / {[(1 + ℯ⋅sinφ1) / (1 – ℯ⋅sinφ1)]^(ℯ/2)}
+             *   mF = cosφ1 / √[1 – ℯ²⋅sin²φ1]
+             *   k₀ = mF⋅√[(1+ℯ)^(1+ℯ) ⋅ (1–ℯ)^(1–ℯ)] / (2⋅tF)
+             *
+             * In our case:
+             *
+             *   tF = expOfNorthing(φ1, ℯ⋅sinφ1)
+             *   mF = cos(φ1) / rν(sinφ1)
+             *   ρ  = mF / tF
+             *   k₀ = ρ⋅√[…]/2  but we do not need that value.
+             *
              * In the spherical case, should give ρ = 1 + sinφ1   (Synder 21-7 and 21-11).
              */
             final double sinφ1 = sin(φ1);
-            ρ = cos(φ1) * expOfNorthing(φ1, sinφ1) / rν(sinφ1);
+            final double mF = cos(φ1) / rν(sinφ1);
+            ρ = mF / expOfNorthing(φ1, excentricity*sinφ1);
+            if (variant == C) {
+                ρF = -mF;
+            }
         }
         /*
          * At this point, all parameters have been processed. Now process to their
@@ -175,14 +213,42 @@ public class PolarStereographic extends
          */
         final MatrixSIS denormalize = context.getMatrix(false);
         denormalize.convertBefore(0, ρ, null);
-        denormalize.convertBefore(1, ρ, null);
-        if (φ0 >= 0) {  // North pole.
+        denormalize.convertBefore(1, ρ, ρF);
+        if (φ1 >= 0) {  // North pole.
             context.getMatrix(true).convertAfter(1, -1, null);
             denormalize.convertBefore(1, -1, null);
         }
     }
 
     /**
+     * Creates a new projection initialized to the same parameters than the given one.
+     */
+    PolarStereographic(final PolarStereographic other) {
+        super(other);
+    }
+
+    /**
+     * Returns the sequence of <cite>normalization</cite> → {@code this} → <cite>denormalization</cite> transforms
+     * as a whole. The transform returned by this method except (<var>longitude</var>, <var>latitude</var>)
+     * coordinates in <em>degrees</em> and returns (<var>x</var>,<var>y</var>) coordinates in <em>metres</em>.
+     *
+     * <p>The non-linear part of the returned transform will be {@code this} transform, except if the ellipsoid
+     * is spherical. In the later case, {@code this} transform will be replaced by a simplified implementation.</p>
+     *
+     * @param  factory The factory to use for creating the transform.
+     * @return The map projection from (λ,φ) to (<var>x</var>,<var>y</var>) coordinates.
+     * @throws FactoryException if an error occurred while creating a transform.
+     */
+    @Override
+    public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
+        PolarStereographic kernel = this;
+        if (excentricity == 0) {
+            kernel = new Spherical(this);
+        }
+        return context.completeTransform(factory, kernel);
+    }
+
+    /**
      * Converts the specified (θ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
      * In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
      *
@@ -206,7 +272,7 @@ public class PolarStereographic extends
         /*
          * From EPSG guide:
          *
-         *    t = tan(π/4 + φ/2) / {[(1+esinφ) / (1–esinφ)]^(e/2)}
+         *    t = tan(π/4 + φ/2) / {[(1 + ℯ⋅sinφ)  /  (1 – ℯ⋅sinφ)]^(ℯ/2)}
          *
          * 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.
@@ -242,6 +308,96 @@ public class PolarStereographic extends
         final double x = srcPts[srcOff  ];
         final double y = srcPts[srcOff+1];
         dstPts[dstOff  ] = atan2(x, y);     // Really (x,y), not (y,x)
-        dstPts[dstOff+1] = φ(hypot(x, y));
+        dstPts[dstOff+1] = -φ(hypot(x, y));
+    }
+
+
+    /**
+     * Provides the transform equations for the spherical case of the polar stereographic projection.
+     *
+     * @author  Gerald Evenden (USGS)
+     * @author  André Gosselin (MPO)
+     * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
+     * @author  Rueben Schulz (UBC)
+     * @since   0.6
+     * @version 0.6
+     * @module
+     */
+    static final class Spherical extends PolarStereographic {
+        /**
+         * For compatibility with different versions during deserialization.
+         */
+        private static final long serialVersionUID = 1655096575897215547L;
+
+        /**
+         * Constructs a new map projection from the parameters of the given projection.
+         *
+         * @param other The other projection (usually ellipsoidal) from which to copy the parameters.
+         */
+        protected Spherical(final PolarStereographic other) {
+            super(other);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Matrix transform(final double[] srcPts, final int srcOff,
+                                final double[] dstPts, final int dstOff,
+                                final boolean derivate) throws ProjectionException
+        {
+            final double θ    = srcPts[srcOff  ];  // θ = λ - λ₀
+            final double φ    = srcPts[srcOff+1];
+            final double sinθ = sin(θ);
+            final double cosθ = cos(θ);
+            final double t    = tan(PI/4 + 0.5*φ);
+            final double x    = t * sinθ;          // Synder 21-5
+            final double y    = t * cosθ;          // Synder 21-6
+            Matrix derivative = null;
+            if (derivate) {
+                final double dt = t / cos(φ);
+                derivative = new Matrix2(y, dt*sinθ,   // ∂x/∂λ , ∂x/∂φ
+                                        -x, dt*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;
+            }
+            return derivative;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected void inverseTransform(final double[] srcPts, final int srcOff,
+                                        final double[] dstPts, final int dstOff)
+                throws ProjectionException
+        {
+            double x = srcPts[srcOff  ];
+            double y = srcPts[srcOff+1];
+            final double ρ = hypot(x, y);
+            x = atan2(x, y);        // Really (x,y), not (y,x)
+            y = 2*atan(ρ) - PI/2;   // (20-14) with φ1=90° and cos(y) = sin(π/2 + y).
+            assert checkInverseTransform(srcPts, srcOff, dstPts, dstOff, x, y);
+            dstPts[dstOff  ] = x;
+            dstPts[dstOff+1] = y;
+        }
+
+        /**
+         * Computes using ellipsoidal formulas and compare with the
+         * result from spherical formulas. Used in assertions only.
+         */
+        private boolean checkInverseTransform(final double[] srcPts, final int srcOff,
+                                              final double[] dstPts, final int dstOff,
+                                              final double λ, final double φ)
+                throws ProjectionException
+        {
+            super.inverseTransform(srcPts, srcOff, dstPts, dstOff);
+            return Assertions.checkInverseTransform(dstPts, dstOff, λ, φ);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/PolarStereographicTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/PolarStereographicTest.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/PolarStereographicTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/PolarStereographicTest.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -19,9 +19,15 @@ package org.apache.sis.referencing.opera
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.provider.PolarStereographicA;
+import org.apache.sis.internal.referencing.provider.PolarStereographicB;
+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.junit.Test;
 
+import static java.lang.StrictMath.*;
+
 
 /**
  * Tests the {@link PolarStereographic} class.
@@ -34,6 +40,54 @@ import org.junit.Test;
 @DependsOn(NormalizedProjectionTest.class)
 public final strictfp class PolarStereographicTest extends MapProjectionTestCase {
     /**
+     * Creates a new instance of {@link PolarStereographic}.
+     *
+     * @param ellipse {@code false} for a sphere, or {@code true} for WGS84 ellipsoid.
+     * @param latitudeOfOrigin The latitude of origin, in decimal degrees.
+     */
+    private void initialize(final boolean ellipse, final double latitudeOfOrigin) {
+        final PolarStereographicA method = new PolarStereographicA();
+        final Parameters parameters = parameters(method, ellipse);
+        parameters.getOrCreate(PolarStereographicA.LATITUDE_OF_ORIGIN).setValue(latitudeOfOrigin);
+        transform = new PolarStereographic(method, parameters);
+        if (!ellipse) {
+            transform = new PolarStereographic.Spherical((PolarStereographic) transform);
+        }
+        tolerance = NORMALIZED_TOLERANCE;
+        validate();
+    }
+
+    /**
+     * Verifies the consistency between spherical and elliptical formulas in the South pole.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    public void testSphericalCaseSouth() throws FactoryException, TransformException {
+        initialize(false, -90);
+        final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres.
+        derivativeDeltas = new double[] {delta, delta};
+        verifyInDomain(CoordinateDomain.GEOGRAPHIC_RADIANS_SOUTH, 56763886);
+    }
+
+    /**
+     * Verifies the consistency between spherical and elliptical formulas in the North pole.
+     * This is the same formulas than the South case, but with the sign of some coefficients negated.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    @DependsOnMethod("testSphericalCaseSouth")
+    public void testSphericalCaseNorth() throws FactoryException, TransformException {
+        initialize(false, 90);
+        final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres.
+        derivativeDeltas = new double[] {delta, delta};
+        verifyInDomain(CoordinateDomain.GEOGRAPHIC_RADIANS_NORTH, 56763886);
+    }
+
+    /**
      * Tests the <cite>Polar Stereographic (variant A)</cite> case (EPSG:9810).
      * This test is defined in GeoAPI conformance test suite.
      *
@@ -43,8 +97,21 @@ public final strictfp class PolarStereog
      * @see org.opengis.test.referencing.ParameterizedTransformTest#testPolarStereographicA()
      */
     @Test
-    @org.junit.Ignore("To debug")
-    public void testTransverseMercator() throws FactoryException, TransformException {
+    public void testPolarStereographicA() throws FactoryException, TransformException {
         createGeoApiTest(new PolarStereographicA()).testPolarStereographicA();
     }
+
+    /**
+     * Tests the <cite>Polar Stereographic (variant B)</cite> case (EPSG:9829).
+     * 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#testPolarStereographicB()
+     */
+    @Test
+    public void testPolarStereographicB() throws FactoryException, TransformException {
+        createGeoApiTest(new PolarStereographicB()).testPolarStereographicB();
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java?rev=1691751&r1=1691750&r2=1691751&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java [UTF-8] Sat Jul 18 16:35:54 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
 import java.util.Random;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
+
 import static java.lang.StrictMath.*;
 import static org.apache.sis.internal.metadata.ReferencingServices.AUTHALIC_RADIUS;
 



Mime
View raw message