*/
private static MatrixSIS createTransform(final Envelope srcEnvelope, final AxisDirection[] srcAxes,
final Envelope dstEnvelope, final AxisDirection[] dstAxes,
final boolean useEnvelopes)
{
final DirectPosition dstCorner, srcCorner, srcOppositeCorner;
if (useEnvelopes) {
dstCorner = dstEnvelope.getLowerCorner();
srcCorner = srcEnvelope.getLowerCorner();
srcOppositeCorner = srcEnvelope.getUpperCorner();
} else {
dstCorner = srcCorner = srcOppositeCorner = null;
}
final MatrixSIS matrix = createZero(dstAxes.length+1, srcAxes.length+1);
/*
* Maps source axes to destination axes. If no axis is moved (for example if the user
* want to transform (NORTH,EAST) to (SOUTH,EAST)), then source and destination index
* will be equal. If some axes are moved (for example if the user want to transform
* (NORTH,EAST) to (EAST,NORTH)), then ordinates at index {@code srcIndex} will have
* to be moved at index {@code dstIndex}.
*/
for (int dstIndex = 0; dstIndex < dstAxes.length; dstIndex++) {
boolean hasFound = false;
final AxisDirection dstDir = dstAxes[dstIndex];
final AxisDirection search = AxisDirections.absolute(dstDir);
for (int srcIndex = 0; srcIndex < srcAxes.length; srcIndex++) {
final AxisDirection srcDir = srcAxes[srcIndex];
if (search.equals(AxisDirections.absolute(srcDir))) {
if (hasFound) {
throw new IllegalArgumentException(Errors.format(
Errors.Keys.ColinearAxisDirections_2, srcDir, dstDir));
}
hasFound = true;
/*
* Set the matrix elements. Some matrix elements will never be set.
* They will be left to zero, which is their desired value.
*/
final boolean same = srcDir.equals(dstDir);
double scale = same ? +1 : -1;
double translate = 0;
if (useEnvelopes) {
// See the comment in transform(Envelope, Envelope) for an explanation about why
// we use the lower/upper corners instead than getMinimum()/getMaximum() methods.
translate = dstCorner.getOrdinate(dstIndex);
scale *= dstEnvelope.getSpan(dstIndex) /
srcEnvelope.getSpan(srcIndex);
translate -= scale * (same ? srcCorner : srcOppositeCorner).getOrdinate(srcIndex);
}
matrix.setElement(dstIndex, srcIndex, scale);