Class LongitudeWraparound
java.lang.Object
org.apache.sis.io.wkt.FormattableObject
org.apache.sis.referencing.operation.transform.AbstractMathTransform
org.apache.sis.referencing.operation.transform.AbstractMathTransform2D
org.apache.sis.referencing.operation.projection.LongitudeWraparound
- All Implemented Interfaces:
Serializable
,Parameterized
,LenientComparable
,org.opengis.referencing.operation.MathTransform
,org.opengis.referencing.operation.MathTransform2D
If the scaled longitude θ=n⋅λ is outside the [−n⋅π … n⋅π] range, maybe shifts θ to that range.
This transform intentionally does not force θ to be inside that range in all cases.
We avoid explicit wraparounds as much as possible (as opposed to implicit wraparounds performed by
trigonometric functions) because they tend to introduce discontinuities. We perform wraparounds only
when necessary for the problem of area crossing the anti-meridian (±180°).
Example:
a CRS for Alaska may have the central meridian at λ₀=−154° of longitude. If the point to project is
at λ=177° of longitude, calculations will be performed with Δλ=331° while the correct value that we
need to use is Δλ=−29°.
In order to avoid wraparound operations as much as possible, we test only the bound where anti-meridian
problem may happen; no wraparound will be applied for the opposite bound. Furthermore, we add or subtract
360° only once. Even if the point did many turns around the Earth, the 360° shift will still be applied
at most once. The desire to apply the minimal amount of shifts is the reason why we do not use
Math.IEEEremainder(double, double)
.
When to use
Many map projections implicitly wraparound longitude values through the use of trigonometric functions (sin(λ)
, cos(λ)
, etc). For those map projections, the wraparound is unconditional
and this LongitudeWraparound
class is not needed. This class is used only when the wraparound is
not implicitly done and the central meridian is not zero. The latter condition is because subtraction of
central meridian may cause longitude values to go outside the −180° … +180° range.
This transform is hidden in WKT (it does not appear as a concatenation).
- Since:
- 1.3
- Version:
- 1.3
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final class
Longitude wraparound applied on reverse projection. -
Field Summary
FieldsModifier and TypeFieldDescription(package private) final double
A bound of the [−n⋅π … n⋅π] range which, if exceeded, should cause wraparound.private final LongitudeWraparound.Inverse
The inverse of this operation.(package private) final boolean
Whether the bound is on the side of negative longitudes.(package private) final NormalizedProjection
The actual map projection to execute after the longitude wraparound.private static final long
For cross-version compatibility.Fields inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform2D
DIMENSION
-
Constructor Summary
ConstructorsConstructorDescriptionLongitudeWraparound
(NormalizedProjection projection, double bound, double rotation) Creates a new transform for wrapping around the longitude values before a map projection. -
Method Summary
Modifier and TypeMethodDescription(package private) static double
boundOfScaledLongitude
(MatrixSIS normalize, boolean negative) Returns a bound of the [−n⋅π … n⋅π] domain where n is a map projection dependent factor.protected int
Computes a hash value for this transform.boolean
equals
(Object object, ComparisonMode mode) Compares the specified object with this math transform for equality.protected ContextualParameters
Returns the parameters for a sequence of normalize →this
→ denormalize.Optional<org.opengis.geometry.Envelope>
getDomain
(DomainDefinition criteria) Returns the ranges of coordinate values which can be used as inputs.org.opengis.parameter.ParameterDescriptorGroup
Returns the parameter descriptors for this math transform, ornull
if unknown.org.opengis.parameter.ParameterValueGroup
Returns the parameter values for this math transform, ornull
if unknown.org.opengis.referencing.operation.MathTransform2D
inverse()
Returns the inverse transform of this object.org.opengis.referencing.operation.Matrix
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) Transforms a single coordinate tuple in an array, and optionally computes the transform derivative.void
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) Transforms a list of coordinate tuples.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, hashCode, isIdentity, transform, transform, transform, transform, tryConcatenate
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
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDFor cross-version compatibility.- See Also:
-
projection
The actual map projection to execute after the longitude wraparound. -
bound
final double boundA bound of the [−n⋅π … n⋅π] range which, if exceeded, should cause wraparound. Some (not all) θ = n⋅λ values need to be shifted inside that range before to use them in trigonometric functions.The sign is significant. A negative value means that the wraparound is applied only on longitudes less than −180°. A positive value means that the wraparound is applied only on longitudes greater than +180°.
-
negative
final boolean negativeWhether the bound is on the side of negative longitudes. This isbound < 0
. This field is trivial inLongitudeWraparound
case, but more important inLongitudeWraparound.Inverse
case becauserotation - bound
may cancel to zero. -
inverse
The inverse of this operation.- See Also:
-
-
Constructor Details
-
LongitudeWraparound
LongitudeWraparound(NormalizedProjection projection, double bound, double rotation) Creates a new transform for wrapping around the longitude values before a map projection.- Parameters:
projection
- the actual map projection to execute after the longitude wraparound.bound
- one bound of the [−n⋅π … n⋅π] range, on the side where wraparound needs to be applied.rotation
- longitude rotation applied by the normalization matrix after conversion to projection domain.
-
-
Method Details
-
boundOfScaledLongitude
Returns a bound of the [−n⋅π … n⋅π] domain where n is a map projection dependent factor. The factor is inferred from theNormalizedProjection.context
.- Parameters:
normalize
- the normalization matrix of the projection for which to get a bound.negative
-true
for the −180° bound, orfalse
for the +180° bound.- Returns:
- a bound of the [−n⋅π … n⋅π] range.
-
getDomain
public Optional<org.opengis.geometry.Envelope> getDomain(DomainDefinition criteria) throws org.opengis.referencing.operation.TransformException Returns the ranges of coordinate values which can be used as inputs. Theprojection
domain is used verbatim, without wraparound adjustment.- Overrides:
getDomain
in classAbstractMathTransform
- Parameters:
criteria
- controls the definition of transform domain.- Returns:
- estimation of a domain where this transform is considered numerically applicable.
- Throws:
org.opengis.referencing.operation.TransformException
- if the domain cannot be estimated.- See Also:
-
MathTransforms.getDomain(MathTransform)
CoordinateOperation.getDomainOfValidity()
-
getParameterDescriptors
public org.opengis.parameter.ParameterDescriptorGroup getParameterDescriptors()Returns the parameter descriptors for this math transform, ornull
if unknown. Delegates toprojection
since thisLongitudeWraparound
is hidden. This is used by WKT formatting.- Specified by:
getParameterDescriptors
in interfaceParameterized
- Overrides:
getParameterDescriptors
in classAbstractMathTransform
- Returns:
- the parameter descriptors for this math transform, or
null
if unspecified. - See Also:
-
getParameterValues
public org.opengis.parameter.ParameterValueGroup getParameterValues()Returns the parameter values for this math transform, ornull
if unknown. Delegates toprojection
since thisLongitudeWraparound
is hidden. This is used by WKT formatting.- Specified by:
getParameterValues
in interfaceParameterized
- Overrides:
getParameterValues
in classAbstractMathTransform
- Returns:
- the parameter values for this math transform, or
null
if unspecified. Note that those parameters may be normalized (e.g. represent a transformation of an ellipsoid of semi-major axis length of 1). - See Also:
-
getContextualParameters
Returns the parameters for a sequence of normalize →this
→ denormalize. Delegates toprojection
since thisLongitudeWraparound
is hidden. This is used by WKT formatting.- Overrides:
getContextualParameters
in classAbstractMathTransform
- Returns:
- the parameter values for the sequence of normalize →
this
→ denormalize transforms, ornull
if unspecified. Callers should not modify the returned parameters, since modifications (if allowed) will generally not be reflected back in thisMathTransform
.
-
transform
public org.opengis.referencing.operation.Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) throws org.opengis.referencing.operation.TransformException Transforms a single coordinate tuple in an array, and optionally computes the transform derivative. The wraparound is applied, if needed, on the longitude value before to delegate toprojection
.- Specified by:
transform
in classAbstractMathTransform
- Parameters:
srcPts
- the array containing the source coordinates (cannot benull
).srcOff
- the offset to the point to be transformed in the source array.dstPts
- the array into which the transformed coordinates is returned. May be the same thansrcPts
. May benull
if only the derivative matrix is desired.dstOff
- the offset to the location of the transformed point that is stored in the destination array.derivate
-true
for computing the derivative, orfalse
if not needed.- Returns:
- the matrix of the transform derivative at the given source position,
or
null
if thederivate
argument isfalse
. - Throws:
org.opengis.referencing.operation.TransformException
- if the point cannot be transformed or if a problem occurred while calculating the derivative.- See Also:
-
transform
public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException Transforms a list of coordinate tuples. This method is provided for efficiently transforming many points. Wraparound is applied on all longitude values before to delegate toprojection
.- Specified by:
transform
in interfaceorg.opengis.referencing.operation.MathTransform
- Overrides:
transform
in classAbstractMathTransform
- Parameters:
srcPts
- the array containing the source point coordinates.srcOff
- the offset to the first point to be transformed in the source array.dstPts
- the array into which the transformed point coordinates are returned. May be the same thansrcPts
.dstOff
- the offset to the location of the first transformed point that is stored in the destination array.numPts
- the number of point objects to be transformed.- Throws:
org.opengis.referencing.operation.TransformException
- if a point cannot be transformed. Some implementations will stop at the first failure, wile some other implementations will fill the untransformable points with Double.NaN values, continue and throw the exception only at end. Implementations that fall in the latter case should set the last completed transform tothis
.
-
inverse
public org.opengis.referencing.operation.MathTransform2D inverse() throws org.opengis.referencing.operation.NoninvertibleTransformExceptionReturns the inverse transform of this object.- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform
- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform2D
- Overrides:
inverse
in classAbstractMathTransform2D
- Throws:
org.opengis.referencing.operation.NoninvertibleTransformException
-
computeHashCode
protected int computeHashCode()Computes a hash value for this transform.- Overrides:
computeHashCode
in classAbstractMathTransform
- Returns:
- the hash code value. This value may change between different execution of the Apache SIS library.
-
equals
Compares the specified object with this math transform for equality.- Specified by:
equals
in interfaceLenientComparable
- Overrides:
equals
in classAbstractMathTransform
- Parameters:
object
- the object to compare with this transform.mode
- the strictness level of the comparison. Default toSTRICT
.- Returns:
true
if the given object is considered equals to this math transform.- See Also:
-