# Interface MathTransformProvider

Functional Interface:
  This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface MathTransformProvider
An object capable to create `MathTransform` instances from given parameter values. This interface is the Apache SIS mechanism by which formula are concretized as Java code. A math transform provider ignores the source and target CRS and works with coordinates in predefined axis order and units — typically (east, north, up) in degrees or meters — although some variations are allowed in the number of dimensions (typically the "up" dimension being optional). Adjustments for CRS axis order, units and exact number of dimensions are caller's responsibility.

This interface is generally not used directly. The recommended way to get a `MathTransform` is to find the coordinate operation (generally from a pair of source and target CRS), then to invoke `CoordinateOperation​.getMathTransform()`. Alternatively, one can also use a math transform factory.

Implementations of this interface usually extend `DefaultOperationMethod`, but this is not mandatory. This interface can also be used alone since `MathTransform` instances can be created for other purpose than coordinate operations.

## How to add custom coordinate operations to Apache SIS

`DefaultMathTransformFactory` can discover automatically new coordinate operations (including map projections) by scanning the module path. To define a custom coordinate operation, one needs to define a thread-safe class implementing both this `MathTransformProvider` interface and the `OperationMethod` one. While not mandatory, we suggest to extend `DefaultOperationMethod`. Example:

    public class MyOperationProvider extends DefaultOperationMethod implements MathTransformProvider {
        private static final ParameterDescriptor<Foo> FOO;
        private static final ParameterDescriptor<Bar> BAR;
        private static final ParameterDescriptorGroup PARAMETERS;
        static {
            final var builder = new ParameterBuilder();
            FOO = builder.addName("Foo").create(Foo.class, null);
            BAR = builder.addName("Bar").create(Bar.class, null);
            PARAMETERS = builder.addName("My operation").createGroup(FOO, BAR);
        }

        public MyOperationProvider() {
            super(Map.of(NAME_KEY, PARAMETERS.getName()), PARAMETERS);
        }

        @Override
        public MathTransform createMathTransform(Context context) {
            var pg  = Parameters.castOrWrap(context.getCompletedParameters();
            Foo foo = pg.getMandatoryValue(FOO);
            Bar bar = pg.getMandatoryValue(BAR);
            return new MyOperation(foo, bar);
        }
    }

In the common case where the provider needs numerical parameter values in a specific units of measurement, the following pattern can be used:

        double semiMajor = values.parameter("semi_major").doubleValue(Units.METRE);
        double semiMinor = values.parameter("semi_minor").doubleValue(Units.METRE);

Then the class name of that implementation shall be declared in `module-info​.java` as a provider of the `org​.opengis​.referencing​.operation​.OperationMethod` service.

Since:
  0.6
See Also:
  - `DefaultOperationMethod`
  - `DefaultMathTransformFactory`
  - `AbstractMathTransform`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static interface`
  `MathTransformProvider​.Context`
  The parameter values that define the transform to create, together with its context.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `MathTransform`
  `createMathTransform(MathTransformProvider​.Context context)`
  Creates a math transform from a group of parameter values and its context.
  `default MathTransform`
  `createMathTransform(MathTransformFactory factory, ParameterValueGroup parameters)`
  Creates a math transform from the specified group of parameter values.

- ## Method Details

  - ### createMathTransform

    default MathTransform createMathTransform(MathTransformFactory factory, ParameterValueGroup parameters) throws InvalidParameterNameException, ParameterNotFoundException, InvalidParameterValueException, FactoryException
    Creates a math transform from the specified group of parameter values. Invoking this method is equivalent to invoking `createMathTransform(Context)` with the given factory and parameters wrapped in an instance of `Context`.
    Parameters:
      `factory` - the factory to use if this constructor needs to create other math transforms.
      `parameters` - the parameter values that define the transform to create.
    Returns:
      the math transform created from the given parameters.
    Throws:
      `InvalidParameterNameException` - if the given parameter group contains an unknown parameter.
      `ParameterNotFoundException` - if a required parameter was not found.
      `InvalidParameterValueException` - if a parameter has an invalid value.
      `FactoryException` - if the math transform cannot be created for some other reason (for example a required file was not found).

  - ### createMathTransform

    MathTransform createMathTransform(MathTransformProvider.Context context) throws InvalidParameterNameException, ParameterNotFoundException, InvalidParameterValueException, FactoryException
    Creates a math transform from a group of parameter values and its context. The context includes the factory to use and the desired number of source and target dimensions. The given number of dimensions is only a hint. Providers can use different numbers of dimensions (often hard-coded in the formulas) than the ones specified in the `context`. Callers should check the actual number of dimensions of the returned transform.
    Parameters:
      `context` - the parameter values that define the transform to create, together with its context.
    Returns:
      the math transform created from the given parameters.
    Throws:
      `InvalidParameterNameException` - if the parameter group contains an unknown parameter.
      `ParameterNotFoundException` - if a required parameter was not found.
      `InvalidParameterValueException` - if a parameter has an invalid value.
      `FactoryException` - if the math transform cannot be created for some other reason (for example a required file was not found).
    Since:
      1.5