# Class ContextualParameters

Object
Parameters
ContextualParameters

All Implemented Interfaces:
  `Serializable, Cloneable, Printable, GeneralParameterValue, ParameterValueGroup`

public class ContextualParameters extends Parameters implements Serializable
The parameters that describe a sequence of normalize → non-linear kernel → denormalize transforms as a whole. The normalize and denormalize steps must be affine transforms, while the non-linear kernel is arbitrary. This separation is useful for doing in the linear steps any unit conversions and axis swapping necessary for allowing the non-linear step to work in some predefined (implementation specific) coordinate system.

Contextual parameters are associated to the non-linear kernel step of the above-cited sequence. Since the parameter values of the non-linear kernel contains only normalized parameters (e.g. a map projection on an ellipsoid having a semi-major axis length of 1), Apache SIS needs contextual information for reconstructing the parameters of the complete transforms chain.

## Usage in map projections

This object is used mostly for Apache SIS implementation of map projections, where the non-linear kernel is a normalized projection working on (longitude, latitude) coordinates in radians. The complete map projection (ignoring changes of axis order) is a chain of 3 transforms as shown below:
[ π/180 0 -λ 0 ⋅ (π/180) 0 π/180 0 0 0 1 ]
→
Map projection on a normalized ellipsoid
→
[ a ⋅ k 0 0 FE 0 a ⋅ k 0 FN 0 0 1 ]
`ContextualParameters` is typically created and used as below:

1. A `MathTransformProvider` instantiates a non-linear transform working in a predefined coordinate system. Note that different providers may instantiate the same transform class but with different parameters. For example, both Mercator (variant A) and Mercator (variant B) operation methods instantiate the same Mercator projection class, but with different ways to represent the parameters.
2. The map projection constructor fetches all parameters that it needs from the user supplied `Parameters`, initializes the projection, then saves the parameter values that it actually used in a new `ContextualParameters` instance.
3. The map projection constructor may keep only the non-linear parameters for itself, and gives the linear parameters to the `normalizeGeographicInputs(…)` and `MatrixSIS​.convertAfter(…)` methods, which will create the matrices show above. The projection constructor is free to apply additional operations on the two affine transforms (normalize / denormalize) before or after the above-cited methods have been invoked.
4. After all parameter values have been set and the normalize / denormalize matrices defined, the `completeTransform(…)` method will mark this `ContextualParameters` object as unmodifiable and create the chain of transforms from (λ,φ) in angular degrees to (x,y) in metres. Note that conversions to other units and changes in axis order are not the purpose of this transforms chain – they are separated steps.

## Serialization

Serialized instances of this class 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.6
See Also:
  - `AbstractMathTransform​.getContextualParameters()`
  - Serialized Form

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `ContextualParameters​.MatrixRole`
  Whether a matrix is used for normalization or denormalization before or after a non-linear operation.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `ContextualParameters(ParameterDescriptorGroup descriptor, int srcDim, int tgtDim)`
  Creates a new group of parameters with the given descriptor.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `ParameterValueGroup`
  `addGroup(String name)`
  Unsupported operation, since `ContextualParameters` groups do not contain sub-groups.
  `ContextualParameters`
  `clone()`
  Returns a modifiable clone of this parameter value group.
  `MathTransform`
  `completeTransform(MathTransformFactory factory, MathTransform kernel)`
  Marks this `ContextualParameter` as unmodifiable and creates the normalize → `kernel` → denormalize transforms chain.
  `MatrixSIS`
  `denormalizeGeographicOutputs(double λ0)`
  Appends a denormalization step after the non-linear kernel, which will convert input coordinates in the two first dimensions from radians to degrees.
  `boolean`
  `equals(Object object)`
  Compares the given object with the parameters for equality.
  `final ParameterDescriptorGroup`
  `getDescriptor()`
  Returns the parameters for the normalize → non-linear kernel → denormalize sequence as a whole.
  `final MatrixSIS`
  `getMatrix(ContextualParameters​.MatrixRole role)`
  Returns the affine transforms to be applied before or after the non-linear kernel operation.
  `List<ParameterValueGroup>`
  `groups(String name)`
  Unsupported operation, since `ContextualParameters` groups do not contain sub-groups.
  `int`
  `hashCode()`
  Returns a hash code value for this object.
  `MatrixSIS`
  `normalizeGeographicInputs(double λ0)`
  Prepends a normalization step converting input coordinates in the two first dimensions from degrees to radians.
  `ParameterValue<?>`
  `parameter(String name)`
  Returns the parameter value of the given name.
  `ContextualParameters`
  `redimension(int srcDim, int tgtDim)`
  Returns the same parameters but for an operation having the specified number of dimensions.
  `List<GeneralParameterValue>`
  `values()`
  Returns an unmodifiable list containing all parameters in this group.

  ### Methods inherited from class Parameters

  `booleanValue, cast, cast, castOrWrap, copy, doubleValue, doubleValue, doubleValueList, getDescriptors, getMandatoryValue, getMemberName, getOrCreate, getSourceFile, getValue, getValueDomain, intValue, intValueList, isUnmodifiable, print, stringValue, toString, unmodifiable, unmodifiable`

  ### Methods inherited from class Object

  `finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### ContextualParameters

    public ContextualParameters(ParameterDescriptorGroup descriptor, int srcDim, int tgtDim)
    Creates a new group of parameters with the given descriptor. The method parameters shall describe the normalize → non-linear kernel → denormalize sequence as a whole. After construction, callers shall:
    - Set the relevant parameter values by calls to `parameter(…).setValue(…)`.
    - Modify the element values in normalization / denormalization affine transforms, optionally by calls to the convenience methods in this class.
    - Get the complete transforms chain with a call `completeTransform(…)`
    See class javadoc for more information.
    Parameters:
      `descriptor` - the parameter descriptor.
      `srcDim` - number of source dimensions.
      `tgtDim` - number of target dimensions.
    Since:
      1.0

- ## Method Details

  - ### getDescriptor

    public final ParameterDescriptorGroup getDescriptor()
    Returns the parameters for the normalize → non-linear kernel → denormalize sequence as a whole. This is the parameter descriptor of the operation method given to the constructor.

    The values for those parameters are given by the `values()` method. Those values may be used by the normalization / denormalization linear steps, by the non-linear kernel, or both.

    Specified by:
      `getDescriptor` in interface `GeneralParameterValue`
    Specified by:
      `getDescriptor` in interface `ParameterValueGroup`
    Returns:
      the description of the parameters.

  - ### getMatrix

    public final MatrixSIS getMatrix(ContextualParameters.MatrixRole role)
    Returns the affine transforms to be applied before or after the non-linear kernel operation. Immediately after construction, those matrices are modifiable identity matrices. Callers can modify the matrix element values, typically by calls to the `MatrixSIS​.convertBefore(…)` method. Alternatively, the following methods can be invoked for applying some frequently used configurations:
    - `normalizeGeographicInputs(double)`
    - `denormalizeGeographicOutputs(double)`
    After the `completeTransform(…)` method has been invoked, the matrices returned by this method are unmodifiable.

    #### Application to map projections

    After the construction of a non-linear kernel working on (longitude, latitude) coordinates in radians, the matrices returned by `projection​.getContextualParameters()​.getMatrix(…)` are initialized to the values shown below.

    Initial matrix coefficients after `NormalizedProjection` construction
    `getMatrix(NORMALIZATION)` | `getMatrix(DENORMALIZATION)`
    --- | ---
    [ π/180 0 -λ 0 ⋅ (π/180) 0 π/180 0 0 0 1 ] | [ a ⋅ k 0 0 FE 0 a ⋅ k 0 FN 0 0 1 ]

    Parameters:
      `role` - `NORMALIZATION` for fetching the normalization transform to apply before the kernel, `DENORMALIZATION` for the denormalization transform to apply after the kernel, or `INVERSE_*` for the inverse of the above-cited matrices.
    Returns:
      the matrix for the requested normalization or denormalization affine transform.
    Since:
      0.7

  - ### normalizeGeographicInputs

    public MatrixSIS normalizeGeographicInputs(double λ0)
    Prepends a normalization step converting input coordinates in the two first dimensions from degrees to radians. The normalization can optionally subtract the given λ₀ value (in degrees) from the longitude.

    Invoking this method is equivalent to concatenating the normalization matrix with the following matrix. This will have the effect of applying the conversion described above before any other operation:

    [ π/180 0 -λ 0 ⋅ (π/180) 0 π/180 0 0 0 1 ]
    Parameters:
      `λ0` - longitude of the central meridian, in degrees.
    Returns:
      the normalization affine transform as a matrix. Callers can change that matrix directly if they want to apply additional normalization operations.
    Throws:
      `IllegalStateException` - if this `ContextualParameter` has been made unmodifiable.

  - ### denormalizeGeographicOutputs

    public MatrixSIS denormalizeGeographicOutputs(double λ0)
    Appends a denormalization step after the non-linear kernel, which will convert input coordinates in the two first dimensions from radians to degrees. After this conversion, the denormalization can optionally add the given λ₀ value (in degrees) to the longitude.

    Invoking this method is equivalent to concatenating the denormalization matrix with the following matrix. This will have the effect of applying the conversion described above after the non-linear kernel operation:

    [ 180/π 0 λ 0 0 180/π 0 0 0 1 ]
    Parameters:
      `λ0` - longitude of the central meridian, in degrees.
    Returns:
      the denormalization affine transform as a matrix. Callers can change that matrix directly if they want to apply additional denormalization operations.
    Throws:
      `IllegalStateException` - if this `ContextualParameter` has been made unmodifiable.

  - ### completeTransform

    public MathTransform completeTransform(MathTransformFactory factory, MathTransform kernel) throws FactoryException
    Marks this `ContextualParameter` as unmodifiable and creates the normalize → `kernel` → denormalize transforms chain. This method shall be invoked only after the (de)normalization matrices have been set to their final values.

    The transforms chain created by this method does not include any step for changing axis order or for converting to units other than degrees or metres. Such steps, if desired, should be defined outside `ContextualParameters`. Efficient concatenation of those steps will happen "under the hood".

    Parameters:
      `factory` - the factory to use for creating math transform instances.
      `kernel` - the non-linear kernel which expects "normalized" coordinates in a predefined coordinate system.
    Returns:
      the concatenation of normalize → the given kernel → denormalize transforms.
    Throws:
      `FactoryException` - if an error occurred while creating a math transform instance.

  - ### parameter

    public ParameterValue<?> parameter(String name) throws ParameterNotFoundException
    Returns the parameter value of the given name. Before the call to `completeTransform(…)`, this method can be used for setting parameter values like below:

        parameter("Scale factor").setValue(0.9996);   // Scale factor of Universal Transverse Mercator (UTM) projections.

    After the call to `completeTransform(…)`, the returned parameters are read-only.
    Specified by:
      `parameter` in interface `ParameterValueGroup`
    Parameters:
      `name` - the name of the parameter to search.
    Returns:
      the parameter value for the given name.
    Throws:
      `ParameterNotFoundException` - if there is no parameter of the given name.

  - ### values

    public List<GeneralParameterValue> values()
    Returns an unmodifiable list containing all parameters in this group. Callers should not attempt to modify the parameter values in this list.
    Specified by:
      `values` in interface `ParameterValueGroup`
    Returns:
      all parameter values.

  - ### groups

    public List<ParameterValueGroup> groups(String name)
    Unsupported operation, since `ContextualParameters` groups do not contain sub-groups.
    Specified by:
      `groups` in interface `ParameterValueGroup`
    Parameters:
      `name` - ignored.
    Returns:
      never returned.

  - ### addGroup

    public ParameterValueGroup addGroup(String name)
    Unsupported operation, since `ContextualParameters` groups do not contain sub-groups.
    Specified by:
      `addGroup` in interface `ParameterValueGroup`
    Parameters:
      `name` - ignored.
    Returns:
      never returned.

  - ### redimension

    public ContextualParameters redimension(int srcDim, int tgtDim)
    Returns the same parameters but for an operation having the specified number of dimensions. The returned instance has a normalization matrix set to a square matrix of size `srcDim`+1, and a denormalization matrix set to a square matrix of size `tgtDim`+1. See `Matrices​.resizeAffine(…)` for details about which matrix values are copied.

    If this group of parameters is unmodifiable, then the returned group is also unmodifiable. If the specified dimensions result in no change, then this method returns `this`.

    #### Purpose

    This method is mostly for deriving a two-dimensional variant of a three-dimensional operation by dropping the last dimensions. The `completeTransform(…)` method of the returned instance should be invoked with a kernel transform having compatible dimensions.
    Parameters:
      `srcDim` - new number of source dimensions.
      `tgtDim` - new number of target dimensions.
    Returns:
      parameters for an operation having the given number of dimensions, or `this` if there is no change.
    Throws:
      `IllegalArgumentException` - if a dimension is zero or negative.
    Since:
      1.5
    See Also:
      - `Matrices​.resizeAffine(Matrix, int, int)`

  - ### clone

    public ContextualParameters clone()
    Returns a modifiable clone of this parameter value group.
    Specified by:
      `clone` in interface `GeneralParameterValue`
    Specified by:
      `clone` in interface `ParameterValueGroup`
    Overrides:
      `clone` in class `Parameters`
    Returns:
      a clone of this parameter value group.
    See Also:
      - `Parameters​.copy(ParameterValueGroup, ParameterValueGroup)`

  - ### hashCode

    public int hashCode()
    Returns a hash code value for this object. This value is implementation-dependent and may change in any future version.
    Overrides:
      `hashCode` in class `Object`
    Returns:
      a hash code value.

  - ### equals

    public boolean equals(Object object)
    Compares the given object with the parameters for equality.
    Overrides:
      `equals` in class `Object`
    Parameters:
      `object` - the object to compare with the parameters.
    Returns:
      `true` if the given object is equal to this one.