Package org.apache.sis.referencing.operation

## Class CoordinateOperationFinder

- Object
- - CoordinateOperationFinder

-     public class CoordinateOperationFinder
      extends Object

  Finds a conversion or transformation path from a source CRS to a target CRS. This class implements two strategies for searching the coordinate operation:
  1. When `createOperation(sourceCRS, targetCRS)` is invoked, this class first tries to find the authority codes for the given source and target CRS. If such codes are found, they are submitted to a registry of coordinate operations. If an operation is found, it will be returned.
     Note: the above is known as the late-binding approach. The late-binding approach allows the authority to define better suited operations than what we would get if we were transforming everything from and to a pivot system (e.g. WGS84). In addition, this approach provides useful information like the coordinate operation scope and domain of validity, accuracy.
  2. If the above authority factory does not know about the specified CRS, then this class tries to infer the coordinate operation by itself. The CRS type is examined and the work is dispatched to one or many of the `createOperationStep(…)` protected methods defined in this class. Those methods use properties associated to the CRS, including `BOUNDCRS` or `TOWGS84` elements found in Well Known Text (WKT).
     Note: the use of elements like `TOWGS84` is known as the early-binding approach. The operation found by this approach may be sub-optimal. The early-binding approach is used only as a fallback when the late-binding approach gave no result.
  Customization
  Instances of this class are created by `DefaultCoordinateOperationFactory`. The only public method is `createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)`, which dispatches its work to the `createOperationStep(…)` protected methods. Developers can override those protected methods if they want to alter the way some operations are created.
  Limitations
  - Each instance of this class shall be used only once.
  - This class is not thread-safe. A new instance shall be created for each coordinate operation to infer.
  Since:
    0.7
  See Also:
    `DefaultCoordinateOperationFactory​.createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)`

  Defined in the `sis-referencing` module

- - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `protected Extent` | `areaOfInterest` | The spatiotemporal area of interest, or `null` if none.
    `protected double` | `desiredAccuracy` | The desired accuracy in metres, or 0 for the best accuracy available.
    `protected CoordinateOperationFactory` | `factory` | The factory to use for creating coordinate operations not found in the registry.
    `protected CoordinateOperationAuthorityFactory` | `registry` | The factory to use for creating operations as defined by authority, or `null` if none.

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `CoordinateOperationFinder​(CoordinateOperationAuthorityFactory registry, CoordinateOperationFactory factory, CoordinateOperationContext context)` | Creates a new instance for the given factory and context.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `CoordinateOperation` | `createOperation​(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)` | Infers an operation for conversion or transformation between two coordinate reference systems.
    `List<CoordinateOperation>` | `createOperations​(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)` | Infers operations for conversions or transformations between two coordinate reference systems.
    `protected List<CoordinateOperation>` | `createOperationStep​(CoordinateReferenceSystem sourceCRS, List<? extends SingleCRS> sourceComponents, CoordinateReferenceSystem targetCRS, List<? extends SingleCRS> targetComponents)` | Creates an operation between at least one `CompoundCRS` (usually the source) and an arbitrary CRS.
    `protected List<CoordinateOperation>` | `createOperationStep​(GeneralDerivedCRS sourceCRS, GeneralDerivedCRS targetCRS)` | Creates an operation between two derived coordinate reference systems.
    `protected List<CoordinateOperation>` | `createOperationStep​(GeneralDerivedCRS sourceCRS, SingleCRS targetCRS)` | Creates an operation from a derived CRS to an arbitrary single coordinate reference system.
    `protected List<CoordinateOperation>` | `createOperationStep​(GeodeticCRS sourceCRS, GeodeticCRS targetCRS)` | Creates an operation between two geodetic (geographic or geocentric) coordinate reference systems.
    `protected List<CoordinateOperation>` | `createOperationStep​(GeodeticCRS sourceCRS, VerticalCRS targetCRS)` | Creates an operation between a geodetic and a vertical coordinate reference systems.
    `protected List<CoordinateOperation>` | `createOperationStep​(SingleCRS sourceCRS, GeneralDerivedCRS targetCRS)` | Creates operations from an arbitrary single CRS to a derived coordinate reference system.
    `protected List<CoordinateOperation>` | `createOperationStep​(TemporalCRS sourceCRS, TemporalCRS targetCRS)` | Creates an operation between two temporal coordinate reference systems.
    `protected List<CoordinateOperation>` | `createOperationStep​(VerticalCRS sourceCRS, VerticalCRS targetCRS)` | Creates an operation between two vertical coordinate reference systems.

    - ### Methods inherited from class Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### registry

          protected final CoordinateOperationAuthorityFactory registry

      The factory to use for creating operations as defined by authority, or `null` if none. This is the factory used by the late-binding approach.

    - #### factory

          protected final CoordinateOperationFactory factory

      The factory to use for creating coordinate operations not found in the registry. This is the factory used by the early-binding approach.

    - #### areaOfInterest

          protected Extent areaOfInterest

      The spatiotemporal area of interest, or `null` if none. When a new `CoordinateOperationFinder` instance is created with a non-null `CoordinateOperationContext`, the context is used for initializing this value. After initialization, this field may be updated as `CoordinateOperationFinder` progresses in its search for a coordinate operation.
      See Also:
        `CoordinateOperationContext​.getAreaOfInterest()`

    - #### desiredAccuracy

          protected double desiredAccuracy

      The desired accuracy in metres, or 0 for the best accuracy available.
      See Also:
        `CoordinateOperationContext​.getDesiredAccuracy()`

  - ### Constructor Detail

    - #### CoordinateOperationFinder

          public CoordinateOperationFinder​(CoordinateOperationAuthorityFactory registry,
                                           CoordinateOperationFactory factory,
                                           CoordinateOperationContext context)
                                    throws FactoryException

      Creates a new instance for the given factory and context.
      Parameters:
        `registry` - the factory to use for creating operations as defined by authority, or `null` if none.
        `factory` - the factory to use for creating operations not found in the registry.
        `context` - the area of interest and desired accuracy, or `null` if none.
      Throws:
        `FactoryException` - if an error occurred while initializing this `CoordinateOperationFinder`.
      See Also:
        `DefaultCoordinateOperationFactory​.createOperationFinder(CoordinateOperationAuthorityFactory, CoordinateOperationContext)`

  - ### Method Detail

    - #### createOperation

          public CoordinateOperation createOperation​(CoordinateReferenceSystem sourceCRS,
                                                     CoordinateReferenceSystem targetCRS)
                                              throws OperationNotFoundException,
                                                     FactoryException

      Infers an operation for conversion or transformation between two coordinate reference systems. If a non-null authority factory – the registry – has been specified at construction time, then this method will first query that factory (late-binding approach – see class javadoc). If no operation has been found in the registry or if no registry has been specified to the constructor, this method inspects the given CRS and delegates the work to one or many `createOperationStep(…)` methods (early-binding approach).

      The default implementation invokes `createOperations(sourceCRS, targetCRS)`, then returns the first operation in the returned list or throws an exception if the list is empty.

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `OperationNotFoundException` - if no operation path was found from `sourceCRS` to `targetCRS`.
        `FactoryException` - if the operation creation failed for some other reason.

    - #### createOperations

          public List<CoordinateOperation> createOperations​(CoordinateReferenceSystem sourceCRS,
                                                            CoordinateReferenceSystem targetCRS)
                                                     throws FactoryException

      Infers operations for conversions or transformations between two coordinate reference systems. If a non-null authority factory – the registry – has been specified at construction time, then this method will first query that factory (late-binding approach – see class javadoc). If no operation has been found in the registry or if no registry has been specified to the constructor, this method inspects the given CRS and delegates the work to one or many `createOperationStep(…)` methods (early-binding approach).

      At first, this method is invoked with the `sourceCRS` and `targetCRS` arguments given to the `CoordinateOperationFactory​.createOperation(…)` method. But then, this method may be invoked recursively by some `createOperationStep(…)` methods with different source or target CRS, for example in order to process the base geographic CRS of a projected CRS.

      Coordinate operations are returned in preference order: best operations for the area of interest should be first. The returned list is modifiable: callers can add, remove or set elements without impact on this `CoordinateOperationFinder` instance.

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        coordinate operations from `sourceCRS` to `targetCRS`.
      Throws:
        `OperationNotFoundException` - if no operation path was found from `sourceCRS` to `targetCRS`.
        `FactoryException` - if the operation creation failed for some other reason.
      Since:
        1.0

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(SingleCRS sourceCRS,
                                                                  GeneralDerivedCRS targetCRS)
                                                           throws FactoryException

      Creates operations from an arbitrary single CRS to a derived coordinate reference system. Conversions from `GeographicCRS` to `ProjectedCRS` are also handled by this method, since projected CRS are a special kind of `GeneralDerivedCRS`.

      The default implementation constructs the following operation chain:

      > `sourceCRS → baseCRS → targetCRS`

      where the conversion from `baseCRS` to `targetCRS` is obtained from `targetCRS.getConversionFromBase()`.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        coordinate operations from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(GeneralDerivedCRS sourceCRS,
                                                                  SingleCRS targetCRS)
                                                           throws FactoryException

      Creates an operation from a derived CRS to an arbitrary single coordinate reference system. Conversions from `ProjectedCRS` to `GeographicCRS` are also handled by this method, since projected CRS are a special kind of `GeneralDerivedCRS`.

      The default implementation constructs the following operation chain:

      > `sourceCRS → baseCRS → targetCRS`

      where the conversion from `sourceCRS` to `baseCRS` is obtained from the inverse of `sourceCRS.getConversionFromBase()`.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(GeneralDerivedCRS sourceCRS,
                                                                  GeneralDerivedCRS targetCRS)
                                                           throws FactoryException

      Creates an operation between two derived coordinate reference systems. The default implementation performs three steps:
      1. Convert from `sourceCRS` to its base CRS.
      2. Convert the source base CRS to target base CRS.
      3. Convert from the target base CRS to the `targetCRS`.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(GeodeticCRS sourceCRS,
                                                                  GeodeticCRS targetCRS)
                                                           throws FactoryException

      Creates an operation between two geodetic (geographic or geocentric) coordinate reference systems. The default implementation can:
      - adjust axis order and orientation, for example converting from (North, West) axes to (East, North) axes,
      - apply units conversion if needed,
      - perform longitude rotation if needed,
      - perform datum shift if Bursa-Wolf parameters are available for the area of interest.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(GeodeticCRS sourceCRS,
                                                                  VerticalCRS targetCRS)
                                                           throws FactoryException

      Creates an operation between a geodetic and a vertical coordinate reference systems. The height returned by this method will usually be part of a pass-through operation.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(VerticalCRS sourceCRS,
                                                                  VerticalCRS targetCRS)
                                                           throws FactoryException

      Creates an operation between two vertical coordinate reference systems. The default implementation checks if both CRS use the same datum, then adjusts for axis direction and units.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.
      TODO:
        Needs to implement vertical datum shift.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(TemporalCRS sourceCRS,
                                                                  TemporalCRS targetCRS)
                                                           throws FactoryException

      Creates an operation between two temporal coordinate reference systems. The default implementation checks if both CRS use the same datum, then adjusts for axis direction, units and epoch.

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `targetCRS` - output coordinate reference system.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.

    - #### createOperationStep

          protected List<CoordinateOperation> createOperationStep​(CoordinateReferenceSystem sourceCRS,
                                                                  List<? extends SingleCRS> sourceComponents,
                                                                  CoordinateReferenceSystem targetCRS,
                                                                  List<? extends SingleCRS> targetComponents)
                                                           throws FactoryException

      Creates an operation between at least one `CompoundCRS` (usually the source) and an arbitrary CRS. The default implementation tries to invoke the `createOperation(…)` method with various combinations of source and target components. A preference is given for components of the same type (e.g. source `GeodeticCRS` with target `GeodeticCRS`, etc.).

      This method returns only one step for a chain of concatenated operations (to be built by the caller). But a list is returned because the same step may be implemented by different operation methods. Only one element in the returned list should be selected (usually the first one).

      Parameters:
        `sourceCRS` - input coordinate reference system.
        `sourceComponents` - components of the source CRS.
        `targetCRS` - output coordinate reference system.
        `targetComponents` - components of the target CRS.
      Returns:
        a coordinate operation from `sourceCRS` to `targetCRS`.
      Throws:
        `FactoryException` - if the operation can not be constructed.