Class Formulas
- Since:
- 0.4
- Version:
- 1.3
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final double
Default tolerance threshold for comparing coordinate values in a geographic CRS, assuming that the unit of measurement is decimal degrees and using the standard nautical mile length.static final long
The length of a Julian year in milliseconds.static final double
Default tolerance threshold for comparing coordinate values in a projected CRS, assuming that the unit of measurement is metre.static final double
The maximal longitude value before normalization if a centimetric precision is desired.static final int
Maximum number of iterations for iterative computations.static final double
Default tolerance threshold for comparing coordinate values in temporal CRS, assuming that the unit of measurement is second. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic double
fastHypot
(double x, double y) Returnssqrt(x² + y²)
for coordinate values on an ellipsoid of semi-major axis length of 1.static double
getAuthalicRadius
(double a, double b) Returns the radius of a hypothetical sphere having the same surface than the ellipsoid specified by the given axis length.static double
getAuthalicRadius
(org.opengis.referencing.datum.Ellipsoid ellipsoid) Returns the radius of a hypothetical sphere having the same surface than the given ellipsoid.static double
getInverseFlattening
(double semiMajorAxis, double semiMinorAxis) Computes the inverse flattening factor from the given axis lengths.static double
getRadius
(org.opengis.referencing.datum.Ellipsoid ellipsoid, double φ) Returns the radius at the given latitude.static double
getSemiMinor
(double semiMajorAxis, double inverseFlattening) Computes the semi-minor axis length from the given semi-major axis and inverse flattening factor.static boolean
isPoleToPole
(double ymin, double ymax) Returnstrue
ifymin
is the south pole andymax
is the north pole.static double
radiusOfConformalSphere
(org.opengis.referencing.datum.Ellipsoid ellipsoid, double φ) Returns the radius of the conformal sphere at a given latitude.static double
scaleComparedToEarth
(org.opengis.referencing.datum.Ellipsoid planet) Returns the size of a planet described by the given ellipsoid compared to earth.
-
Field Details
-
LINEAR_TOLERANCE
public static final double LINEAR_TOLERANCEDefault tolerance threshold for comparing coordinate values in a projected CRS, assuming that the unit of measurement is metre. This constant determines also (indirectly) the minimum accuracy of iterative methods in map projections.Maintenance
If this value is modified, then all usages of this constant should be verified. Some usages may need to be compensated. For example,GeodesicsOnEllipsoid
uses a millimetric precision by dividing the tolerance by 10 or more. We way want to keep the same precision there even ifLINEAR_TOLERANCE
was made smaller. -
ANGULAR_TOLERANCE
public static final double ANGULAR_TOLERANCEDefault tolerance threshold for comparing coordinate values in a geographic CRS, assuming that the unit of measurement is decimal degrees and using the standard nautical mile length.For a
LINEAR_TOLERANCE
of 1 centimetre, this is slightly less than 1E-7°. -
TEMPORAL_TOLERANCE
public static final double TEMPORAL_TOLERANCEDefault tolerance threshold for comparing coordinate values in temporal CRS, assuming that the unit of measurement is second. Current value is arbitrary and may change in any future Apache SIS version.- See Also:
-
LONGITUDE_MAX
public static final double LONGITUDE_MAXThe maximal longitude value before normalization if a centimetric precision is desired. This is about 4×10⁸ degrees. -
JULIAN_YEAR_LENGTH
public static final long JULIAN_YEAR_LENGTHThe length of a Julian year in milliseconds. From Wikipedia, "In astronomy, a Julian year (symbol: a) is a unit of measurement of time defined as exactly 365.25 days of 86,400 SI seconds each.". -
MAXIMUM_ITERATIONS
public static final int MAXIMUM_ITERATIONSMaximum number of iterations for iterative computations. Defined in thisFormulas
class as a default value, but some classes may use a derived value (for example twice this amount). This constant is mostly useful for identifying places where iterations occur.Current value has been determined empirically for allowing
GeodesicsOnEllipsoidTest
to pass.- See Also:
-
-
Constructor Details
-
Formulas
private Formulas()Do not allow instantiation of this class.
-
-
Method Details
-
isPoleToPole
public static boolean isPoleToPole(double ymin, double ymax) Returnstrue
ifymin
is the south pole andymax
is the north pole.- Parameters:
ymin
- the minimal latitude to test.ymax
- the maximal latitude to test.- Returns:
true
if the given latitudes are south pole to north pole respectively.
-
scaleComparedToEarth
public static double scaleComparedToEarth(org.opengis.referencing.datum.Ellipsoid planet) Returns the size of a planet described by the given ellipsoid compared to earth. This method returns a ratio of given planet authalic radius compared to WGS84. This can be used for adjustingLINEAR_TOLERANCE
andANGULAR_TOLERANCE
to another planet.- Parameters:
planet
- ellipsoid of the other planet to compare to Earth, ornull
.- Returns:
- ratio of planet authalic radius on WGS84 authalic radius, or
NaN
if the given ellipsoid is null.
-
getAuthalicRadius
public static double getAuthalicRadius(org.opengis.referencing.datum.Ellipsoid ellipsoid) Returns the radius of a hypothetical sphere having the same surface than the given ellipsoid.- Parameters:
ellipsoid
- the ellipsoid for which to get the radius, ornull
.- Returns:
- the authalic radius, or
Double.NaN
if the given ellipsoid is null.
-
getAuthalicRadius
public static double getAuthalicRadius(double a, double b) Returns the radius of a hypothetical sphere having the same surface than the ellipsoid specified by the given axis length.- Parameters:
a
- the semi-major axis length.b
- the semi-minor axis length.- Returns:
- the radius of a sphere having the same surface than the specified ellipsoid.
- See Also:
-
radiusOfConformalSphere
public static double radiusOfConformalSphere(org.opengis.referencing.datum.Ellipsoid ellipsoid, double φ) Returns the radius of the conformal sphere at a given latitude. The radius of conformal sphere is computed as below:Rc = √(1 – ℯ²) / (1 – ℯ²sin²φ) where ℯ² = 1 - (b/a)²
This is a function of latitude and therefore not constant.- Parameters:
ellipsoid
- the ellipsoid for which to compute the radius of conformal sphere.\u03c6
- the latitude in radians where to compute the radius of conformal sphere.- Returns:
- radius of the conformal sphere at latitude φ.
-
getRadius
public static double getRadius(org.opengis.referencing.datum.Ellipsoid ellipsoid, double φ) Returns the radius at the given latitude.- Parameters:
ellipsoid
- the ellipsoid for which to compute the radius.\u03c6
- the latitude in radians where to compute the radius.- Returns:
- radius at latitude φ.
-
getSemiMinor
public static double getSemiMinor(double semiMajorAxis, double inverseFlattening) Computes the semi-minor axis length from the given semi-major axis and inverse flattening factor.- Parameters:
semiMajorAxis
- the semi-major axis length.inverseFlattening
- the inverse flattening factor.- Returns:
- the semi-minor axis length.
-
getInverseFlattening
public static double getInverseFlattening(double semiMajorAxis, double semiMinorAxis) Computes the inverse flattening factor from the given axis lengths.- Parameters:
semiMajorAxis
- the semi-major axis length.semiMinorAxis
- the semi-minor axis length.- Returns:
- the inverse flattening factor.
-
fastHypot
public static double fastHypot(double x, double y) Returnssqrt(x² + y²)
for coordinate values on an ellipsoid of semi-major axis length of 1. This method does not provides the accuracy guarantees offered byMath.hypot(double, double)
. However for values close to 1, this approximation seems to stay within 1 ULP ofMath.hypot(…)
. We tested with random values in ranges up to [-6 … +6].We define this method because
Math.hypot(double, double)
has been measured with JMH as 6 times slower thanMath.sqrt(double)
on Java 14. According posts on internet, the same performance cost is observed in C/C++ too. Despite its cost,hypot(…)
is generally recommended because computing a hypotenuse from large magnitudes has accuracy problems. But in the context ofNormalizedProjection
where semi-axis lengths are close to 1, input values should be (x,y) coordinates in the [−1 … +1] range. The actual range may be greater (e.g. [−5 … +5]), but it still far from ranges requiring protection against overflow.Caution
We may not need the fullMath.hypot(x,y)
accuracy in the context of map projections on ellipsoids. However, some projection formulas require thatfastHypot(x,y) ≥ max(|x|,|y|)
, otherwise normalizations such asx/hypot(x,y)
could result in values larger than 1, which in turn result inDouble.NaN
when given toMath.asin(double)
. The assumption on x, y andsqrt(x²+y²)
relative magnitude is broken when x=0 and |y| ≤ 1.4914711209038602E-154 or conversely. This method does not check for such cases; it is caller responsibility to add this check is necessary, for example as below: According JMH, above check is 1.65 time slower thanfastHypot
without checks. We define thisfastHypot(…)
method for tracing wheresqrt(x² + y²)
is used, so we can verify if it is used in context where the inaccuracy is acceptable.When to use
We reserve this method to ellipsoidal formulas where approximations are used anyway. Implementations using exact formulas, such as spherical formulas, should useMath.hypot(double, double)
for its accuracy.- Parameters:
x
- one side of the triangle. Should be approximately in the [-1 … +1] range.y
- other side of the triangle. Should be approximately in the [-1 … +1] range.- Returns:
- hypotenuse, not smaller than
max(|x|,|y|)
unless the values are less than 1.5E-154. - See Also:
-