All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotoolkit.referencing.operation.MathTransforms Maven / Gradle / Ivy

/*
 *    Geotoolkit.org - An Open Source Java GIS Toolkit
 *    http://www.geotoolkit.org
 *
 *    (C) 2011-2012, Open Source Geospatial Foundation (OSGeo)
 *    (C) 2011-2012, Geomatys
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotoolkit.referencing.operation;

import java.awt.geom.AffineTransform;

import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.MathTransform2D;
import org.opengis.referencing.operation.TransformException;

import org.geotoolkit.lang.Static;
import org.geotoolkit.internal.referencing.DirectPositionView;
import org.geotoolkit.referencing.operation.matrix.Matrices;
import org.geotoolkit.referencing.operation.transform.AbstractMathTransform;
import org.geotoolkit.referencing.operation.transform.ConcatenatedTransform;
import org.geotoolkit.referencing.operation.transform.LinearTransform;
import org.geotoolkit.referencing.operation.transform.LinearTransform1D;
import org.geotoolkit.referencing.operation.transform.AffineTransform2D;
import org.geotoolkit.referencing.operation.transform.ProjectiveTransform;

import static org.geotoolkit.util.ArgumentChecks.*;


/**
 * Utility methods related to {@link MathTransform}s. This class centralizes in one place some of
 * the most commonly used functions from the {@link org.geotoolkit.referencing.operation.transform}
 * package, thus reducing the need to explore that low-level package. The {@code MathTransforms}
 * class provides the following services:
 * 

*

    *
  • Create various Geotk implementations of {@link MathTransform}
  • *
  • Perform non-standard operations on arbitrary instances
  • *
*

* The factory static methods are provided as convenient alternatives to the GeoAPI * {@link org.opengis.referencing.operation.MathTransformFactory} interface. However * users seeking for more implementation neutrality are encouraged to limit themselves * to the GeoAPI factory interfaces instead. * * @author Martin Desruisseaux (Geomatys) * @version 3.20 * * @see org.opengis.referencing.operation.MathTransformFactory * * @since 3.20 * @module */ public final class MathTransforms extends Static { /** * Do not allow instantiation of this class. */ private MathTransforms() { } /** * Returns an identity transform of the specified dimension. In the special case of * dimension 1 and 2, this method returns instances of {@link LinearTransform1D} or * {@link AffineTransform2D} respectively. * * @param dimension The dimension of the transform to be returned. * @return An identity transform of the specified dimension. */ public static LinearTransform identity(final int dimension) { ensureStrictlyPositive("dimension", dimension); return ProjectiveTransform.identity(dimension); } /** * Creates an affine transform that apply the same linear conversion for all dimensions. * For each dimension, input values x are converted into output values * y using the following equation: * *

y  =  x × {@code scale} + {@code offset}
* * @param dimension The input and output dimensions. * @param scale The {@code scale} term in the linear equation. * @param offset The {@code offset} term in the linear equation. * @return The linear transform for the given scale and offset. */ public static LinearTransform linear(final int dimension, final double scale, final double offset) { ensureStrictlyPositive("dimension", dimension); if (offset == 0 && scale == 1) { return identity(dimension); } if (dimension == 1) { return LinearTransform1D.create(scale, offset); } final Matrix matrix = Matrices.create(dimension + 1); for (int i=0; ij'th ordinate of the moved origin. *

* The matrix is usually square and affine, but this is not mandatory. Non-affine transforms * are allowed. * * @param matrix The matrix used to define the linear transform. * @return The linear transform. * * @see org.opengis.referencing.operation.MathTransformFactory#createAffineTransform(Matrix) */ public static LinearTransform linear(final Matrix matrix) { ensureNonNull("matrix", matrix); return ProjectiveTransform.create(matrix); } /** * Creates an affine transform from the specified * Java2D object. * The matrix coefficients are used in the same way than {@link #linear(Matrix)}. * * @param matrix The matrix used to define the affine transform. * @return The affine transform. */ public static LinearTransform linear(final AffineTransform matrix) { ensureNonNull("matrix", matrix); if (matrix instanceof AffineTransform2D) { return (AffineTransform2D) matrix; } return matrix.isIdentity() ? identity(2) : new AffineTransform2D(matrix); } /** * Creates an affine transform that keep only a subset of the source ordinate values. * The dimension of source coordinates is {@code sourceDim} and * the dimension of target coordinates is {@code toKeep.length}. * * @param sourceDim the dimension of source coordinates. * @param toKeep the indices of source ordinate values to keep. * @return The affine transform keeping only the given dimensions, and discarding all others. * @throws IndexOutOfBoundsException if a value of {@code toKeep} * is lower than 0 or not smaller than {@code sourceDim}. * * @see Matrices#createDimensionFilter(int, int[]) */ public static LinearTransform dimensionFilter(final int sourceDim, final int[] toKeep) throws IndexOutOfBoundsException { return linear(Matrices.createDimensionFilter(sourceDim, toKeep)); } /** * Concatenates the two given transforms. The returned transform will implement * {@link MathTransform1D} or {@link MathTransform2D} if the dimensions of the * concatenated transform are equal to 1 or 2 respectively. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @return The concatenated transform. * * @see org.opengis.referencing.operation.MathTransformFactory#createConcatenatedTransform(MathTransform, MathTransform) */ public static MathTransform concatenate(MathTransform tr1, MathTransform tr2) { ensureNonNull("tr1", tr1); ensureNonNull("tr2", tr2); return ConcatenatedTransform.create(tr1, tr2); } /** * Concatenates the given two-dimensional transforms. This is a convenience methods * delegating to {@link #concatenate(MathTransform, MathTransform)} and casting the * result to a {@link MathTransform2D} instance. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @return The concatenated transform. */ public static MathTransform2D concatenate(MathTransform2D tr1, MathTransform2D tr2) { return (MathTransform2D) concatenate((MathTransform) tr1, (MathTransform) tr2); } /** * Concatenates the given one-dimensional transforms. This is a convenience methods * delegating to {@link #concatenate(MathTransform, MathTransform)} and casting the * result to a {@link MathTransform1D} instance. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @return The concatenated transform. */ public static MathTransform1D concatenate(MathTransform1D tr1, MathTransform1D tr2) { return (MathTransform1D) concatenate((MathTransform) tr1, (MathTransform) tr2); } /** * Concatenates the three given transforms. This is a convenience methods doing its job * as two consecutive concatenations. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @param tr3 The third math transform. * @return The concatenated transform. */ public static MathTransform concatenate(MathTransform tr1, MathTransform tr2, MathTransform tr3) { ensureNonNull("tr1", tr1); ensureNonNull("tr2", tr2); ensureNonNull("tr3", tr3); return concatenate(concatenate(tr1, tr2), tr3); } /** * Concatenates the three given two-dimensional transforms. This is a convenience methods * delegating to {@link #concatenate(MathTransform, MathTransform, MathTransform)} and * casting the result to a {@link MathTransform2D} instance. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @param tr3 The third math transform. * @return The concatenated transform. */ public static MathTransform2D concatenate(MathTransform2D tr1, MathTransform2D tr2, MathTransform2D tr3) { return (MathTransform2D) concatenate((MathTransform) tr1, (MathTransform) tr2, (MathTransform) tr3); } /** * Concatenates the three given one-dimensional transforms. This is a convenience methods * delegating to {@link #concatenate(MathTransform, MathTransform, MathTransform)} and * casting the result to a {@link MathTransform1D} instance. * * @param tr1 The first math transform. * @param tr2 The second math transform. * @param tr3 The third math transform. * @return The concatenated transform. */ public static MathTransform1D concatenate(MathTransform1D tr1, MathTransform1D tr2, MathTransform1D tr3) { return (MathTransform1D) concatenate((MathTransform) tr1, (MathTransform) tr2, (MathTransform) tr3); } /** * A buckle method for calculating derivative and coordinate transformation in a single step. * The transform result is stored in the given destination array, and the derivative matrix * is returned. Invoking this method is equivalent to the following code, except that it may * execute faster with some {@code MathTransform} implementations: * * {@preformat java * DirectPosition ptSrc = ...; * DirectPosition ptDst = ...; * Matrix matrixDst = derivative(ptSrc); * ptDst = transform(ptSrc, ptDst); * } * * @param transform The transform to use. * @param srcPts The array containing the source coordinate. * @param srcOff The offset to the point to be transformed in the source array. * @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. * @return The matrix of the transform derivative at the given source position. * @throws TransformException If the point can't be transformed or if a problem occurred while * calculating the derivative. */ public static Matrix derivativeAndTransform(final MathTransform transform, final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff) throws TransformException { if (transform instanceof AbstractMathTransform) { return ((AbstractMathTransform) transform).transform(srcPts, srcOff, dstPts, dstOff, true); } // Must be calculated before to transform the coordinate. final Matrix derivative = transform.derivative(new DirectPositionView(srcPts, srcOff, transform.getSourceDimensions())); if (dstPts != null) { transform.transform(srcPts, srcOff, dstPts, dstOff, 1); } return derivative; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy