Search in sources :

Example 11 with NoninvertibleTransformException

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

the class Geographic3Dto2DTest method createDatumShiftForGeographic2D.

/**
 * Creates a "Geographic 2D to 3D → Geocentric → Affine → Geographic → Geographic 3D to 2D" chain.
 * This method is used for integration tests.
 *
 * @param  factory  the math transform factory to use for creating and concatenating the transform.
 * @param  affine   the math transform for the operation in geocentric Cartesian domain.
 * @param  pv       the parameters for the operation in geographic coordinates.
 * @return the chain of transforms.
 * @throws FactoryException if an error occurred while creating a transform.
 *
 * @see GeocentricTranslationTest#createDatumShiftForGeographic2D(MathTransformFactory)
 */
static MathTransform createDatumShiftForGeographic2D(final MathTransformFactory factory, final MathTransform affine, final Parameters pv) throws FactoryException {
    assertEquals("sourceDimensions", 3, affine.getSourceDimensions());
    assertEquals("targetDimensions", 3, affine.getTargetDimensions());
    /*
         * Create a "Geographic to Geocentric" conversion with ellipsoid axis length units converted to metres
         * (the unit implied by SRC_SEMI_MAJOR) because it is the unit of Bursa-Wolf parameters that we created above.
         */
    Parameters step = Parameters.castOrWrap(factory.getDefaultParameters(GeographicToGeocentric.NAME));
    step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.SRC_SEMI_MAJOR));
    step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.SRC_SEMI_MINOR));
    MathTransform toGeocentric = factory.createParameterizedTransform(step);
    assertEquals("sourceDimensions", 3, toGeocentric.getSourceDimensions());
    assertEquals("targetDimensions", 3, toGeocentric.getTargetDimensions());
    final MathTransform reduce = factory.createParameterizedTransform(factory.getDefaultParameters("Geographic3D to 2D conversion"));
    assertEquals("sourceDimensions", 3, reduce.getSourceDimensions());
    assertEquals("targetDimensions", 2, reduce.getTargetDimensions());
    try {
        toGeocentric = factory.createConcatenatedTransform(reduce.inverse(), toGeocentric);
    } catch (NoninvertibleTransformException e) {
        throw new FactoryException(e);
    }
    assertEquals("sourceDimensions", 2, toGeocentric.getSourceDimensions());
    assertEquals("targetDimensions", 3, toGeocentric.getTargetDimensions());
    /*
         * Create a "Geocentric to Geographic" conversion with ellipsoid axis length units converted to metres
         * because this is the unit of the Geocentric CRS used above.
         */
    step = Parameters.castOrWrap(factory.getDefaultParameters(GeocentricToGeographic.NAME));
    step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.TGT_SEMI_MAJOR));
    step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.TGT_SEMI_MINOR));
    MathTransform toGeographic = factory.createParameterizedTransform(step);
    assertEquals("sourceDimensions", 3, toGeographic.getSourceDimensions());
    assertEquals("targetDimensions", 3, toGeographic.getTargetDimensions());
    toGeographic = factory.createConcatenatedTransform(toGeographic, reduce);
    assertEquals("sourceDimensions", 3, toGeographic.getSourceDimensions());
    assertEquals("targetDimensions", 2, toGeographic.getTargetDimensions());
    /*
         * The  Geocentric → Affine → Geographic  chain.
         */
    return factory.createConcatenatedTransform(toGeocentric, factory.createConcatenatedTransform(affine, toGeographic));
}
Also used : NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) Parameters(org.apache.sis.parameter.Parameters) MathTransform(org.opengis.referencing.operation.MathTransform) FactoryException(org.opengis.util.FactoryException)

Example 12 with NoninvertibleTransformException

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

the class AbstractLinearTransform method equals.

/**
 * Compares the specified object with this linear transform for equality.
 * This implementation returns {@code true} if the following conditions are meet:
 * <ul>
 *   <li>In {@code STRICT} mode, the objects are of the same class and {@link #equalsSameClass(Object)}
 *       returns {@code true}.</li>
 *   <li>In other modes, the matrix are equals or approximatively equals (depending on the mode).</li>
 * </ul>
 *
 * @param  object  the object to compare with this transform.
 * @param  mode    the strictness level of the comparison. Default to {@link ComparisonMode#STRICT STRICT}.
 * @return {@code true} if the given object is considered equals to this math transform.
 */
@Override
public final boolean equals(final Object object, final ComparisonMode mode) {
    if (object == this) {
        // Slight optimization
        return true;
    }
    if (object == null) {
        return false;
    }
    final boolean isApproximative = mode.isApproximative();
    if (!isApproximative && getClass() == object.getClass()) {
        if (!equalsSameClass(object)) {
            return false;
        }
    } else if (mode == ComparisonMode.STRICT) {
        return false;
    } else {
        final Matrix m;
        if (object instanceof LinearTransform) {
            m = ((LinearTransform) object).getMatrix();
        } else if (object instanceof Matrix) {
            m = (Matrix) object;
        } else {
            return false;
        }
        if (!Matrices.equals(this, m, mode)) {
            return false;
        }
    }
    /*
         * At this point the transforms are considered equal. In theory we would not need to check
         * the inverse transforms since if A and B are equal, then A⁻¹ and B⁻¹ should be equal too.
         * However in Apache SIS this is not exactly true because computation of inverse transforms
         * avoid NaN values in some circumstances. For example the inverse of a 2×3 matrix normally
         * sets the "new" dimensions to NaN, but in the particular case where the transform is used
         * for a "Geographic 2D to 3D" conversion it will rather set the new dimensions to zero. So
         * A⁻¹ and B⁻¹ may differ in their "NaN versus 0" values even if A and B are equal.
         *
         * Opportunistically, the comparison of inverse transforms in approximative mode also ensures
         * that we are below the tolerance threshold not only for this matrix, but for the inverse one
         * as well.
         */
    if (object instanceof AbstractLinearTransform) {
        /*
             * If the 'inverse' matrix was not computed in any of the transforms being compared
             * (i.e. if 'this.inverse' and 'object.inverse' are both null), then assume that the
             * two transforms will compute their inverse in the same way. The intent is to avoid
             * to trig the inverse transform computation.
             *
             * Note that this code requires the 'inverse' fields to be volatile
             * (otherwise we would need to synchronize).
             */
        if (inverse == ((AbstractLinearTransform) object).inverse) {
            return true;
        }
    }
    /*
         * Get the matrices of inverse transforms. In the following code 'null' is really the intended
         * value for non-invertible matrices because the Matrices.equals(…) methods accept null values,
         * so we are okay to ignore NoninvertibleTransformException in this particular case.
         */
    Matrix mt = null, mo = null;
    try {
        mt = inverse().getMatrix();
    } catch (NoninvertibleTransformException e) {
    // Leave 'mt' to null.
    }
    try {
        if (object instanceof LinearTransform) {
            mo = ((LinearTransform) object).inverse().getMatrix();
        } else if (object instanceof Matrix) {
            mo = Matrices.inverse((Matrix) object);
        }
    } catch (NoninvertibleTransformException e) {
    // Leave 'mo' to null.
    }
    return Matrices.equals(mt, mo, isApproximative ? Numerics.COMPARISON_THRESHOLD : 0, isApproximative);
}
Also used : NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) Matrix(org.opengis.referencing.operation.Matrix)

Example 13 with NoninvertibleTransformException

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

the class LinearInterpolator1D method create.

/**
 * Creates a <i>y=f(x)</i> transform for the given preimage (<var>x</var>) and values (<var>y</var>).
 * See {@link MathTransforms#interpolate(double[], double[])} javadoc for more information.
 */
static MathTransform1D create(final double[] preimage, final double[] values) {
    final int length;
    if (preimage == null) {
        if (values == null) {
            return IdentityTransform1D.INSTANCE;
        }
        length = values.length;
    } else {
        length = preimage.length;
        if (values != null && values.length != length) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedArrayLengths));
        }
    }
    switch(length) {
        case 0:
            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, (preimage != null) ? "preimage" : "values"));
        case 1:
            return LinearTransform1D.constant((preimage != null) ? preimage[0] : Double.NaN, (values != null) ? values[0] : Double.NaN);
    }
    /*
         * A common usage of this 'create' method is for creating a "gridToCRS" transform from grid coordinates
         * to something else, in which case the preimage array is null. In the less frequent case where preimage
         * is non-null, we first convert from preimage to indices, then from indices to y values.
         */
    MathTransform1D tr = null;
    if (values != null) {
        tr = create(values.clone());
    }
    if (preimage != null) {
        final MathTransform1D indexToValues = tr;
        try {
            // preimageToIndex transform.
            tr = create(preimage.clone()).inverse();
        } catch (NoninvertibleTransformException e) {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.NonMonotonicSequence_1, "preimage"), e);
        }
        if (indexToValues != null) {
            tr = MathTransforms.concatenate(tr, indexToValues);
        }
    }
    return tr;
}
Also used : NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) MathTransform1D(org.opengis.referencing.operation.MathTransform1D)

Aggregations

NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)13 MathTransform (org.opengis.referencing.operation.MathTransform)7 Path (java.nio.file.Path)4 FactoryException (org.opengis.util.FactoryException)4 IOException (java.io.IOException)3 Parameters (org.apache.sis.parameter.Parameters)3 Cache (org.apache.sis.util.collection.Cache)3 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)3 ReadableByteChannel (java.nio.channels.ReadableByteChannel)2 Angle (javax.measure.quantity.Angle)2 Length (javax.measure.quantity.Length)2 AbstractCoordinateOperation (org.apache.sis.referencing.operation.AbstractCoordinateOperation)2 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)2 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)2 MathTransform1D (org.opengis.referencing.operation.MathTransform1D)2 TransformException (org.opengis.referencing.operation.TransformException)2 Point2D (java.awt.geom.Point2D)1 BufferedReader (java.io.BufferedReader)1 ByteBuffer (java.nio.ByteBuffer)1 FloatBuffer (java.nio.FloatBuffer)1