sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1693439 [2/2] - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/projection/ test/java/org/apache/sis/referencing/operation/projection/
Date Thu, 30 Jul 2015 15:27:52 GMT
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=1693439&r1=1693438&r2=1693439&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] Thu Jul 30 15:27:52 2015
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.referencing.operation.projection;
 
-import java.util.Map;
 import java.util.EnumMap;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterDescriptor;
@@ -30,6 +29,7 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.referencing.provider.PolarStereographicB;
 import org.apache.sis.internal.referencing.provider.PolarStereographicC;
 import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Workaround;
@@ -86,12 +86,30 @@ public class PolarStereographic extends
     }
 
     /**
-     * Returns the (<var>role</var> → <var>parameter</var>) associations
for a Polar Stereographic projection.
+     * Creates a Polar Stereographic projection from the given parameters.
+     * The {@code method} argument can be the description of one of the following:
+     *
+     * <ul>
+     *   <li><cite>"Polar Stereographic (Variant A)"</cite>.</li>
+     *   <li><cite>"Polar Stereographic (Variant B)"</cite>.</li>
+     *   <li><cite>"Polar Stereographic (Variant C)"</cite>.</li>
+     * </ul>
      *
-     * @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.
+     * @param method     Description of the projection parameters.
+     * @param parameters The parameter values of the projection to create.
      */
-    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final
byte variant) {
+    public PolarStereographic(final OperationMethod method, final Parameters parameters)
{
+        this(initializer(method, parameters));
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    @SuppressWarnings("fallthrough")
+    @Workaround(library="JDK", version="1.7")
+    private static Initializer initializer(final OperationMethod method, final Parameters
parameters) {
+        final byte variant = getVariant(method);
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new
EnumMap<>(ParameterRole.class);
         ParameterDescriptor<Double> falseEasting  = PolarStereographicA.FALSE_EASTING;
         ParameterDescriptor<Double> falseNorthing = PolarStereographicA.FALSE_NORTHING;
@@ -105,24 +123,7 @@ public class PolarStereographic extends
         roles.put(ParameterRole.CENTRAL_MERIDIAN, (variant == A)
                 ? PolarStereographicA.LONGITUDE_OF_ORIGIN
                 : PolarStereographicB.LONGITUDE_OF_ORIGIN);
-        return roles;
-    }
-
-    /**
-     * Creates a Polar Stereographic projection from the given parameters.
-     * The {@code method} argument can be the description of one of the following:
-     *
-     * <ul>
-     *   <li><cite>"Polar Stereographic (Variant A)"</cite>.</li>
-     *   <li><cite>"Polar Stereographic (Variant B)"</cite>.</li>
-     *   <li><cite>"Polar Stereographic (Variant C)"</cite>.</li>
-     * </ul>
-     *
-     * @param method     Description of the projection parameters.
-     * @param parameters The parameter values of the projection to create.
-     */
-    public PolarStereographic(final OperationMethod method, final Parameters parameters)
{
-        this(method, parameters, getVariant(method));
+        return new Initializer(method, parameters, roles, variant);
     }
 
     /**
@@ -130,8 +131,9 @@ public class PolarStereographic extends
      * ("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));
+    private PolarStereographic(final Initializer initializer) {
+        super(initializer);
+        final byte variant = initializer.variant;
         /*
          * "Standard parallel" and "Latitude of origin" should be mutually exclusive,
          * but this is not a strict requirement for the constructor.
@@ -149,9 +151,9 @@ public class PolarStereographic extends
          */
         double φ0;
         if (variant == A) {
-            φ0 = getAndStore(parameters, PolarStereographicA.LATITUDE_OF_ORIGIN);   // Mandatory
+            φ0 = initializer.getAndStore(PolarStereographicA.LATITUDE_OF_ORIGIN);   // Mandatory
         } else {
-            φ0 = getAndStore(parameters, PolarStereographicA.LATITUDE_OF_ORIGIN,    // Optional
(should not be present)
+            φ0 = initializer.getAndStore(PolarStereographicA.LATITUDE_OF_ORIGIN,    // Optional
(should not be present)
                     (variant == NORTH) ? Latitude.MAX_VALUE :
                     (variant == SOUTH) ? Latitude.MIN_VALUE : Double.NaN);
         }
@@ -161,9 +163,9 @@ public class PolarStereographic extends
         }
         double φ1;
         if (variant == B || variant == C || Double.isNaN(φ0)) {
-            φ1 = getAndStore(parameters, PolarStereographicB.STANDARD_PARALLEL);       
// Mandatory
+            φ1 = initializer.getAndStore(PolarStereographicB.STANDARD_PARALLEL);       
// Mandatory
         } else {
-            φ1 = getAndStore(parameters, PolarStereographicB.STANDARD_PARALLEL, φ0);  
 // Optional
+            φ1 = initializer.getAndStore(PolarStereographicB.STANDARD_PARALLEL, φ0);  
 // Optional
         }
         /*
          * At this point we should ensure that the sign of φ0 is the same than the sign
of φ1,
@@ -183,8 +185,8 @@ public class PolarStereographic extends
             φ1 = -φ1;
         }
         φ1 = toRadians(φ1);  // May be anything in [-π/2 … 0] range.
-        final double ρ;
-        Double ρF = null;    // Actually -ρF (compared to EPSG guide).
+        final DoubleDouble ρ;
+        DoubleDouble ρF = null;    // Actually -ρF (compared to EPSG guide).
         if (abs(φ1 + PI/2) < ANGULAR_TOLERANCE) {
             /*
              * Polar Stereographic (variant A)
@@ -197,8 +199,19 @@ public class PolarStereographic extends
              *    - the 't' factor, because it needs to be computed in the transform(…)
method.
              *
              * In the spherical case, should give ρ == 2.
+             *
+             * Opportunistically use double-double arithmetic below since this is what we
will store in the
+             * (de)normalization matrices. The extra precision that we get is not necessarily
significant,
+             * but we do that more in an attempt to reduce rounding errors in concatenations
of a sequence
+             * of MathTransforms (through matrix multiplications) than for map projection
precisions.
+             * Equivalent Java code for the following double-double arithmetic:
+             *
+             *     ρ = 2 / sqrt(pow(1+excentricity, 1+excentricity) * pow(1-excentricity,
1-excentricity));
              */
-            ρ = 2 / sqrt(pow(1+excentricity, 1+excentricity) * pow(1-excentricity, 1-excentricity));
+            ρ = new DoubleDouble(pow(1+excentricity, 1+excentricity), 0);
+            ρ.multiply          (pow(1-excentricity, 1-excentricity), 0);
+            ρ.sqrt();
+            ρ.inverseDivide(2, 0);
         } else {
             /*
              * Polar Stereographic (variant B or C)
@@ -216,13 +229,21 @@ public class PolarStereographic extends
              *   k₀ = ρ⋅√[…]/2  but we do not need that value.
              *
              * In the spherical case, should give ρ = 1 + sinφ1   (Synder 21-7 and 21-11).
+             *
+             * Equivalent Java code for the following double-double arithmetic:
+             *
+             *     final double mF = cos(φ1) / rν(sinφ1);
+             *     ρ = mF / expOfNorthing(φ1, excentricity*sinφ1);
+             *     if (variant == C) ρF = -mF;
              */
             final double sinφ1 = sin(φ1);
-            final double mF = cos(φ1) / rν(sinφ1);
-            ρ = mF / expOfNorthing(φ1, excentricity*sinφ1);
+            ρ = initializer.rν(sinφ1);
+            ρ.inverseDivide(cos(φ1), 0);
             if (variant == C) {
-                ρF = -mF;
+                ρF = new DoubleDouble(ρ);
+                ρF.negate();
             }
+            ρ.divide(expOfNorthing(φ1, excentricity*sinφ1), 0);
         }
         /*
          * At this point, all parameters have been processed. Now process to their

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1693439&r1=1693438&r2=1693439&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
[UTF-8] Thu Jul 30 15:27:52 2015
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.referencing.operation.projection;
 
-import java.util.Map;
 import java.util.EnumMap;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.referencing.operation.Matrix;
@@ -27,6 +26,7 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Workaround;
 
 import static java.lang.Math.*;
 import static org.apache.sis.math.MathFunctions.asinh;
@@ -72,11 +72,29 @@ public class TransverseMercator extends
     private final double h1, h2, h3, h4, ih1, ih2, ih3, ih4;
 
     /**
-     * Returns the (<var>role</var> → <var>parameter</var>) associations
for a Transverse Mercator projection.
+     * Creates a Transverse Mercator projection from the given parameters.
+     * The {@code method} argument can be the description of one of the following:
+     *
+     * <ul>
+     *   <li><cite>"Transverse Mercator"</cite>.</li>
+     *   <li><cite>"Transverse Mercator (South Orientated)"</cite>.</li>
+     * </ul>
      *
-     * @return The roles map to give to super-class constructor.
+     * @param method     Description of the projection parameters.
+     * @param parameters The parameter values of the projection to create.
      */
-    private static Map<ParameterRole, ParameterDescriptor<Double>> roles(final
boolean isSouth) {
+    public TransverseMercator(final OperationMethod method, final Parameters parameters)
{
+        this(initializer(method, parameters));
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    @SuppressWarnings("fallthrough")
+    @Workaround(library="JDK", version="1.7")
+    private static Initializer initializer(final OperationMethod method, final Parameters
parameters) {
+        final boolean isSouth = identMatch(method, "(?i).*\\bSouth\\b.*", TransverseMercatorSouth.IDENTIFIER);
         final EnumMap<ParameterRole, ParameterDescriptor<Double>> roles = new
EnumMap<>(ParameterRole.class);
         ParameterRole xOffset = ParameterRole.FALSE_EASTING;
         ParameterRole yOffset = ParameterRole.FALSE_NORTHING;
@@ -88,34 +106,20 @@ public class TransverseMercator extends
         roles.put(ParameterRole.SCALE_FACTOR,     org.apache.sis.internal.referencing.provider.TransverseMercator.SCALE_FACTOR);
         roles.put(xOffset,                        org.apache.sis.internal.referencing.provider.TransverseMercator.FALSE_EASTING);
         roles.put(yOffset,                        org.apache.sis.internal.referencing.provider.TransverseMercator.FALSE_NORTHING);
-        return roles;
+        return new Initializer(method, parameters, roles, isSouth ? (byte) 1 : (byte) 0);
     }
 
     /**
-     * Returns the type of the projection based on the name and identifier of the given operation
method.
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
      */
-    private static boolean isSouth(final OperationMethod method) {
-        return identMatch(method, "(?i).*\\bSouth\\b.*", TransverseMercatorSouth.IDENTIFIER);
-    }
-
-    /**
-     * Creates a Transverse Mercator projection from the given parameters.
-     * The {@code method} argument can be the description of one of the following:
-     *
-     * <ul>
-     *   <li><cite>"Transverse Mercator"</cite>.</li>
-     *   <li><cite>"Transverse Mercator (South Orientated)"</cite>.</li>
-     * </ul>
-     *
-     * @param method     Description of the projection parameters.
-     * @param parameters The parameter values of the projection to create.
-     */
-    public TransverseMercator(final OperationMethod method, final Parameters parameters)
{
-        super(method, parameters, roles(isSouth(method)));
-        final double φ0 = toRadians(getAndStore(parameters,
+    @Workaround(library="JDK", version="1.7")
+    private TransverseMercator(final Initializer initializer) {
+        super(initializer);
+        final double φ0 = toRadians(initializer.getAndStore(
                 org.apache.sis.internal.referencing.provider.TransverseMercator.LATITUDE_OF_ORIGIN));
-        final double rs = parameters.doubleValue(MapProjection.SEMI_MINOR)
-                        / parameters.doubleValue(MapProjection.SEMI_MAJOR);
+        final double rs = initializer.parameters.doubleValue(MapProjection.SEMI_MINOR)
+                        / initializer.parameters.doubleValue(MapProjection.SEMI_MAJOR);
 
         final double n  = (1 - rs) / (1 + rs);       // Rewrite of n = f / (2-f)
         final double n2 = n  * n;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java?rev=1693439&r1=1693438&r2=1693439&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java
[UTF-8] Thu Jul 30 15:27:52 2015
@@ -87,7 +87,7 @@ public final strictfp class LambertConic
         createNormalizedProjection(true, 40);
         assertWktEqualsRegex("\\Q" +
                 "PARAM_MT[“Lambert conic conformal”,\n" +
-                "  PARAMETER[“excentricity”, 0.08181919084262157],\n" +
+                "  PARAMETER[“excentricity”, 0.08181919084262244],\n" +
                 "  PARAMETER[“n”, 0.64278760968653\\E\\d*\\]\\]");  // 0.6427876096865393
in the original test.
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java?rev=1693439&r1=1693438&r2=1693439&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] Thu Jul 30 15:27:52 2015
@@ -75,7 +75,7 @@ public final strictfp class MercatorTest
         createNormalizedProjection(true);
         assertWktEquals(
                 "PARAM_MT[“Mercator”,\n" +
-                "  PARAMETER[“excentricity”, 0.08181919084262157]]");
+                "  PARAMETER[“excentricity”, 0.08181919084262244]]");
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java?rev=1693439&r1=1693438&r2=1693439&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java
[UTF-8] Thu Jul 30 15:27:52 2015
@@ -61,9 +61,9 @@ final strictfp class NoOp extends Confor
      */
     @Workaround(library="JDK", version="1.7")
     private NoOp(final Parameters parameters) {
-        super(new DefaultOperationMethod(
+        super(new Initializer(new DefaultOperationMethod(
                 Collections.singletonMap(DefaultOperationMethod.NAME_KEY, parameters.getDescriptor().getName()),
-                2, 2, parameters.getDescriptor()), parameters, Collections.emptyMap());
+                2, 2, parameters.getDescriptor()), parameters, Collections.emptyMap(), (byte)
0));
     }
 
     /**



Mime
View raw message