Search in sources :

Example 61 with Matrix

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

the class EllipsoidToCentricTransform method tryConcatenate.

/**
 * If this transform expects three-dimensional inputs, and if the transform just before this one
 * unconditionally sets the height to zero, then replaces this transform by a two-dimensional one.
 * The intent is to handle the following sequence of operations defined in the EPSG database:
 *
 * <ol>
 *   <li>Inverse of <cite>Geographic 3D to 2D conversion</cite> (EPSG:9659)</li>
 *   <li><cite>Geographic/geocentric conversions</cite> (EPSG:9602)</li>
 * </ol>
 *
 * Replacing the above sequence by a two-dimensional {@code EllipsoidToCentricTransform} instance
 * allow the following optimizations:
 *
 * <ul>
 *   <li>Avoid computation of <var>h</var> value.</li>
 *   <li>Allow use of the more efficient {@link java.awt.geom.AffineTransform} before this transform
 *       instead than a transform based on a matrix of size 4×3.</li>
 * </ul>
 *
 * @return the combined math transform, or {@code null} if no optimized combined transform is available.
 * @throws FactoryException if an error occurred while combining the transforms.
 */
@Override
protected MathTransform tryConcatenate(final boolean applyOtherFirst, final MathTransform other, final MathTransformFactory factory) throws FactoryException {
    if (applyOtherFirst && withHeight && other instanceof LinearTransform && other.getSourceDimensions() == 2) {
        /*
             * Found a 4×3 matrix before this transform. We can reduce to a 3×3 matrix only if the row that we are
             * about to drop unconditionnaly set the height to zero (i.e. all coefficients in that row are zero).
             */
        Matrix matrix = ((LinearTransform) other).getMatrix();
        if (matrix.getElement(2, 0) == 0 && matrix.getElement(2, 1) == 0 && matrix.getElement(2, 2) == 0) {
            matrix = MatrixSIS.castOrCopy(matrix).removeRows(2, 3);
            final MathTransform tr2D = create2D();
            if (factory != null) {
                return factory.createConcatenatedTransform(factory.createAffineTransform(matrix), tr2D);
            } else {
                return ConcatenatedTransform.create(MathTransforms.linear(matrix), tr2D, factory);
            }
        }
    }
    return super.tryConcatenate(applyOtherFirst, other, factory);
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) MathTransform(org.opengis.referencing.operation.MathTransform)

Example 62 with Matrix

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

the class InterpolatedGeocentricTransform method transform.

/**
 * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS,
 * and optionally returns the derivative at that location.
 *
 * @return {@inheritDoc}
 * @throws TransformException if the point can not be transformed or
 *         if a problem occurred while calculating the derivative.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) throws TransformException {
    /*
         * Interpolate the geocentric translation (ΔX,ΔY,ΔZ) for the source coordinate (λ,φ).
         * The translation that we got is in metres, which we convert into normalized units.
         */
    final double[] vector = new double[3];
    // In radians
    grid.interpolateInCell(// In radians
    grid.normalizedToGridX(srcPts[srcOff]), grid.normalizedToGridY(srcPts[srcOff + 1]), vector);
    final double tX = vector[0] / semiMajor;
    final double tY = vector[1] / semiMajor;
    final double tZ = vector[2] / semiMajor;
    /*
         * Geographic → Geocentric conversion. Result stored in a temporary array
         * because we do not check if the target points are two or three dimensional.
         */
    final Matrix m1 = ellipsoidToCentric.transform(srcPts, srcOff, vector, 0, derivate);
    /*
         * Apply the geocentric translation on the geocentric coordinates. If the coordinates were in metres,
         * we would have only additions. But since we use normalized units, we also need to convert from the
         * normalization relative to the source ellipsoid to normalization relative to the target ellipsoid.
         * This is the purpose of the scale factor.
         */
    vector[0] = (vector[0] + tX) * scale;
    vector[1] = (vector[1] + tY) * scale;
    vector[2] = (vector[2] + tZ) * scale;
    /*
         * Final Geocentric → Geographic conversion, and compute the derivative matrix if the user asked for it.
         */
    final Matrix m2 = centricToEllipsoid.transform(vector, 0, dstPts, dstOff, derivate);
    if (m1 == null || m2 == null) {
        return null;
    }
    return concatenate(m1, m2);
}
Also used : Matrix(org.opengis.referencing.operation.Matrix)

Example 63 with Matrix

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

the class PassThroughTransform method create.

/**
 * Creates a transform which passes through a subset of ordinates to another transform.
 * This method returns a transform having the following dimensions:
 *
 * {@preformat java
 *     Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
 *     Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates
 * }
 *
 * Affected ordinates will range from {@code firstAffectedOrdinate} inclusive to
 * {@code dimTarget - numTrailingOrdinates} exclusive.
 *
 * @param  firstAffectedOrdinate  index of the first affected ordinate.
 * @param  subTransform           the sub-transform to apply on modified coordinates.
 * @param  numTrailingOrdinates   number of trailing ordinates to pass through.
 * @return a pass-through transform, not necessarily a {@code PassThroughTransform} instance.
 */
public static MathTransform create(final int firstAffectedOrdinate, final MathTransform subTransform, final int numTrailingOrdinates) {
    ensureNonNull("subTransform", subTransform);
    ensurePositive("firstAffectedOrdinate", firstAffectedOrdinate);
    ensurePositive("numTrailingOrdinates", numTrailingOrdinates);
    if (firstAffectedOrdinate == 0 && numTrailingOrdinates == 0) {
        return subTransform;
    }
    /*
         * Optimizes the "Identity transform" case.
         */
    if (subTransform.isIdentity()) {
        final int dimension = subTransform.getSourceDimensions();
        if (dimension == subTransform.getTargetDimensions()) {
            return IdentityTransform.create(firstAffectedOrdinate + dimension + numTrailingOrdinates);
        }
    }
    /*
         * Special case for transformation backed by a matrix. Is is possible to use a
         * new matrix for such transform, instead of wrapping the sub-transform into a
         * PassThroughTransform object. It is faster and easier to concatenate.
         */
    Matrix matrix = MathTransforms.getMatrix(subTransform);
    if (matrix != null) {
        matrix = expand(MatrixSIS.castOrCopy(matrix), firstAffectedOrdinate, numTrailingOrdinates, 1);
        return MathTransforms.linear(matrix);
    }
    /*
         * Constructs the general PassThroughTransform object. An optimization is done right in
         * the constructor for the case where the sub-transform is already a PassThroughTransform.
         */
    int dim = subTransform.getSourceDimensions();
    if (subTransform.getTargetDimensions() == dim) {
        dim += firstAffectedOrdinate + numTrailingOrdinates;
        if (dim == 2) {
            return new PassThroughTransform2D(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
        }
    }
    return new PassThroughTransform(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
}
Also used : Matrix(org.opengis.referencing.operation.Matrix)

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