Search in sources :

Example 1 with NoninvertibleMatrixException

use of org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException in project sis by apache.

the class ContextualParameters method getMatrix.

/**
 * Returns the affine transforms to be applied before or after the non-linear kernel operation.
 * Immediately after {@linkplain #ContextualParameters(OperationMethod) construction}, those matrices
 * are modifiable identity matrices. Callers can modify the matrix element values, typically by calls to
 * the {@link MatrixSIS#convertBefore(int, Number, Number) MatrixSIS.convertBefore(…)} method.
 * Alternatively, the following methods can be invoked for applying some frequently used configurations:
 *
 * <ul>
 *   <li>{@link #normalizeGeographicInputs(double)}</li>
 *   <li>{@link #denormalizeGeographicOutputs(double)}</li>
 * </ul>
 *
 * After the {@link #completeTransform(MathTransformFactory, MathTransform) completeTransform(…)} method has been
 * invoked, the matrices returned by this method are {@linkplain Matrices#unmodifiable(Matrix) unmodifiable}.
 *
 * <div class="note"><b>Application to map projections:</b>
 * after {@link org.apache.sis.referencing.operation.projection.NormalizedProjection} construction, the matrices
 * returned by {@code projection.getContextualParameters().getMatrix(…)} are initialized to the values shown below.
 * Note that some {@code NormalizedProjection} subclasses apply further modifications to those matrices.
 *
 * <table class="sis">
 *   <caption>Initial matrix coefficients after {@code NormalizedProjection} construction</caption>
 *   <tr>
 *     <th>{@code getMatrix(NORMALIZATION)}</th>
 *     <th class="sep">{@code getMatrix(DENORMALIZATION)}</th>
 *   </tr><tr>
 *     <td>{@include formulas.html#NormalizeGeographic}</td>
 *     <td class="sep">{@include formulas.html#DenormalizeCartesian}</td>
 *   </tr>
 * </table>
 * </div>
 *
 * @param  role  {@code NORMALIZATION} for fetching the <cite>normalization</cite> transform to apply before the kernel,
 *               {@code DENORMALIZATION} for the <cite>denormalization</cite> transform to apply after the kernel, or
 *               {@code INVERSE_*} for the inverse of the above-cited matrices.
 * @return the matrix for the requested normalization or denormalization affine transform.
 *
 * @since 0.7
 */
public final MatrixSIS getMatrix(MatrixRole role) {
    final Matrix fallback;
    final ContextualParameters inverse;
    synchronized (this) {
        switch(role) {
            default:
                throw new AssertionError(role);
            case NORMALIZATION:
                return toMatrixSIS(normalize);
            case DENORMALIZATION:
                return toMatrixSIS(denormalize);
            case INVERSE_NORMALIZATION:
                role = MatrixRole.DENORMALIZATION;
                fallback = normalize;
                break;
            case INVERSE_DENORMALIZATION:
                role = MatrixRole.NORMALIZATION;
                fallback = denormalize;
                break;
        }
        // Copy the reference while we are inside the synchronized block.
        inverse = this.inverse;
    }
    /*
         * Following must be outside the synchronized block in order to avoid potential deadlock while invoking
         * inverse.getMatrix(role). We do not cache the matrix here, but 'inverse' is likely to have cached it.
         */
    final Matrix m;
    if (inverse != null) {
        m = inverse.getMatrix(role);
    } else
        try {
            m = Matrices.inverse(fallback);
        } catch (NoninvertibleMatrixException e) {
            throw new IllegalStateException(Errors.format(Errors.Keys.CanNotCompute_1, role), e);
        }
    return Matrices.unmodifiable(m);
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) ExtendedPrecisionMatrix(org.apache.sis.internal.referencing.ExtendedPrecisionMatrix) NoninvertibleMatrixException(org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException)

Example 2 with NoninvertibleMatrixException

use of org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException in project sis by apache.

the class InterpolatedTransform method createGeodeticTransformation.

/**
 * Creates a transformation between two geodetic CRS. This factory method combines the
 * {@code InterpolatedTransform} instance with the steps needed for converting values between
 * geodetic and grid coordinates.
 *
 * <div class="section">Unit of measurement</div>
 * The unit of measurement is determined by {@link DatumShiftGrid#getCoordinateUnit()}:
 * <ul>
 *   <li>If the datum shift unit {@linkplain Units#isAngular(Unit) is angular}, then the transform
 *       will work with input and output coordinates in degrees of angle.</li>
 *   <li>If the datum shift unit {@linkplain Units#isLinear(Unit) is linear}, then the transform
 *       will work with input and output coordinates in metres.</li>
 *   <li>If the datum shift unit {@linkplain Units#isTemporal(Unit) is temporal}, then the transform
 *       will work with input and output coordinates in seconds.</li>
 *   <li>Generally for all units other than angular, the transform will work with input and output
 *       coordinates in the unit given by {@link Unit#getSystemUnit()}.</li>
 * </ul>
 *
 * @param  <T>      dimension of the coordinate and the translation unit.
 * @param  factory  the factory to use for creating the transform.
 * @param  grid     the grid of datum shifts from source to target datum.
 *                  The {@link DatumShiftGrid#interpolateInCell DatumShiftGrid.interpolateInCell(…)}
 *                  method shall compute translations from <em>source</em> to <em>target</em> as
 *                  {@linkplain DatumShiftGrid#isCellValueRatio() ratio of offsets divided by cell sizes}.
 * @return the transformation between geodetic coordinates.
 * @throws FactoryException if an error occurred while creating a transform.
 */
public static <T extends Quantity<T>> MathTransform createGeodeticTransformation(final MathTransformFactory factory, final DatumShiftGrid<T, T> grid) throws FactoryException {
    ArgumentChecks.ensureNonNull("grid", grid);
    final InterpolatedTransform tr;
    try {
        if (grid.getTranslationDimensions() == 2) {
            tr = new InterpolatedTransform2D(grid);
        } else {
            tr = new InterpolatedTransform(grid);
        }
    } catch (NoninvertibleMatrixException e) {
        throw new FactoryException(e.getLocalizedMessage(), e);
    }
    return tr.context.completeTransform(factory, tr);
}
Also used : FactoryException(org.opengis.util.FactoryException) NoninvertibleMatrixException(org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException)

Aggregations

NoninvertibleMatrixException (org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException)2 ExtendedPrecisionMatrix (org.apache.sis.internal.referencing.ExtendedPrecisionMatrix)1 Matrix (org.opengis.referencing.operation.Matrix)1 FactoryException (org.opengis.util.FactoryException)1