/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2006-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 org.opengis.referencing.operation.TransformException;
/**
* Base class for transformations from a <cite>height above the ellipsoid</cite> to a
* <cite>height above the geoid</cite>. This transform expects three-dimensional geographic
* coordinates in (<var>longitude</var>,<var>latitude</var>,<var>height</var>) order. The
* transformations are usually backed by some ellipsoid-dependent database.
*
* @since 2.3
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux
*/
public abstract class VerticalTransform extends AbstractMathTransform {
/**
* Creates a new instance of {@code VerticalTransform}.
*/
protected VerticalTransform() {
}
/**
* Gets the dimension of input points.
*/
public final int getSourceDimensions() {
return 3;
}
/**
* Gets the dimension of output points.
*/
public final int getTargetDimensions() {
return 3;
}
/**
* Returns the value to add to a <cite>height above the ellipsoid</cite> in order to get a
* <cite>height above the geoid</cite> for the specified geographic coordinate.
*
* @param longitude The geodetic longitude, in decimal degrees.
* @param latitude The geodetic latitude, in decimal degrees.
* @param height The height above the ellipsoid in metres.
* @return The value to add in order to get the height above the geoid (in metres).
* @throws TransformException if the offset can't be computed for the specified coordinates.
*/
protected abstract double heightOffset(double longitude, double latitude, double height)
throws TransformException;
/**
* Transforms a list of coordinate point ordinal values.
*/
@Override
public void transform(final float[] srcPts, int srcOff,
final float[] dstPts, int dstOff, int numPts)
throws TransformException
{
final int step;
if (srcPts == dstPts && srcOff < dstOff) {
srcOff += 3*(numPts-1);
dstOff += 3*(numPts-1);
step = -3;
} else {
step = +3;
}
while (--numPts >= 0) {
final float x,y,z;
dstPts[dstOff + 0] = (x = srcPts[srcOff + 0]);
dstPts[dstOff + 1] = (y = srcPts[srcOff + 1]);
dstPts[dstOff + 2] = (float) ((z = srcPts[srcOff + 2]) + heightOffset(x,y,z));
srcOff += step;
dstOff += step;
}
}
/**
* Transforms a list of coordinate point ordinal values.
*/
public void transform(final double[] srcPts, int srcOff,
final double[] dstPts, int dstOff, int numPts)
throws TransformException
{
final int step;
if (srcPts == dstPts && srcOff < dstOff) {
srcOff += 3*(numPts-1);
dstOff += 3*(numPts-1);
step = -3;
} else {
step = +3;
}
while (--numPts >= 0) {
final double x,y,z;
dstPts[dstOff + 0] = (x = srcPts[srcOff + 0]);
dstPts[dstOff + 1] = (y = srcPts[srcOff + 1]);
dstPts[dstOff + 2] = (z = srcPts[srcOff + 2]) + heightOffset(x,y,z);
srcOff += step;
dstOff += step;
}
}
}