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

org.cts.op.Geocentric2Geographic Maven / Gradle / Ivy

Go to download

Coordinate Transformation Suite (abridged CTS) is a library developed to perform coordinate transformations using well known geodetic algorithms and parameter sets. It strives to be simple, flexible and interoperable, in this order.

There is a newer version: 1.7.1
Show newest version
/*
 * Coordinate Transformations Suite (abridged CTS)  is a library developped to 
 * perform Coordinate Transformations using well known geodetic algorithms 
 * and parameter sets. 
 * Its main focus are simplicity, flexibility, interoperability, in this order.
 *
 * This library has been originally developed by Michaël Michaud under the JGeod
 * name. It has been renamed CTS in 2009 and shared to the community from 
 * the OrbisGIS code repository.
 *
 * CTS 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 3 of the License.
 *
 * CTS 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
 * CTS. If not, see .
 *
 * For more information, please consult: 
 */

package org.cts.op;

import static java.lang.Math.abs;
import static java.lang.Math.atan;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;

import org.cts.CoordinateDimensionException;
import org.cts.Identifier;
import org.cts.IllegalCoordinateException;
import org.cts.datum.Ellipsoid;

/**
 * 

Transform geographic coordinates (latitude, longitude, ellipsoidal height * into geocentric coordinates.

*

Geographic coordinates and geocentric coordinates are supposed to use the * same reference datum and to be standardized :

*
    *
  • Geographic coordinates are given in the following order : latitude * (radians), longitude (radians from Greenwich) and optionnaly ellipsoidal * height (default = 0.0).
  • *
  • The center of the geocentric system (center of the mass) is equal to the * geographic coordinates reference ellipsoid.

    *
  • Z axis is oriented from origin to North Pole
  • *
  • Y axis is oriented from origin to intersection of equator and Greenwich * Meridian
  • *
  • OXYZ is direct
  • *
  • Units = radian, meter (to facilitate transformation operations).
  • *
* * @author Michaël Michaud */ public class Geocentric2Geographic extends AbstractCoordinateOperation { /** * The Identifier used for all Geocentric to geographic conversions. */ private static final Identifier opId = new Identifier("EPSG", "9602", "Geocentric to geographic conversion", "Geocentric to geographic"); /** * The ellipsoid used to define geographic coordinates. */ private Ellipsoid ellipsoid; /** * Stop condition for the Geocentric to Geographic transformation algorithm. * epsilon is a value in radian, 1E-11 is the default epsilon and it means * that error is less than 1E-4 m. */ private double epsilon; /** *

Create a new Geographic2Geocentric transformation for a specific * ellipsoid. The reference datum for both geographic and geocentric * coordinates is the same.

* * @param ellipsoid the ellipsoid used to define geographic coordinates */ public Geocentric2Geographic(Ellipsoid ellipsoid) { super(opId); this.ellipsoid = ellipsoid; this.precision = 1E-4; // 0.0001 mm this.epsilon = 1E-11; // condition d'arret = 1E-11 radian < 1E-4 m } /** *

Create a new Geographic2Geocentric transformation for a specific * ellipsoid. The reference datum for both geographic and geocentric * coordinates is the same.

* * @param ellipsoid the ellipsoid used to define geographic coordinates * @param epsilon stop condition for the Geocentric to Geographic * transformation algorithm (epsilon is a value in radian, 1E-11 is the * default epsilon and it means that error is less than 1E-4 m) */ public Geocentric2Geographic(Ellipsoid ellipsoid, double epsilon) { super(opId); this.ellipsoid = ellipsoid; this.precision = 1E-4; // 0.0001 mm this.epsilon = epsilon; // condition d'arret = 1E-11 radian < 1E-4 m } /** *

Return coordinates representing the same point in a standard * geocentric coordinate system.

* * @param coord is an array containing 2 or 3 double representing geographic * coordinates in the following order : latitude (radians), longitude * (radians from Greenwich) and optionnaly ellipsoidal height (if coord * contains only 2 double's, height is set to 0). * @throws IllegalCoordinateException if coord is not * compatible with this CoordinateOperation. */ @Override public double[] transform(double[] coord) throws IllegalCoordinateException { if (coord.length < 3) { throw new CoordinateDimensionException(coord, 3); } double X = coord[0]; double Y = coord[1]; double Z = coord[2]; double a = ellipsoid.getSemiMajorAxis(); double e2 = ellipsoid.getSquareEccentricity(); // Calcul de la longitude double lon = atan2(Y, X); // Calcul de la latitude double XY2 = sqrt(X * X + Y * Y); double lat0 = atan(Z / (XY2 * (1 - (a * e2 / sqrt(X * X + Y * Y + Z * Z))))); double lati = lat0; double lati1 = 0; while (abs(lati1 - lati) > epsilon) { lati = lati1; double exp1 = a * e2 * cos(lati); double exp2 = sqrt(1 - (e2 * sin(lati) * sin(lati))); lati1 = atan((Z / XY2) / (1 - (exp1 / (XY2 * exp2)))); } double lat = lati1; // Calcul de la hauteur double height = XY2 / cos(lat) - a / sqrt(1 - (e2 * sin(lat) * sin(lat))); coord[0] = lat; coord[1] = lon; coord[2] = height; return coord; } /** * Creates the inverse CoordinateOperation. */ @Override public CoordinateOperation inverse() throws NonInvertibleOperationException { return new Geographic2Geocentric(ellipsoid); } /** * Return a String representation of this Geographic/Geocentric converter. */ @Override public String toString() { return getName() + " (" + ellipsoid.getName() + ")"; } public Ellipsoid getEllipsoid() { return ellipsoid; } /** * Returns true if object is equals to * this. Tests equality between the ellipsoid used by the * transformation. * * @param object The object to compare this Geocentric2Geographic against */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o instanceof Geocentric2Geographic) { Geocentric2Geographic gc2gg = (Geocentric2Geographic) o; return getEllipsoid().equals(gc2gg.getEllipsoid()); } return false; } /** * Returns the hash code for this Geocentric2Geographic. */ @Override public int hashCode() { int hash = 5; hash = 89 * hash + (this.ellipsoid != null ? this.ellipsoid.hashCode() : 0); return hash; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy