use of org.apache.sis.referencing.operation.transform.PassThroughTransform in project sis by apache.
the class AbstractSingleOperation method checkDimensions.
/**
* Checks if an operation method and a math transform have a compatible number of source and target dimensions.
* In the particular case of a {@linkplain PassThroughTransform pass through transform} with more dimensions
* than what we would expect from the given method, the check will rather be performed against the
* {@linkplain PassThroughTransform#getSubTransform() sub transform}.
* The intent is to allow creation of a three-dimensional {@code ProjectedCRS} with a two-dimensional
* {@code OperationMethod}, where the third-dimension just pass through.
*
* <p>This method tries to locates what seems to be the "core" of the given math transform. The definition
* of "core" is imprecise and may be adjusted in future SIS versions. The current algorithm is as below:</p>
*
* <ul>
* <li>If the given transform can be decomposed in {@linkplain MathTransforms#getSteps(MathTransform) steps},
* then the steps for {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes axis
* swapping and scaling} are ignored.</li>
* <li>If the given transform or its non-ignorable step is a {@link PassThroughTransform}, then its sub-transform
* is taken. Only one non-ignorable step may exist, otherwise we do not try to select any of them.</li>
* </ul>
*
* @param method the operation method to compare to the math transform.
* @param interpDim the number of interpolation dimension, or 0 if none.
* @param transform the math transform to compare to the operation method.
* @param properties properties of the caller object being constructed, used only for formatting error message.
* @throws IllegalArgumentException if the number of dimensions are incompatible.
*/
static void checkDimensions(final OperationMethod method, final int interpDim, MathTransform transform, final Map<String, ?> properties) throws IllegalArgumentException {
int actual = transform.getSourceDimensions();
Integer expected = method.getSourceDimensions();
if (expected != null && actual > expected + interpDim) {
/*
* The given MathTransform uses more dimensions than the OperationMethod.
* Try to locate one and only one sub-transform, ignoring axis swapping and scaling.
*/
MathTransform subTransform = null;
for (final MathTransform step : MathTransforms.getSteps(transform)) {
if (!isIgnorable(step)) {
if (subTransform == null && step instanceof PassThroughTransform) {
subTransform = ((PassThroughTransform) step).getSubTransform();
} else {
subTransform = null;
break;
}
}
}
if (subTransform != null) {
transform = subTransform;
actual = transform.getSourceDimensions();
}
}
/*
* Now verify if the MathTransform dimensions are equal to the OperationMethod ones,
* ignoring null java.lang.Integer instances. We do not specify whether the method
* dimensions should include the interpolation dimensions or not, so we accept both.
*/
// 0 == false: the wrong dimension is the source one.
int isTarget = 0;
if (expected == null || (actual == expected) || (actual == expected + interpDim)) {
actual = transform.getTargetDimensions();
expected = method.getTargetDimensions();
if (expected == null || (actual == expected) || (actual == expected + interpDim)) {
return;
}
// 1 == true: the wrong dimension is the target one.
isTarget = 1;
}
/*
* At least one dimension does not match. In principle this is an error, but we make an exception for the
* "Affine parametric transformation" (EPSG:9624). The reason is that while OGC define that transformation
* as two-dimensional, it can easily be extended to any number of dimensions. Note that Apache SIS already
* has special handling for this operation (a TensorParameters dedicated class, etc.)
*/
if (!IdentifiedObjects.isHeuristicMatchForName(method, Constants.AFFINE)) {
throw new IllegalArgumentException(Resources.forProperties(properties).getString(Resources.Keys.MismatchedTransformDimension_3, isTarget, expected, actual));
}
}
use of org.apache.sis.referencing.operation.transform.PassThroughTransform in project sis by apache.
the class DefaultPassThroughOperation method getModifiedCoordinates.
/**
* Returns the ordered sequence of indices in a source coordinate tuple of the coordinates
* affected by this pass-through operation.
*
* @return zero-based indices of the modified source coordinates.
*
* @see PassThroughTransform#getModifiedCoordinates()
*/
@Override
public int[] getModifiedCoordinates() {
final MathTransform transform = super.getMathTransform();
if (transform instanceof PassThroughTransform) {
return ((PassThroughTransform) transform).getModifiedCoordinates();
} else {
/*
* Should not happen with objects created by public methods since the constructor created the transform
* itself. However may happen with operations parsed from GML. As a fallback, search in the components
* of CompoundCRS. This is not a universal fallback, but work for the most straightforward cases.
*/
final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
if (sourceCRS instanceof CompoundCRS) {
int firstAffectedOrdinate = 0;
final CoordinateReferenceSystem search = operation.getSourceCRS();
for (final CoordinateReferenceSystem c : ((CompoundCRS) sourceCRS).getComponents()) {
final int dim = ReferencingUtilities.getDimension(c);
if (c == search) {
final int[] indices = new int[dim];
for (int i = 0; i < dim; i++) {
indices[i] = firstAffectedOrdinate + i;
}
return indices;
}
firstAffectedOrdinate += dim;
}
}
throw new UnsupportedImplementationException(transform.getClass());
}
}
Aggregations