Class ConformalProjection
- All Implemented Interfaces:
Serializable
,Parameterized
,LenientComparable
,org.opengis.referencing.operation.MathTransform
,org.opengis.referencing.operation.MathTransform2D
- Direct Known Subclasses:
LambertConicConformal
,Mercator
,ObliqueMercator
,PolarStereographic
LambertConicConformal
, Mercator
and PolarStereographic
projections.
Those projections have in common the property of being conformal, i.e. they preserve angles locally.
However, we do not put this base class in public API because not all conformal projections extend this base class.
For example, the TransverseMercator
projection, despite being conformal, uses very different formulas.
Note that no projection can be both conformal and equal-area. So the formulas in this class are usually
mutually exclusive with formulas in AuthalicConversion
class (used for equal-area projections).
This base class can be seen as a generalization of Lambert Conic Conformal projection, which includes some other projections like Mercator and Polar Stereographic as special cases. For this base class, the Mercator projection is considered as "a special limiting case of the Lambert Conic Conformal map projection with the equator as the single standard parallel." (Source: §1.3.3 in IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015). Indeed, those two projections have some equation in commons which are provided in this base class.
The Polar Stereographic projection is not documented as a special case of Lambert Conic Conformal,
but the equations in the PolarStereographic.transform(…)
and inverseTransform(…)
methods
appear to be the same with the n factor fixed to 1 or -1, so we leverage the code provided by
this base class. This class hierarchy is only an implementation convenience and not part of public API.
The Transverse Mercator projection is also conformal, but does not use the formulas provided in this class.
It will instead compute the coefficients itself and use its own, more complex, formulas with those coefficients.
However, the formulas provided in this ConformalProjection
class can be seen as a special case of
Transverse Mercator formulas for x = 0.
- Since:
- 0.6
- Version:
- 1.0
-
Nested Class Summary
Nested classes/interfaces inherited from class org.apache.sis.referencing.operation.projection.NormalizedProjection
NormalizedProjection.ParameterRole
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final double
Coefficients of the first terms in the series expansion of the reverse projection.private final double
Coefficients of the first terms in the series expansion of the reverse projection.private final double
Coefficients of the first terms in the series expansion of the reverse projection.private final double
Coefficients of the first terms in the series expansion of the reverse projection.(package private) static final double
The threshold value ofNormalizedProjection.eccentricity
at which we consider the accuracy of the series expansion insufficient.private static final long
For cross-version compatibility.private final boolean
true
if theNormalizedProjection.eccentricity
value is greater than or equals toECCENTRICITY_THRESHOLD
, in which case theφ(double)
method will need to use an iterative method.Fields inherited from class org.apache.sis.referencing.operation.projection.NormalizedProjection
ANGULAR_TOLERANCE, context, eccentricity, eccentricitySquared, ITERATION_TOLERANCE, LARGE_LONGITUDE_LIMIT, MAXIMUM_ITERATIONS, POLAR_AREA_LIMIT
Fields inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform2D
DIMENSION
-
Constructor Summary
ConstructorsConstructorDescriptionCreates a new projection initialized to the values of the given one.ConformalProjection
(Initializer initializer) Creates a new normalized projection from the parameters computed by the given initializer. -
Method Summary
Modifier and TypeMethodDescription(package private) final double
dy_dφ
(double sinφ, double cosφ) Computes the partial derivative of a Mercator projection at the given latitude.(package private) final double
expΨ
(double φ, double ℯsinφ) Computesexp(Ψ)
where Ψ is the isometric latitude.(package private) final double
φ
(double rexpΨ) Computes the latitude for a value closely related to the y value of a Mercator projection.Methods inherited from class org.apache.sis.referencing.operation.projection.NormalizedProjection
completeWithWraparound, computeHashCode, createMapProjection, delegate, equals, getContextualParameters, getInternalParameterNames, getInternalParameterValues, getParameterDescriptors, getParameterValues, getWraparoundLongitude, inverse, inverseTransform, transform, tryConcatenate, tryConcatenate, variant
Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform2D
createTransformedShape, derivative, getSourceDimensions, getTargetDimensions, transform
Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
derivative, equals, formatTo, getDomain, hashCode, isIdentity, transform, transform, transform, transform, transform
Methods inherited from class org.apache.sis.io.wkt.FormattableObject
print, toString, toString, toWKT
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.opengis.referencing.operation.MathTransform
derivative, isIdentity, toWKT, transform, transform, transform, transform, transform
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDFor cross-version compatibility.- See Also:
-
ECCENTRICITY_THRESHOLD
static final double ECCENTRICITY_THRESHOLDThe threshold value ofNormalizedProjection.eccentricity
at which we consider the accuracy of the series expansion insufficient. This threshold is determined empirically with the help of theMercatorMethodComparison
class in the test directory. We choose the value where:- the average error of series expansion become greater than
NormalizedProjection.ITERATION_TOLERANCE
, - the maximal error of series expansion become greater than
NormalizedProjection.ANGULAR_TOLERANCE
.
- See Also:
- the average error of series expansion become greater than
-
useIterations
private final boolean useIterationstrue
if theNormalizedProjection.eccentricity
value is greater than or equals toECCENTRICITY_THRESHOLD
, in which case theφ(double)
method will need to use an iterative method. -
c2χ
private final double c2χCoefficients of the first terms in the series expansion of the reverse projection. Values of those coefficients depend only on eccentricity value. The series expansion is published under the following form, where χ is the conformal latitude:c₂⋅sin(2χ) + c₄⋅sin(4χ) + c₆⋅sin(6χ) + c₈⋅sin(8χ)
However, we rewrite above series expansion for taking advantage of trigonometric identities. The equation become (with different c values):sin(2χ)⋅(c₂ + cos(2χ)⋅(c₄ + cos(2χ)⋅(c₆ + cos(2χ)⋅c₈)))
Serialization note: we do not strictly need to serialize those fields since they could be computed after deserialization. Bu we serialize them anyway in order to simplify a little bit this class (it allows us to keep those fields final) and because values computed after deserialization could be slightly different than the ones computed after construction if a future version of the constructor uses the double-double values provided byInitializer
. -
c4χ
private final double c4χCoefficients of the first terms in the series expansion of the reverse projection. Values of those coefficients depend only on eccentricity value. The series expansion is published under the following form, where χ is the conformal latitude:c₂⋅sin(2χ) + c₄⋅sin(4χ) + c₆⋅sin(6χ) + c₈⋅sin(8χ)
However, we rewrite above series expansion for taking advantage of trigonometric identities. The equation become (with different c values):sin(2χ)⋅(c₂ + cos(2χ)⋅(c₄ + cos(2χ)⋅(c₆ + cos(2χ)⋅c₈)))
Serialization note: we do not strictly need to serialize those fields since they could be computed after deserialization. Bu we serialize them anyway in order to simplify a little bit this class (it allows us to keep those fields final) and because values computed after deserialization could be slightly different than the ones computed after construction if a future version of the constructor uses the double-double values provided byInitializer
. -
c6χ
private final double c6χCoefficients of the first terms in the series expansion of the reverse projection. Values of those coefficients depend only on eccentricity value. The series expansion is published under the following form, where χ is the conformal latitude:c₂⋅sin(2χ) + c₄⋅sin(4χ) + c₆⋅sin(6χ) + c₈⋅sin(8χ)
However, we rewrite above series expansion for taking advantage of trigonometric identities. The equation become (with different c values):sin(2χ)⋅(c₂ + cos(2χ)⋅(c₄ + cos(2χ)⋅(c₆ + cos(2χ)⋅c₈)))
Serialization note: we do not strictly need to serialize those fields since they could be computed after deserialization. Bu we serialize them anyway in order to simplify a little bit this class (it allows us to keep those fields final) and because values computed after deserialization could be slightly different than the ones computed after construction if a future version of the constructor uses the double-double values provided byInitializer
. -
c8χ
private final double c8χCoefficients of the first terms in the series expansion of the reverse projection. Values of those coefficients depend only on eccentricity value. The series expansion is published under the following form, where χ is the conformal latitude:c₂⋅sin(2χ) + c₄⋅sin(4χ) + c₆⋅sin(6χ) + c₈⋅sin(8χ)
However, we rewrite above series expansion for taking advantage of trigonometric identities. The equation become (with different c values):sin(2χ)⋅(c₂ + cos(2χ)⋅(c₄ + cos(2χ)⋅(c₆ + cos(2χ)⋅c₈)))
Serialization note: we do not strictly need to serialize those fields since they could be computed after deserialization. Bu we serialize them anyway in order to simplify a little bit this class (it allows us to keep those fields final) and because values computed after deserialization could be slightly different than the ones computed after construction if a future version of the constructor uses the double-double values provided byInitializer
.
-
-
Constructor Details
-
ConformalProjection
ConformalProjection(Initializer initializer) Creates a new normalized projection from the parameters computed by the given initializer. This constructor computes the coefficients in the series expansion from theNormalizedProjection.eccentricitySquared
value.- Parameters:
initializer
- the initializer for computing map projection internal parameters.
-
ConformalProjection
ConformalProjection(ConformalProjection other) Creates a new projection initialized to the values of the given one. This constructor may be invoked after we determined that the default implementation can be replaced by another one, for example using spherical formulas instead of the ellipsoidal ones. This constructor allows to transfer all parameters to the new instance without recomputing them.
-
-
Method Details
-
φ
Computes the latitude for a value closely related to the y value of a Mercator projection. This formula is also part of other projections, since Mercator can be considered as a special case of Lambert Conic Conformal for instance.This function is almost the converse of the
expΨ(double, double)
function. In a Mercator reverse projection, the value of therexpΨ
argument isexp(-Ψ)
.The input should be a positive number, otherwise the result will be either outside the [-π/2 … π/2] range, or will be NaN. Its behavior at some particular points is:
- φ(0) = π/2
- φ(1) = 0
- φ(∞) = -π/2
MercatorMethodComparison
class in the test package for more discussion.- Parameters:
rexpΨ
- the reciprocal of the value returned byexpΨ(double, double)
.- Returns:
- the latitude in radians.
- Throws:
ProjectionException
- if the iteration does not converge.- See Also:
-
expΨ
final double expΨ(double φ, double ℯsinφ) Computesexp(Ψ)
where Ψ is the isometric latitude. This is part of the Mercator projection for the given latitude. This formula is also part of Lambert Conic Conformal projection, since Mercator can be considered as a special case of that Lambert projection with the equator as the single standard parallel.The isometric latitude is given by the natural logarithm of the value returned by this method. The reciprocal of this function
1/expΨ(φ)
is the converse ofφ(double)
. Isometric latitude Ψ is related to conformal latitude χ by χ(φ) = gd(Ψ(φ)) where gd(x) is the Gudermannian function. There is many representations of that function, e.g. gd(Ψ) = 2⋅atan(expΨ) - π/2.In IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015, a function closely related to this method has the letter t.
Properties
This function is used with φ values in the [-π/2 … π/2] range and has a periodicity of 2π. The result is always a positive number when the φ argument is inside the above-cited range. If, after removal of any 2π periodicity, φ is still outside the [-π/2 … π/2] range, then the result is a negative number. In a Mercator projection, such negative number will result in NaN.Some values are:
- expΨ(NaN) = NaN
- expΨ(±∞) = NaN
- expΨ(-π/2) = 0
- expΨ( 0 ) = 1
- expΨ(+π/2) → ∞ (actually some large value like 1.633E+16)
- expΨ(-φ) = 1 / expΨ(φ)
The π/2 special case
The value atMath.PI/2
is not exactly infinity because there is no exact representation of π/2. However, since the conversion of 90° to radians givesMath.PI/2
, we can presume that the user was expecting infinity. The caller should check for the PI/2 special case himself if desired, as this method does nothing special about it.Note that the result for the φ value after
Math.PI/2
(as given byMath.nextUp(double)
) is still positive, maybe because PI/2 < π/2 < nextUp(PI/2). Only thenextUp(nextUp(PI/2))
value become negative. Callers may need to take this behavior in account: special check forMath.PI/2
is not sufficient, the check needs to include at least thenextUp(Math.PI/2)
case.Relationship with Snyder
This function is related to the following functions from Snyder:- (7-7) in the Mercator projection chapter.
- Reciprocal of (9-13) in the Oblique Mercator projection chapter.
- Reciprocal of (15-9) in the Lambert Conformal Conic projection chapter.
- Parameters:
φ
- the latitude in radians.ℯsinφ
- the sine of the φ argument multiplied byNormalizedProjection.eccentricity
.- Returns:
Math.exp(Ψ)
where Ψ is the isometric latitude.- See Also:
-
dy_dφ
final double dy_dφ(double sinφ, double cosφ) Computes the partial derivative of a Mercator projection at the given latitude. This formula is also part of other projections, since Mercator can be considered as a special case of Lambert Conic Conformal for instance.In order to get the derivative of the
expΨ(double, double)
function, caller can multiply the returned value byexpΨ
.- Parameters:
sinφ
- the sine of latitude.cosφ
- the cosine of latitude.- Returns:
- the partial derivative of a Mercator projection at the given latitude.
- See Also:
-