Author: desruisseaux
Date: Fri Jul 31 14:09:09 2015
New Revision: 1693603
URL: http://svn.apache.org/r1693603
Log:
Minor consolidation: factor out the computation of semi-minor axis length and
inverse flattening factor, provide some analysis in the comment about the
accuracy.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionParameters.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -125,4 +125,36 @@ public final class Formulas extends Stat
return a;
}
}
+
+ /**
+ * Computes the semi-minor axis length from the given semi-major axis and
inverse flattening factor.
+ *
+ * @param semiMajorAxis The semi-major axis length.
+ * @param inverseFlattening The inverse flattening factor.
+ * @return The semi-minor axis length.
+ */
+ public static double getSemiMinor(final double semiMajorAxis, final double
inverseFlattening) {
+ /*
+ * Note: double-double arithmetic does not increase the accuracy here,
unless the inverse flattening
+ * factor given to this method is very high (i.e. the planet is very
close to a perfect sphere).
+ */
+ return semiMajorAxis * (1 - 1/inverseFlattening);
+ }
+
+ /**
+ * Computes the inverse flattening factor from the given axis lengths.
+ *
+ * @param semiMajorAxis The semi-major axis length.
+ * @param semiMinorAxis The semi-minor axis length.
+ * @return The inverse flattening factor.
+ */
+ public static double getInverseFlattening(final double semiMajorAxis,
final double semiMinorAxis) {
+ /*
+ * Note: double-double arithmetic here sometime change the last digit.
We ignore for now.
+ * We may consider using double-double arithmetic in a future SIS
version, not for more
+ * accurate map projection but rather for being able to find back the
original value after
+ * we convert back and forward betwen inverse flattening and
semi-minor axis length.
+ */
+ return semiMajorAxis / (semiMajorAxis - semiMinorAxis);
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -135,15 +135,15 @@ public abstract class MapProjection exte
*
* @see #createConstant(ParameterBuilder, Double)
*/
- public static void validate(final ParameterDescriptor<Double> descriptor,
final double value)
+ public static void validate(final ParameterDescriptor<? extends Number>
descriptor, final double value)
throws IllegalArgumentException
{
if (Double.isNaN(value) || Double.isInfinite(value)) {
throw new
IllegalArgumentException(Errors.format(Errors.Keys.IllegalParameterValue_2,
descriptor.getName(), value));
}
- final Comparable<Double> min = descriptor.getMinimumValue();
- final Comparable<Double> max = descriptor.getMaximumValue();
+ final Comparable<? extends Number> min = descriptor.getMinimumValue();
+ final Comparable<? extends Number> max = descriptor.getMaximumValue();
if (!Objects.equals(min, max)) {
/*
* RATIONAL: why we do not check the bounds if (min == max):
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -322,8 +322,9 @@ public class DefaultParameterDescriptor<
* or {@code null} if it does not apply or if there is no
restriction.
*/
@Override
+ @SuppressWarnings("ReturnOfCollectionOrArrayField")
public Set<T> getValidValues() {
- return validValues;
+ return validValues; // Null or unmodifiable
}
/**
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionParameters.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionParameters.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionParameters.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionParameters.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -271,7 +271,7 @@ final class MapProjectionParameters exte
if (!Double.isNaN(ivf)) {
final Double a = (Double) semiMajor.getValue();
if (a != null) {
- semiMinor.setValue(a * (1 - 1/ivf), semiMajor.getUnit());
+ semiMinor.setValue(Formulas.getSemiMinor(a, ivf),
semiMajor.getUnit());
}
}
}
@@ -284,8 +284,7 @@ final class MapProjectionParameters exte
public double doubleValue() {
final Double a = (Double) semiMajor.getValue();
if (a != null && semiMinor.getValue() != null) {
- final double b = semiMinor.doubleValue(semiMajor.getUnit());
- return a / (a - b);
+ return Formulas.getInverseFlattening(a,
semiMinor.doubleValue(semiMajor.getUnit()));
}
return Double.NaN;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -296,7 +296,7 @@ public class DefaultEllipsoid extends Ab
return new Sphere(properties, semiMajorAxis, false, unit);
} else {
return new DefaultEllipsoid(properties, semiMajorAxis,
semiMinorAxis,
- semiMajorAxis / (semiMajorAxis - semiMinorAxis), false,
unit);
+ Formulas.getInverseFlattening(semiMajorAxis,
semiMinorAxis), false, unit);
}
}
@@ -320,7 +320,8 @@ public class DefaultEllipsoid extends Ab
return new Sphere(properties, semiMajorAxis, true, unit);
} else {
return new DefaultEllipsoid(properties, semiMajorAxis,
- semiMajorAxis * (1 - 1/inverseFlattening),
inverseFlattening, true, unit);
+ Formulas.getSemiMinor(semiMajorAxis, inverseFlattening),
+ inverseFlattening, true, unit);
}
}
@@ -358,11 +359,11 @@ public class DefaultEllipsoid extends Ab
private void afterUnmarshal() {
if (ivfDefinitive) {
if (semiMinorAxis == 0) {
- semiMinorAxis = semiMajorAxis * (1 - 1/inverseFlattening);
+ semiMinorAxis = Formulas.getSemiMinor(semiMajorAxis,
inverseFlattening);
}
} else {
if (inverseFlattening == 0) {
- inverseFlattening = semiMajorAxis / (semiMajorAxis -
semiMinorAxis);
+ inverseFlattening =
Formulas.getInverseFlattening(semiMajorAxis, semiMinorAxis);
}
}
if (unit == null) {
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -86,7 +86,7 @@ final class Initializer {
* <cite>false easting</cite>, <cite>false northing</cite> and
other values.
*/
Initializer(final OperationMethod method, final Parameters parameters,
- final Map<ParameterRole, ? extends ParameterDescriptor<Double>>
roles,
+ final Map<ParameterRole, ? extends ParameterDescriptor<? extends
Number>> roles,
final byte variant)
{
ensureNonNull("method", method);
@@ -100,8 +100,8 @@ final class Initializer {
* a null value to keys (we are paranoiac...) and because it conflicts
with the "? extends" part of
* in this constructor signature.
*/
- ParameterDescriptor<Double> semiMajor =
roles.get(ParameterRole.SEMI_MAJOR);
- ParameterDescriptor<Double> semiMinor =
roles.get(ParameterRole.SEMI_MINOR);
+ ParameterDescriptor<? extends Number> semiMajor =
roles.get(ParameterRole.SEMI_MAJOR);
+ ParameterDescriptor<? extends Number> semiMinor =
roles.get(ParameterRole.SEMI_MINOR);
if (semiMajor == null) semiMajor = MapProjection.SEMI_MAJOR;
if (semiMinor == null) semiMinor = MapProjection.SEMI_MINOR;
@@ -131,7 +131,7 @@ final class Initializer {
excentricitySquared.value = 1;
excentricitySquared.subtract(rs);
}
- final ParameterDescriptor<Double> radius =
roles.get(ParameterRole.LATITUDE_OF_CONFORMAL_SPHERE_RADIUS);
+ final ParameterDescriptor<? extends Number> radius =
roles.get(ParameterRole.LATITUDE_OF_CONFORMAL_SPHERE_RADIUS);
if (radius != null) {
/*
* EPSG said: R is the radius of the sphere and will normally
be one of the CRS parameters.
@@ -154,7 +154,7 @@ final class Initializer {
}
}
context.normalizeGeographicInputs(λ0);
- final ParameterDescriptor<Double> scaleFactor =
roles.get(ParameterRole.SCALE_FACTOR);
+ final ParameterDescriptor<? extends Number> scaleFactor =
roles.get(ParameterRole.SCALE_FACTOR);
if (scaleFactor != null) {
k.multiply(getAndStore(scaleFactor));
}
@@ -166,7 +166,7 @@ final class Initializer {
/**
* Gets a parameter value identified by the given descriptor and stores it
in the {@link #context}.
* A "contextual parameter" is a parameter that apply to the normalize →
{@code this} → denormalize
- * chain as a whole. It does not really apply to this {@code
NormalizedProjection} instance when taken alone.
+ * chain as a whole. It does not really apply to a {@code
NormalizedProjection} instance taken alone.
*
* <p>This method performs the following actions:</p>
* <ul>
@@ -175,12 +175,12 @@ final class Initializer {
* <li>Store the value only if different than the default value.</li>
* </ul>
*/
- final double getAndStore(final ParameterDescriptor<Double> descriptor) {
+ final double getAndStore(final ParameterDescriptor<? extends Number>
descriptor) {
if (descriptor == null) {
return 0; // Default value for all parameters except scale
factor.
}
final double value = parameters.doubleValue(descriptor); // Apply a
unit conversion if needed.
- final Double defaultValue = descriptor.getDefaultValue();
+ final Number defaultValue = descriptor.getDefaultValue();
if (defaultValue == null || !defaultValue.equals(value)) {
MapProjection.validate(descriptor, value);
context.getOrCreate(descriptor).setValue(value);
@@ -236,15 +236,10 @@ final class Initializer {
t.multiply(t);
t.multiply(excentricitySquared);
- // Save result of ℯ²⋅sin²φ
- final double value = t.value;
- final double error = t.error;
-
- // Compute 1 - above. Since above may be small, this
- // is where double-double arithmetic has more value.
- t.clear();
- t.value = 1;
- t.subtract(value, error);
+ // Compute 1 - ℯ²⋅sin²φ. Since ℯ²⋅sin²φ may be small,
+ // this is where double-double arithmetic has more value.
+ t.negate();
+ t.add(1,0);
return t;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -397,7 +397,7 @@ public abstract class NormalizedProjecti
* <cite>false easting</cite>, <cite>false northing</cite> and
other values.
*/
protected NormalizedProjection(final OperationMethod method, final
Parameters parameters,
- final Map<ParameterRole, ? extends ParameterDescriptor<Double>>
roles)
+ final Map<ParameterRole, ? extends ParameterDescriptor<? extends
Number>> roles)
{
this(new Initializer(method, parameters, roles, (byte) 0));
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java?rev=1693603&r1=1693602&r2=1693603&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
[UTF-8] Fri Jul 31 14:09:09 2015
@@ -78,4 +78,25 @@ public final strictfp class FormulasTest
public void testGetAuthalicRadius() {
assertEquals(ReferencingServices.AUTHALIC_RADIUS,
Formulas.getAuthalicRadius(6378137, 6356752), 0.5);
}
+
+ /**
+ * Tests {@link Formulas#getSemiMinor(double, double)}.
+ */
+ @Test
+ public void testGetSemiMinor() {
+ assertEquals("WGS 84", 6356752.314245179,
Formulas.getSemiMinor(6378137, 298.257223563), 1E-9);
+ assertEquals("International 1924", 6356911.9461279465,
Formulas.getSemiMinor(6378388, 297), 1E-9);
+ assertEquals("Clarke 1858", 20855233, // Unit in feet. Is the
definitive parameter for this ellipsoid.
+ Formulas.getSemiMinor(20926348, 294.26067636926103), 1E-8);
+ }
+
+ /**
+ * Tests {@link Formulas#getInverseFlattening(double, double)}.
+ */
+ @Test
+ public void testGetInverseFlattening() {
+ assertEquals("WGS 84", 298.2572235629972,
Formulas.getInverseFlattening(6378137, 6356752.314245179), 1E-11);
+ assertEquals("International 1924", 297,
Formulas.getInverseFlattening(6378388, 6356911.9461279465), 1E-11);
+ assertEquals("Clarke 1858", 294.26067636926103,
Formulas.getInverseFlattening(20926348, 20855233), 1E-11);
+ }
}