GeographicLib
2.7
Toggle main menu visibility
Loading...
Searching...
No Matches
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-2022) <karney@alum.mit.edu> and licensed
6
* under the MIT/X11 License. For more information, see
7
* https://geographiclib.sourceforge.io/
8
**********************************************************************/
9
10
#if !defined(GEOGRAPHICLIB_GNOMONIC_HPP)
11
#define GEOGRAPHICLIB_GNOMONIC_HPP 1
12
13
#include <
GeographicLib/Geodesic.hpp
>
14
#include <
GeographicLib/GeodesicLine.hpp
>
15
#include <
GeographicLib/Constants.hpp
>
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://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://doi.org/10.1007/s00190-012-0578-z">
29
* 10.1007/s00190-012-0578-z</a>;
30
* addenda:
31
* <a href="https://geographiclib.sourceforge.io/geod-addenda.html">
32
* geod-addenda.html</a>.
33
* .
34
* The projection of \e P is defined as follows: compute the geodesic line
35
* from \e C to \e P; compute the reduced length \e m12, geodesic scale \e
36
* M12, and ρ = <i>m12</i>/\e M12; finally \e x = ρ sin \e azi1; \e
37
* y = ρ cos \e azi1, where \e azi1 is the azimuth of the geodesic at \e
38
* C. The Gnomonic::Forward and Gnomonic::Reverse methods also return the
39
* azimuth \e azi of the geodesic at \e P and reciprocal scale \e rk in the
40
* azimuthal direction. The scale in the radial direction if
41
* 1/<i>rk</i><sup>2</sup>.
42
*
43
* For a sphere, ρ is reduces to \e a tan(<i>s12</i>/<i>a</i>), where \e
44
* s12 is the length of the geodesic from \e C to \e P, and the gnomonic
45
* projection has the property that all geodesics appear as straight lines.
46
* For an ellipsoid, this property holds only for geodesics interesting the
47
* centers. However geodesic segments close to the center are approximately
48
* straight.
49
*
50
* Consider a geodesic segment of length \e l. Let \e T be the point on the
51
* geodesic (extended if necessary) closest to \e C the center of the
52
* projection and \e t be the distance \e CT. To lowest order, the maximum
53
* deviation (as a true distance) of the corresponding gnomonic line segment
54
* (i.e., with the same end points) from the geodesic is<br>
55
* <br>
56
* (<i>K</i>(<i>T</i>) - <i>K</i>(<i>C</i>))
57
* <i>l</i><sup>2</sup> \e t / 32.<br>
58
* <br>
59
* where \e K is the Gaussian curvature.
60
*
61
* This result applies for any surface. For an ellipsoid of revolution,
62
* consider all geodesics whose end points are within a distance \e r of \e
63
* C. For a given \e r, the deviation is maximum when the latitude of \e C
64
* is 45°, when endpoints are a distance \e r away, and when their
65
* azimuths from the center are ± 45° or ± 135°.
66
* To lowest order in \e r and the flattening \e f, the deviation is \e f
67
* (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r.
68
*
69
* The conversions all take place using a Geodesic object (by default
70
* Geodesic::WGS84()). For more information on geodesics see \ref geodesic.
71
*
72
* \warning The definition of this projection for a sphere is
73
* standard. However, there is no standard for how it should be extended to
74
* an ellipsoid. The choices are:
75
* - Declare that the projection is undefined for an ellipsoid.
76
* - Project to a tangent plane from the center of the ellipsoid. This
77
* causes great ellipses to appear as straight lines in the projection;
78
* i.e., it generalizes the spherical great circle to a great ellipse.
79
* This was proposed by independently by Bowring and Williams in 1997.
80
* - Project to the conformal sphere with the constant of integration chosen
81
* so that the values of the latitude match for the center point and
82
* perform a central projection onto the plane tangent to the conformal
83
* sphere at the center point. This causes normal sections through the
84
* center point to appear as straight lines in the projection; i.e., it
85
* generalizes the spherical great circle to a normal section. This was
86
* proposed by I. G. Letoval'tsev, Generalization of the gnomonic
87
* projection for a spheroid and the principal geodetic problems involved
88
* in the alignment of surface routes, Geodesy and Aerophotography (5),
89
* 271--274 (1963).
90
* - The projection given here. This causes geodesics close to the center
91
* point to appear as straight lines in the projection; i.e., it
92
* generalizes the spherical great circle to a geodesic.
93
*
94
* Example of use:
95
* \include example-Gnomonic.cpp
96
*
97
* <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utility
98
* providing access to the functionality of AzimuthalEquidistant, Gnomonic,
99
* and CassiniSoldner.
100
**********************************************************************/
101
102
class
GEOGRAPHICLIB_EXPORT
Gnomonic
{
103
private
:
104
typedef
Math::real
real;
105
real eps0_, eps_;
106
Geodesic
_earth;
107
real _a, _f;
108
// numit_ increased from 10 to 20 to fix convergence failure with high
109
// precision (e.g., GEOGRAPHICLIB_DIGITS=2000) calculations. Reverse uses
110
// Newton's method which converges quadratically and so numit_ = 10 would
111
// normally be big enough. However, since the Geodesic class is based on a
112
// series it is of limited accuracy; in particular, the derivative rules
113
// used by Reverse only hold approximately. Consequently, after a few
114
// iterations, the convergence in the Reverse falls back to improvements in
115
// each step by a constant (albeit small) factor.
116
static
const
int
numit_ = 20;
117
public
:
118
119
/**
120
* Constructor for Gnomonic.
121
*
122
* @param[in] earth the Geodesic object to use for geodesic calculations.
123
* By default this uses the WGS84 ellipsoid.
124
**********************************************************************/
125
explicit
Gnomonic
(
const
Geodesic
& earth =
Geodesic::WGS84
());
126
127
/**
128
* Forward projection, from geographic to gnomonic.
129
*
130
* @param[in] lat0 latitude of center point of projection (degrees).
131
* @param[in] lon0 longitude of center point of projection (degrees).
132
* @param[in] lat latitude of point (degrees).
133
* @param[in] lon longitude of point (degrees).
134
* @param[out] x easting of point (meters).
135
* @param[out] y northing of point (meters).
136
* @param[out] azi azimuth of geodesic at point (degrees).
137
* @param[out] rk reciprocal of azimuthal scale at point.
138
*
139
* \e lat0 and \e lat should be in the range [−90°, 90°].
140
* The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radial"
141
* direction, \e azi clockwise from true north, and is 1/\e rk in the
142
* direction perpendicular to this. If the point lies "over the horizon",
143
* i.e., if \e rk ≤ 0, then NaNs are returned for \e x and \e y (the
144
* correct values are returned for \e azi and \e rk). A call to Forward
145
* followed by a call to Reverse will return the original (\e lat, \e lon)
146
* (to within roundoff) provided the point in not over the horizon.
147
**********************************************************************/
148
void
Forward
(real lat0, real lon0, real lat, real lon,
149
real& x, real& y, real& azi, real& rk)
const
;
150
151
/**
152
* Reverse projection, from gnomonic to geographic.
153
*
154
* @param[in] lat0 latitude of center point of projection (degrees).
155
* @param[in] lon0 longitude of center point of projection (degrees).
156
* @param[in] x easting of point (meters).
157
* @param[in] y northing of point (meters).
158
* @param[out] lat latitude of point (degrees).
159
* @param[out] lon longitude of point (degrees).
160
* @param[out] azi azimuth of geodesic at point (degrees).
161
* @param[out] rk reciprocal of azimuthal scale at point.
162
*
163
* \e lat0 should be in the range [−90°, 90°]. \e lat will
164
* be in the range [−90°, 90°] and \e lon will be in the
165
* range [−180°, 180°]. The scale of the projection is
166
* 1/<i>rk</i><sup>2</sup> in the "radial" direction, \e azi clockwise from
167
* true north, and is 1/\e rk in the direction perpendicular to this. Even
168
* though all inputs should return a valid \e lat and \e lon, it's possible
169
* that the procedure fails to converge for very large \e x or \e y; in
170
* this case NaNs are returned for all the output arguments. A call to
171
* Reverse followed by a call to Forward will return the original (\e x, \e
172
* y) (to roundoff).
173
**********************************************************************/
174
void
Reverse
(real lat0, real lon0, real x, real y,
175
real& lat, real& lon, real& azi, real& rk)
const
;
176
177
/**
178
* Gnomonic::Forward without returning the azimuth and scale.
179
**********************************************************************/
180
void
Forward
(real lat0, real lon0, real lat, real lon,
181
real& x, real& y)
const
{
182
real azi, rk;
183
Forward
(lat0, lon0, lat, lon, x, y, azi, rk);
184
}
185
186
/**
187
* Gnomonic::Reverse without returning the azimuth and scale.
188
**********************************************************************/
189
void
Reverse
(real lat0, real lon0, real x, real y,
190
real& lat, real& lon)
const
{
191
real azi, rk;
192
Reverse
(lat0, lon0, x, y, lat, lon, azi, rk);
193
}
194
195
/** \name Inspector functions
196
**********************************************************************/
197
///@{
198
/**
199
* @return \e a the equatorial radius of the ellipsoid (meters). This is
200
* the value inherited from the Geodesic object used in the constructor.
201
**********************************************************************/
202
Math::real
EquatorialRadius
()
const
{
return
_earth.EquatorialRadius(); }
203
204
/**
205
* @return \e f the flattening of the ellipsoid. This is the value
206
* inherited from the Geodesic object used in the constructor.
207
**********************************************************************/
208
Math::real
Flattening
()
const
{
return
_earth.Flattening(); }
209
///@}
210
211
};
212
213
}
// namespace GeographicLib
214
215
#endif
// GEOGRAPHICLIB_GNOMONIC_HPP
Constants.hpp
Header for GeographicLib::Constants class.
GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_EXPORT
Definition
Constants.hpp:59
GeodesicLine.hpp
Header for GeographicLib::GeodesicLine class.
Geodesic.hpp
Header for GeographicLib::Geodesic class.
GeographicLib::Geodesic
Geodesic calculations
Definition
Geodesic.hpp:175
GeographicLib::Geodesic::WGS84
static const Geodesic & WGS84()
Definition
Geodesic.cpp:94
GeographicLib::Gnomonic::EquatorialRadius
Math::real EquatorialRadius() const
Definition
Gnomonic.hpp:202
GeographicLib::Gnomonic::Forward
void Forward(real lat0, real lon0, real lat, real lon, real &x, real &y) const
Definition
Gnomonic.hpp:180
GeographicLib::Gnomonic::Gnomonic
Gnomonic(const Geodesic &earth=Geodesic::WGS84())
Definition
Gnomonic.cpp:21
GeographicLib::Gnomonic::Reverse
void Reverse(real lat0, real lon0, real x, real y, real &lat, real &lon) const
Definition
Gnomonic.hpp:189
GeographicLib::Gnomonic::Flattening
Math::real Flattening() const
Definition
Gnomonic.hpp:208
GeographicLib::Gnomonic::Forward
void Forward(real lat0, real lon0, real lat, real lon, real &x, real &y, real &azi, real &rk) const
Definition
Gnomonic.cpp:29
GeographicLib::Gnomonic::Reverse
void Reverse(real lat0, real lon0, real x, real y, real &lat, real &lon, real &azi, real &rk) const
Definition
Gnomonic.cpp:46
GeographicLib::Math::real
double real
Definition
Math.hpp:115
GeographicLib
Namespace for GeographicLib.
Definition
Accumulator.cpp:12
include
GeographicLib
Gnomonic.hpp
Generated by
1.17.0