001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.referencing.operation.transform;
017:
018: // OpenGIS dependencies
019: import org.opengis.referencing.operation.TransformException;
020:
021: /**
022: * Base class for transformations from a <cite>height above the ellipsoid</cite> to a
023: * <cite>height above the geoid</cite>. This transform expects three-dimensional geographic
024: * coordinates in (<var>longitude</var>,<var>latitude</var>,<var>height</var>) order. The
025: * transformations are usually backed by some ellipsoid-dependent database.
026: *
027: * @since 2.3
028: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/referencing3D/src/main/java/org/geotools/referencing/operation/transform/VerticalTransform.java $
029: * @version $Id: VerticalTransform.java 20875 2006-08-07 12:47:06Z jgarnett $
030: * @author Martin Desruisseaux
031: */
032: public abstract class VerticalTransform extends AbstractMathTransform {
033: /**
034: * Creates a new instance of {@code VerticalTransform}.
035: */
036: protected VerticalTransform() {
037: }
038:
039: /**
040: * Gets the dimension of input points.
041: */
042: public final int getSourceDimensions() {
043: return 3;
044: }
045:
046: /**
047: * Gets the dimension of output points.
048: */
049: public final int getTargetDimensions() {
050: return 3;
051: }
052:
053: /**
054: * Returns the value to add to a <cite>height above the ellipsoid</cite> in order to get a
055: * <cite>height above the geoid</cite> for the specified geographic coordinate.
056: *
057: * @param longitude The geodetic longitude, in decimal degrees.
058: * @param latitude The geodetic latitude, in decimal degrees.
059: * @param height The height above the ellipsoid in metres.
060: * @return The value to add in order to get the height above the geoid (in metres).
061: * @throws TransformException if the offset can't be computed for the specified coordinates.
062: */
063: protected abstract double heightOffset(double longitude,
064: double latitude, double height) throws TransformException;
065:
066: /**
067: * Transforms a list of coordinate point ordinal values.
068: */
069: public void transform(final float[] srcPts, int srcOff,
070: final float[] dstPts, int dstOff, int numPts)
071: throws TransformException {
072: final int step;
073: if (srcPts == dstPts && srcOff < dstOff) {
074: srcOff += 3 * (numPts - 1);
075: dstOff += 3 * (numPts - 1);
076: step = -3;
077: } else {
078: step = +3;
079: }
080: while (--numPts >= 0) {
081: final float x, y, z;
082: dstPts[dstOff + 0] = (float) (x = srcPts[srcOff + 0]);
083: dstPts[dstOff + 1] = (float) (y = srcPts[srcOff + 1]);
084: dstPts[dstOff + 2] = (float) ((z = srcPts[srcOff + 2]) + heightOffset(
085: x, y, z));
086: srcOff += step;
087: dstOff += step;
088: }
089: }
090:
091: /**
092: * Transforms a list of coordinate point ordinal values.
093: */
094: public void transform(final double[] srcPts, int srcOff,
095: final double[] dstPts, int dstOff, int numPts)
096: throws TransformException {
097: final int step;
098: if (srcPts == dstPts && srcOff < dstOff) {
099: srcOff += 3 * (numPts - 1);
100: dstOff += 3 * (numPts - 1);
101: step = -3;
102: } else {
103: step = +3;
104: }
105: while (--numPts >= 0) {
106: final double x, y, z;
107: dstPts[dstOff + 0] = (x = srcPts[srcOff + 0]);
108: dstPts[dstOff + 1] = (y = srcPts[srcOff + 1]);
109: dstPts[dstOff + 2] = (z = srcPts[srcOff + 2])
110: + heightOffset(x, y, z);
111: srcOff += step;
112: dstOff += step;
113: }
114: }
115: }
|