use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class SpecializableTransform method transform.
/**
* Transforms a single coordinate point in an array, and optionally computes the transform
* derivative at that location. This method delegates to the most specialized transform.
*/
@Override
public final Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, boolean derivate) throws TransformException {
final DirectPositionView pos = new DirectPositionView.Double(srcPts, srcOff, global.getSourceDimensions());
final MathTransform tr = forDomain(SubArea.find(domains, pos));
if (tr instanceof AbstractMathTransform) {
return ((AbstractMathTransform) tr).transform(srcPts, srcOff, dstPts, dstOff, derivate);
} else {
// Must be before transform(srcPts, …).
Matrix derivative = derivate ? tr.derivative(pos) : null;
if (dstPts != null) {
tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
}
return derivative;
}
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class AbstractMathTransform method derivative.
/**
* Gets the derivative of this transform at a point.
* The default implementation performs the following steps:
*
* <ul>
* <li>Ensure that the {@code point} dimension is equals to this math transform
* {@linkplain #getSourceDimensions() source dimensions}.</li>
* <li>Copy the coordinate in a temporary array and pass that array to the
* {@link #transform(double[], int, double[], int, boolean)} method,
* with the {@code derivate} boolean argument set to {@code true}.</li>
* <li>If the later method returned a non-null matrix, returns that matrix.
* Otherwise throws {@link TransformException}.</li>
* </ul>
*
* @param point the coordinate point where to evaluate the derivative.
* @return the derivative at the specified point (never {@code null}).
* @throws NullPointerException if the derivative depends on coordinate and {@code point} is {@code null}.
* @throws MismatchedDimensionException if {@code point} does not have the expected dimension.
* @throws TransformException if the derivative can not be evaluated at the specified point.
*/
@Override
public Matrix derivative(final DirectPosition point) throws TransformException {
final int dimSource = getSourceDimensions();
final double[] coordinate = point.getCoordinate();
if (coordinate.length != dimSource) {
throw mismatchedDimension("point", dimSource, coordinate.length);
}
final Matrix derivative = transform(coordinate, 0, null, 0, true);
if (derivative == null) {
throw new TransformException(Resources.format(Resources.Keys.CanNotComputeDerivative));
}
return derivative;
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class MathTransformContext method getMatrix.
/**
* Returns the normalization or denormalization matrix.
*/
@Override
@SuppressWarnings("fallthrough")
public Matrix getMatrix(final MatrixRole role) throws FactoryException {
final CoordinateSystem cs;
boolean inverse = false;
double rotation;
switch(role) {
default:
throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "role", role));
// Fall through
case INVERSE_NORMALIZATION:
inverse = true;
case NORMALIZATION:
rotation = sourceMeridian;
cs = getSourceCS();
break;
// Fall through
case INVERSE_DENORMALIZATION:
inverse = true;
case DENORMALIZATION:
inverse = !inverse;
rotation = targetMeridian;
cs = getTargetCS();
break;
}
Matrix matrix = super.getMatrix(role);
if (rotation != 0) {
if (inverse)
rotation = -rotation;
MatrixSIS cm = MatrixSIS.castOrCopy(matrix);
if (cs instanceof CartesianCS) {
rotation = Math.toRadians(rotation);
final Matrix4 rot = new Matrix4();
rot.m00 = rot.m11 = Math.cos(rotation);
rot.m01 = -(rot.m10 = Math.sin(rotation));
if (inverse) {
// Apply the rotation after denormalization.
matrix = Matrices.multiply(rot, cm);
} else {
// Apply the rotation before normalization.
matrix = cm.multiply(rot);
}
} else if (cs == null || cs instanceof EllipsoidalCS || cs instanceof SphericalCS) {
final Double value = rotation;
if (inverse) {
// Longitude is the first axis in normalized CS.
cm.convertBefore(0, null, value);
} else {
cm.convertAfter(0, null, value);
}
matrix = cm;
} else {
throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getName()));
}
}
return matrix;
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class SubOperationInfo method sourceToSelected.
/**
* Returns a matrix for an affine transform from all source coordinates to the coordinates of the
* source components selected for participating in the coordinate operation.
*
* @param sourceDimensions number of dimension of the source {@code CompoundCRS}.
* @param selectedDimensions number of source dimensions needed by the coordinate operations.
* @param selected all {@code SourceComponent} instances needed for the target {@code CompoundCRS}.
*/
static Matrix sourceToSelected(final int sourceDimensions, final int selectedDimensions, final SubOperationInfo[] selected) {
final Matrix select = Matrices.createZero(selectedDimensions + 1, sourceDimensions + 1);
select.setElement(selectedDimensions, sourceDimensions, 1);
int j = 0;
for (final SubOperationInfo component : selected) {
for (int i = component.startAtDimension; i < component.endAtDimension; i++) {
select.setElement(j++, i, 1);
}
}
return select;
}
use of org.opengis.referencing.operation.Matrix in project sis by apache.
the class TransformSeparatorTest method testLinearTransform.
/**
* Tests separation of a linear transform.
*
* @throws FactoryException if an error occurred while creating a new transform.
*/
@Test
public void testLinearTransform() throws FactoryException {
Matrix matrix = Matrices.create(4, 4, new double[] { // Some random values.
2, // Some random values.
0, // Some random values.
0, // Some random values.
7, 0, 5, 0, 6, 1, 0, 3, 8, 0, 0, 0, 1 });
final TransformSeparator s = new TransformSeparator(MathTransforms.linear(matrix));
/*
* Trivial case: no dimension specified, we should get the transform unchanged.
*/
assertSame("transform", s.transform, s.separate());
assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 0, 1, 2 }, s.getTargetDimensions());
/*
* Filter only target dimensions. This is the easiest non-trivial case since we just
* need to drop some rows. There is no analysis to perform on the matrix values.
*/
matrix = Matrices.create(3, 4, new double[] { 2, 0, 0, 7, 1, 0, 3, 8, 0, 0, 0, 1 });
s.clear();
s.addTargetDimensions(0, 2);
assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
assertArrayEquals("sourceDimensions", new int[] { 0, 1, 2 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 0, 2 }, s.getTargetDimensions());
/*
* Filter only source dimensions. Do not specify any target dimensions for now.
* TransformSeparator needs to examine the matrix values and drop all target dimensions
* that depend on an excluded source dimensions.
*/
matrix = Matrices.create(2, 3, new double[] { 5, 0, 6, 0, 0, 1 });
s.clear();
s.addSourceDimensions(1, 2);
assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
assertArrayEquals("sourceDimensions", new int[] { 1, 2 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 1 }, s.getTargetDimensions());
/*
* Filter both source and target dimensions. Source dimensions 0 and 2 allow the target dimensions 0 and 2
* (target dimension 1 is discarded because it depends on source dimension 1). Then the target dimensions
* are filtered for retaining only dimension 0.
*/
matrix = Matrices.create(2, 3, new double[] { 2, 0, 7, 0, 0, 1 });
s.clear();
s.addSourceDimensions(0, 2);
s.addTargetDimensions(0);
assertMatrixEquals("transform", matrix, ((LinearTransform) s.separate()).getMatrix(), STRICT);
assertArrayEquals("sourceDimensions", new int[] { 0, 2 }, s.getSourceDimensions());
assertArrayEquals("targetDimensions", new int[] { 0 }, s.getTargetDimensions());
/*
* Try again, but with the addition of a target dimension that TransformSeparator can not keep.
* It shall cause an exception to be thrown.
*/
s.addTargetDimensions(1);
try {
s.separate();
fail("Should not have been able to separate that transform.");
} catch (FactoryException e) {
// This is the expected exception.
assertNotNull(e.getMessage());
}
}
Aggregations