Search in sources :

Example 36 with Matrix

use of org.opengis.referencing.operation.Matrix in project sis by apache.

the class SpecializableTransform method transform.

/**
 * Transforms a single coordinate point in an array, and optionally computes the transform
 * derivative at that location. This method delegates to the most specialized transform.
 */
@Override
public final Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, boolean derivate) throws TransformException {
    final DirectPositionView pos = new DirectPositionView.Double(srcPts, srcOff, global.getSourceDimensions());
    final MathTransform tr = forDomain(SubArea.find(domains, pos));
    if (tr instanceof AbstractMathTransform) {
        return ((AbstractMathTransform) tr).transform(srcPts, srcOff, dstPts, dstOff, derivate);
    } else {
        // Must be before transform(srcPts, …).
        Matrix derivative = derivate ? tr.derivative(pos) : null;
        if (dstPts != null) {
            tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
        }
        return derivative;
    }
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) MathTransform(org.opengis.referencing.operation.MathTransform) DirectPositionView(org.apache.sis.internal.referencing.DirectPositionView)

Example 37 with Matrix

use of org.opengis.referencing.operation.Matrix in project sis by apache.

the class AbstractMathTransform method derivative.

/**
 * Gets the derivative of this transform at a point.
 * The default implementation performs the following steps:
 *
 * <ul>
 *   <li>Ensure that the {@code point} dimension is equals to this math transform
 *       {@linkplain #getSourceDimensions() source dimensions}.</li>
 *   <li>Copy the coordinate in a temporary array and pass that array to the
 *       {@link #transform(double[], int, double[], int, boolean)} method,
 *       with the {@code derivate} boolean argument set to {@code true}.</li>
 *   <li>If the later method returned a non-null matrix, returns that matrix.
 *       Otherwise throws {@link TransformException}.</li>
 * </ul>
 *
 * @param  point  the coordinate point where to evaluate the derivative.
 * @return the derivative at the specified point (never {@code null}).
 * @throws NullPointerException if the derivative depends on coordinate and {@code point} is {@code null}.
 * @throws MismatchedDimensionException if {@code point} does not have the expected dimension.
 * @throws TransformException if the derivative can not be evaluated at the specified point.
 */
@Override
public Matrix derivative(final DirectPosition point) throws TransformException {
    final int dimSource = getSourceDimensions();
    final double[] coordinate = point.getCoordinate();
    if (coordinate.length != dimSource) {
        throw mismatchedDimension("point", dimSource, coordinate.length);
    }
    final Matrix derivative = transform(coordinate, 0, null, 0, true);
    if (derivative == null) {
        throw new TransformException(Resources.format(Resources.Keys.CanNotComputeDerivative));
    }
    return derivative;
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) TransformException(org.opengis.referencing.operation.TransformException)

Example 38 with Matrix

use of org.opengis.referencing.operation.Matrix in project sis by apache.

the class MathTransformContext method getMatrix.

/**
 * Returns the normalization or denormalization matrix.
 */
@Override
@SuppressWarnings("fallthrough")
public Matrix getMatrix(final MatrixRole role) throws FactoryException {
    final CoordinateSystem cs;
    boolean inverse = false;
    double rotation;
    switch(role) {
        default:
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "role", role));
        // Fall through
        case INVERSE_NORMALIZATION:
            inverse = true;
        case NORMALIZATION:
            rotation = sourceMeridian;
            cs = getSourceCS();
            break;
        // Fall through
        case INVERSE_DENORMALIZATION:
            inverse = true;
        case DENORMALIZATION:
            inverse = !inverse;
            rotation = targetMeridian;
            cs = getTargetCS();
            break;
    }
    Matrix matrix = super.getMatrix(role);
    if (rotation != 0) {
        if (inverse)
            rotation = -rotation;
        MatrixSIS cm = MatrixSIS.castOrCopy(matrix);
        if (cs instanceof CartesianCS) {
            rotation = Math.toRadians(rotation);
            final Matrix4 rot = new Matrix4();
            rot.m00 = rot.m11 = Math.cos(rotation);
            rot.m01 = -(rot.m10 = Math.sin(rotation));
            if (inverse) {
                // Apply the rotation after denormalization.
                matrix = Matrices.multiply(rot, cm);
            } else {
                // Apply the rotation before normalization.
                matrix = cm.multiply(rot);
            }
        } else if (cs == null || cs instanceof EllipsoidalCS || cs instanceof SphericalCS) {
            final Double value = rotation;
            if (inverse) {
                // Longitude is the first axis in normalized CS.
                cm.convertBefore(0, null, value);
            } else {
                cm.convertAfter(0, null, value);
            }
            matrix = cm;
        } else {
            throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getName()));
        }
    }
    return matrix;
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) SphericalCS(org.opengis.referencing.cs.SphericalCS) Matrix(org.opengis.referencing.operation.Matrix) FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS) Matrix4(org.apache.sis.referencing.operation.matrix.Matrix4)

Example 39 with Matrix

use of org.opengis.referencing.operation.Matrix in project sis by apache.

the class SubOperationInfo method sourceToSelected.

/**
 * Returns a matrix for an affine transform from all source coordinates to the coordinates of the
 * source components selected for participating in the coordinate operation.
 *
 * @param sourceDimensions    number of dimension of the source {@code CompoundCRS}.
 * @param selectedDimensions  number of source dimensions needed by the coordinate operations.
 * @param selected            all {@code SourceComponent} instances needed for the target {@code CompoundCRS}.
 */
static Matrix sourceToSelected(final int sourceDimensions, final int selectedDimensions, final SubOperationInfo[] selected) {
    final Matrix select = Matrices.createZero(selectedDimensions + 1, sourceDimensions + 1);
    select.setElement(selectedDimensions, sourceDimensions, 1);
    int j = 0;
    for (final SubOperationInfo component : selected) {
        for (int i = component.startAtDimension; i < component.endAtDimension; i++) {
            select.setElement(j++, i, 1);
        }
    }
    return select;
}
Also used : Matrix(org.opengis.referencing.operation.Matrix)

Example 40 with Matrix

use of org.opengis.referencing.operation.Matrix in project sis by apache.

the class TransformSeparatorTest method testLinearTransform.

/**
 * Tests separation of a linear transform.
 *
 * @throws FactoryException if an error occurred while creating a new transform.
 */
@Test
public void testLinearTransform() throws FactoryException {
    Matrix matrix = Matrices.create(4, 4, new double[] { // Some random values.
    2, // Some random values.
    0, // Some random values.
    0, // Some random values.
    7, 0, 5, 0, 6, 1, 0, 3, 8, 0, 0, 0, 1 });
    final TransformSeparator s = new TransformSeparator(MathTransforms.linear(matrix));
    /*
         * Trivial case: no dimension specified, we should get the transform unchanged.
         */
    assertSame("transform", s.transform, s.separate());
    assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2 }, s.getSourceDimensions());
    assertArrayEquals("targetDimensions", new int[] { 0, 1, 2 }, s.getTargetDimensions());
    /*
         * Filter only target dimensions. This is the easiest non-trivial case since we just
         * need to drop some rows. There is no analysis to perform on the matrix values.
         */
    matrix = Matrices.create(3, 4, new double[] { 2, 0, 0, 7, 1, 0, 3, 8, 0, 0, 0, 1 });
    s.clear();
    s.addTargetDimensions(0, 2);
    assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
    assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2 }, s.getSourceDimensions());
    assertArrayEquals("targetDimensions", new int[] { 0, 2 }, s.getTargetDimensions());
    /*
         * Filter only source dimensions. Do not specify any target dimensions for now.
         * TransformSeparator needs to examine the matrix values and drop all target dimensions
         * that depend on an excluded source dimensions.
         */
    matrix = Matrices.create(2, 3, new double[] { 5, 0, 6, 0, 0, 1 });
    s.clear();
    s.addSourceDimensions(1, 2);
    assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
    assertArrayEquals("sourceDimensions", new int[] { 1, 2 }, s.getSourceDimensions());
    assertArrayEquals("targetDimensions", new int[] { 1 }, s.getTargetDimensions());
    /*
         * Filter both source and target dimensions. Source dimensions 0 and 2 allow the target dimensions 0 and 2
         * (target dimension 1 is discarded because it depends on source dimension 1).  Then the target dimensions
         * are filtered for retaining only dimension 0.
         */
    matrix = Matrices.create(2, 3, new double[] { 2, 0, 7, 0, 0, 1 });
    s.clear();
    s.addSourceDimensions(0, 2);
    s.addTargetDimensions(0);
    assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
    assertArrayEquals("sourceDimensions", new int[] { 0, 2 }, s.getSourceDimensions());
    assertArrayEquals("targetDimensions", new int[] { 0 }, s.getTargetDimensions());
    /*
         * Try again, but with the addition of a target dimension that TransformSeparator can not keep.
         * It shall cause an exception to be thrown.
         */
    s.addTargetDimensions(1);
    try {
        s.separate();
        fail("Should not have been able to separate that transform.");
    } catch (FactoryException e) {
        // This is the expected exception.
        assertNotNull(e.getMessage());
    }
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) FactoryException(org.opengis.util.FactoryException) Test(org.junit.Test)

Aggregations

Matrix (org.opengis.referencing.operation.Matrix)63 Test (org.junit.Test)20 DependsOnMethod (org.apache.sis.test.DependsOnMethod)11 MathTransform (org.opengis.referencing.operation.MathTransform)8 HashMap (java.util.HashMap)6 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)6 NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)5 TransformException (org.opengis.referencing.operation.TransformException)5 FormattableObject (org.apache.sis.io.wkt.FormattableObject)4 DirectPosition1D (org.apache.sis.geometry.DirectPosition1D)3 ExtendedPrecisionMatrix (org.apache.sis.internal.referencing.ExtendedPrecisionMatrix)3 Matrix3 (org.apache.sis.referencing.operation.matrix.Matrix3)3 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)3 FactoryException (org.opengis.util.FactoryException)3 DirectPosition2D (org.apache.sis.geometry.DirectPosition2D)2 DirectPositionView (org.apache.sis.internal.referencing.DirectPositionView)2 Parameterized (org.apache.sis.parameter.Parameterized)2 MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)2 GeneralParameterValue (org.opengis.parameter.GeneralParameterValue)2 ParameterValue (org.opengis.parameter.ParameterValue)2