Class ConcatenatedTransform

All Implemented Interfaces:
Serializable, Parameterized, LenientComparable, org.opengis.referencing.operation.MathTransform
Direct Known Subclasses:
ConcatenatedTransform1D, ConcatenatedTransform2D, ConcatenatedTransformDirect

class ConcatenatedTransform extends AbstractMathTransform implements Serializable
Base class for concatenated transforms. Instances can be created by calls to the create(MathTransform, MathTransform, MathTransformFactory) method. When possible, the above-cited method concatenates projective transforms before to fallback on the creation of new ConcatenatedTransform instances.

Concatenated transforms are serializable if all their step transforms are serializable.

Since:
0.5
Version:
1.3
See Also:
  • MathTransformFactory.createConcatenatedTransform(MathTransform, MathTransform)
  • Nested Class Summary

    Nested classes/interfaces inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform

    AbstractMathTransform.Inverse
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final double
    Tolerance threshold for considering a matrix as identity.
    private org.opengis.referencing.operation.MathTransform
    The inverse transform.
    private static final long
    Serial number for inter-operability with different versions.
    protected final org.opengis.referencing.operation.MathTransform
    The first math transform.
    protected final org.opengis.referencing.operation.MathTransform
    The second math transform.

    Fields inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform

    MAXIMUM_BUFFER_SIZE, MAXIMUM_FAILURES
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    ConcatenatedTransform(org.opengis.referencing.operation.MathTransform transform1, org.opengis.referencing.operation.MathTransform transform2)
    Constructs a concatenated transform.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected int
    Computes a hash value for this transform.
    static org.opengis.referencing.operation.MathTransform
    create(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory)
    Concatenates the two given transforms.
    org.opengis.referencing.operation.Matrix
    derivative(org.opengis.geometry.DirectPosition point)
    Gets the derivative of this transform at a point.
    boolean
    equals(Object object, ComparisonMode mode)
    Compares the specified object with this math transform for equality.
    protected String
    formatTo(Formatter formatter)
    Formats the inner part of a Well Known Text version 1 (WKT 1) element.
    final Optional<org.opengis.geometry.Envelope>
    Returns the intersection of domains declared in transform steps.
    private static String
    getName(org.opengis.referencing.operation.MathTransform transform)
    Returns a name for the specified math transform.
    org.opengis.parameter.ParameterDescriptorGroup
    Returns the parameter descriptor, or null if none.
    If there is exactly one transform step which is parameterized, returns that transform step.
    org.opengis.parameter.ParameterValueGroup
    Returns the parameter values, or null if none.
    private List<Object>
    Returns all concatenated transforms, modified with the pre- and post-processing required for WKT formatting.
    final int
    Gets the dimension of input points.
    private int
    Returns the number of single MathTransform steps.
    private static int
    getStepCount(org.opengis.referencing.operation.MathTransform transform)
    Returns the number of single math transform steps performed by the given transform.
    final List<org.opengis.referencing.operation.MathTransform>
    Returns all concatenated transforms.
    private void
    getSteps(List<? super org.opengis.referencing.operation.MathTransform> transforms)
    Adds all concatenated transforms in the given list.
    final int
    Gets the dimension of output points.
    org.opengis.referencing.operation.MathTransform
    Creates the inverse transform of this object.
    boolean
    Tests whether this transform does not move any points.
    (package private) boolean
    Checks if transforms are compatibles.
    private static org.opengis.referencing.operation.MathTransform
    multiply(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory)
    Returns a transform resulting from the multiplication of the matrices of given transforms.
    (package private) static void
    setInverse(org.opengis.referencing.operation.MathTransform tr, org.opengis.referencing.operation.MathTransform inverse)
    If the given transform is an instance of ConcatenatedTransform, sets its inverse to the given value.
    org.opengis.referencing.operation.Matrix
    transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate)
    Transforms a single position in a list of coordinate values, and optionally returns the derivative at that location.
    void
    transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts)
    Transforms many positions in a list of coordinate values.
    void
    transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts)
    Transforms many positions in a list of coordinate values.
    void
    transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts)
    Transforms many positions in a list of coordinate values.
    void
    transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts)
    Transforms many positions in a list of coordinate values.
    org.opengis.geometry.DirectPosition
    transform(org.opengis.geometry.DirectPosition ptSrc, org.opengis.geometry.DirectPosition ptDst)
    Transforms the specified ptSrc and stores the result in ptDst.
    protected org.opengis.referencing.operation.MathTransform
    tryConcatenate(boolean applyOtherFirst, org.opengis.referencing.operation.MathTransform other, org.opengis.referencing.operation.MathTransformFactory factory)
    Concatenates or pre-concatenates in an optimized way this transform with the given transform, if possible.
    private static org.opengis.referencing.operation.MathTransform
    tryOptimized(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory)
    Tries to returns an optimized concatenation, for example by merging two affine transforms into a single one.

    Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform

    beforeFormat, equals, getContextualParameters, hashCode, isInverseEquals, mismatchedDimension

    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

    toWKT
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serial number for inter-operability with different versions.
      See Also:
    • IDENTITY_TOLERANCE

      private static final double IDENTITY_TOLERANCE
      Tolerance threshold for considering a matrix as identity. Since the value used here is smaller than 1 ULP (about 2.22E-16), it applies only to the zero terms in the matrix. The terms on the diagonal are still expected to be exactly 1.
      See Also:
    • transform1

      protected final org.opengis.referencing.operation.MathTransform transform1
      The first math transform.
    • transform2

      protected final org.opengis.referencing.operation.MathTransform transform2
      The second math transform.
    • inverse

      private org.opengis.referencing.operation.MathTransform inverse
      The inverse transform. This field will be computed only when needed. But it is serialized in order to avoid rounding errors if the inverse transform is serialized instead of the original one.
      See Also:
  • Constructor Details

    • ConcatenatedTransform

      protected ConcatenatedTransform(org.opengis.referencing.operation.MathTransform transform1, org.opengis.referencing.operation.MathTransform transform2)
      Constructs a concatenated transform. This constructor is for subclasses only. To create a concatenated transform, use the create(MathTransform, MathTransform, MathTransformFactory) factory method instead.
      Parameters:
      transform1 - the first math transform.
      transform2 - the second math transform.
  • Method Details

    • create

      public static org.opengis.referencing.operation.MathTransform create(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory) throws org.opengis.util.FactoryException, org.opengis.geometry.MismatchedDimensionException
      Concatenates the two given transforms. If the concatenation result works with two-dimensional input and output points, then the returned transform will implement MathTransform2D. Likewise if the concatenation result works with one-dimensional input and output points, then the returned transform will implement MathTransform1D.
      Implementation note: ConcatenatedTransform implementations are available in two versions: direct and non-direct. The "non-direct" versions use an intermediate buffer when performing transformations; they are slower and consume more memory. They are used only as a fallback when a "direct" version cannot be created.
      Parameters:
      tr1 - the first math transform.
      tr2 - the second math transform.
      factory - the factory which is (indirectly) invoking this method, or null if none.
      Returns:
      the concatenated transform.
      Throws:
      org.opengis.util.FactoryException
      org.opengis.geometry.MismatchedDimensionException
      See Also:
    • tryOptimized

      private static org.opengis.referencing.operation.MathTransform tryOptimized(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory) throws org.opengis.util.FactoryException
      Tries to returns an optimized concatenation, for example by merging two affine transforms into a single one. If no optimized case has been found, returns null. In the latter case, the caller will need to create a more heavy ConcatenatedTransform instance.
      Parameters:
      factory - the factory which is (indirectly) invoking this method, or null if none.
      Throws:
      org.opengis.util.FactoryException
    • multiply

      private static org.opengis.referencing.operation.MathTransform multiply(org.opengis.referencing.operation.MathTransform tr1, org.opengis.referencing.operation.MathTransform tr2, org.opengis.referencing.operation.MathTransformFactory factory) throws org.opengis.util.FactoryException
      Returns a transform resulting from the multiplication of the matrices of given transforms. If the given transforms does not provide matrix, then this method returns null.
      Parameters:
      factory - the factory which is (indirectly) invoking this method, or null if none.
      Throws:
      org.opengis.util.FactoryException
    • getName

      private static String getName(org.opengis.referencing.operation.MathTransform transform)
      Returns a name for the specified math transform.
    • isValid

      boolean isValid()
      Checks if transforms are compatibles. The default implementation check if transfer dimension match.
    • getSourceDimensions

      public final int getSourceDimensions()
      Gets the dimension of input points.
      Specified by:
      getSourceDimensions in interface org.opengis.referencing.operation.MathTransform
      Specified by:
      getSourceDimensions in class AbstractMathTransform
      Returns:
      the number of dimensions of input points.
      See Also:
    • getTargetDimensions

      public final int getTargetDimensions()
      Gets the dimension of output points.
      Specified by:
      getTargetDimensions in interface org.opengis.referencing.operation.MathTransform
      Specified by:
      getTargetDimensions in class AbstractMathTransform
      Returns:
      the number of dimensions of output points.
      See Also:
    • getStepCount

      private int getStepCount()
      Returns the number of single MathTransform steps. Nested concatenated transforms (if any) are explored recursively in order to get the count of single (non-nested) transforms.
      Returns:
      the number of single transform steps.
    • getStepCount

      private static int getStepCount(org.opengis.referencing.operation.MathTransform transform)
      Returns the number of single math transform steps performed by the given transform. As a special case, we returns 0 for the identity transform since it should be omitted from the final chain.
    • getSteps

      public final List<org.opengis.referencing.operation.MathTransform> getSteps()
      Returns all concatenated transforms. The returned list contains only single transforms, i.e. all nested concatenated transforms (if any) have been flattened.
      Returns:
      all single math transforms performed by this concatenated transform.
      See Also:
    • getPseudoSteps

      private List<Object> getPseudoSteps()
      Returns all concatenated transforms, modified with the pre- and post-processing required for WKT formatting. More specifically, if there is any Apache SIS implementation of Map Projection in the chain, then the (normalize, normalized projection, denormalize) tuples are replaced by single (projection) elements, which does not need to be instances of MathTransform.

      This method is used only for producing human-readable parameter values. It is not used for coordinate operations or construction of operation chains.

    • getSteps

      private void getSteps(List<? super org.opengis.referencing.operation.MathTransform> transforms)
      Adds all concatenated transforms in the given list.
      Parameters:
      transforms - the list where to add concatenated transforms.
    • getParameterised

      private Parameterized getParameterised()
      If there is exactly one transform step which is parameterized, returns that transform step. Otherwise returns null.

      This method normally requires that there is exactly one transform step remaining after we processed map projections in the special way described in getParameterValues(), because if they were more than one remaining steps, the returned parameters would not be sufficient for rebuilding the full concatenated transform. Returning parameters when there is more than one remaining step, even if all other transform steps are not parameterizable, would be a contract violation.

      However, in the special case where we are getting the parameters of a CoordinateOperation instance through AbstractCoordinateOperation.getParameterValues() method (often indirectly trough WKT formatting of a "ProjectedCRS" element), then the above rule is slightly relaxed: we ignore affine transforms in order to accept axis swapping or unit conversions. We do that in that particular case only because the coordinate systems given with the enclosing CoordinateOperation or GeneralDerivedCRS specify the axis swapping and unit conversions. This special case is internal to SIS implementation and should be unknown to users.

      Returns:
      the parameterizable transform step, or null if none.
    • getParameterDescriptors

      public org.opengis.parameter.ParameterDescriptorGroup getParameterDescriptors()
      Returns the parameter descriptor, or null if none. This method performs the same special check than getParameterValues().
      Specified by:
      getParameterDescriptors in interface Parameterized
      Overrides:
      getParameterDescriptors in class AbstractMathTransform
      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, or null if none. Concatenated transforms usually have no parameters; instead the parameters of the individual components (transform1 and transform2) need to be inspected. However, map projections in SIS are implemented as (normalizenon-linear kerneldenormalize) tuples. This method detects such concatenation chains in order to return the parameter values that describe the projection as a whole.
      Specified by:
      getParameterValues in interface Parameterized
      Overrides:
      getParameterValues in class AbstractMathTransform
      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:
    • transform

      public org.opengis.geometry.DirectPosition transform(org.opengis.geometry.DirectPosition ptSrc, org.opengis.geometry.DirectPosition ptDst) throws org.opengis.referencing.operation.TransformException
      Transforms the specified ptSrc and stores the result in ptDst.
      Specified by:
      transform in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      transform in class AbstractMathTransform
      Parameters:
      ptSrc - the coordinate tuple to be transformed.
      ptDst - the coordinate tuple that stores the result of transforming ptSrc, or null.
      Returns:
      the coordinate tuple after transforming ptSrc and storing the result in ptDst, or a newly created point if ptDst was null.
      Throws:
      org.opengis.referencing.operation.TransformException - if transform1 or transform2 failed.
    • 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 position in a list of coordinate values, and optionally returns the derivative at that location.
      Specified by:
      transform in class AbstractMathTransform
      Parameters:
      srcPts - the array containing the source coordinates (cannot be null).
      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 than srcPts. May be null 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, or false if not needed.
      Returns:
      the matrix of the transform derivative at the given source position, or null if the derivate argument is false.
      Throws:
      org.opengis.referencing.operation.TransformException - if transform1 or transform2 failed.
      See Also:
    • transform

      public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException
      Transforms many positions in a list of coordinate values. The source points are first transformed by transform1, then the intermediate points are transformed by transform2. The transformations are performed without intermediate buffer if it can be avoided.
      Specified by:
      transform in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      transform in class AbstractMathTransform
      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 than srcPts.
      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 transform1 or transform2 failed.
    • transform

      public void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException
      Transforms many positions in a list of coordinate values. The source points are first transformed by transform1, then the intermediate points are transformed by transform2. An intermediate buffer of type double[] for intermediate results is used for reducing rounding errors.
      Specified by:
      transform in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      transform in class AbstractMathTransform
      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 than srcPts.
      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 transform1 or transform2 failed.
    • transform

      public void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException
      Transforms many positions in a list of coordinate values. The source points are first transformed by transform1, then the intermediate points are transformed by transform2. An intermediate buffer of type double[] for intermediate results is used for reducing rounding errors.
      Specified by:
      transform in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      transform in class AbstractMathTransform
      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:
      org.opengis.referencing.operation.TransformException - if transform1 or transform2 failed.
    • transform

      public void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException
      Transforms many positions in a list of coordinate values. The source points are first transformed by transform1, then the intermediate points are transformed by transform2. The transformations are performed without intermediate buffer if it can be avoided.
      Specified by:
      transform in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      transform in class AbstractMathTransform
      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:
      org.opengis.referencing.operation.TransformException - if transform1 or transform2 failed.
    • derivative

      public org.opengis.referencing.operation.Matrix derivative(org.opengis.geometry.DirectPosition point) throws org.opengis.referencing.operation.TransformException
      Gets the derivative of this transform at a point.
      Specified by:
      derivative in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      derivative in class AbstractMathTransform
      Parameters:
      point - the position where to evaluate the derivative.
      Returns:
      the derivative at the specified point (never null).
      Throws:
      org.opengis.referencing.operation.TransformException - if the derivative cannot be evaluated at the specified point.
    • inverse

      public org.opengis.referencing.operation.MathTransform inverse() throws org.opengis.referencing.operation.NoninvertibleTransformException
      Creates the inverse transform of this object.
      Specified by:
      inverse in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      inverse in class AbstractMathTransform
      Throws:
      org.opengis.referencing.operation.NoninvertibleTransformException
    • setInverse

      static void setInverse(org.opengis.referencing.operation.MathTransform tr, org.opengis.referencing.operation.MathTransform inverse)
      If the given transform is an instance of ConcatenatedTransform, sets its inverse to the given value. Otherwise does nothing.
      Parameters:
      tr - the transform on which to set the inverse.
      inverse - the inverse to assign to the given transform.
    • getDomain

      public final Optional<org.opengis.geometry.Envelope> getDomain(DomainDefinition criteria) throws org.opengis.referencing.operation.TransformException
      Returns the intersection of domains declared in transform steps. The result is in the units of input coordinates.

      This method shall not be invoked recursively; the result would be in wrong units. The estimateOnInverse(…) method implementations performs instanceof checks for preventing that.

      Overrides:
      getDomain in class AbstractMathTransform
      Parameters:
      criteria - domain builder passed to each transform steps.
      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:
    • tryConcatenate

      protected org.opengis.referencing.operation.MathTransform tryConcatenate(boolean applyOtherFirst, org.opengis.referencing.operation.MathTransform other, org.opengis.referencing.operation.MathTransformFactory factory) throws org.opengis.util.FactoryException
      Concatenates or pre-concatenates in an optimized way this transform with the given transform, if possible. This method tries to delegate the concatenation to transform1 or transform2. Assuming that transforms are associative, this is equivalent to trying the following arrangements:
      Overrides:
      tryConcatenate in class AbstractMathTransform
      Parameters:
      applyOtherFirst - true if the transformation order is other followed by this, or false if the transformation order is this followed by other.
      other - the other math transform to (pre-)concatenate with this transform.
      factory - the factory which is (indirectly) invoking this method, or null if none.
      Returns:
      the simplified transform, or null if no such optimization is available.
      Throws:
      org.opengis.util.FactoryException - if an error occurred while combining the transforms.
      See Also:
    • isIdentity

      public boolean isIdentity()
      Tests whether this transform does not move any points. Implementation checks if the two transforms are identity.
      Note: this method should always returns false, since create(…) should have created specialized implementations for identity cases. Nevertheless we perform the full check as a safety, in case someone instantiated this class directly instead of using a factory method, or in case the given math transforms are mutable (they should not, be we cannot control what the user gave to us).
      Specified by:
      isIdentity in interface org.opengis.referencing.operation.MathTransform
      Overrides:
      isIdentity in class AbstractMathTransform
    • computeHashCode

      protected int computeHashCode()
      Computes a hash value for this transform. This method is invoked by AbstractMathTransform.hashCode() when first needed.
      Overrides:
      computeHashCode in class AbstractMathTransform
      Returns:
      the hash code value. This value may change between different execution of the Apache SIS library.
    • equals

      public boolean equals(Object object, ComparisonMode mode)
      Compares the specified object with this math transform for equality.
      Specified by:
      equals in interface LenientComparable
      Overrides:
      equals in class AbstractMathTransform
      Parameters:
      object - the object to compare with this transform.
      mode - the strictness level of the comparison. Default to STRICT.
      Returns:
      true if the given object is considered equals to this math transform.
      See Also:
    • formatTo

      protected String formatTo(Formatter formatter)
      Formats the inner part of a Well Known Text version 1 (WKT 1) element.
      Compatibility note: Concat_MT is defined in the WKT 1 specification only.
      Overrides:
      formatTo in class AbstractMathTransform
      Parameters:
      formatter - the formatter to use.
      Returns:
      the WKT element name, which is "Concat_MT".
      See Also: