use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class TransformSeparatorTest method testPassThroughTransform.
/**
* Tests separation of a pass through transform.
*
* @throws FactoryException if an error occurred while creating a new transform.
*/
@Test
@DependsOnMethod("testLinearTransform")
public void testPassThroughTransform() throws FactoryException {
final MathTransform nonLinear = new EllipsoidToCentricTransform(6378137, 6356752.314245179, Units.METRE, false, EllipsoidToCentricTransform.TargetType.CARTESIAN);
final TransformSeparator s = new TransformSeparator(PassThroughTransform.create(2, nonLinear, 3));
/*
* Trivial case: no dimension specified, we should get the transform unchanged.
*/
assertSame("transform", s.transform, s.separate());
assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2, 3, 4, 5, 6 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }, s.getTargetDimensions());
/*
* Filter only target dimensions. If the requested indices overlap the pass-through transform,
* TransformSeparator will just concatenate a matrix after the transform for dropping dimensions.
*/
Matrix matrix = Matrices.create(4, 9, new double[] { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
s.clear();
s.addTargetDimensions(1, 2, 7);
MathTransform r = s.separate();
assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2, 3, 4, 5, 6 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 1, 2, 7 }, s.getTargetDimensions());
assertInstanceOf("separate()", ConcatenatedTransform.class, r);
assertSame(s.transform, ((ConcatenatedTransform) r).transform1);
assertMatrixEquals("separate().transform2", matrix, ((LinearTransform) (((ConcatenatedTransform) r).transform2)).getMatrix(), STRICT);
/*
* Filter only target dimensions, but with indices that are all outside the pass-through transform.
* TransformSeparator should be able to give us a simple affine transform.
*/
matrix = Matrices.create(4, 8, new double[] { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
s.clear();
s.addTargetDimensions(1, 5, 7);
r = s.separate();
assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2, 3, 4, 5, 6 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 1, 5, 7 }, s.getTargetDimensions());
assertInstanceOf("separate()", LinearTransform.class, r);
assertMatrixEquals("separate().transform2", matrix, ((LinearTransform) r).getMatrix(), STRICT);
/*
* Filter source dimensions. If we ask only for dimensions not in the pass-through transform,
* then TransformSeparator should return an affine transform.
*/
matrix = Matrices.create(3, 3, new double[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 });
s.clear();
s.addSourceDimensions(0, 6);
r = s.separate();
assertArrayEquals("sourceDimensions", new int[] { 0, 6 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 0, 7 }, s.getTargetDimensions());
assertInstanceOf("separate()", LinearTransform.class, r);
assertMatrixEquals("separate().transform2", matrix, ((LinearTransform) r).getMatrix(), STRICT);
/*
* Filter source dimensions, now with overlapping in the pass-through transform.
* TransformSeparator is expected to create a new PassThroughTransform.
*/
s.clear();
s.addSourceDimensions(1, 2, 3, 4, 5);
r = s.separate();
assertArrayEquals("sourceDimensions", new int[] { 1, 2, 3, 4, 5 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 1, 2, 3, 4, 5, 6 }, s.getTargetDimensions());
assertInstanceOf("separate()", PassThroughTransform.class, r);
assertSame("subTransform", nonLinear, ((PassThroughTransform) r).subTransform);
assertEquals("firstAffectedOrdinate", 1, ((PassThroughTransform) r).firstAffectedOrdinate);
assertEquals("numTrailingOrdinates", 2, ((PassThroughTransform) r).numTrailingOrdinates);
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class PassThroughTransformTest method testLinear.
/**
* Tests the pass-through transform using an affine transform.
* The "pass-through" of such transforms are optimized using matrix arithmetic.
*
* @throws TransformException should never happen.
*/
@Test
public void testLinear() throws TransformException {
final Matrix matrix = new Matrix3(4, 0, 0, 0, 3, 0, 0, 0, 1);
runTest(MathTransforms.linear(matrix), LinearTransform.class);
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class PseudoTransform method transform.
/**
* Pseudo-transform a point in the given array.
*
* @throws TransformException should never occurs in this class,
* but can occur in method overridden by subclasses.
*/
@Override
public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) throws TransformException {
final Matrix derivative = derivate ? derivative(new DirectPositionView.Double(srcPts, srcOff, getSourceDimensions())) : null;
System.arraycopy(srcPts, srcOff, buffer, 0, sourceDimension);
for (int i = 0; i < targetDimension; i++) {
double v = buffer[i % sourceDimension];
v += (i + 1) * 1000 + round(v * 1000);
dstPts[dstOff + i] = v;
}
return derivative;
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class RandomFailureTransform method transform.
/**
* Pseudo-transform a point in the given array, with intentional random failures.
*
* @throws TransformException thrown randomly at the frequency given at construction time.
*/
@Override
public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) throws TransformException {
final Matrix derivative = super.transform(srcPts, srcOff, dstPts, dstOff, derivate);
final int index = ordinal++;
if (random.nextInt(denominator) == 0) {
assertTrue("Clash in coordinate ordinal.", failures.add(index));
throw new TransformException("Random exception for testing purpose.");
}
return derivative;
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class Envelopes method derivativeAndTransform.
/**
* A buckle method for calculating derivative and coordinate transformation in a single step,
* if the given {@code derivative} argument is {@code true}.
*
* @param transform the transform to use.
* @param srcPts the array containing the source coordinate at offset 0.
* @param dstPts the array into which the transformed coordinate is returned.
* @param dstOff the offset to the location of the transformed point that is stored in the destination array.
* @param derivate {@code true} for computing the derivative, or {@code false} if not needed.
* @return the matrix of the transform derivative at the given source position,
* or {@code null} if the {@code derivate} argument is {@code false}.
* @throws TransformException if the point can not be transformed
* or if a problem occurred while calculating the derivative.
*/
static Matrix derivativeAndTransform(final MathTransform transform, final double[] srcPts, final double[] dstPts, final int dstOff, final boolean derivate) throws TransformException {
if (transform instanceof AbstractMathTransform) {
return ((AbstractMathTransform) transform).transform(srcPts, 0, dstPts, dstOff, derivate);
}
// Derivative must be calculated before to transform the coordinate.
final Matrix derivative = derivate ? transform.derivative(new DirectPositionView.Double(srcPts, 0, transform.getSourceDimensions())) : null;
transform.transform(srcPts, 0, dstPts, dstOff, 1);
return derivative;
}
Aggregations