Search in sources :

Example 16 with MatrixSIS

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

the class BursaWolfParametersTest method getPositionVectorTransformation.

/**
 * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)}
 * and compares with our own matrix calculated using double arithmetic.
 */
private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) {
    final double S = 1 + p.dS / BursaWolfParameters.PPM;
    final double RS = TO_RADIANS * S;
    final Matrix4 expected = new Matrix4(S, -p.rZ * RS, +p.rY * RS, p.tX, +p.rZ * RS, S, -p.rX * RS, p.tY, -p.rY * RS, +p.rX * RS, S, p.tZ, 0, 0, 0, 1);
    final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation(null));
    assertMatrixEquals("getPositionVectorTransformation", expected, matrix, p.isTranslation() ? 0 : 1E-14);
    return matrix;
}
Also used : Matrix4(org.apache.sis.referencing.operation.matrix.Matrix4) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Example 17 with MatrixSIS

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

the class ContextualParameters method denormalizeGeographicOutputs.

/**
 * Appends a denormalization step after the non-linear kernel, which will convert input ordinates
 * in the two first dimensions from radians to degrees. After this conversion, the denormalization
 * can optionally add the given λ₀ value (in degrees) to the longitude.
 *
 * <p>Invoking this method is equivalent to {@linkplain java.awt.geom.AffineTransform#concatenate concatenating}
 * the denormalization matrix with the following matrix. This will have the effect of applying the conversion
 * described above after the non-linear kernel operation:</p>
 *
 * <center>{@include formulas.html#DenormalizeGeographic}</center>
 *
 * @param  λ0  longitude of the central meridian, in degrees.
 * @return the denormalization affine transform as a matrix.
 *         Callers can change that matrix directly if they want to apply additional denormalization operations.
 * @throws IllegalStateException if this {@code ContextualParameter} has been made unmodifiable.
 */
public synchronized MatrixSIS denormalizeGeographicOutputs(final double λ0) {
    ensureModifiable();
    final DoubleDouble toDegrees = DoubleDouble.createRadiansToDegrees();
    // Must be the same instance, not a copy.
    final MatrixSIS denormalize = (MatrixSIS) this.denormalize;
    denormalize.convertAfter(0, toDegrees, (λ0 != 0) ? λ0 : null);
    denormalize.convertAfter(1, toDegrees, null);
    return denormalize;
}
Also used : MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS) DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Example 18 with MatrixSIS

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

the class CopyTransform method inverse.

/**
 * Creates the inverse transform of this object.
 */
@Override
// Okay since 'inverse' is volatile.
@SuppressWarnings("DoubleCheckedLocking")
public LinearTransform inverse() throws NoninvertibleTransformException {
    LinearTransform inv = inverse;
    if (inv == null) {
        synchronized (this) {
            inv = inverse;
            if (inv == null) {
                /*
                     * Note: no need to perform the following check at this point because MathTransforms.linear(…)
                     *       should never instantiate this class in the identity case and because we perform an
                     *       equivalent check later anyway.
                     *
                     *       if (isIdentity()) {
                     *           inverse = this;
                     *       } else { ... }
                     */
                final int srcDim = this.srcDim;
                final int dstDim = indices.length;
                final int[] reverse = new int[srcDim];
                Arrays.fill(reverse, -1);
                for (int i = dstDim; --i >= 0; ) {
                    reverse[indices[i]] = i;
                }
                /*
                     * Check if there is any unassigned dimension. In such case,
                     * delegates to the generic ProjectiveTransform with a matrix
                     * which set the missing values to NaN.
                     */
                for (int j = srcDim; --j >= 0; ) {
                    if (reverse[j] < 0) {
                        final MatrixSIS matrix = Matrices.createZero(srcDim + 1, dstDim + 1);
                        for (j = 0; j < srcDim; j++) {
                            // Okay to reuse 'j' since the outer loop will not continue.
                            final int i = reverse[j];
                            if (i >= 0) {
                                matrix.setElement(j, i, 1);
                            } else {
                                matrix.setElement(j, dstDim, Double.NaN);
                            }
                        }
                        matrix.setElement(srcDim, dstDim, 1);
                        inv = MathTransforms.linear(matrix);
                        if (inv instanceof AbstractLinearTransform) {
                            ((AbstractLinearTransform) inv).inverse = this;
                        }
                        inverse = inv;
                        return inv;
                    }
                }
                /*
                     * At this point, we know that we can create the inverse transform.
                     * If this transform is the identity transform or an anti-diagonal matrix except last row
                     * (e.g. matrix used for swapping axis order), then the old and new arrays would be equal.
                     */
                CopyTransform copyInverse = this;
                if (!Arrays.equals(reverse, indices)) {
                    copyInverse = new CopyTransform(indices.length, reverse);
                    copyInverse.inverse = this;
                }
                inverse = inv = copyInverse;
            }
        }
    }
    return inv;
}
Also used : MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Example 19 with MatrixSIS

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

the class EllipsoidToCentricTransform method createGeodeticConversion.

/**
 * Creates a transform from geographic to geocentric coordinates. This factory method combines the
 * {@code EllipsoidToCentricTransform} instance with the steps needed for converting degrees to
 * radians and expressing the results in units of the given ellipsoid.
 *
 * <p>Input coordinates are expected to contain:</p>
 * <ol>
 *   <li>longitudes in <strong>degrees</strong> relative to the prime meridian (usually Greenwich),</li>
 *   <li>latitudes in <strong>degrees</strong>,</li>
 *   <li>optionally heights above the ellipsoid, in units of the ellipsoid axis (usually metres).</li>
 * </ol>
 *
 * Output coordinates are as below, in units of the ellipsoid axis (usually metres):
 * <ol>
 *   <li>distance from Earth center on the X axis (toward the intersection of prime meridian and equator),</li>
 *   <li>distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),</li>
 *   <li>distance from Earth center on the Z axis (toward North pole).</li>
 * </ol>
 *
 * @param  factory     the factory to use for creating and concatenating the affine transforms.
 * @param  semiMajor   the semi-major axis length.
 * @param  semiMinor   the semi-minor axis length.
 * @param  unit        the unit of measurement for the semi-axes and the ellipsoidal height.
 * @param  withHeight  {@code true} if source geographic coordinates include an ellipsoidal height
 *                     (i.e. are 3-D), or {@code false} if they are only 2-D.
 * @param  target      whether the target coordinate shall be Cartesian or Spherical.
 * @return the conversion from geographic to geocentric coordinates.
 * @throws FactoryException if an error occurred while creating a transform.
 */
public static MathTransform createGeodeticConversion(final MathTransformFactory factory, final double semiMajor, final double semiMinor, final Unit<Length> unit, final boolean withHeight, final TargetType target) throws FactoryException {
    if (Math.abs(semiMajor - semiMinor) <= semiMajor * (Formulas.LINEAR_TOLERANCE / ReferencingServices.AUTHALIC_RADIUS)) {
        /*
             * If semi-major axis length is almost equal to semi-minor axis length, uses spherical equations instead.
             * We need to add the sphere radius to the elevation before to perform spherical to Cartesian conversion.
             */
        final MatrixSIS translate = Matrices.createDiagonal(4, withHeight ? 4 : 3);
        translate.setElement(2, withHeight ? 3 : 2, semiMajor);
        if (!withHeight) {
            translate.setElement(3, 2, 1);
        }
        final MathTransform tr = SphericalToCartesian.INSTANCE.completeTransform(factory);
        return factory.createConcatenatedTransform(factory.createAffineTransform(translate), tr);
    }
    EllipsoidToCentricTransform tr = new EllipsoidToCentricTransform(semiMajor, semiMinor, unit, withHeight, target);
    return tr.context.completeTransform(factory, tr);
}
Also used : MathTransform(org.opengis.referencing.operation.MathTransform) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Example 20 with MatrixSIS

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

the class ProjectiveTransform method derivative.

/**
 * Gets the derivative of this transform at a point.
 * For a matrix transform, the derivative is the same everywhere.
 *
 * @param  point  ignored (can be {@code null}).
 */
@Override
public final Matrix derivative(final DirectPosition point) {
    final int srcDim = numCol - 1;
    final int dstDim = numRow - 1;
    final MatrixSIS matrix = Matrices.createZero(dstDim, srcDim);
    int mix = 0;
    for (int j = 0; j < dstDim; j++) {
        for (int i = 0; i < srcDim; i++) {
            matrix.setElement(j, i, elt[mix++]);
        }
        // Skip translation column.
        mix++;
    }
    return matrix;
}
Also used : MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Aggregations

MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)20 DoubleDouble (org.apache.sis.internal.util.DoubleDouble)5 Test (org.junit.Test)4 Matrix4 (org.apache.sis.referencing.operation.matrix.Matrix4)3 DependsOnMethod (org.apache.sis.test.DependsOnMethod)3 MathTransform (org.opengis.referencing.operation.MathTransform)3 FactoryException (org.opengis.util.FactoryException)3 ExtendedPrecisionMatrix (org.apache.sis.internal.referencing.ExtendedPrecisionMatrix)2 Parameters (org.apache.sis.parameter.Parameters)2 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)2 Matrix (org.opengis.referencing.operation.Matrix)2 AffineTransform (java.awt.geom.AffineTransform)1 Date (java.util.Date)1 IncommensurableException (javax.measure.IncommensurableException)1 DirectPosition2D (org.apache.sis.geometry.DirectPosition2D)1 ParameterizedAffine (org.apache.sis.internal.referencing.j2d.ParameterizedAffine)1 FormattableObject (org.apache.sis.io.wkt.FormattableObject)1 Line (org.apache.sis.math.Line)1 Plane (org.apache.sis.math.Plane)1 InvalidGeodeticParameterException (org.apache.sis.referencing.factory.InvalidGeodeticParameterException)1