Class AbstractMathTransform
- All Implemented Interfaces:
Parameterized
,LenientComparable
,MathTransform
- Direct Known Subclasses:
AbstractMathTransform.Inverse
,AbstractMathTransform1D
,AbstractMathTransform2D
,DatumShiftTransform
,EllipsoidToCentricTransform
,PassThroughTransform
,WraparoundTransform
MathTransform
interface.
A MathTransform
is an object that actually does the work of applying a
formula to coordinate values.
The math transform does not know or care how the coordinates relate to positions in the real world.
For example if an affine transform scales z values by a factor of 1000,
then it could be converting metres to millimetres, or it could be converting kilometres to metres.
AbstractMathTransform
provides a convenient base class from which MathTransform
implementations
can be easily derived. It also defines a few additional SIS-specific methods for convenience of performance.
The simplest way to implement this abstract class is to provide an implementation for the following methods only:
transform(…)
methods as well.
Immutability and thread safety
All Apache SIS implementations ofMathTransform
are immutable and thread-safe.
It is highly recommended that third-party implementations be immutable and thread-safe too.
This means that unless otherwise noted in the javadoc, MathTransform
instances can
be shared by many objects and passed between threads without synchronization.
Serialization
MathTransform
may or may not be serializable, at implementation choices.
Most Apache SIS implementations are serializable, but the serialized objects are not guaranteed to be compatible
with future SIS versions. Serialization should be used only for short term storage or RMI between applications
running the same SIS version.- Since:
- 0.5
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionprotected static class
Base class for implementations of inverse math transforms. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected int
Computes a hash value for this transform.derivative
(DirectPosition point) Gets the derivative of this transform at a point.final boolean
Compares the specified object with this math transform for strict equality.boolean
equals
(Object object, ComparisonMode mode) Compares the specified object with this math transform for equality.protected String
Formats the inner part of a Well Known Text version 1 (WKT 1) element.protected ContextualParameters
Returns the parameters for a sequence of normalize →this
→ denormalize transforms (optional operation).getDomain
(DomainDefinition criteria) Returns the ranges of coordinate values which can be used as inputs.Returns the parameter descriptors for this math transform, ornull
if unknown.Returns the parameter values for this math transform, ornull
if unknown.abstract int
Returns the number of dimensions of input points.abstract int
Returns the number of dimensions of output points.final int
Returns a hash value for this transform.inverse()
Returns the inverse transform of this object.boolean
Tests whether this transform does not move any points.abstract 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 at that location.void
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) Transforms a list of coordinate tuples.void
transform
(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) Transforms a list of coordinate tuples.void
transform
(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) Transforms a list of coordinate tuples.void
transform
(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) Transforms a list of coordinate tuples.transform
(DirectPosition ptSrc, DirectPosition ptDst) Transforms the specifiedptSrc
and stores the result inptDst
.protected MathTransform
tryConcatenate
(boolean applyOtherFirst, MathTransform other, MathTransformFactory factory) Concatenates or pre-concatenates in an optimized way this math transform with the given one, if possible.Methods inherited from class FormattableObject
print, toString, toString, toWKT
Methods inherited from class Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface MathTransform
toWKT
-
Constructor Details
-
AbstractMathTransform
protected AbstractMathTransform()Constructor for subclasses.
-
-
Method Details
-
getSourceDimensions
public abstract int getSourceDimensions()Returns the number of dimensions of input points.- Specified by:
getSourceDimensions
in interfaceMathTransform
- Returns:
- the number of dimensions of input points.
- See Also:
-
getTargetDimensions
public abstract int getTargetDimensions()Returns the number of dimensions of output points.- Specified by:
getTargetDimensions
in interfaceMathTransform
- Returns:
- the number of dimensions of output points.
- See Also:
-
getDomain
Returns the ranges of coordinate values which can be used as inputs. They are limits where the transform is mathematically and numerically applicable. This is not the domain of validity for which a coordinate reference system has been defined, because this method ignores "real world" considerations such as datum and country boundaries.This method is for allowing callers to crop their data for removing areas that may cause numerical problems. For example, results of Mercator projection tend to infinity when the latitude value approaches a pole. For avoiding data structures with unreasonably large values or
Double.NaN
, we commonly crop data to some arbitrary maximal latitude value (typically 80 or 84°) before projection. Those limits are arbitrary, the transform does not become suddenly invalid after a limit. TheDomainDefinition
gives some controls on the criteria for choosing a limit.Many transforms, in particular all affine transforms, have no mathematical limits. Consequently, the default implementation returns an empty value. Again it does not mean that the coordinate operation has no geospatial domain of validity, but the latter is not the purpose of this method. This method is (for example) for preventing a viewer to crash when attempting to render a world-wide image.
Callers do not need to search through transform steps. SIS implementation of
concatenated transforms
do that automatically.- Parameters:
criteria
- controls the definition of transform domain.- Returns:
- estimation of a domain where this transform is considered numerically applicable.
- Throws:
TransformException
- if the domain cannot be estimated.- Since:
- 1.3
- See Also:
-
getParameterDescriptors
Returns the parameter descriptors for this math transform, ornull
if unknown.Relationship with ISO 19111
This method is similar toOperationMethod.getParameters()
, except that typicalMathTransform
implementations return parameters in standard units (usually metres or decimal degrees).- Specified by:
getParameterDescriptors
in interfaceParameterized
- Returns:
- the parameter descriptors for this math transform, or
null
if unspecified. - See Also:
-
getParameterValues
Returns the parameter values for this math transform, ornull
if unknown. This is not necessarily the parameters that the user specified at construction time, since implementations may have applied normalizations.Normalized and contextual parameters
Most Apache SIS implementations of map projections perform their calculations on an ellipsoid having a semi-major axis length of 1. In such cases, the group returned by this method contains a"semi_major"
parameter with a value of 1. If the real axis length is desired, we need to take in account the context of this math transform, i.e. the scales and offsets applied before and after this transform. This information is provided bygetContextualParameters()
.- Specified by:
getParameterValues
in interfaceParameterized
- 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 transforms (optional operation). Subclasses can override this method if they choose to split their computation in linear and non-linear parts. Such split is optional: it can leads to better performance (because SIS can concatenate efficiently consecutive linear transforms), but should not change significantly the result (ignoring differences in rounding errors). If a split has been done, then thisMathTransform
represents only the non-linear step and Apache SIS needs this method for reconstructing the parameters of the complete transform.- 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
. - Since:
- 0.6
-
isIdentity
public boolean isIdentity()Tests whether this transform does not move any points. The default implementation always returnsfalse
.- Specified by:
isIdentity
in interfaceMathTransform
-
transform
public DirectPosition transform(DirectPosition ptSrc, DirectPosition ptDst) throws TransformException Transforms the specifiedptSrc
and stores the result inptDst
. The default implementation performs the following steps:- Ensures that the dimension of the given points are consistent with the source and target dimensions of this math transform.
- Delegates to the
transform(double[], int, double[], int, boolean)
method.
CoordinateReferenceSystem
value.- Specified by:
transform
in interfaceMathTransform
- Parameters:
ptSrc
- the coordinate tuple to be transformed.ptDst
- the coordinate tuple that stores the result of transformingptSrc
, ornull
.- Returns:
- the coordinate tuple after transforming
ptSrc
and storing the result inptDst
, or a newly created point ifptDst
was null. - Throws:
MismatchedDimensionException
- ifptSrc
orptDst
doesn't have the expected dimension.TransformException
- if the point cannot be transformed.
-
transform
public abstract Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) throws TransformException Transforms a single coordinate tuple in an array, and optionally computes the transform derivative at that location. Invoking this method is conceptually equivalent to running the following:Matrix derivative = null; if (derivate) { double[] coordinates = Arrays.copyOfRange(srcPts, srcOff, srcOff + getSourceDimensions()); derivative = this.derivative(new GeneralDirectPosition(coordinates)); } this.transform(srcPts, srcOff, dstPts, dstOff, 1); // May overwrite srcPts. return derivative;
- It is usually easier to implement for
AbstractMathTransform
subclasses. The defaulttransform(double[], int, double[], int, int)
method implementation will invoke this method in a loop, taking care of the iteration strategy depending on the argument value. - When both the transformed point and its derivative are needed, this method may be significantly faster than
invoking the
transform
andderivative
methods separately because many internal calculations are the same. Computing those two information in a single step can help to reduce redundant calculation.
Note for implementers
The source and destination may overlap. Consequently, implementers must read all source coordinate values before to start writing the transformed coordinates in the destination array.- 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:
TransformException
- if the point cannot be transformed or if a problem occurred while calculating the derivative.- See Also:
- It is usually easier to implement for
-
transform
public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException Transforms a list of coordinate tuples. This method is provided for efficiently transforming many points. The supplied array of coordinate values will contain packed coordinate values.Example
If the source dimension is 3, then the coordinates will be packed in this order: (x₀,y₀,z₀, x₁,y₁,z₁ …).Implementation note
The default implementation invokestransform(double[], int, double[], int, boolean)
in a loop, using an iteration strategy determined from the arguments for iterating over the points. For creating a more efficient implementation, seeIterationStrategy
javadoc for a method skeleton.- Specified by:
transform
in interfaceMathTransform
- 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:
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
.
-
transform
public void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws TransformException Transforms a list of coordinate tuples. The default implementation delegates totransform(double[], int, double[], int, int)
using a temporary array of doubles.Implementation note
SeeIterationStrategy
javadoc for a method skeleton.- Specified by:
transform
in interfaceMathTransform
- 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:
TransformException
- if a point cannot be transformed. Some implementations will stop at the first failure, wile some other implementations will fill the un-transformable points withFloat.NaN
values, continue and throw the exception only at end. Implementations that fall in the latter case should set the last completed transform tothis
.
-
transform
public void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws TransformException Transforms a list of coordinate tuples. The default implementation delegates totransform(double[], int, double[], int, int)
using a temporary array of doubles.- Specified by:
transform
in interfaceMathTransform
- 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.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:
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 Float.NaN values, continue and throw the exception only at end. Implementations that fall in the latter case should set the last completed transform tothis
.
-
transform
public void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException Transforms a list of coordinate tuples. The default implementation delegates totransform(double[], int, double[], int, int)
using a temporary array of doubles if necessary.- Specified by:
transform
in interfaceMathTransform
- 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.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:
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
.
-
derivative
Gets the derivative of this transform at a point. The default implementation performs the following steps:- Ensure that the
point
dimension is equal to this math transform source dimensions. - Copy the coordinates in a temporary array and pass that array to the
transform(double[], int, double[], int, boolean)
method, with thederivate
boolean argument set totrue
. - If the latter method returned a non-null matrix, returns that matrix.
Otherwise throws
TransformException
.
- Specified by:
derivative
in interfaceMathTransform
- Parameters:
point
- the coordinate tuple where to evaluate the derivative.- Returns:
- the derivative at the specified point (never
null
). - Throws:
NullPointerException
- if the derivative depends on coordinates andpoint
isnull
.MismatchedDimensionException
- ifpoint
does not have the expected dimension.TransformException
- if the derivative cannot be evaluated at the specified point.
- Ensure that the
-
inverse
Returns the inverse transform of this object. The default implementation returnsthis
if this transform is an identity transform, or throws an exception otherwise. Subclasses should override this method.Implementation note
TheAbstractMathTransform.Inverse
inner class can be used as a base for inverse transform implementations.- Specified by:
inverse
in interfaceMathTransform
- Throws:
NoninvertibleTransformException
-
tryConcatenate
protected MathTransform tryConcatenate(boolean applyOtherFirst, MathTransform other, MathTransformFactory factory) throws FactoryException Concatenates or pre-concatenates in an optimized way this math transform with the given one, if possible. If an optimization is possible, a new math transform is created to perform the combined transformation. TheapplyOtherFirst
value determines the transformation order as bellow:- If
applyOtherFirst
istrue
, then transforming a point p by the combined transform is equivalent to first transforming p byother
and then transforming the result bythis
. - If
applyOtherFirst
isfalse
, then transforming a point p by the combined transform is equivalent to first transforming p bythis
and then transforming the result byother
.
null
. In the latter case, the concatenation will be prepared byDefaultMathTransformFactory
using a generic implementation.The default implementation returns the identity transform if the other transform is the inverse of this transform, or returns
null
otherwise. This method is ought to be overridden by subclasses capable of concatenating some combination of transforms in a special way.LinearTransform
implementations do not need to override this method since matrix multiplications will be handled automatically, and this method does not need to handle theisIdentity()
case.- Parameters:
applyOtherFirst
-true
if the transformation order isother
followed bythis
, orfalse
if the transformation order isthis
followed byother
.other
- the other math transform to (pre-)concatenate with this transform.factory
- the factory which is (indirectly) invoking this method, ornull
if none.- Returns:
- the math transforms combined in an optimized way, or
null
if no such optimization is available. - Throws:
FactoryException
- if an error occurred while combining the transforms.- Since:
- 0.8
- See Also:
- If
-
hashCode
public final int hashCode()Returns a hash value for this transform. This method invokescomputeHashCode()
when first needed and caches the value for future invocations. Subclasses shall overridecomputeHashCode()
instead of this method. -
computeHashCode
protected int computeHashCode()Computes a hash value for this transform. This method is invoked byhashCode()
when first needed.- 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 strict equality. This method is implemented as below (omitting assertions):return equals(other, ComparisonMode.STRICT);
- Specified by:
equals
in interfaceLenientComparable
- Overrides:
equals
in classObject
- Parameters:
object
- the object to compare with this transform.- Returns:
true
if the given object is a transform of the same class and using the same parameter values.- Throws:
AssertionError
- if assertions are enabled and the objects are equal but their hash codes are different.- See Also:
-
equals
Compares the specified object with this math transform for equality. Two math transforms are considered equal if, given identical source positions, their transformed positions would be equal orapproximately
equal. This method may conservatively returnsfalse
if unsure.The default implementation returns
true
if the following conditions are met:object
is an instance of the same class thanthis
. We require the same class because there is no interface for the various kinds of transform.- If the hash code value has already been computed for both instances, their values are the same (opportunist performance enhancement).
- The contextual parameters are equal according the given comparison mode.
- Specified by:
equals
in interfaceLenientComparable
- 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:
-
formatTo
Formats the inner part of a Well Known Text version 1 (WKT 1) element. The default implementation formats all parameter values returned bygetParameterValues()
. The parameter group name is used as the math transform name.Compatibility note
Param_MT
is defined in the WKT 1 specification only. If the formatter convention is set to WKT 2, then this method silently uses the WKT 1 convention without raising an error (unless thisMathTransform
cannot be formatted as valid WKT 1 neither).- Specified by:
formatTo
in classFormattableObject
- Parameters:
formatter
- the formatter to use.- Returns:
- the WKT element name, which is
"Param_MT"
in the default implementation. - See Also:
-