GeographicLib  1.43
Gnomonic.hpp
Go to the documentation of this file.
1 /**
2  * \file Gnomonic.hpp
3  * \brief Header for GeographicLib::Gnomonic class
4  *
5  * Copyright (c) Charles Karney (2010-2011) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_GNOMONIC_HPP)
11 #define GEOGRAPHICLIB_GNOMONIC_HPP 1
12 
16 
17 namespace GeographicLib {
18 
19  /**
20  * \brief %Gnomonic projection
21  *
22  * %Gnomonic projection centered at an arbitrary position \e C on the
23  * ellipsoid. This projection is derived in Section 8 of
24  * - C. F. F. Karney,
25  * <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
26  * Algorithms for geodesics</a>,
27  * J. Geodesy <b>87</b>, 43--55 (2013);
28  * DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
29  * 10.1007/s00190-012-0578-z</a>;
30  * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
31  * geod-addenda.html</a>.
32  * .
33  * The projection of \e P is defined as follows: compute the geodesic line
34  * from \e C to \e P; compute the reduced length \e m12, geodesic scale \e
35  * M12, and &rho; = <i>m12</i>/\e M12; finally \e x = &rho; sin \e azi1; \e
36  * y = &rho; cos \e azi1, where \e azi1 is the azimuth of the geodesic at \e
37  * C. The Gnomonic::Forward and Gnomonic::Reverse methods also return the
38  * azimuth \e azi of the geodesic at \e P and reciprocal scale \e rk in the
39  * azimuthal direction. The scale in the radial direction if
40  * 1/<i>rk</i><sup>2</sup>.
41  *
42  * For a sphere, &rho; is reduces to \e a tan(<i>s12</i>/<i>a</i>), where \e
43  * s12 is the length of the geodesic from \e C to \e P, and the gnomonic
44  * projection has the property that all geodesics appear as straight lines.
45  * For an ellipsoid, this property holds only for geodesics interesting the
46  * centers. However geodesic segments close to the center are approximately
47  * straight.
48  *
49  * Consider a geodesic segment of length \e l. Let \e T be the point on the
50  * geodesic (extended if necessary) closest to \e C the center of the
51  * projection and \e t be the distance \e CT. To lowest order, the maximum
52  * deviation (as a true distance) of the corresponding gnomonic line segment
53  * (i.e., with the same end points) from the geodesic is<br>
54  * <br>
55  * (<i>K</i>(<i>T</i>) - <i>K</i>(<i>C</i>))
56  * <i>l</i><sup>2</sup> \e t / 32.<br>
57  * <br>
58  * where \e K is the Gaussian curvature.
59  *
60  * This result applies for any surface. For an ellipsoid of revolution,
61  * consider all geodesics whose end points are within a distance \e r of \e
62  * C. For a given \e r, the deviation is maximum when the latitude of \e C
63  * is 45&deg;, when endpoints are a distance \e r away, and when their
64  * azimuths from the center are &plusmn; 45&deg; or &plusmn; 135&deg;.
65  * To lowest order in \e r and the flattening \e f, the deviation is \e f
66  * (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r.
67  *
68  * The conversions all take place using a Geodesic object (by default
69  * Geodesic::WGS84()). For more information on geodesics see \ref geodesic.
70  *
71  * <b>CAUTION:</b> The definition of this projection for a sphere is
72  * standard. However, there is no standard for how it should be extended to
73  * an ellipsoid. The choices are:
74  * - Declare that the projection is undefined for an ellipsoid.
75  * - Project to a tangent plane from the center of the ellipsoid. This
76  * causes great ellipses to appear as straight lines in the projection;
77  * i.e., it generalizes the spherical great circle to a great ellipse.
78  * This was proposed by independently by Bowring and Williams in 1997.
79  * - Project to the conformal sphere with the constant of integration chosen
80  * so that the values of the latitude match for the center point and
81  * perform a central projection onto the plane tangent to the conformal
82  * sphere at the center point. This causes normal sections through the
83  * center point to appear as straight lines in the projection; i.e., it
84  * generalizes the spherical great circle to a normal section. This was
85  * proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic
86  * Projection for a Spheroid and the Principal Geodetic Problems Involved
87  * in the Alignment of Surface Routes, Geodesy and Aerophotography (5),
88  * 271--274 (1963).
89  * - The projection given here. This causes geodesics close to the center
90  * point to appear as straight lines in the projection; i.e., it
91  * generalizes the spherical great circle to a geodesic.
92  *
93  * Example of use:
94  * \include example-Gnomonic.cpp
95  *
96  * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utility
97  * providing access to the functionality of AzimuthalEquidistant, Gnomonic,
98  * and CassiniSoldner.
99  **********************************************************************/
100 
102  private:
103  typedef Math::real real;
104  real eps0_, eps_;
105  Geodesic _earth;
106  real _a, _f;
107  static const int numit_ = 10;
108  public:
109 
110  /**
111  * Constructor for Gnomonic.
112  *
113  * @param[in] earth the Geodesic object to use for geodesic calculations.
114  * By default this uses the WGS84 ellipsoid.
115  **********************************************************************/
116  explicit Gnomonic(const Geodesic& earth = Geodesic::WGS84());
117 
118  /**
119  * Forward projection, from geographic to gnomonic.
120  *
121  * @param[in] lat0 latitude of center point of projection (degrees).
122  * @param[in] lon0 longitude of center point of projection (degrees).
123  * @param[in] lat latitude of point (degrees).
124  * @param[in] lon longitude of point (degrees).
125  * @param[out] x easting of point (meters).
126  * @param[out] y northing of point (meters).
127  * @param[out] azi azimuth of geodesic at point (degrees).
128  * @param[out] rk reciprocal of azimuthal scale at point.
129  *
130  * \e lat0 and \e lat should be in the range [&minus;90&deg;, 90&deg;] and
131  * \e lon0 and \e lon should be in the range [&minus;540&deg;, 540&deg;).
132  * The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radial"
133  * direction, \e azi clockwise from true north, and is 1/\e rk in the
134  * direction perpendicular to this. If the point lies "over the horizon",
135  * i.e., if \e rk &le; 0, then NaNs are returned for \e x and \e y (the
136  * correct values are returned for \e azi and \e rk). A call to Forward
137  * followed by a call to Reverse will return the original (\e lat, \e lon)
138  * (to within roundoff) provided the point in not over the horizon.
139  **********************************************************************/
140  void Forward(real lat0, real lon0, real lat, real lon,
141  real& x, real& y, real& azi, real& rk) const;
142 
143  /**
144  * Reverse projection, from gnomonic to geographic.
145  *
146  * @param[in] lat0 latitude of center point of projection (degrees).
147  * @param[in] lon0 longitude of center point of projection (degrees).
148  * @param[in] x easting of point (meters).
149  * @param[in] y northing of point (meters).
150  * @param[out] lat latitude of point (degrees).
151  * @param[out] lon longitude of point (degrees).
152  * @param[out] azi azimuth of geodesic at point (degrees).
153  * @param[out] rk reciprocal of azimuthal scale at point.
154  *
155  * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
156  * lon0 should be in the range [&minus;540&deg;, 540&deg;). \e lat
157  * will be in the range [&minus;90&deg;, 90&deg;] and \e lon will
158  * be in the range [&minus;180&deg;, 180&deg;). The scale of the
159  * projection is 1/<i>rk</i><sup>2</sup> in the "radial" direction, \e azi
160  * clockwise from true north, and is 1/\e rk in the direction perpendicular
161  * to this. Even though all inputs should return a valid \e lat and \e
162  * lon, it's possible that the procedure fails to converge for very large
163  * \e x or \e y; in this case NaNs are returned for all the output
164  * arguments. A call to Reverse followed by a call to Forward will return
165  * the original (\e x, \e y) (to roundoff).
166  **********************************************************************/
167  void Reverse(real lat0, real lon0, real x, real y,
168  real& lat, real& lon, real& azi, real& rk) const;
169 
170  /**
171  * Gnomonic::Forward without returning the azimuth and scale.
172  **********************************************************************/
173  void Forward(real lat0, real lon0, real lat, real lon,
174  real& x, real& y) const {
175  real azi, rk;
176  Forward(lat0, lon0, lat, lon, x, y, azi, rk);
177  }
178 
179  /**
180  * Gnomonic::Reverse without returning the azimuth and scale.
181  **********************************************************************/
182  void Reverse(real lat0, real lon0, real x, real y,
183  real& lat, real& lon) const {
184  real azi, rk;
185  Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
186  }
187 
188  /** \name Inspector functions
189  **********************************************************************/
190  ///@{
191  /**
192  * @return \e a the equatorial radius of the ellipsoid (meters). This is
193  * the value inherited from the Geodesic object used in the constructor.
194  **********************************************************************/
195  Math::real MajorRadius() const { return _earth.MajorRadius(); }
196 
197  /**
198  * @return \e f the flattening of the ellipsoid. This is the value
199  * inherited from the Geodesic object used in the constructor.
200  **********************************************************************/
201  Math::real Flattening() const { return _earth.Flattening(); }
202  ///@}
203 
204  /// \cond SKIP
205  /**
206  * <b>DEPRECATED</b>
207  * @return \e r the inverse flattening of the ellipsoid.
208  **********************************************************************/
209  Math::real InverseFlattening() const
210  { return _earth.InverseFlattening(); }
211  /// \endcond
212  };
213 
214 } // namespace GeographicLib
215 
216 #endif // GEOGRAPHICLIB_GNOMONIC_HPP
Header for GeographicLib::GeodesicLine class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:90
Math::real MajorRadius() const
Definition: Geodesic.hpp:857
GeographicLib::Math::real real
Definition: GeodSolve.cpp:32
static const Geodesic & WGS84()
Definition: Geodesic.cpp:89
Gnomonic projection
Definition: Gnomonic.hpp:101
void Reverse(real lat0, real lon0, real x, real y, real &lat, real &lon) const
Definition: Gnomonic.hpp:182
Math::real Flattening() const
Definition: Gnomonic.hpp:201
Header for GeographicLib::Geodesic class.
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
Math::real Flattening() const
Definition: Geodesic.hpp:863
void Forward(real lat0, real lon0, real lat, real lon, real &x, real &y) const
Definition: Gnomonic.hpp:173
Header for GeographicLib::Constants class.
Math::real MajorRadius() const
Definition: Gnomonic.hpp:195
Geodesic calculations
Definition: Geodesic.hpp:171