# Class EllipsoidToCentricTransform

Object
FormattableObject
AbstractMathTransform
EllipsoidToCentricTransform

All Implemented Interfaces:
  `Serializable, Parameterized, LenientComparable, Printable, MathTransform`

public class EllipsoidToCentricTransform extends AbstractMathTransform implements Serializable
Transform from two- or three- dimensional ellipsoidal coordinates to geocentric or planetocentric coordinates. This transform is usually (but not necessarily) part of a conversion from geographic to geocentric coordinates. Each input coordinate tuple is expected to contain:

1. longitude (λ) relative to the prime meridian (usually Greenwich),
2. latitude (φ),
3. optionally height above the ellipsoid (h).

Output coordinates are as below:

- In the Cartesian case:
  1. distance from Earth center on the X axis (toward the intersection of prime meridian and equator),
  2. distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),
  3. distance from Earth center on the Z axis (toward North pole).
- In the spherical case:
  1. spherical longitude (same as the geodetic longitude given in input),
  2. spherical latitude (slightly different than the geodetic latitude),
  3. distance from Earth center (radius).

The units of measurements depend on how the `MathTransform` has been created:

- `EllipsoidToCentricTransform` instances created directly by the constructor expect (λ,φ) values in radians and compute (X,Y,Z) values in units of an ellipsoid having a semi-major axis length of 1.
- Transforms created by the `createGeodeticConversion(…)` static method expect (λ,φ) values in degrees and compute (X,Y,Z) values in units of the ellipsoid axes (usually metres).

Since:
  0.7
See Also:
  - Serialized Form

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `EllipsoidToCentricTransform​.TargetType`
  Whether the output coordinate system is Cartesian or spherical.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final double`
  `eccentricitySquared`
  The square of the eccentricity.
  `protected final boolean`
  `withHeight`
  Whether the ellipsoidal coordinate tuples include an ellipsoidal height (3D case).

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `EllipsoidToCentricTransform(Ellipsoid source, boolean withHeight, EllipsoidToCentricTransform​.TargetType csType)`
  Creates a transform from angles in radians on an ellipsoid having a semi-major axis length of 1.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static MathTransform`
  `createGeodeticConversion(MathTransformFactory factory, Ellipsoid ellipsoid, boolean withHeight)`
  Creates a transform from geographic to Cartesian geocentric coordinates (convenience method).
  `static MathTransform`
  `createGeodeticConversion(MathTransformFactory factory, Ellipsoid source, boolean withHeight, EllipsoidToCentricTransform​.TargetType target)`
  Creates a transform from geographic to geocentric coordinates.
  `Matrix`
  `derivative(DirectPosition point)`
  Computes the derivative at the given location.
  `protected ContextualParameters`
  `getContextualParameters()`
  Returns the parameters used for creating the complete conversion.
  `ParameterDescriptorGroup`
  `getParameterDescriptors()`
  Returns a description of the internal parameters of this `EllipsoidToCentricTransform` transform.
  `ParameterValueGroup`
  `getParameterValues()`
  Returns a copy of internal parameter values of this `EllipsoidToCentricTransform` transform.
  `final int`
  `getSourceDimensions()`
  Gets the dimension of input points, which is 2 or 3.
  `final int`
  `getTargetDimensions()`
  Gets the dimension of output points, which is 3.
  `final EllipsoidToCentricTransform​.TargetType`
  `getTargetType()`
  Returns whether the target coordinate system is Cartesian or spherical.
  `MathTransform`
  `inverse()`
  Returns the inverse of this transform.
  `protected void`
  `inverseTransform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts)`
  Converts Cartesian coordinates (X,Y,Z) to ellipsoidal coordinates (λ,φ) or (λ,φ,h).
  `Matrix`
  `transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate)`
  Converts the (λ,φ) or (λ,φ,h) geodetic coordinates to to (X,Y,Z) geocentric coordinates, and optionally returns the derivative at that location.
  `void`
  `transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts)`
  Converts the (λ,φ) or (λ,φ,h) geodetic coordinates to to (X,Y,Z) geocentric coordinates.
  `protected void`
  `tryConcatenate(TransformJoiner context)`
  If this transform expects three-dimensional inputs, and if the transform just before this one unconditionally sets the height to zero, then replaces this transform by a two-dimensional one.

  ### Methods inherited from class AbstractMathTransform

  `equals, formatTo, getDomain, hashCode, isIdentity, transform, transform, transform, transform`

  ### 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`

- ## Field Details

  - ### eccentricitySquared

    protected final double eccentricitySquared
    The square of the eccentricity. This is defined as ℯ² = (a²-b²)/a² where a is the semi-major axis length and b is the semi-minor axis length.

  - ### withHeight

    protected final boolean withHeight
    Whether the ellipsoidal coordinate tuples include an ellipsoidal height (3D case). If `false`, then the input coordinate tuples are expected to be two-dimensional and the ellipsoidal height is assumed to be 0.
    Since:
      1.5
    See Also:
      - `getSourceDimensions()`

- ## Constructor Details

  - ### EllipsoidToCentricTransform

    public EllipsoidToCentricTransform(Ellipsoid source, boolean withHeight, EllipsoidToCentricTransform.TargetType csType)
    Creates a transform from angles in radians on an ellipsoid having a semi-major axis length of 1. While a full ellipsoid is specified to this constructor, only the ratio of axis lengths is used. `EllipsoidToCentricTransform` instances expect input coordinate tuples as below:
    1. longitudes in radians (unit constraint is relaxed in the spherical case),
    2. latitudes in radians,
    3. optionally heights above the ellipsoid, in units of an ellipsoid having a semi-major axis length of 1.
    Output coordinates depends on the target type. For a Cartesian coordinate system, the output are as below, in units of an ellipsoid having a semi-major axis length of 1:
    1. distance from Earth center on the X axis (toward the intersection of prime meridian and equator),
    2. distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),
    3. distance from Earth center on the Z axis (toward North pole).
    For a spherical coordinate system, the output are spherical longitude, spherical latitude and radius with longitudes in any unit of measurement since they are copied verbatim without being used in calculations. It is okay to keep longitudes in degrees for avoiding rounding errors during conversions.

    #### Geographic to geocentric conversions

    For converting geographic coordinates to geocentric coordinates, `EllipsoidToCentricTransform` instances need to be concatenated with the following affine transforms:
    - Normalization before `EllipsoidToCentricTransform`:
      - Conversion of (λ,φ) from degrees to radians
      - Division of (h) by the semi-major axis length
    - Denormalization after `EllipsoidToCentricTransform`:
      - Multiplication of (X,Y,Z) by the semi-major axis length
    After `EllipsoidToCentricTransform` construction, the full conversion chain including the above affine transforms can be created by `getContextualParameters().completeTransform(factory, this)}`.
    Parameters:
      `source` - the ellipsoid of the geographic CRS of the coordinates to convert.
      `withHeight` - `true` if source geographic coordinates include an ellipsoidal height (i.e. are 3-D), or `false` if they are only 2-D.
      `csType` - whether the target coordinate system shall be Cartesian or spherical.
    Since:
      1.5
    See Also:
      - `createGeodeticConversion(MathTransformFactory, Ellipsoid, boolean, TargetType)`

- ## Method Details

  - ### createGeodeticConversion

    public static MathTransform createGeodeticConversion(MathTransformFactory factory, Ellipsoid source, boolean withHeight, EllipsoidToCentricTransform.TargetType target) throws FactoryException
    Creates a transform from geographic to geocentric coordinates. This factory method combines the `EllipsoidToCentricTransform` instance with the steps needed for converting degrees to radians and expressing the results in units of the given ellipsoid.

    Input coordinates are expected to contain:

    1. longitudes in degrees (unit constraint is relaxed in the spherical case),
    2. latitudes in degrees,
    3. optionally heights above the ellipsoid, in units of the ellipsoid axis (usually metres).
    Output coordinates depends on the target type. For a Cartesian coordinate system, the output coordinates are as below, in units of the ellipsoid axis (usually metres):
    1. distance from Earth center on the X axis (toward the intersection of prime meridian and equator),
    2. distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),
    3. distance from Earth center on the Z axis (toward North pole).
    For a spherical coordinate system, the output are spherical longitude, spherical latitude and radius with longitude in any unit of measurement since they are copied verbatim without being used in calculations.
    Parameters:
      `factory` - the factory to use for creating and concatenating the affine transforms.
      `source` - the ellipsoid of the geographic CRS of the coordinates to convert.
      `withHeight` - `true` if source geographic coordinates include an ellipsoidal height (i.e. are 3-D), or `false` if they are only 2-D.
      `target` - whether the target coordinate system shall be Cartesian or spherical.
    Returns:
      the conversion from geographic to geocentric coordinates.
    Throws:
      `FactoryException` - if an error occurred while creating a transform.
    Since:
      1.5

  - ### createGeodeticConversion

    public static MathTransform createGeodeticConversion(MathTransformFactory factory, Ellipsoid ellipsoid, boolean withHeight) throws FactoryException
    Creates a transform from geographic to Cartesian geocentric coordinates (convenience method). This is a shortcut for the above method with a default parameter value or `EllipsoidToCentricTransform​.TargetType​.CARTESIAN`. The Cartesian coordinate system is the most usual target of the Geographic/geocentric conversions (EPSG:9602) operation and is the target assumed by Well Known Text (WKT).
    Parameters:
      `factory` - the factory to use for creating and concatenating the affine transforms.
      `ellipsoid` - the semi-major and semi-minor axis lengths with their unit of measurement.
      `withHeight` - `true` if source geographic coordinates include an ellipsoidal height (i.e. are 3-D), or `false` if they are only 2-D.
    Returns:
      the conversion from geographic to Cartesian geocentric coordinates.
    Throws:
      `FactoryException` - if an error occurred while creating a transform.

  - ### getContextualParameters

    protected ContextualParameters getContextualParameters()
    Returns the parameters used for creating the complete conversion. Those parameters describe a sequence of normalize → `this` → denormalize transforms, not including axis swapping. Those parameters are used for formatting Well Known Text (WKT) and error messages.
    Overrides:
      `getContextualParameters` in class `AbstractMathTransform`
    Returns:
      the parameter values for the normalize → `this` → denormalize chain of transforms.

  - ### getParameterValues

    @Debug public ParameterValueGroup getParameterValues()
    Returns a copy of internal parameter values of this `EllipsoidToCentricTransform` transform. The returned group contains parameter values for the number of dimensions, the eccentricity and the target type (Cartesian or spherical).

    #### Usage note

    This method is mostly for debugging purposes since the isolation of non-linear parameters in this class is highly implementation dependent. Most GIS applications will instead be interested in the contextual parameters.
    Specified by:
      `getParameterValues` in interface `Parameterized`
    Overrides:
      `getParameterValues` in class `AbstractMathTransform`
    Returns:
      a copy of the internal parameter values for this transform.
    See Also:
      - `AbstractMathTransform​.getContextualParameters()`
      - `SingleOperation​.getParameterValues()`

  - ### getParameterDescriptors

    @Debug public ParameterDescriptorGroup getParameterDescriptors()
    Returns a description of the internal parameters of this `EllipsoidToCentricTransform` transform. The returned group contains parameter descriptors for the number of dimensions and the eccentricity.
    Specified by:
      `getParameterDescriptors` in interface `Parameterized`
    Overrides:
      `getParameterDescriptors` in class `AbstractMathTransform`
    Returns:
      a description of the internal parameters.
    See Also:
      - `DefaultOperationMethod​.getParameters()`

  - ### getSourceDimensions

    public final int getSourceDimensions()
    Gets the dimension of input points, which is 2 or 3.
    Specified by:
      `getSourceDimensions` in interface `MathTransform`
    Specified by:
      `getSourceDimensions` in class `AbstractMathTransform`
    Returns:
      2 or 3.
    See Also:
      - `DefaultOperationMethod​.getSourceDimensions()`

  - ### getTargetDimensions

    public final int getTargetDimensions()
    Gets the dimension of output points, which is 3.
    Specified by:
      `getTargetDimensions` in interface `MathTransform`
    Specified by:
      `getTargetDimensions` in class `AbstractMathTransform`
    Returns:
      always 3.
    See Also:
      - `DefaultOperationMethod​.getTargetDimensions()`

  - ### getTargetType

    public final EllipsoidToCentricTransform.TargetType getTargetType()
    Returns whether the target coordinate system is Cartesian or spherical.
    Returns:
      whether the target coordinate system is Cartesian or spherical.

  - ### derivative

    public Matrix derivative(DirectPosition point) throws TransformException
    Computes the derivative at the given location. This method relaxes a little bit the `MathTransform` contract by accepting two- or three-dimensional points even if the number of dimensions does not match the `getSourceDimensions()` value.

    #### Rational

    That flexibility on the number of dimensions is required for calculation of inverse transform derivative, because that calculation needs to inverse a square matrix with all terms in it before to drop the last row in the two-dimensional case.
    Specified by:
      `derivative` in interface `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:
      `TransformException` - if the derivative cannot be evaluated at the specified point.

  - ### transform

    public Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) throws TransformException
    Converts the (λ,φ) or (λ,φ,h) geodetic coordinates to to (X,Y,Z) geocentric coordinates, 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 as `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:
      `TransformException` - if the point cannot be transformed or if a problem occurred while calculating the derivative.
    See Also:
      - `AbstractMathTransform​.derivative(DirectPosition)`
      - `AbstractMathTransform​.transform(DirectPosition, DirectPosition)`
      - `MathTransforms​.derivativeAndTransform(MathTransform, double[], int, double[], int)`

  - ### transform

    public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException
    Converts the (λ,φ) or (λ,φ,h) geodetic coordinates to to (X,Y,Z) geocentric coordinates. This method performs the same conversion as `transform(double[], int, double[], int, boolean)`, but the formulas are repeated here for performance reasons.
    Specified by:
      `transform` in interface `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 as `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:
      `TransformException` - if a point cannot be transformed.

  - ### inverseTransform

    protected void inverseTransform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException
    Converts Cartesian coordinates (X,Y,Z) to ellipsoidal coordinates (λ,φ) or (λ,φ,h). This method is invoked by the transform returned by `inverse()`.
    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 as `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:
      `TransformException` - if the calculation does not converge.

  - ### inverse

    public MathTransform inverse()
    Returns the inverse of this transform. The default implementation returns a transform that will delegate its work to `inverseTransform(double[], int, double[], int, int)`.
    Specified by:
      `inverse` in interface `MathTransform`
    Overrides:
      `inverse` in class `AbstractMathTransform`
    Returns:
      the conversion from geocentric or planetocentric to ellipsoidal coordinates.

  - ### tryConcatenate

    protected void tryConcatenate(TransformJoiner context) throws FactoryException
    If this transform expects three-dimensional inputs, and if the transform just before this one unconditionally sets the height to zero, then replaces this transform by a two-dimensional one. The intent is to handle the following sequence of operations defined in the EPSG database:
    1. Inverse of Geographic 3D to 2D conversion (EPSG:9659)
    2. Geographic/geocentric conversions (EPSG:9602)
    Replacing the above sequence by a two-dimensional `EllipsoidToCentricTransform` instance allow the following optimizations:
    - Avoid computation of h value.
    - Allow use of the more efficient `AffineTransform` before this transform instead of a transform based on a matrix of size 4×3.
    Overrides:
      `tryConcatenate` in class `AbstractMathTransform`
    Parameters:
      `context` - information about the neighbor transforms, and the object where to set the result.
    Throws:
      `FactoryException` - if an error occurred while combining the transforms.
    See Also:
      - `DefaultMathTransformFactory​.createConcatenatedTransform(MathTransform, MathTransform)`