/* * Geotools 2 - OpenSource mapping toolkit * (C) 2003, Geotools Project Managment Committee (PMC) * (C) 2001, Institut de Recherche pour le Développement * * 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; either * version 2.1 of the License, or (at your option) any later version. * * 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * This package contains documentation from OpenGIS specifications. * OpenGIS consortium's work is fully acknowledged here. */ package org.geotools.ct; // J2SE dependencies import java.io.Serializable; import java.rmi.RemoteException; import java.util.Arrays; import org.geotools.pt.CoordinatePoint; import org.geotools.pt.Matrix; import org.geotools.resources.Utilities; import org.opengis.ct.CT_MathTransform; import org.opengis.pt.PT_CoordinatePoint; import org.opengis.referencing.operation.NoninvertibleTransformException; import org.opengis.referencing.operation.TransformException; /** * Wrap an {@link CT_MathTransform} into a {@link MathTransform}. * This class is provided for compatibility with OpenGIS. It is * serializable if the underlying {@link CT_MathTransform} is * serializable too. * * @source $URL$ * @version 1.0 * @author Martin Desruisseaux * * @deprecated No replacement for RMI objects. */ class MathTransformAdapter extends AbstractMathTransform implements Serializable { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = 4497134108375420674L; /** * The OpenGIS math transform. */ protected final CT_MathTransform transform; /** * Dimension of output points. */ private final int dimSource; /** * Dimension of input points. */ private final int dimTarget; /** * true if this transform does not move any points. */ private final boolean isIdentity; /** * The inverse transform. This field * will be computed only when needed. */ protected transient MathTransformAdapter inverse; /** * Construct an adapter. * * @throws RemoteException if a remote call failed. */ public MathTransformAdapter(final CT_MathTransform transform) throws RemoteException { super(transform); this.transform = transform; this.dimSource = transform.getDimSource(); this.dimTarget = transform.getDimTarget(); this.isIdentity = transform.isIdentity(); } /** * Transforms a list of coordinate point ordinal values. * * @throws TransformException if the points can't be * transformed, or if a remote call failed. */ public final void transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final int numPts) throws TransformException { try { if (srcOff==0 && dstOff==0 && srcPts==dstPts && dimSource==dimTarget && numPts*dimSource==srcPts.length) { // Special optimization without intermediate buffer. final double[] array = transform.transformList(srcPts); if (array!=dstPts) { System.arraycopy(array, 0, dstPts, 0, array.length); Arrays.fill(dstPts, array.length, dstPts.length, Double.NaN); } } else { // The following array way be larger than necessary, but we make // it large enough to give a change to 'transformList' to reuse it. double[] array = new double[numPts*Math.max(dimSource, dimTarget)]; System.arraycopy(srcPts, srcOff, array, 0, numPts*dimSource); array = transform.transformList(array); System.arraycopy(array, 0, dstPts, dstOff, array.length); Arrays.fill(dstPts, array.length, numPts*dimTarget, Double.NaN); } } catch (RemoteException exception) { final Throwable cause = exception.detail; if (cause instanceof TransformException) { throw (TransformException) cause; } throw new TransformException(exception.getLocalizedMessage(), exception); } } /** * Transforms a list of coordinate point ordinal values. * * @throws TransformException if the points can't be * transformed, or if a remote call failed. */ public final void transform(final float[] srcPts, final int srcOff, final float[] dstPts, final int dstOff, final int numPts) throws TransformException { try { // The following array way be larger than necessary, but we make // it large enough to give a change to 'transformList' to reuse it. double[] array = new double[numPts*Math.max(dimSource, dimTarget)]; for (int i=numPts*dimSource; --i>=0;) { array[i] = srcPts[i+srcOff]; } array = transform.transformList(array); for (int i=array.length; --i>=0;) { dstPts[i+dstOff] = (float)array[i]; } Arrays.fill(dstPts, array.length, numPts*dimTarget, Float.NaN); } catch (RemoteException exception) { final Throwable cause = exception.detail; if (cause instanceof TransformException) { throw (TransformException) cause; } throw new TransformException(exception.getLocalizedMessage(), exception); } } /** * Gets the derivative of this transform at a point. * * @param point The coordinate point where to evaluate the derivative. * @return The derivative at the specified point (never null). * @throws TransformException if the derivative can't be evaluated at the specified point. */ public Matrix derivative(final CoordinatePoint point) throws TransformException { try { final PT_CoordinatePoint ogPoint; if (point!=null) { ogPoint = new PT_CoordinatePoint(); ogPoint.ord = point.ord; } else { ogPoint = null; } return new Matrix(transform.derivative(ogPoint).elt); } catch (RemoteException exception) { final Throwable cause = exception.detail; if (cause instanceof TransformException) { throw (TransformException) cause; } throw new TransformException(exception.getLocalizedMessage(), exception); } } /** * Creates the inverse transform of this object. * * @throws NoninvertibleTransformException if the inverse transform * can't be created, or if a remote call failed. */ public synchronized MathTransform inverse() throws NoninvertibleTransformException { if (inverse==null) { try { inverse = new MathTransformAdapter(transform.inverse()); inverse.inverse = this; } catch (RemoteException exception) { final Throwable cause = exception.detail; if (cause instanceof NoninvertibleTransformException) { throw (NoninvertibleTransformException) cause; } throw new NoninvertibleTransformException(exception.getLocalizedMessage(), exception); } } return inverse; } /** * Gets the dimension of input points. */ public final int getDimSource() { return dimSource; } /** * Gets the dimension of output points. */ public final int getDimTarget() { return dimTarget; } /** * Tests whether this transform does not move any points. */ public final boolean isIdentity() { return isIdentity; } /** * Compares the specified object with * this math transform for equality. */ public final boolean equals(final Object object) { if (object==this) { // Slight optimization return true; } if (super.equals(object)) { return Utilities.equals(((MathTransformAdapter) object).transform, transform); } return false; } }