/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.referencing.operation.transform; import java.awt.geom.AffineTransform; import java.io.Serializable; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import org.opengis.geometry.DirectPosition; import org.geotools.geometry.GeneralDirectPosition; import org.geotools.referencing.operation.LinearTransform; import org.geotools.referencing.operation.matrix.MatrixFactory; /** * The identity transform. The data are only copied without any transformation. This class is * used for identity transform of dimension greater than 2. For 1D and 2D identity transforms, * {@link LinearTransform1D} and {@link java.awt.geom.AffineTransform} already provide their * own optimisations. * * @since 2.0 * * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) */ public class IdentityTransform extends AbstractMathTransform implements LinearTransform, Serializable { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = -5339040282922138164L; /** * The input and output dimension. */ private final int dimension; /** * Identity transforms for dimensions ranging from to 0 to 7. * Elements in this array will be created only when first requested. */ private static final LinearTransform[] POOL = new LinearTransform[8]; /** * Constructs an identity transform of the specified dimension. */ protected IdentityTransform(final int dimension) { this.dimension = dimension; } /** * Constructs an identity transform of the specified dimension. */ public static synchronized LinearTransform create(final int dimension) { LinearTransform candidate; if (dimension < POOL.length) { candidate = POOL[dimension]; if (candidate != null) { return candidate; } } switch (dimension) { case 1: candidate = LinearTransform1D.IDENTITY; break; case 2: candidate = new AffineTransform2D(new AffineTransform()); break; default: candidate = new IdentityTransform(dimension); break; } if (dimension < POOL.length) { POOL[dimension] = candidate; } return candidate; } /** * Tests whether this transform does not move any points. * This implementation always returns {@code true}. */ @Override public boolean isIdentity() { return true; } /** * Tests whether this transform does not move any points. * This implementation always returns {@code true}. */ public boolean isIdentity(double tolerance) { return true; } /** * Gets the dimension of input points. */ public int getSourceDimensions() { return dimension; } /** * Gets the dimension of output points. */ public int getTargetDimensions() { return dimension; } /** * Returns the parameter descriptors for this math transform. */ @Override public ParameterDescriptorGroup getParameterDescriptors() { return ProjectiveTransform.ProviderAffine.PARAMETERS; } /** * Returns the matrix elements as a group of parameters values. * * @return A copy of the parameter values for this math transform. */ @Override public ParameterValueGroup getParameterValues() { return ProjectiveTransform.getParameterValues(getMatrix()); } /** * Returns a copy of the identity matrix. */ public Matrix getMatrix() { return MatrixFactory.create(dimension+1); } /** * Gets the derivative of this transform at a point. For an identity transform, * the derivative is the same everywhere. */ @Override public Matrix derivative(final DirectPosition point) { return MatrixFactory.create(dimension); } /** * Copies the values from {@code ptSrc} to {@code ptDst}. * Overrides the super-class method for performance reason. * * @since 2.2 */ @Override public DirectPosition transform(final DirectPosition ptSrc, final DirectPosition ptDst) { if (ptSrc.getDimension() == dimension) { if (ptDst == null) { return new GeneralDirectPosition(ptSrc); } if (ptDst.getDimension() == dimension) { for (int i=0; i