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);
}
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);
}
Aggregations