use of org.apache.sis.referencing.operation.matrix.Matrix4 in project sis by apache.
the class MathTransformsTest method testCompound.
/**
* Tests {@link MathTransforms#compound(MathTransform...)}.
* This test uses linear transforms because they are easy to test, but the
* {@code MathTransforms.compound(…)} method should work with any transforms.
*/
@Test
public void testCompound() {
final MathTransform t1 = MathTransforms.linear(new Matrix2(// Random numbers (no real meaning)
3, // Random numbers (no real meaning)
-1, 0, 1));
final MathTransform t2 = MathTransforms.linear(new Matrix4(0, 8, 0, 9, 5, 0, 0, -7, 0, 0, 2, 0, 0, 0, 0, 1));
final MathTransform t3 = MathTransforms.linear(new Matrix3(0, -5, -3, 7, 0, -9, 0, 0, 1));
final MathTransform r = MathTransforms.compound(t1, t2, t3);
assertMatrixEquals("compound", Matrices.create(7, 7, new double[] { 3, 0, 0, 0, 0, 0, -1, 0, 0, 8, 0, 0, 0, 9, 0, 5, 0, 0, 0, 0, -7, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, -5, -3, 0, 0, 0, 0, 7, 0, -9, 0, 0, 0, 0, 0, 0, 1 }), MathTransforms.getMatrix(r), STRICT);
}
use of org.apache.sis.referencing.operation.matrix.Matrix4 in project sis by apache.
the class ScaleTransformTest method testConstantDimension.
/**
* Tests a transform created from a square matrix with no error terms.
* In this test, no dimension are dropped.
*
* @throws TransformException should never happen.
*/
@Test
public void testConstantDimension() throws TransformException {
create(3, 3, new Matrix4(2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 0, 0, 0, 0, 1));
verifyTransform(new double[] { 1, 1, 1, 6, 0, 2, 2, Double.NaN, 6 }, new double[] { 2, 3, 8, 12, 0, 16, 4, Double.NaN, 48 });
}
use of org.apache.sis.referencing.operation.matrix.Matrix4 in project sis by apache.
the class BursaWolfParameters method getPositionVectorTransformation.
/**
* Returns the position vector transformation (geocentric domain) as an affine transform.
* For transformations that do not depend on time, the formula is as below where {@code R}
* is a conversion factor from arc-seconds to radians:
*
* <blockquote><pre> R = toRadians(1″)
* S = 1 + {@linkplain #dS}/1000000
* ┌ ┐ ┌ ┐ ┌ ┐
* │ X' │ │ S -{@linkplain #rZ}*RS +{@linkplain #rY}*RS {@linkplain #tX} │ │ X │
* │ Y' │ = │ +{@linkplain #rZ}*RS S -{@linkplain #rX}*RS {@linkplain #tY} │ │ Y │
* │ Z' │ │ -{@linkplain #rY}*RS +{@linkplain #rX}*RS S {@linkplain #tZ} │ │ Z │
* │ 1 │ │ 0 0 0 1 │ │ 1 │
* └ ┘ └ ┘ └ ┘</pre></blockquote>
*
* This affine transform can be applied on <strong>geocentric</strong> coordinates.
* This is identified as operation method 1033 in the EPSG database.
* Those geocentric coordinates are typically converted from geographic coordinates
* in the region or timeframe given by {@link #getDomainOfValidity()}.
*
* <p>If the source datum and the {@linkplain #getTargetDatum() target datum} do not use the same
* {@linkplain DefaultGeodeticDatum#getPrimeMeridian() prime meridian}, then it is caller's responsibility
* to apply longitude rotation before to use the matrix returned by this method.</p>
*
* <div class="section">Time-dependent transformation</div>
* Some transformations use parameters that vary with time (e.g. operation method EPSG:1053).
* Users can optionally specify a date for which the transformation is desired.
* For transformations that do not depends on time, this date is ignored and can be null.
* For time-dependent transformations, {@code null} values default to the transformation's
* {@linkplain TimeDependentBWP#getTimeReference() reference time}.
*
* <div class="section">Inverse transformation</div>
* The inverse transformation can be approximated by reversing the sign of the 7 parameters before to use them
* in the above matrix. This is often considered sufficient since <cite>position vector transformations</cite>
* are themselves approximations. However Apache SIS will rather use
* {@link org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse()} in order to increase the chances
* that concatenation of transformations <var>A</var> → <var>B</var> followed by <var>B</var> → <var>A</var>
* gives back the identity transform.
*
* @param time date for which the transformation is desired, or {@code null} for the transformation's reference time.
* @return an affine transform in geocentric space created from this Bursa-Wolf parameters and the given time.
*
* @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum, Extent)
*/
public Matrix getPositionVectorTransformation(final Date time) {
final DoubleDouble period = period(time);
if (period == null && isTranslation()) {
final Matrix4 matrix = new Matrix4();
matrix.m03 = tX;
matrix.m13 = tY;
matrix.m23 = tZ;
return matrix;
}
/*
* Above was an optimization for the common case where the Bursa-Wolf parameters contain only
* translation terms. If we have rotation or scale terms, then use double-double arithmetic.
*/
final DoubleDouble RS = DoubleDouble.createSecondsToRadians();
final DoubleDouble S = param(6, period);
S.divide(PPM, 0);
// S = 1 + dS / PPM;
S.add(1, 0);
// RS = toRadians(1″) * S;
RS.multiply(S);
final DoubleDouble X = param(3, period);
X.multiply(RS);
final DoubleDouble Y = param(4, period);
Y.multiply(RS);
final DoubleDouble Z = param(5, period);
Z.multiply(RS);
final DoubleDouble mX = new DoubleDouble(X);
mX.negate();
final DoubleDouble mY = new DoubleDouble(Y);
mY.negate();
final DoubleDouble mZ = new DoubleDouble(Z);
mZ.negate();
// Fetch Integer instance only once.
final Integer O = 0;
return Matrices.create(4, 4, new Number[] { S, mZ, Y, param(0, period), Z, S, mX, param(1, period), mY, X, S, param(2, period), O, O, O, 1 });
}
use of org.apache.sis.referencing.operation.matrix.Matrix4 in project sis by apache.
the class GeographicOffsets method createMathTransform.
/**
* Creates a transform from the specified group of parameter values.
* The parameter values are unconditionally converted to degrees and metres.
*
* @param factory ignored (can be null).
* @param values the group of parameter values.
* @return the created math transform.
* @throws ParameterNotFoundException if a required parameter was not found.
*/
@Override
public MathTransform createMathTransform(MathTransformFactory factory, ParameterValueGroup values) throws ParameterNotFoundException {
final Parameters pv = Parameters.castOrWrap(values);
final Matrix4 t = new Matrix4();
t.m03 = pv.doubleValue(TX);
t.m13 = pv.doubleValue(TY);
t.m23 = pv.doubleValue(vertical());
return MathTransforms.linear(t);
}
use of org.apache.sis.referencing.operation.matrix.Matrix4 in project sis by apache.
the class GeocentricTranslationTest method createDatumShiftForGeographic3D.
/**
* Creates a datum shift operation without using the provider. This method is equivalent to the
* <cite>"Geocentric translations (geog3D domain)"</cite> method (EPSG:1035), but the transform
* steps are created without the use of any {@link ParameterValueGroup}. This way to create the
* datum shift is provided for better separation of aspects being tested.
*
* @param factory the factory to use for creating the transforms.
* @param source the source ellipsoid.
* @param target the target ellipsoid.
* @param tX geocentric translation on the X axis.
* @param tY geocentric translation on the Y axis.
* @param tZ geocentric translation on the Z axis.
* @return transform performing the datum shift.
* @throws FactoryException if an error occurred while creating the transform.
* @throws NoninvertibleTransformException if an error occurred while creating the transform.
*
* @see #testGeographicDomain()
*/
public static MathTransform createDatumShiftForGeographic3D(final MathTransformFactory factory, final Ellipsoid source, final Ellipsoid target, final double tX, final double tY, final double tZ) throws FactoryException, NoninvertibleTransformException {
final Matrix4 translation = new Matrix4();
translation.m03 = tX;
translation.m13 = tY;
translation.m23 = tZ;
final MathTransform step1 = EllipsoidToCentricTransform.createGeodeticConversion(factory, source, true);
final MathTransform step3 = EllipsoidToCentricTransform.createGeodeticConversion(factory, target, true).inverse();
final MathTransform step2 = factory.createAffineTransform(translation);
return factory.createConcatenatedTransform(step1, factory.createConcatenatedTransform(step2, step3));
}
Aggregations