Geodetic.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: Geodetic.cpp 2944 2011-10-27 08:04:41Z yanweignss $"
00002 
00003 
00004 
00005 //============================================================================
00006 //
00007 //  This file is part of GPSTk, the GPS Toolkit.
00008 //
00009 //  The GPSTk is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Lesser General Public License as published
00011 //  by the Free Software Foundation; either version 2.1 of the License, or
00012 //  any later version.
00013 //
00014 //  The GPSTk is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with GPSTk; if not, write to the Free Software Foundation,
00021 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 //  Copyright 2004, The University of Texas at Austin
00024 //
00025 //============================================================================
00026 
00027 //============================================================================
00028 //
00029 //This software developed by Applied Research Laboratories at the University of
00030 //Texas at Austin, under contract to an agency or agencies within the U.S.
00031 //Department of Defense. The U.S. Government retains all rights to use,
00032 //duplicate, distribute, disclose, or release this software.
00033 //
00034 //Pursuant to DoD Directive 523024
00035 //
00036 // DISTRIBUTION STATEMENT A: This software has been approved for public
00037 //                           release, distribution is unlimited.
00038 //
00039 //=============================================================================
00040 
00041 
00042 
00043 
00044 
00045 
00051 #include "geometry.hpp"
00052 #include "Geodetic.hpp"
00053 #include "MiscMath.hpp"
00054 #include "icd_200_constants.hpp"  // for TWO_PI
00055 
00056 namespace gpstk
00057 {
00058    using namespace std;
00059 
00060    Geodetic :: Geodetic()
00061          : Triple(), geoid(NULL)
00062    {
00063    }
00064 
00065    Geodetic :: Geodetic(const Geodetic& right)
00066          : Triple(right), geoid(right.geoid)
00067    {
00068    }
00069 
00070    Geodetic :: Geodetic(const double& lat, const double& lon, const double& alt,
00071                         GeoidModel* geo)
00072          : Triple(lat, lon, alt), geoid(geo)
00073    {
00074    }
00075 
00076    Geodetic :: Geodetic(const Triple& t, GeoidModel* geo)
00077          : Triple(t), geoid(geo)
00078    {
00079    }
00080 
00081    Geodetic :: Geodetic(const ECEF& right, GeoidModel* geo)
00082       throw(NoGeoidException)
00083    {
00084       double X = right[0];     // m
00085       double Y = right[1];     // m
00086       double Z = right[2];     // m
00087       double p = RSS(X,Y);
00088       double latd = atan2(Z, p * (1.0 - geo->eccSquared()) );
00089       double ht = 0.0, slatd, N, htold, latdold;
00090 
00091       for(int i=0; i<5; i++)
00092       {
00093          slatd = ::sin(latd);
00094          N = geo->a() / SQRT(1.0 - geo->eccSquared() * slatd * slatd);
00095          htold = ht;
00096          ht = p/::cos(latd) - N;
00097          latdold = latd;
00098          latd = ::atan2(Z, p * (1.0 - geo->eccSquared() * (N/(N+ht)) ) );
00099          if(ABS(latd-latdold) < 1.0e-9 &&
00100             ABS(ht-htold) < (1.0e-9 * geo->a()))    break;
00101       }
00102 
00103       double lon = ::atan2(Y,X);
00104 
00105       if(lon < 0.0)
00106          lon += TWO_PI;
00107 
00108       theArray[0] = latd * RAD_TO_DEG; // deg
00109       theArray[1] = lon * RAD_TO_DEG;  // deg
00110       theArray[2] = ht;                // m
00111       geoid = geo;
00112    }
00113 
00114    Geodetic& Geodetic :: operator=(const Geodetic& right)
00115    {
00116       Triple::operator=(right);
00117       geoid = right.geoid;
00118       return *this;
00119    }
00120 
00121 #if 0
00122       // This function is preserved here in case someone actually goes
00123       // about verifying it and finishing it.
00124       // As of July 31, 2002, David Munton, who implemented this
00125       // particular bit of code, recommends not using it.
00126    void tidal_corrections ( double rad_gdlat, double rad_gdlon,
00127                             double& xval, double& yval, double& zval)
00128    {
00129       double radial_correction, transverse_correction;
00130       double gclat, re1;
00131       double corr_array[3];
00132 
00133       /*convert lat to geocentric */
00134       /* re1 = rad_earth(gdlat)
00135          gclat=geod_to_geoc(gdlat,re1);*/
00136 
00137       /* compute radial correction */
00138 
00139       radial_correction=-0.1196*(1.50*pow(sin(rad_gdlat),2)-0.5);
00140 
00141       /* compute tranverse correction */
00142 
00143       transverse_correction=-0.0247*sin(2.0*rad_gdlat);
00144 
00145       /* compute correction components then add to station locations*/
00146 
00147       corr_array[0]=radial_correction*cos(rad_gdlat)*cos(rad_gdlon) -
00148          transverse_correction*sin(rad_gdlat)*cos(rad_gdlon);
00149       corr_array[1]=radial_correction*cos(rad_gdlat)*sin(rad_gdlon) -
00150          transverse_correction*sin(rad_gdlat)*sin(rad_gdlon);
00151       corr_array[2]=radial_correction*sin(rad_gdlat) +
00152          transverse_correction*cos(rad_gdlat);
00153 
00154       /* scale results to km units */
00155 
00156       //corr_array[0]=corr_array[0]*0.001;
00157       //corr_array[1]=corr_array[1]*0.001;
00158       //corr_array[2]=corr_array[2]*0.001;
00159 
00160       xval = xval + corr_array[0];
00161       yval = yval + corr_array[1];
00162       zval = zval + corr_array[2];
00163    }
00164 #endif
00165 
00166       // based on formulae 2.30 and 2.31 in section 2.1.4, page 19 of
00167       // Satellite Geodesy by Gunter Seeber, 1993.
00168    gpstk::ECEF Geodetic :: asECEF() const throw(NoGeoidException)
00169    {
00170       double rad_cur, gdlat, gdlon;
00171       double gdalt = getAltitude();
00172 
00173       if (geoid == NULL)
00174       {
00175          NoGeoidException exc
00176             ("Must specify a geoid to use to change systems");
00177          GPSTK_THROW(exc);
00178       }
00179 
00180          // convert angles to radians
00181       gdlat = DEG_TO_RAD * getLatitude();
00182       gdlon = DEG_TO_RAD * getLongitude();
00183 
00184          // radius of curvature in the prime vertical, formula 2.31
00185       rad_cur  = geoid->a() /
00186          ::sqrt(1.0-geoid->eccSquared()*::pow((::sin(gdlat)),2.0));
00187 
00188          // formula 2.30
00189       double xval = (rad_cur + gdalt) * ::cos(gdlat) * ::cos(gdlon);
00190       double yval = (rad_cur + gdalt) * ::cos(gdlat) * ::sin(gdlon);
00191       double zval = ((1.0 - geoid->eccSquared()) * rad_cur + gdalt) * ::sin(gdlat);
00192 
00193       ECEF ecef(xval, yval, zval);
00194 
00195          // see comments for tidalCorrections above for why this is
00196          // commented out.
00197 //      tidalCorrections(gdlat, gdlon, xarray[0], xarray[1], xarray[2]);
00198 
00199       return ecef;
00200    }
00201 } // namespace gpstk

Generated on Wed Feb 8 03:30:59 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1