You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/07/30 17:27:52 UTC
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/
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));
}
/**