00001 /** 00002 * \file Geocentric.hpp 00003 * \brief Header for GeographicLib::Geocentric class 00004 * 00005 * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> 00006 * and licensed under the LGPL. For more information, see 00007 * http://geographiclib.sourceforge.net/ 00008 **********************************************************************/ 00009 00010 #if !defined(GEOGRAPHICLIB_GEOCENTRIC_HPP) 00011 #define GEOGRAPHICLIB_GEOCENTRIC_HPP "$Id: Geocentric.hpp 6827 2010-05-20 19:56:18Z karney $" 00012 00013 #include "GeographicLib/Constants.hpp" 00014 00015 namespace GeographicLib { 00016 00017 /** 00018 * \brief %Geocentric coordinates 00019 * 00020 * Convert between geodetic coordinates latitude = \e lat, longitude = \e 00021 * lon, height = \e h (measured vertically from the surface of the ellipsoid) 00022 * to geocentric coordinates (\e x, \e y, \e z). The origin of geocentric 00023 * coordinates is at the center of the earth. The \e z axis goes thru the 00024 * north pole, \e lat = 90<sup>o</sup>. The \e x axis goes thru \e lat = 0, 00025 * \e lon = 0. Geocentric coordinates are also known as earth centered, 00026 * earth fixed (ECEF) coordinates. 00027 * 00028 * The conversion from geographic to geocentric coordinates is 00029 * straightforward. For the reverse transformation we use 00030 * - H. Vermeille, 00031 * <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct 00032 * transformation from geocentric coordinates to geodetic coordinates</a>, 00033 * J. Geodesy 76, 451–454 (2002). 00034 * . 00035 * Several changes have been made to ensure that the method returns accurate 00036 * results for all finite inputs (even if \e h is infinite). See 00037 * \ref geocentric for details. 00038 * 00039 * The errors in these routines are close to round-off. Specifically, for 00040 * points within 5000 km of the surface of the ellipsoid (either inside or 00041 * outside the ellipsoid), the error is bounded by 7 nm for the WGS84 00042 * ellipsoid. See \ref geocentric for further information on the errors. 00043 **********************************************************************/ 00044 00045 class Geocentric { 00046 private: 00047 typedef Math::real real; 00048 const real _a, _r, _f, _e2, _e2m, _e2a, _e4a, _maxrad; 00049 static inline real sq(real x) throw() { return x * x; } 00050 public: 00051 00052 /** 00053 * Constructor for a ellipsoid radius \e a (meters) and reciprocal 00054 * flattening \e r. Setting \e r = 0 implies \e r = inf or flattening = 0 00055 * (i.e., a sphere). Negative \e r indicates a prolate spheroid. An 00056 * exception is thrown if \e a is not positive. 00057 **********************************************************************/ 00058 Geocentric(real a, real r); 00059 00060 /** 00061 * Convert from geodetic coordinates \e lat, \e lon (degrees), \e h 00062 * (meters) to geocentric coordinates \e x, \e y, \e z (meters). \e lat 00063 * should be in the range [-90, 90]; \e lon and \e lon0 should be in the 00064 * range [-180, 360]. 00065 **********************************************************************/ 00066 void Forward(real lat, real lon, real h, real& x, real& y, real& z) 00067 const throw(); 00068 00069 /** 00070 * Convert from geocentric coordinates \e x, \e y, \e z (meters) to 00071 * geodetic \e lat, \e lon (degrees), \e h (meters). In general there are 00072 * multiple solutions and the result which minimizes the absolute value of 00073 * \e h is returned. If there are still multiple solutions with different 00074 * latitutes (applies only if \e z = 0), then the solution with \e lat > 0 00075 * is returned. If there are still multiple solutions with different 00076 * longitudes (applies only if \e x = \e y = 0) then \e lon = 0 is 00077 * returned. The value of \e h returned satisfies \e h >= - \e a (1 - \e 00078 * e<sup>2</sup>) / sqrt(1 - \e e<sup>2</sup> sin<sup>2</sup>\e lat). The 00079 * value of \e lon returned is in the range [-180, 180). 00080 **********************************************************************/ 00081 void Reverse(real x, real y, real z, real& lat, real& lon, real& h) 00082 const throw(); 00083 00084 /** 00085 * The major radius of the ellipsoid (meters). This is that value of \e a 00086 * used in the constructor. 00087 **********************************************************************/ 00088 Math::real MajorRadius() const throw() { return _a; } 00089 00090 /** 00091 * The inverse flattening of the ellipsoid. This is that value of \e r 00092 * used in the constructor. A value of 0 is returned for a sphere 00093 * (infinite inverse flattening). 00094 **********************************************************************/ 00095 Math::real InverseFlattening() const throw() { return _r; } 00096 00097 /** 00098 * A global instantiation of Geocentric with the parameters for the WGS84 00099 * ellipsoid. 00100 **********************************************************************/ 00101 const static Geocentric WGS84; 00102 }; 00103 00104 } // namespace GeographicLib 00105 #endif