GeodesicLine.hpp

Go to the documentation of this file.
00001 /**
00002  * \file GeodesicLine.hpp
00003  * \brief Header for GeographicLib::GeodesicLine class
00004  *
00005  * Copyright (c) Charles Karney (2009, 2010, 2011) <charles@karney.com>
00006  * and licensed under the LGPL.  For more information, see
00007  * http://geographiclib.sourceforge.net/
00008  **********************************************************************/
00009 
00010 #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP)
00011 #define GEOGRAPHICLIB_GEODESICLINE_HPP "$Id: GeodesicLine.hpp 6950 2011-02-11 04:09:24Z karney $"
00012 
00013 #include "GeographicLib/Constants.hpp"
00014 #include "GeographicLib/Geodesic.hpp"
00015 
00016 namespace GeographicLib {
00017 
00018   /**
00019    * \brief A geodesic line.
00020    *
00021    * GeodesicLine facilitates the determination of a series of points on a
00022    * single geodesic.  The starting point (\e lat1, \e lon1) and the azimuth \e
00023    * azi1 are specified in the constructor.  GeodesicLine.Position returns the
00024    * location of point 2 a distance \e s12 along the geodesic.  Alternatively
00025    * GeodesicLine.ArcPosition gives the position of point 2 an arc length \e
00026    * a12 along the geodesic.  An example of use of this class is:
00027    \code
00028    #include <iostream>
00029    #include <iomanip>
00030    #include <cmath>
00031    #include "GeographicLib/Geodesic.hpp"
00032    #include "GeographicLib/GeodesicLine.hpp"
00033 
00034    int main() {
00035      // Print waypoints between JFK and SIN at
00036      // approximately 100km intervals.
00037      double
00038        lat1 = 40.640, lon1 = -73.779, // JFK
00039        lat2 = 1.359, lon2 = 177.486;  // SIN
00040      const GeographicLib::Geodesic&
00041        g = GeographicLib::Geodesic::WGS84;
00042      double azi1, azi2,
00043        a12 = g.Inverse(lat1, lon1, lat2, lon2, azi1, azi2);
00044      double ds = 100e3;  // Nominal distance between points = 100 km
00045      int num = std::ceil(a12/ (90 * ds / 10e6)); // 90 deg = 10e6 m
00046      double da = a12/num;              // Arc length between points
00047      const GeographicLib::GeodesicLine l(g, lat1, lon1, azi1);
00048      std::cout << std::fixed << std::setprecision(3);
00049      for (int i = 0; i <= num; ++i) {
00050        double lat, lon;
00051        l.ArcPosition(i * da, lat, lon);
00052        std::cout << lat << " " << lon << "\n";
00053      }
00054    }
00055    \endcode
00056    * The default copy constructor and assignment operators work with this
00057    * class, so that, for example, the previous example could start
00058    \code
00059        GeographicLib::GeodesicLine l;
00060        l = g.Line(lat1, lon1, azi1);
00061    \endcode
00062    * Similarly, a vector can be used to hold GeodesicLine objects.
00063    *
00064    * The calculations are accurate to better than 15 nm.  See Sec. 9 of
00065    * <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a> for details.
00066    *
00067    * The algorithms are described in
00068    * - C. F. F. Karney,
00069    *   <a href="http://arxiv.org/abs/1102.1215">Geodesics
00070    *   on an ellipsoid of revolution</a>,
00071    *   Feb. 2011;
00072    *   preprint
00073    *   <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a>.
00074    * .
00075    * For more information on geodesics see \ref geodesic.
00076    **********************************************************************/
00077 
00078   class GeodesicLine {
00079   private:
00080     typedef Math::real real;
00081     friend class Geodesic;
00082     static const int nC1 = Geodesic::nC1, nC1p = Geodesic::nC1p,
00083       nC2 = Geodesic::nC2, nC3 = Geodesic::nC3, nC4 = Geodesic::nC4;
00084 
00085     real _lat1, _lon1, _azi1;
00086     real _a, _r, _b, _c2, _f1, _salp0, _calp0, _k2,
00087       _salp1, _calp1, _ssig1, _csig1, _stau1, _ctau1, _somg1, _comg1,
00088       _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41;
00089     // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused
00090     real _C1a[nC1 + 1], _C1pa[nC1p + 1], _C2a[nC2 + 1], _C3a[nC3],
00091       _C4a[nC4];    // all the elements of _C4a are used
00092     bool _areap;
00093     unsigned _caps;
00094 
00095     static inline real sq(real x) throw() { return x * x; }
00096     enum captype {
00097       CAP_NONE = Geodesic::CAP_NONE,
00098       CAP_C1   = Geodesic::CAP_C1,
00099       CAP_C1p  = Geodesic::CAP_C1p,
00100       CAP_C2   = Geodesic::CAP_C2,
00101       CAP_C3   = Geodesic::CAP_C3,
00102       CAP_C4   = Geodesic::CAP_C4,
00103       CAP_ALL  = Geodesic::CAP_ALL,
00104       OUT_ALL  = Geodesic::OUT_ALL,
00105     };
00106   public:
00107 
00108     /**
00109      * Bit masks for what calculations to do.  These masks do double duty.
00110      * They signify to the GeodesicLine::GeodesicLine constructor and to
00111      * Geodesic::Line what capabilities should be included in the GeodesicLine
00112      * object.  They also specify which results to return in the general
00113      * routines Geodesic::GenDirect and Geodesic::GenInverse routines.  This is
00114      * merely a duplication of Geodesic::mask.
00115      **********************************************************************/
00116     enum mask {
00117       /**
00118        * No capabilities, no output.
00119        * @hideinitializer
00120        **********************************************************************/
00121       NONE          = Geodesic::NONE,
00122       /**
00123        * Calculate latitude \e lat2.  (It's not necessary to include this as a
00124        * capability to GeodesicLine because this is included by default.)
00125        * @hideinitializer
00126        **********************************************************************/
00127       LATITUDE      = Geodesic::LATITUDE,
00128       /**
00129        * Calculate longitude \e lon2.
00130        * @hideinitializer
00131        **********************************************************************/
00132       LONGITUDE     = Geodesic::LONGITUDE,
00133       /**
00134        * Calculate azimuths \e azi1 and \e azi2.  (It's not necessary to
00135        * include this as a capability to GeodesicLine because this is included
00136        * by default.)
00137        * @hideinitializer
00138        **********************************************************************/
00139       AZIMUTH       = Geodesic::AZIMUTH,
00140       /**
00141        * Calculate distance \e s12.
00142        * @hideinitializer
00143        **********************************************************************/
00144       DISTANCE      = Geodesic::DISTANCE,
00145       /**
00146        * Allow distance \e s12 to be used as input in the direct geodesic
00147        * problem.
00148        * @hideinitializer
00149        **********************************************************************/
00150       DISTANCE_IN   = Geodesic::DISTANCE_IN,
00151       /**
00152        * Calculate reduced length \e m12.
00153        * @hideinitializer
00154        **********************************************************************/
00155       REDUCEDLENGTH = Geodesic::REDUCEDLENGTH,
00156       /**
00157        * Calculate geodesic scales \e M12 and \e M21.
00158        * @hideinitializer
00159        **********************************************************************/
00160       GEODESICSCALE = Geodesic::GEODESICSCALE,
00161       /**
00162        * Calculate area \e S12.
00163        * @hideinitializer
00164        **********************************************************************/
00165       AREA          = Geodesic::AREA,
00166       /**
00167        * All capabilities.  Calculate everything.
00168        * @hideinitializer
00169        **********************************************************************/
00170       ALL           = Geodesic::ALL,
00171     };
00172 
00173     /** \name Constructors
00174      **********************************************************************/
00175     ///@{
00176 
00177     /**
00178      * Constructor for a geodesic line staring at latitude \e lat1, longitude
00179      * \e lon1, and aziumuth \e azi1 (all in degrees).
00180      *
00181      * @param[in] g A Geodesic object used to compute the necessary information
00182      *   about the GeodesicLine.
00183      *
00184      * @param[in] lat1 latitude of point 1 (degrees).
00185      * @param[in] lon1 longitude of point 1 (degrees).
00186      * @param[in] azi1 azimuth at point 1 (degrees).
00187      * @param[in] caps bitor'ed combination of GeodesicLine::mask values
00188      *   specifying the capabilities the GeodesicLine object should possess,
00189      *   i.e., which quantities can be returned in calls to
00190      *   GeodesicLib::Position.
00191      *
00192      * The GeodesicLine::mask values are
00193      * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is
00194      *   added automatically
00195      * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2
00196      * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
00197      *   added automatically
00198      * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12
00199      * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12
00200      * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
00201      *   and \e M21
00202      * - \e caps |= GeodesicLine::AREA for the area \e S12
00203      * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
00204      *   geodesic to be given in terms of \e s12; without this capability the
00205      *   length can only be specified in terms of arc length.
00206      * .
00207      * The default value of \e caps is GeodesicLine::ALL which turns on all the
00208      * capabilities.
00209      *
00210      * If the point is at a pole, the azimuth is defined by keeping the \e lon1
00211      * fixed and writing \e lat1 = 90 - \e eps or -90 + \e eps and taking the
00212      * limit \e eps -> 0 from above.
00213      **********************************************************************/
00214     GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1,
00215                  unsigned caps = ALL)
00216       throw();
00217 
00218     /**
00219      * A default constructor.  If GeodesicLine::Position is called on the
00220      * resulting object, it returns immediately (without doing any
00221      * calculations).  The object can be set with a call to Geodesic::Line.
00222      * Use Init() to test whether object is still in this uninitialized state.
00223      **********************************************************************/
00224     GeodesicLine() throw() : _caps(0U) {};
00225     ///@}
00226 
00227     /** \name Position in terms of distance
00228      **********************************************************************/
00229     ///@{
00230 
00231     /**
00232      * Compute the position of point 2 which is a distance \e s12 (meters)
00233      * from point 1.
00234      *
00235      * @param[in] s12 distance between point 1 and point 2 (meters); it can be
00236      *   signed.
00237      * @param[out] lat2 latitude of point 2 (degrees).
00238      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00239      *   GeodesicLine object was constructed with \e caps |=
00240      *   GeodesicLine::LONGITUDE.
00241      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00242      * @param[out] m12 reduced length of geodesic (meters); requires that the
00243      *   GeodesicLine object was constructed with \e caps |=
00244      *   GeodesicLine::REDUCEDLENGTH.
00245      * @param[out] M12 geodesic scale of point 2 relative to point 1
00246      *   (dimensionless); requires that the GeodesicLine object was constructed
00247      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00248      * @param[out] M21 geodesic scale of point 1 relative to point 2
00249      *   (dimensionless); requires that the GeodesicLine object was constructed
00250      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00251      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00252      *   that the GeodesicLine object was constructed with \e caps |=
00253      *   GeodesicLine::AREA.
00254      * @return \e a12 arc length of between point 1 and point 2 (degrees).
00255      *
00256      * The GeodesicLine object \e must have been constructed with \e caps |=
00257      * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
00258      * parameters are set.  Requesting a value which the GeodesicLine object is
00259      * not capable of computing is not an error; the corresponding argument
00260      * will not be altered.
00261      *
00262      * The following functions are overloaded versions of
00263      * GeodesicLine::Position which omit some of the output parameters.  Note,
00264      * however, that the arc length is always computed and returned as the
00265      * function value.
00266      **********************************************************************/
00267     Math::real Position(real s12,
00268                         real& lat2, real& lon2, real& azi2,
00269                         real& m12, real& M12, real& M21,
00270                         real& S12) const throw() {
00271       real t;
00272       return GenPosition(false, s12,
00273                          LATITUDE | LONGITUDE | AZIMUTH |
00274                          REDUCEDLENGTH | GEODESICSCALE | AREA,
00275                          lat2, lon2, azi2, t, m12, M12, M21, S12);
00276     }
00277 
00278     /**
00279      * See the documentation for GeodesicLine::Position.
00280      **********************************************************************/
00281     Math::real Position(real s12, real& lat2, real& lon2) const throw() {
00282       real t;
00283       return GenPosition(false, s12,
00284                          LATITUDE | LONGITUDE,
00285                          lat2, lon2, t, t, t, t, t, t);
00286     }
00287 
00288     /**
00289      * See the documentation for GeodesicLine::Position.
00290      **********************************************************************/
00291     Math::real Position(real s12, real& lat2, real& lon2,
00292                         real& azi2) const throw() {
00293       real t;
00294       return GenPosition(false, s12,
00295                          LATITUDE | LONGITUDE | AZIMUTH,
00296                          lat2, lon2, azi2, t, t, t, t, t);
00297     }
00298 
00299     /**
00300      * See the documentation for GeodesicLine::Position.
00301      **********************************************************************/
00302     Math::real Position(real s12, real& lat2, real& lon2,
00303                         real& azi2, real& m12) const throw() {
00304       real t;
00305       return GenPosition(false, s12,
00306                          LATITUDE | LONGITUDE |
00307                          AZIMUTH | REDUCEDLENGTH,
00308                          lat2, lon2, azi2, t, m12, t, t, t);
00309     }
00310 
00311     /**
00312      * See the documentation for GeodesicLine::Position.
00313      **********************************************************************/
00314     Math::real Position(real s12, real& lat2, real& lon2,
00315                         real& azi2, real& M12, real& M21)
00316       const throw() {
00317       real t;
00318       return GenPosition(false, s12,
00319                          LATITUDE | LONGITUDE |
00320                          AZIMUTH | GEODESICSCALE,
00321                          lat2, lon2, azi2, t, t, M12, M21, t);
00322     }
00323 
00324     /**
00325      * See the documentation for GeodesicLine::Position.
00326      **********************************************************************/
00327     Math::real Position(real s12,
00328                         real& lat2, real& lon2, real& azi2,
00329                         real& m12, real& M12, real& M21)
00330       const throw() {
00331       real t;
00332       return GenPosition(false, s12,
00333                          LATITUDE | LONGITUDE | AZIMUTH |
00334                          REDUCEDLENGTH | GEODESICSCALE,
00335                          lat2, lon2, azi2, t, m12, M12, M21, t);
00336     }
00337 
00338     ///@}
00339 
00340     /** \name Position in terms of arc length
00341      **********************************************************************/
00342     ///@{
00343 
00344     /**
00345      * Compute the position of point 2 which is an arc length \e a12 (degrees)
00346      * from point 1.
00347      *
00348      * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
00349      *   be signed.
00350      * @param[out] lat2 latitude of point 2 (degrees).
00351      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00352      *   GeodesicLine object was constructed with \e caps |=
00353      *   GeodesicLine::LONGITUDE.
00354      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00355      * @param[out] s12 distance between point 1 and point 2 (meters); requires
00356      *   that the GeodesicLine object was constructed with \e caps |=
00357      *   GeodesicLine::DISTANCE.
00358      * @param[out] m12 reduced length of geodesic (meters); requires that the
00359      *   GeodesicLine object was constructed with \e caps |=
00360      *   GeodesicLine::REDUCEDLENGTH.
00361      * @param[out] M12 geodesic scale of point 2 relative to point 1
00362      *   (dimensionless); requires that the GeodesicLine object was constructed
00363      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00364      * @param[out] M21 geodesic scale of point 1 relative to point 2
00365      *   (dimensionless); requires that the GeodesicLine object was constructed
00366      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00367      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00368      *   that the GeodesicLine object was constructed with \e caps |=
00369      *   GeodesicLine::AREA.
00370      *
00371      * Requesting a value which the GeodesicLine object is not capable of
00372      * computing is not an error; the corresponding argument will not be
00373      * altered.
00374      *
00375      * The following functions are overloaded versions of
00376      * GeodesicLine::ArcPosition which omit some of the output parameters.
00377      **********************************************************************/
00378     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00379                      real& s12, real& m12, real& M12, real& M21,
00380                      real& S12) const throw() {
00381       GenPosition(true, a12,
00382                   LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
00383                   REDUCEDLENGTH | GEODESICSCALE | AREA,
00384                   lat2, lon2, azi2, s12, m12, M12, M21, S12);
00385     }
00386 
00387     /**
00388      * See the documentation for GeodesicLine::ArcPosition.
00389      **********************************************************************/
00390     void ArcPosition(real a12, real& lat2, real& lon2)
00391       const throw() {
00392       real t;
00393       GenPosition(true, a12,
00394                   LATITUDE | LONGITUDE,
00395                   lat2, lon2, t, t, t, t, t, t);
00396     }
00397 
00398     /**
00399      * See the documentation for GeodesicLine::ArcPosition.
00400      **********************************************************************/
00401     void ArcPosition(real a12,
00402                      real& lat2, real& lon2, real& azi2)
00403       const throw() {
00404       real t;
00405       GenPosition(true, a12,
00406                   LATITUDE | LONGITUDE | AZIMUTH,
00407                   lat2, lon2, azi2, t, t, t, t, t);
00408     }
00409 
00410     /**
00411      * See the documentation for GeodesicLine::ArcPosition.
00412      **********************************************************************/
00413     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00414                      real& s12) const throw() {
00415       real t;
00416       GenPosition(true, a12,
00417                   LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
00418                   lat2, lon2, azi2, s12, t, t, t, t);
00419     }
00420 
00421     /**
00422      * See the documentation for GeodesicLine::ArcPosition.
00423      **********************************************************************/
00424     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00425                      real& s12, real& m12) const throw() {
00426       real t;
00427       GenPosition(true, a12,
00428                   LATITUDE | LONGITUDE | AZIMUTH |
00429                   DISTANCE | REDUCEDLENGTH,
00430                   lat2, lon2, azi2, s12, m12, t, t, t);
00431     }
00432 
00433     /**
00434      * See the documentation for GeodesicLine::ArcPosition.
00435      **********************************************************************/
00436     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00437                      real& s12, real& M12, real& M21)
00438       const throw() {
00439       real t;
00440       GenPosition(true, a12,
00441                   LATITUDE | LONGITUDE | AZIMUTH |
00442                   DISTANCE | GEODESICSCALE,
00443                   lat2, lon2, azi2, s12, t, M12, M21, t);
00444     }
00445 
00446     /**
00447      * See the documentation for GeodesicLine::ArcPosition.
00448      **********************************************************************/
00449     void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
00450                      real& s12, real& m12, real& M12, real& M21)
00451       const throw() {
00452       real t;
00453       GenPosition(true, a12,
00454                   LATITUDE | LONGITUDE | AZIMUTH |
00455                   DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
00456                   lat2, lon2, azi2, s12, m12, M12, M21, t);
00457     }
00458     ///@}
00459 
00460     /** \name The general position function.
00461      **********************************************************************/
00462     ///@{
00463 
00464     /**
00465      * The general position function.  GeodesicLine::Position and
00466      * GeodesicLine::ArcPosition are defined in terms of this function.
00467      *
00468      * @param[in] arcmode boolean flag determining the meaning of the second
00469      *   parameter; if arcmode is false, then the GeodesicLine object must have
00470      *   been constructed with \e caps |= GeodesicLine::DISTANCE_IN.
00471      * @param[in] s12_a12 if \e arcmode is false, this is the distance between
00472      *   point 1 and point 2 (meters); otherwise it is the arc length between
00473      *   point 1 and point 2 (degrees); it can be signed.
00474      * @param[in] outmask a bitor'ed combination of GeodesicLine::mask values
00475      *   specifying which of the following parameters should be set.
00476      * @param[out] lat2 latitude of point 2 (degrees).
00477      * @param[out] lon2 longitude of point 2 (degrees); requires that the
00478      *   GeodesicLine object was constructed with \e caps |=
00479      *   GeodesicLine::LONGITUDE.
00480      * @param[out] azi2 (forward) azimuth at point 2 (degrees).
00481      * @param[out] s12 distance between point 1 and point 2 (meters); requires
00482      *   that the GeodesicLine object was constructed with \e caps |=
00483      *   GeodesicLine::DISTANCE.
00484      * @param[out] m12 reduced length of geodesic (meters); requires that the
00485      *   GeodesicLine object was constructed with \e caps |=
00486      *   GeodesicLine::REDUCEDLENGTH.
00487      * @param[out] M12 geodesic scale of point 2 relative to point 1
00488      *   (dimensionless); requires that the GeodesicLine object was constructed
00489      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00490      * @param[out] M21 geodesic scale of point 1 relative to point 2
00491      *   (dimensionless); requires that the GeodesicLine object was constructed
00492      *   with \e caps |= GeodesicLine::GEODESICSCALE.
00493      * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires
00494      *   that the GeodesicLine object was constructed with \e caps |=
00495      *   GeodesicLine::AREA.
00496      * @return \e a12 arc length of between point 1 and point 2 (degrees).
00497      *
00498      * The GeodesicLine::mask values possible for \e outmask are
00499      * - \e outmask |= GeodesicLine::LATITUDE for the latitude \e lat2.
00500      * - \e outmask |= GeodesicLine::LONGITUDE for the latitude \e lon2.
00501      * - \e outmask |= GeodesicLine::AZIMUTH for the latitude \e azi2.
00502      * - \e outmask |= GeodesicLine::DISTANCE for the distance \e s12.
00503      * - \e outmask |= GeodesicLine::REDUCEDLENGTH for the reduced length \e
00504      *   m12.
00505      * - \e outmask |= GeodesicLine::GEODESICSCALE for the geodesic scales \e
00506      *   M12 and \e M21.
00507      * - \e outmask |= GeodesicLine::AREA for the area \e S12.
00508      * .
00509      * Requesting a value which the GeodesicLine object is not capable of
00510      * computing is not an error; the corresponding argument will not be
00511      * altered.  Note, however, that the arc length is always computed and
00512      * returned as the function value.
00513      **********************************************************************/
00514     Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
00515                            real& lat2, real& lon2, real& azi2,
00516                            real& s12, real& m12, real& M12, real& M21,
00517                            real& S12) const throw();
00518 
00519     ///@}
00520 
00521     /** \name Inspector functions
00522      **********************************************************************/
00523     ///@{
00524 
00525     /**
00526      * @return true if the object has been initialized.
00527      **********************************************************************/
00528     bool Init() const throw() { return _caps != 0U; }
00529 
00530     /**
00531      * @return \e lat1 the latitude of point 1 (degrees).
00532      **********************************************************************/
00533     Math::real Latitude() const throw() { return Init() ? _lat1 : 0; }
00534 
00535     /**
00536      * @return \e lon1 the longitude of point 1 (degrees).
00537      **********************************************************************/
00538     Math::real Longitude() const throw() { return Init() ? _lon1 : 0; }
00539 
00540     /**
00541      * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1.
00542      **********************************************************************/
00543     Math::real Azimuth() const throw() { return Init() ? _azi1 : 0; }
00544 
00545     /**
00546      * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses
00547      * the equator in a northward direction.
00548      **********************************************************************/
00549     Math::real EquatorialAzimuth() const throw() {
00550       return Init() ? atan2(_salp0, _calp0) / Math::degree<real>() : 0;
00551     }
00552 
00553     /**
00554      * @return \e a1 the arc length (degrees) between the northward equatorial
00555      * crossing and point 1.
00556      **********************************************************************/
00557     Math::real EquatorialArc() const throw() {
00558       return Init() ? atan2(_ssig1, _csig1) / Math::degree<real>() : 0;
00559     }
00560 
00561     /**
00562      * @return \e a the equatorial radius of the ellipsoid (meters).  This is
00563      *   the value inherited from the Geodesic object used in the constructor.
00564      **********************************************************************/
00565     Math::real MajorRadius() const throw() { return Init() ? _a : 0; }
00566 
00567     /**
00568      * @return \e r the inverse flattening of the ellipsoid.  This is the
00569      *   value inherited from the Geodesic object used in the constructor.  A
00570      *   value of 0 is returned for a sphere (infinite inverse flattening).
00571      **********************************************************************/
00572     Math::real InverseFlattening() const throw() { return Init() ? _r : 0; }
00573 
00574     /**
00575      * @return \e caps the computational capabilities that this object was
00576      *   constructed with.  LATITUDE and AZIMUTH are always included.
00577      **********************************************************************/
00578     unsigned Capabilities() const throw() { return _caps; }
00579 
00580     /**
00581      * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
00582      * @return true if the GeodesicLine object has all these capabilities.
00583      **********************************************************************/
00584     bool Capabilities(unsigned testcaps) const throw() {
00585       testcaps &= OUT_ALL;
00586       return (_caps & testcaps) == testcaps;
00587     }
00588     ///@}
00589 
00590     /** \name Deprecated Functions
00591      **********************************************************************/
00592     ///@{
00593 
00594     /**
00595      * <b>DEPRECATED</b>.  Return the latitude, \e lat2, longitude, \e lon2,
00596      * and forward azimuth, \e azi2 (degrees) of the point 2 which is a
00597      * distance, \e s12 (in meters), from point 1.  Also return the reduced
00598      * length \e m12 (meters).  \e s12 can be signed.  If \e arcmode (default
00599      * false) is set to true, \e s12 is interpreted as the arc length \e a12
00600      * (in degrees) on the auxiliary sphere.  Returned value is the arc length
00601      * \e a12 (degrees) if \e arcmode is false, otherwise it is the distance \e
00602      * s12 (meters).
00603      **********************************************************************/
00604     Math::real Position(real s12, real& lat2, real& lon2,
00605                         real& azi2, real &m12, bool arcmode)
00606       const throw() {
00607       if (arcmode) {
00608         real s12x;
00609         ArcPosition(s12, lat2, lon2, azi2, s12x, m12);
00610         return s12x;
00611       } else
00612         return Position(s12, lat2, lon2, azi2, m12);
00613     }
00614 
00615     /**
00616      * <b>DEPRECATED</b>.  Return the scale of the geodesic line extending an
00617      * arc length \e a12 (degrees) from point 1 to point 2.  \e M12 (a number)
00618      * measures the convergence of initially parallel geodesics.  It is defined
00619      * by the following construction: starting at point 1 proceed at azimuth \e
00620      * azi1 + 90<sup>o</sup> a small distance \e dt; turn -90<sup>o</sup> and
00621      * proceed a distance \e s12 (\e not the arc length \e a12); the distance
00622      * to point 2 is given by \e M12 \e dt.  \e M21 is defined analogously.
00623      **********************************************************************/
00624     void Scale(real a12, real& M12, real& M21) const throw() {
00625       real lat2, lon2, azi2, s12;
00626       ArcPosition(a12, lat2, lon2, azi2, s12, M12, M21);
00627     }
00628     ///@}
00629 
00630   };
00631 
00632 } // namespace GeographicLib
00633 #endif