geographiclib 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +12 -0
  3. data/LICENSE +24 -0
  4. data/ext/geographiclib/Accumulator.cpp +23 -0
  5. data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
  6. data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
  7. data/ext/geographiclib/CassiniSoldner.cpp +89 -0
  8. data/ext/geographiclib/CircularEngine.cpp +96 -0
  9. data/ext/geographiclib/DMS.cpp +381 -0
  10. data/ext/geographiclib/Ellipsoid.cpp +125 -0
  11. data/ext/geographiclib/EllipticFunction.cpp +512 -0
  12. data/ext/geographiclib/GARS.cpp +122 -0
  13. data/ext/geographiclib/GeoCoords.cpp +175 -0
  14. data/ext/geographiclib/Geocentric.cpp +172 -0
  15. data/ext/geographiclib/Geodesic.cpp +1908 -0
  16. data/ext/geographiclib/GeodesicExact.cpp +927 -0
  17. data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
  18. data/ext/geographiclib/GeodesicLine.cpp +321 -0
  19. data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
  20. data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
  21. data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
  22. data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
  23. data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
  24. data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
  25. data/ext/geographiclib/GeographicLib/Config.h +12 -0
  26. data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
  27. data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
  28. data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
  29. data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
  30. data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
  31. data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
  32. data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
  33. data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
  34. data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
  35. data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
  36. data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
  37. data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
  38. data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
  39. data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
  40. data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
  41. data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
  42. data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
  43. data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
  44. data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
  45. data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
  46. data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
  47. data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
  48. data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
  49. data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
  50. data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
  51. data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
  52. data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
  53. data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
  54. data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
  55. data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
  56. data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
  57. data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
  58. data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
  59. data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
  60. data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
  61. data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
  62. data/ext/geographiclib/Geohash.cpp +102 -0
  63. data/ext/geographiclib/Geoid.cpp +509 -0
  64. data/ext/geographiclib/Georef.cpp +135 -0
  65. data/ext/geographiclib/Gnomonic.cpp +85 -0
  66. data/ext/geographiclib/GravityCircle.cpp +129 -0
  67. data/ext/geographiclib/GravityModel.cpp +360 -0
  68. data/ext/geographiclib/LambertConformalConic.cpp +456 -0
  69. data/ext/geographiclib/LocalCartesian.cpp +62 -0
  70. data/ext/geographiclib/MGRS.cpp +461 -0
  71. data/ext/geographiclib/MagneticCircle.cpp +52 -0
  72. data/ext/geographiclib/MagneticModel.cpp +269 -0
  73. data/ext/geographiclib/Math.cpp +63 -0
  74. data/ext/geographiclib/NormalGravity.cpp +262 -0
  75. data/ext/geographiclib/OSGB.cpp +167 -0
  76. data/ext/geographiclib/PolarStereographic.cpp +108 -0
  77. data/ext/geographiclib/PolygonArea.cpp +204 -0
  78. data/ext/geographiclib/Rhumb.cpp +383 -0
  79. data/ext/geographiclib/SphericalEngine.cpp +477 -0
  80. data/ext/geographiclib/TransverseMercator.cpp +603 -0
  81. data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
  82. data/ext/geographiclib/UTMUPS.cpp +296 -0
  83. data/ext/geographiclib/Utility.cpp +61 -0
  84. data/ext/geographiclib/extconf.rb +3 -0
  85. data/ext/geographiclib/geographiclib.cpp +62 -0
  86. data/lib/geographiclib.rb +20 -0
  87. metadata +140 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * \file PolarStereographic.hpp
3
+ * \brief Header for GeographicLib::PolarStereographic class
4
+ *
5
+ * Copyright (c) Charles Karney (2008-2015) <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_POLARSTEREOGRAPHIC_HPP)
11
+ #define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ namespace GeographicLib {
16
+
17
+ /**
18
+ * \brief Polar stereographic projection
19
+ *
20
+ * Implementation taken from the report,
21
+ * - J. P. Snyder,
22
+ * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A
23
+ * Working Manual</a>, USGS Professional Paper 1395 (1987),
24
+ * pp. 160--163.
25
+ *
26
+ * This is a straightforward implementation of the equations in Snyder except
27
+ * that Newton's method is used to invert the projection.
28
+ *
29
+ * Example of use:
30
+ * \include example-PolarStereographic.cpp
31
+ **********************************************************************/
32
+ class GEOGRAPHICLIB_EXPORT PolarStereographic {
33
+ private:
34
+ typedef Math::real real;
35
+ real _a, _f, _e2, _es, _e2m, _c;
36
+ real _k0;
37
+ public:
38
+
39
+ /**
40
+ * Constructor for a ellipsoid with
41
+ *
42
+ * @param[in] a equatorial radius (meters).
43
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
44
+ * Negative \e f gives a prolate ellipsoid.
45
+ * @param[in] k0 central scale factor.
46
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k0 is
47
+ * not positive.
48
+ **********************************************************************/
49
+ PolarStereographic(real a, real f, real k0);
50
+
51
+ /**
52
+ * Set the scale for the projection.
53
+ *
54
+ * @param[in] lat (degrees) assuming \e northp = true.
55
+ * @param[in] k scale at latitude \e lat (default 1).
56
+ * @exception GeographicErr \e k is not positive.
57
+ * @exception GeographicErr if \e lat is not in (&minus;90&deg;,
58
+ * 90&deg;].
59
+ **********************************************************************/
60
+ void SetScale(real lat, real k = real(1));
61
+
62
+ /**
63
+ * Forward projection, from geographic to polar stereographic.
64
+ *
65
+ * @param[in] northp the pole which is the center of projection (true means
66
+ * north, false means south).
67
+ * @param[in] lat latitude of point (degrees).
68
+ * @param[in] lon longitude of point (degrees).
69
+ * @param[out] x easting of point (meters).
70
+ * @param[out] y northing of point (meters).
71
+ * @param[out] gamma meridian convergence at point (degrees).
72
+ * @param[out] k scale of projection at point.
73
+ *
74
+ * No false easting or northing is added. \e lat should be in the range
75
+ * (&minus;90&deg;, 90&deg;] for \e northp = true and in the range
76
+ * [&minus;90&deg;, 90&deg;) for \e northp = false.
77
+ **********************************************************************/
78
+ void Forward(bool northp, real lat, real lon,
79
+ real& x, real& y, real& gamma, real& k) const;
80
+
81
+ /**
82
+ * Reverse projection, from polar stereographic to geographic.
83
+ *
84
+ * @param[in] northp the pole which is the center of projection (true means
85
+ * north, false means south).
86
+ * @param[in] x easting of point (meters).
87
+ * @param[in] y northing of point (meters).
88
+ * @param[out] lat latitude of point (degrees).
89
+ * @param[out] lon longitude of point (degrees).
90
+ * @param[out] gamma meridian convergence at point (degrees).
91
+ * @param[out] k scale of projection at point.
92
+ *
93
+ * No false easting or northing is added. The value of \e lon returned is
94
+ * in the range [&minus;180&deg;, 180&deg;).
95
+ **********************************************************************/
96
+ void Reverse(bool northp, real x, real y,
97
+ real& lat, real& lon, real& gamma, real& k) const;
98
+
99
+ /**
100
+ * PolarStereographic::Forward without returning the convergence and scale.
101
+ **********************************************************************/
102
+ void Forward(bool northp, real lat, real lon,
103
+ real& x, real& y) const {
104
+ real gamma, k;
105
+ Forward(northp, lat, lon, x, y, gamma, k);
106
+ }
107
+
108
+ /**
109
+ * PolarStereographic::Reverse without returning the convergence and scale.
110
+ **********************************************************************/
111
+ void Reverse(bool northp, real x, real y,
112
+ real& lat, real& lon) const {
113
+ real gamma, k;
114
+ Reverse(northp, x, y, lat, lon, gamma, k);
115
+ }
116
+
117
+ /** \name Inspector functions
118
+ **********************************************************************/
119
+ ///@{
120
+ /**
121
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
122
+ * the value used in the constructor.
123
+ **********************************************************************/
124
+ Math::real MajorRadius() const { return _a; }
125
+
126
+ /**
127
+ * @return \e f the flattening of the ellipsoid. This is the value used in
128
+ * the constructor.
129
+ **********************************************************************/
130
+ Math::real Flattening() const { return _f; }
131
+
132
+ /**
133
+ * The central scale for the projection. This is the value of \e k0 used
134
+ * in the constructor and is the scale at the pole unless overridden by
135
+ * PolarStereographic::SetScale.
136
+ **********************************************************************/
137
+ Math::real CentralScale() const { return _k0; }
138
+ ///@}
139
+
140
+ /**
141
+ * A global instantiation of PolarStereographic with the WGS84 ellipsoid
142
+ * and the UPS scale factor. However, unlike UPS, no false easting or
143
+ * northing is added.
144
+ **********************************************************************/
145
+ static const PolarStereographic& UPS();
146
+ };
147
+
148
+ } // namespace GeographicLib
149
+
150
+ #endif // GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP
@@ -0,0 +1,288 @@
1
+ /**
2
+ * \file PolygonArea.hpp
3
+ * \brief Header for GeographicLib::PolygonAreaT class
4
+ *
5
+ * Copyright (c) Charles Karney (2010-2016) <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_POLYGONAREA_HPP)
11
+ #define GEOGRAPHICLIB_POLYGONAREA_HPP 1
12
+
13
+ #include <GeographicLib/Geodesic.hpp>
14
+ #include <GeographicLib/GeodesicExact.hpp>
15
+ #include <GeographicLib/Rhumb.hpp>
16
+ #include <GeographicLib/Accumulator.hpp>
17
+
18
+ namespace GeographicLib {
19
+
20
+ /**
21
+ * \brief Polygon areas
22
+ *
23
+ * This computes the area of a polygon whose edges are geodesics using the
24
+ * method given in Section 6 of
25
+ * - C. F. F. Karney,
26
+ * <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
27
+ * Algorithms for geodesics</a>,
28
+ * J. Geodesy <b>87</b>, 43--55 (2013);
29
+ * DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
30
+ * 10.1007/s00190-012-0578-z</a>;
31
+ * addenda:
32
+ * <a href="http://geographiclib.sourceforge.net/geod-addenda.html">
33
+ * geod-addenda.html</a>.
34
+ *
35
+ * This class lets you add vertices and edges one at a time to the polygon.
36
+ * The sequence must start with a vertex and thereafter vertices and edges
37
+ * can be added in any order. Any vertex after the first creates a new edge
38
+ * which is the \e shortest geodesic from the previous vertex. In some
39
+ * cases there may be two or many such shortest geodesics and the area is
40
+ * then not uniquely defined. In this case, either add an intermediate
41
+ * vertex or add the edge \e as an edge (by defining its direction and
42
+ * length).
43
+ *
44
+ * The area and perimeter are accumulated at two times the standard floating
45
+ * point precision to guard against the loss of accuracy with many-sided
46
+ * polygons. At any point you can ask for the perimeter and area so far.
47
+ * There's an option to treat the points as defining a polyline instead of a
48
+ * polygon; in that case, only the perimeter is computed.
49
+ *
50
+ * This is a templated class to allow it to be used with Geodesic,
51
+ * GeodesicExact, and Rhumb. GeographicLib::PolygonArea,
52
+ * GeographicLib::PolygonAreaExact, and GeographicLib::PolygonAreaRhumb are
53
+ * typedefs for these cases.
54
+ *
55
+ * @tparam GeodType the geodesic class to use.
56
+ *
57
+ * Example of use:
58
+ * \include example-PolygonArea.cpp
59
+ *
60
+ * <a href="Planimeter.1.html">Planimeter</a> is a command-line utility
61
+ * providing access to the functionality of PolygonAreaT.
62
+ **********************************************************************/
63
+
64
+ template <class GeodType = Geodesic>
65
+ class PolygonAreaT {
66
+ private:
67
+ typedef Math::real real;
68
+ GeodType _earth;
69
+ real _area0; // Full ellipsoid area
70
+ bool _polyline; // Assume polyline (don't close and skip area)
71
+ unsigned _mask;
72
+ unsigned _num;
73
+ int _crossings;
74
+ Accumulator<> _areasum, _perimetersum;
75
+ real _lat0, _lon0, _lat1, _lon1;
76
+ static inline int transit(real lon1, real lon2) {
77
+ // Return 1 or -1 if crossing prime meridian in east or west direction.
78
+ // Otherwise return zero.
79
+ // Compute lon12 the same way as Geodesic::Inverse.
80
+ lon1 = Math::AngNormalize(lon1);
81
+ lon2 = Math::AngNormalize(lon2);
82
+ real lon12 = Math::AngDiff(lon1, lon2);
83
+ int cross =
84
+ lon1 < 0 && lon2 >= 0 && lon12 > 0 ? 1 :
85
+ (lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0);
86
+ return cross;
87
+ }
88
+ // an alternate version of transit to deal with longitudes in the direct
89
+ // problem.
90
+ static inline int transitdirect(real lon1, real lon2) {
91
+ // We want to compute exactly
92
+ // int(floor(lon2 / 360)) - int(floor(lon1 / 360))
93
+ // Since we only need the parity of the result we can use std::remquo;
94
+ // but this is buggy with g++ 4.8.3 (glibc version < 2.22), see
95
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=17569
96
+ // and requires C++11. So instead we do
97
+ #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4
98
+ using std::remainder;
99
+ lon1 = remainder(lon1, real(720)); lon2 = remainder(lon2, real(720));
100
+ return ( (lon2 >= 0 && lon2 < 360 ? 0 : 1) -
101
+ (lon1 >= 0 && lon1 < 360 ? 0 : 1) );
102
+ #else
103
+ using std::fmod;
104
+ lon1 = fmod(lon1, real(720)); lon2 = fmod(lon2, real(720));
105
+ return ( ((lon2 >= 0 && lon2 < 360) || lon2 < -360 ? 0 : 1) -
106
+ ((lon1 >= 0 && lon1 < 360) || lon1 < -360 ? 0 : 1) );
107
+ #endif
108
+ }
109
+ public:
110
+
111
+ /**
112
+ * Constructor for PolygonAreaT.
113
+ *
114
+ * @param[in] earth the Geodesic object to use for geodesic calculations.
115
+ * @param[in] polyline if true that treat the points as defining a polyline
116
+ * instead of a polygon (default = false).
117
+ **********************************************************************/
118
+ PolygonAreaT(const GeodType& earth, bool polyline = false)
119
+ : _earth(earth)
120
+ , _area0(_earth.EllipsoidArea())
121
+ , _polyline(polyline)
122
+ , _mask(GeodType::LATITUDE | GeodType::LONGITUDE | GeodType::DISTANCE |
123
+ (_polyline ? GeodType::NONE :
124
+ GeodType::AREA | GeodType::LONG_UNROLL))
125
+ { Clear(); }
126
+
127
+ /**
128
+ * Clear PolygonAreaT, allowing a new polygon to be started.
129
+ **********************************************************************/
130
+ void Clear() {
131
+ _num = 0;
132
+ _crossings = 0;
133
+ _areasum = 0;
134
+ _perimetersum = 0;
135
+ _lat0 = _lon0 = _lat1 = _lon1 = Math::NaN();
136
+ }
137
+
138
+ /**
139
+ * Add a point to the polygon or polyline.
140
+ *
141
+ * @param[in] lat the latitude of the point (degrees).
142
+ * @param[in] lon the longitude of the point (degrees).
143
+ *
144
+ * \e lat should be in the range [&minus;90&deg;, 90&deg;].
145
+ **********************************************************************/
146
+ void AddPoint(real lat, real lon);
147
+
148
+ /**
149
+ * Add an edge to the polygon or polyline.
150
+ *
151
+ * @param[in] azi azimuth at current point (degrees).
152
+ * @param[in] s distance from current point to next point (meters).
153
+ *
154
+ * This does nothing if no points have been added yet. Use
155
+ * PolygonAreaT::CurrentPoint to determine the position of the new vertex.
156
+ **********************************************************************/
157
+ void AddEdge(real azi, real s);
158
+
159
+ /**
160
+ * Return the results so far.
161
+ *
162
+ * @param[in] reverse if true then clockwise (instead of counter-clockwise)
163
+ * traversal counts as a positive area.
164
+ * @param[in] sign if true then return a signed result for the area if
165
+ * the polygon is traversed in the "wrong" direction instead of returning
166
+ * the area for the rest of the earth.
167
+ * @param[out] perimeter the perimeter of the polygon or length of the
168
+ * polyline (meters).
169
+ * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
170
+ * if \e polyline is false in the constructor.
171
+ * @return the number of points.
172
+ *
173
+ * More points can be added to the polygon after this call.
174
+ **********************************************************************/
175
+ unsigned Compute(bool reverse, bool sign,
176
+ real& perimeter, real& area) const;
177
+
178
+ /**
179
+ * Return the results assuming a tentative final test point is added;
180
+ * however, the data for the test point is not saved. This lets you report
181
+ * a running result for the perimeter and area as the user moves the mouse
182
+ * cursor. Ordinary floating point arithmetic is used to accumulate the
183
+ * data for the test point; thus the area and perimeter returned are less
184
+ * accurate than if PolygonAreaT::AddPoint and PolygonAreaT::Compute are
185
+ * used.
186
+ *
187
+ * @param[in] lat the latitude of the test point (degrees).
188
+ * @param[in] lon the longitude of the test point (degrees).
189
+ * @param[in] reverse if true then clockwise (instead of counter-clockwise)
190
+ * traversal counts as a positive area.
191
+ * @param[in] sign if true then return a signed result for the area if
192
+ * the polygon is traversed in the "wrong" direction instead of returning
193
+ * the area for the rest of the earth.
194
+ * @param[out] perimeter the approximate perimeter of the polygon or length
195
+ * of the polyline (meters).
196
+ * @param[out] area the approximate area of the polygon
197
+ * (meters<sup>2</sup>); only set if polyline is false in the
198
+ * constructor.
199
+ * @return the number of points.
200
+ *
201
+ * \e lat should be in the range [&minus;90&deg;, 90&deg;].
202
+ **********************************************************************/
203
+ unsigned TestPoint(real lat, real lon, bool reverse, bool sign,
204
+ real& perimeter, real& area) const;
205
+
206
+ /**
207
+ * Return the results assuming a tentative final test point is added via an
208
+ * azimuth and distance; however, the data for the test point is not saved.
209
+ * This lets you report a running result for the perimeter and area as the
210
+ * user moves the mouse cursor. Ordinary floating point arithmetic is used
211
+ * to accumulate the data for the test point; thus the area and perimeter
212
+ * returned are less accurate than if PolygonAreaT::AddEdge and
213
+ * PolygonAreaT::Compute are used.
214
+ *
215
+ * @param[in] azi azimuth at current point (degrees).
216
+ * @param[in] s distance from current point to final test point (meters).
217
+ * @param[in] reverse if true then clockwise (instead of counter-clockwise)
218
+ * traversal counts as a positive area.
219
+ * @param[in] sign if true then return a signed result for the area if
220
+ * the polygon is traversed in the "wrong" direction instead of returning
221
+ * the area for the rest of the earth.
222
+ * @param[out] perimeter the approximate perimeter of the polygon or length
223
+ * of the polyline (meters).
224
+ * @param[out] area the approximate area of the polygon
225
+ * (meters<sup>2</sup>); only set if polyline is false in the
226
+ * constructor.
227
+ * @return the number of points.
228
+ **********************************************************************/
229
+ unsigned TestEdge(real azi, real s, bool reverse, bool sign,
230
+ real& perimeter, real& area) const;
231
+
232
+ /** \name Inspector functions
233
+ **********************************************************************/
234
+ ///@{
235
+ /**
236
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
237
+ * the value inherited from the Geodesic object used in the constructor.
238
+ **********************************************************************/
239
+
240
+ Math::real MajorRadius() const { return _earth.MajorRadius(); }
241
+
242
+ /**
243
+ * @return \e f the flattening of the ellipsoid. This is the value
244
+ * inherited from the Geodesic object used in the constructor.
245
+ **********************************************************************/
246
+ Math::real Flattening() const { return _earth.Flattening(); }
247
+
248
+ /**
249
+ * Report the previous vertex added to the polygon or polyline.
250
+ *
251
+ * @param[out] lat the latitude of the point (degrees).
252
+ * @param[out] lon the longitude of the point (degrees).
253
+ *
254
+ * If no points have been added, then NaNs are returned. Otherwise, \e lon
255
+ * will be in the range [&minus;180&deg;, 180&deg;).
256
+ **********************************************************************/
257
+ void CurrentPoint(real& lat, real& lon) const
258
+ { lat = _lat1; lon = _lon1; }
259
+ ///@}
260
+ };
261
+
262
+ /**
263
+ * @relates PolygonAreaT
264
+ *
265
+ * Polygon areas using Geodesic. This should be used if the flattening is
266
+ * small.
267
+ **********************************************************************/
268
+ typedef PolygonAreaT<Geodesic> PolygonArea;
269
+
270
+ /**
271
+ * @relates PolygonAreaT
272
+ *
273
+ * Polygon areas using GeodesicExact. (But note that the implementation of
274
+ * areas in GeodesicExact uses a high order series and this is only accurate
275
+ * for modest flattenings.)
276
+ **********************************************************************/
277
+ typedef PolygonAreaT<GeodesicExact> PolygonAreaExact;
278
+
279
+ /**
280
+ * @relates PolygonAreaT
281
+ *
282
+ * Polygon areas using Rhumb.
283
+ **********************************************************************/
284
+ typedef PolygonAreaT<Rhumb> PolygonAreaRhumb;
285
+
286
+ } // namespace GeographicLib
287
+
288
+ #endif // GEOGRAPHICLIB_POLYGONAREA_HPP
@@ -0,0 +1,589 @@
1
+ /**
2
+ * \file Rhumb.hpp
3
+ * \brief Header for GeographicLib::Rhumb and GeographicLib::RhumbLine classes
4
+ *
5
+ * Copyright (c) Charles Karney (2014-2015) <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_RHUMB_HPP)
11
+ #define GEOGRAPHICLIB_RHUMB_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+ #include <GeographicLib/Ellipsoid.hpp>
15
+
16
+ #if !defined(GEOGRAPHICLIB_RHUMBAREA_ORDER)
17
+ /**
18
+ * The order of the series approximation used in rhumb area calculations.
19
+ * GEOGRAPHICLIB_RHUMBAREA_ORDER can be set to any integer in [4, 8].
20
+ **********************************************************************/
21
+ # define GEOGRAPHICLIB_RHUMBAREA_ORDER \
22
+ (GEOGRAPHICLIB_PRECISION == 2 ? 6 : \
23
+ (GEOGRAPHICLIB_PRECISION == 1 ? 4 : 8))
24
+ #endif
25
+
26
+ namespace GeographicLib {
27
+
28
+ class RhumbLine;
29
+ template <class T> class PolygonAreaT;
30
+
31
+ /**
32
+ * \brief Solve of the direct and inverse rhumb problems.
33
+ *
34
+ * The path of constant azimuth between two points on a ellipsoid at (\e
35
+ * lat1, \e lon1) and (\e lat2, \e lon2) is called the rhumb line (also
36
+ * called the loxodrome). Its length is \e s12 and its azimuth is \e azi12.
37
+ * (The azimuth is the heading measured clockwise from north.)
38
+ *
39
+ * Given \e lat1, \e lon1, \e azi12, and \e s12, we can determine \e lat2,
40
+ * and \e lon2. This is the \e direct rhumb problem and its solution is
41
+ * given by the function Rhumb::Direct.
42
+ *
43
+ * Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi12
44
+ * and \e s12. This is the \e inverse rhumb problem, whose solution is given
45
+ * by Rhumb::Inverse. This finds the shortest such rhumb line, i.e., the one
46
+ * that wraps no more than half way around the earth. If the end points are
47
+ * on opposite meridians, there are two shortest rhumb lines and the
48
+ * east-going one is chosen.
49
+ *
50
+ * These routines also optionally calculate the area under the rhumb line, \e
51
+ * S12. This is the area, measured counter-clockwise, of the rhumb line
52
+ * quadrilateral with corners (<i>lat1</i>,<i>lon1</i>), (0,<i>lon1</i>),
53
+ * (0,<i>lon2</i>), and (<i>lat2</i>,<i>lon2</i>).
54
+ *
55
+ * Note that rhumb lines may be appreciably longer (up to 50%) than the
56
+ * corresponding Geodesic. For example the distance between London Heathrow
57
+ * and Tokyo Narita via the rhumb line is 11400 km which is 18% longer than
58
+ * the geodesic distance 9600 km.
59
+ *
60
+ * For more information on rhumb lines see \ref rhumb.
61
+ *
62
+ * Example of use:
63
+ * \include example-Rhumb.cpp
64
+ **********************************************************************/
65
+
66
+ class GEOGRAPHICLIB_EXPORT Rhumb {
67
+ private:
68
+ typedef Math::real real;
69
+ friend class RhumbLine;
70
+ template <class T> friend class PolygonAreaT;
71
+ Ellipsoid _ell;
72
+ bool _exact;
73
+ real _c2;
74
+ static const int tm_maxord = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
75
+ static const int maxpow_ = GEOGRAPHICLIB_RHUMBAREA_ORDER;
76
+ // _R[0] unused
77
+ real _R[maxpow_ + 1];
78
+ static inline real gd(real x)
79
+ { using std::atan; using std::sinh; return atan(sinh(x)); }
80
+
81
+ // Use divided differences to determine (mu2 - mu1) / (psi2 - psi1)
82
+ // accurately
83
+ //
84
+ // Definition: Df(x,y,d) = (f(x) - f(y)) / (x - y)
85
+ // See:
86
+ // W. M. Kahan and R. J. Fateman,
87
+ // Symbolic computation of divided differences,
88
+ // SIGSAM Bull. 33(3), 7-28 (1999)
89
+ // https://dx.doi.org/10.1145/334714.334716
90
+ // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
91
+
92
+ static inline real Dlog(real x, real y) {
93
+ real t = x - y;
94
+ return t ? 2 * Math::atanh(t / (x + y)) / t : 1 / x;
95
+ }
96
+ // N.B., x and y are in degrees
97
+ static inline real Dtan(real x, real y) {
98
+ real d = x - y, tx = Math::tand(x), ty = Math::tand(y), txy = tx * ty;
99
+ return d ?
100
+ (2 * txy > -1 ? (1 + txy) * Math::tand(d) : tx - ty) /
101
+ (d * Math::degree()) :
102
+ 1 + txy;
103
+ }
104
+ static inline real Datan(real x, real y) {
105
+ using std::atan;
106
+ real d = x - y, xy = x * y;
107
+ return d ? (2 * xy > -1 ? atan( d / (1 + xy) ) : atan(x) - atan(y)) / d :
108
+ 1 / (1 + xy);
109
+ }
110
+ static inline real Dsin(real x, real y) {
111
+ using std::sin; using std::cos;
112
+ real d = (x - y) / 2;
113
+ return cos((x + y)/2) * (d ? sin(d) / d : 1);
114
+ }
115
+ static inline real Dsinh(real x, real y) {
116
+ using std::sinh; using std::cosh;
117
+ real d = (x - y) / 2;
118
+ return cosh((x + y) / 2) * (d ? sinh(d) / d : 1);
119
+ }
120
+ static inline real Dcosh(real x, real y) {
121
+ using std::sinh;
122
+ real d = (x - y) / 2;
123
+ return sinh((x + y) / 2) * (d ? sinh(d) / d : 1);
124
+ }
125
+ static inline real Dasinh(real x, real y) {
126
+ real d = x - y,
127
+ hx = Math::hypot(real(1), x), hy = Math::hypot(real(1), y);
128
+ return d ? Math::asinh(x*y > 0 ? d * (x + y) / (x*hy + y*hx) :
129
+ x*hy - y*hx) / d :
130
+ 1 / hx;
131
+ }
132
+ static inline real Dgd(real x, real y) {
133
+ using std::sinh;
134
+ return Datan(sinh(x), sinh(y)) * Dsinh(x, y);
135
+ }
136
+ // N.B., x and y are the tangents of the angles
137
+ static inline real Dgdinv(real x, real y)
138
+ { return Dasinh(x, y) / Datan(x, y); }
139
+ // Copied from LambertConformalConic...
140
+ // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
141
+ inline real Deatanhe(real x, real y) const {
142
+ real t = x - y, d = 1 - _ell._e2 * x * y;
143
+ return t ? Math::eatanhe(t / d, _ell._es) / t : _ell._e2 / d;
144
+ }
145
+ // (E(x) - E(y)) / (x - y) -- E = incomplete elliptic integral of 2nd kind
146
+ real DE(real x, real y) const;
147
+ // (mux - muy) / (phix - phiy) using elliptic integrals
148
+ real DRectifying(real latx, real laty) const;
149
+ // (psix - psiy) / (phix - phiy)
150
+ real DIsometric(real latx, real laty) const;
151
+
152
+ // (sum(c[j]*sin(2*j*x),j=1..n) - sum(c[j]*sin(2*j*x),j=1..n)) / (x - y)
153
+ static real SinCosSeries(bool sinp,
154
+ real x, real y, const real c[], int n);
155
+ // (mux - muy) / (chix - chiy) using Krueger's series
156
+ real DConformalToRectifying(real chix, real chiy) const;
157
+ // (chix - chiy) / (mux - muy) using Krueger's series
158
+ real DRectifyingToConformal(real mux, real muy) const;
159
+
160
+ // (mux - muy) / (psix - psiy)
161
+ // N.B., psix and psiy are in degrees
162
+ real DIsometricToRectifying(real psix, real psiy) const;
163
+ // (psix - psiy) / (mux - muy)
164
+ real DRectifyingToIsometric(real mux, real muy) const;
165
+
166
+ real MeanSinXi(real psi1, real psi2) const;
167
+
168
+ // The following two functions (with lots of ignored arguments) mimic the
169
+ // interface to the corresponding Geodesic function. These are needed by
170
+ // PolygonAreaT.
171
+ void GenDirect(real lat1, real lon1, real azi12,
172
+ bool, real s12, unsigned outmask,
173
+ real& lat2, real& lon2, real&, real&, real&, real&, real&,
174
+ real& S12) const {
175
+ GenDirect(lat1, lon1, azi12, s12, outmask, lat2, lon2, S12);
176
+ }
177
+ void GenInverse(real lat1, real lon1, real lat2, real lon2,
178
+ unsigned outmask, real& s12, real& azi12,
179
+ real&, real& , real& , real& , real& S12) const {
180
+ GenInverse(lat1, lon1, lat2, lon2, outmask, s12, azi12, S12);
181
+ }
182
+ public:
183
+
184
+ /**
185
+ * Bit masks for what calculations to do. They specify which results to
186
+ * return in the general routines Rhumb::GenDirect and Rhumb::GenInverse
187
+ * routines. RhumbLine::mask is a duplication of this enum.
188
+ **********************************************************************/
189
+ enum mask {
190
+ /**
191
+ * No output.
192
+ * @hideinitializer
193
+ **********************************************************************/
194
+ NONE = 0U,
195
+ /**
196
+ * Calculate latitude \e lat2.
197
+ * @hideinitializer
198
+ **********************************************************************/
199
+ LATITUDE = 1U<<7,
200
+ /**
201
+ * Calculate longitude \e lon2.
202
+ * @hideinitializer
203
+ **********************************************************************/
204
+ LONGITUDE = 1U<<8,
205
+ /**
206
+ * Calculate azimuth \e azi12.
207
+ * @hideinitializer
208
+ **********************************************************************/
209
+ AZIMUTH = 1U<<9,
210
+ /**
211
+ * Calculate distance \e s12.
212
+ * @hideinitializer
213
+ **********************************************************************/
214
+ DISTANCE = 1U<<10,
215
+ /**
216
+ * Calculate area \e S12.
217
+ * @hideinitializer
218
+ **********************************************************************/
219
+ AREA = 1U<<14,
220
+ /**
221
+ * Unroll \e lon2 in the direct calculation.
222
+ * @hideinitializer
223
+ **********************************************************************/
224
+ LONG_UNROLL = 1U<<15,
225
+ /**
226
+ * Calculate everything. (LONG_UNROLL is not included in this mask.)
227
+ * @hideinitializer
228
+ **********************************************************************/
229
+ ALL = 0x7F80U,
230
+ };
231
+
232
+ /**
233
+ * Constructor for a ellipsoid with
234
+ *
235
+ * @param[in] a equatorial radius (meters).
236
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
237
+ * Negative \e f gives a prolate ellipsoid.
238
+ * @param[in] exact if true (the default) use an addition theorem for
239
+ * elliptic integrals to compute divided differences; otherwise use
240
+ * series expansion (accurate for |<i>f</i>| < 0.01).
241
+ * @exception GeographicErr if \e a or (1 &minus; \e f) \e a is not
242
+ * positive.
243
+ *
244
+ * See \ref rhumb, for a detailed description of the \e exact parameter.
245
+ **********************************************************************/
246
+ Rhumb(real a, real f, bool exact = true);
247
+
248
+ /**
249
+ * Solve the direct rhumb problem returning also the area.
250
+ *
251
+ * @param[in] lat1 latitude of point 1 (degrees).
252
+ * @param[in] lon1 longitude of point 1 (degrees).
253
+ * @param[in] azi12 azimuth of the rhumb line (degrees).
254
+ * @param[in] s12 distance between point 1 and point 2 (meters); it can be
255
+ * negative.
256
+ * @param[out] lat2 latitude of point 2 (degrees).
257
+ * @param[out] lon2 longitude of point 2 (degrees).
258
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
259
+ *
260
+ * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]. The value of
261
+ * \e lon2 returned is in the range [&minus;180&deg;, 180&deg;).
262
+ *
263
+ * If point 1 is a pole, the cosine of its latitude is taken to be
264
+ * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
265
+ * position, which is extremely close to the actual pole, allows the
266
+ * calculation to be carried out in finite terms. If \e s12 is large
267
+ * enough that the rhumb line crosses a pole, the longitude of point 2
268
+ * is indeterminate (a NaN is returned for \e lon2 and \e S12).
269
+ **********************************************************************/
270
+ void Direct(real lat1, real lon1, real azi12, real s12,
271
+ real& lat2, real& lon2, real& S12) const {
272
+ GenDirect(lat1, lon1, azi12, s12,
273
+ LATITUDE | LONGITUDE | AREA, lat2, lon2, S12);
274
+ }
275
+
276
+ /**
277
+ * Solve the direct rhumb problem without the area.
278
+ **********************************************************************/
279
+ void Direct(real lat1, real lon1, real azi12, real s12,
280
+ real& lat2, real& lon2) const {
281
+ real t;
282
+ GenDirect(lat1, lon1, azi12, s12, LATITUDE | LONGITUDE, lat2, lon2, t);
283
+ }
284
+
285
+ /**
286
+ * The general direct rhumb problem. Rhumb::Direct is defined in terms
287
+ * of this function.
288
+ *
289
+ * @param[in] lat1 latitude of point 1 (degrees).
290
+ * @param[in] lon1 longitude of point 1 (degrees).
291
+ * @param[in] azi12 azimuth of the rhumb line (degrees).
292
+ * @param[in] s12 distance between point 1 and point 2 (meters); it can be
293
+ * negative.
294
+ * @param[in] outmask a bitor'ed combination of Rhumb::mask values
295
+ * specifying which of the following parameters should be set.
296
+ * @param[out] lat2 latitude of point 2 (degrees).
297
+ * @param[out] lon2 longitude of point 2 (degrees).
298
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
299
+ *
300
+ * The Rhumb::mask values possible for \e outmask are
301
+ * - \e outmask |= Rhumb::LATITUDE for the latitude \e lat2;
302
+ * - \e outmask |= Rhumb::LONGITUDE for the latitude \e lon2;
303
+ * - \e outmask |= Rhumb::AREA for the area \e S12;
304
+ * - \e outmask |= Rhumb::ALL for all of the above;
305
+ * - \e outmask |= Rhumb::LONG_UNROLL to unroll \e lon2 instead of wrapping
306
+ * it into the range [&minus;180&deg;, 180&deg;).
307
+ * .
308
+ * With the Rhumb::LONG_UNROLL bit set, the quantity \e lon2 &minus;
309
+ * \e lon1 indicates how many times and in what sense the rhumb line
310
+ * encircles the ellipsoid.
311
+ **********************************************************************/
312
+ void GenDirect(real lat1, real lon1, real azi12, real s12, unsigned outmask,
313
+ real& lat2, real& lon2, real& S12) const;
314
+
315
+ /**
316
+ * Solve the inverse rhumb problem returning also the area.
317
+ *
318
+ * @param[in] lat1 latitude of point 1 (degrees).
319
+ * @param[in] lon1 longitude of point 1 (degrees).
320
+ * @param[in] lat2 latitude of point 2 (degrees).
321
+ * @param[in] lon2 longitude of point 2 (degrees).
322
+ * @param[out] s12 rhumb distance between point 1 and point 2 (meters).
323
+ * @param[out] azi12 azimuth of the rhumb line (degrees).
324
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
325
+ *
326
+ * The shortest rhumb line is found. If the end points are on opposite
327
+ * meridians, there are two shortest rhumb lines and the east-going one is
328
+ * chosen. \e lat1 and \e lat2 should be in the range [&minus;90&deg;,
329
+ * 90&deg;]. The value of \e azi12 returned is in the range
330
+ * [&minus;180&deg;, 180&deg;).
331
+ *
332
+ * If either point is a pole, the cosine of its latitude is taken to be
333
+ * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
334
+ * position, which is extremely close to the actual pole, allows the
335
+ * calculation to be carried out in finite terms.
336
+ **********************************************************************/
337
+ void Inverse(real lat1, real lon1, real lat2, real lon2,
338
+ real& s12, real& azi12, real& S12) const {
339
+ GenInverse(lat1, lon1, lat2, lon2,
340
+ DISTANCE | AZIMUTH | AREA, s12, azi12, S12);
341
+ }
342
+
343
+ /**
344
+ * Solve the inverse rhumb problem without the area.
345
+ **********************************************************************/
346
+ void Inverse(real lat1, real lon1, real lat2, real lon2,
347
+ real& s12, real& azi12) const {
348
+ real t;
349
+ GenInverse(lat1, lon1, lat2, lon2, DISTANCE | AZIMUTH, s12, azi12, t);
350
+ }
351
+
352
+ /**
353
+ * The general inverse rhumb problem. Rhumb::Inverse is defined in terms
354
+ * of this function.
355
+ *
356
+ * @param[in] lat1 latitude of point 1 (degrees).
357
+ * @param[in] lon1 longitude of point 1 (degrees).
358
+ * @param[in] lat2 latitude of point 2 (degrees).
359
+ * @param[in] lon2 longitude of point 2 (degrees).
360
+ * @param[in] outmask a bitor'ed combination of Rhumb::mask values
361
+ * specifying which of the following parameters should be set.
362
+ * @param[out] s12 rhumb distance between point 1 and point 2 (meters).
363
+ * @param[out] azi12 azimuth of the rhumb line (degrees).
364
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
365
+ *
366
+ * The Rhumb::mask values possible for \e outmask are
367
+ * - \e outmask |= Rhumb::DISTANCE for the latitude \e s12;
368
+ * - \e outmask |= Rhumb::AZIMUTH for the latitude \e azi12;
369
+ * - \e outmask |= Rhumb::AREA for the area \e S12;
370
+ * - \e outmask |= Rhumb::ALL for all of the above;
371
+ **********************************************************************/
372
+ void GenInverse(real lat1, real lon1, real lat2, real lon2,
373
+ unsigned outmask,
374
+ real& s12, real& azi12, real& S12) const;
375
+
376
+ /**
377
+ * Set up to compute several points on a single rhumb line.
378
+ *
379
+ * @param[in] lat1 latitude of point 1 (degrees).
380
+ * @param[in] lon1 longitude of point 1 (degrees).
381
+ * @param[in] azi12 azimuth of the rhumb line (degrees).
382
+ * @return a RhumbLine object.
383
+ *
384
+ * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
385
+ *
386
+ * If point 1 is a pole, the cosine of its latitude is taken to be
387
+ * 1/&epsilon;<sup>2</sup> (where &epsilon; is 2<sup>-52</sup>). This
388
+ * position, which is extremely close to the actual pole, allows the
389
+ * calculation to be carried out in finite terms.
390
+ **********************************************************************/
391
+ RhumbLine Line(real lat1, real lon1, real azi12) const;
392
+
393
+ /** \name Inspector functions.
394
+ **********************************************************************/
395
+ ///@{
396
+
397
+ /**
398
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
399
+ * the value used in the constructor.
400
+ **********************************************************************/
401
+ Math::real MajorRadius() const { return _ell.MajorRadius(); }
402
+
403
+ /**
404
+ * @return \e f the flattening of the ellipsoid. This is the
405
+ * value used in the constructor.
406
+ **********************************************************************/
407
+ Math::real Flattening() const { return _ell.Flattening(); }
408
+
409
+ Math::real EllipsoidArea() const { return _ell.Area(); }
410
+
411
+ /**
412
+ * A global instantiation of Rhumb with the parameters for the WGS84
413
+ * ellipsoid.
414
+ **********************************************************************/
415
+ static const Rhumb& WGS84();
416
+ };
417
+
418
+ /**
419
+ * \brief Find a sequence of points on a single rhumb line.
420
+ *
421
+ * RhumbLine facilitates the determination of a series of points on a single
422
+ * rhumb line. The starting point (\e lat1, \e lon1) and the azimuth \e
423
+ * azi12 are specified in the call to Rhumb::Line which returns a RhumbLine
424
+ * object. RhumbLine.Position returns the location of point 2 (and,
425
+ * optionally, the corresponding area, \e S12) a distance \e s12 along the
426
+ * rhumb line.
427
+ *
428
+ * There is no public constructor for this class. (Use Rhumb::Line to create
429
+ * an instance.) The Rhumb object used to create a RhumbLine must stay in
430
+ * scope as long as the RhumbLine.
431
+ *
432
+ * Example of use:
433
+ * \include example-RhumbLine.cpp
434
+ **********************************************************************/
435
+
436
+ class GEOGRAPHICLIB_EXPORT RhumbLine {
437
+ private:
438
+ typedef Math::real real;
439
+ friend class Rhumb;
440
+ const Rhumb& _rh;
441
+ bool _exact;
442
+ real _lat1, _lon1, _azi12, _salp, _calp, _mu1, _psi1, _r1;
443
+ RhumbLine& operator=(const RhumbLine&); // copy assignment not allowed
444
+ RhumbLine(const Rhumb& rh, real lat1, real lon1, real azi12,
445
+ bool exact);
446
+ public:
447
+
448
+ /**
449
+ * This is a duplication of Rhumb::mask.
450
+ **********************************************************************/
451
+ enum mask {
452
+ /**
453
+ * No output.
454
+ * @hideinitializer
455
+ **********************************************************************/
456
+ NONE = Rhumb::NONE,
457
+ /**
458
+ * Calculate latitude \e lat2.
459
+ * @hideinitializer
460
+ **********************************************************************/
461
+ LATITUDE = Rhumb::LATITUDE,
462
+ /**
463
+ * Calculate longitude \e lon2.
464
+ * @hideinitializer
465
+ **********************************************************************/
466
+ LONGITUDE = Rhumb::LONGITUDE,
467
+ /**
468
+ * Calculate azimuth \e azi12.
469
+ * @hideinitializer
470
+ **********************************************************************/
471
+ AZIMUTH = Rhumb::AZIMUTH,
472
+ /**
473
+ * Calculate distance \e s12.
474
+ * @hideinitializer
475
+ **********************************************************************/
476
+ DISTANCE = Rhumb::DISTANCE,
477
+ /**
478
+ * Calculate area \e S12.
479
+ * @hideinitializer
480
+ **********************************************************************/
481
+ AREA = Rhumb::AREA,
482
+ /**
483
+ * Unroll \e lon2 in the direct calculation.
484
+ * @hideinitializer
485
+ **********************************************************************/
486
+ LONG_UNROLL = Rhumb::LONG_UNROLL,
487
+ /**
488
+ * Calculate everything. (LONG_UNROLL is not included in this mask.)
489
+ * @hideinitializer
490
+ **********************************************************************/
491
+ ALL = Rhumb::ALL,
492
+ };
493
+
494
+ /**
495
+ * Compute the position of point 2 which is a distance \e s12 (meters) from
496
+ * point 1. The area is also computed.
497
+ *
498
+ * @param[in] s12 distance between point 1 and point 2 (meters); it can be
499
+ * negative.
500
+ * @param[out] lat2 latitude of point 2 (degrees).
501
+ * @param[out] lon2 longitude of point 2 (degrees).
502
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
503
+ *
504
+ * The value of \e lon2 returned is in the range [&minus;180&deg;,
505
+ * 180&deg;).
506
+ *
507
+ * If \e s12 is large enough that the rhumb line crosses a pole, the
508
+ * longitude of point 2 is indeterminate (a NaN is returned for \e lon2 and
509
+ * \e S12).
510
+ **********************************************************************/
511
+ void Position(real s12, real& lat2, real& lon2, real& S12) const {
512
+ GenPosition(s12, LATITUDE | LONGITUDE | AREA, lat2, lon2, S12);
513
+ }
514
+
515
+ /**
516
+ * Compute the position of point 2 which is a distance \e s12 (meters) from
517
+ * point 1. The area is not computed.
518
+ **********************************************************************/
519
+ void Position(real s12, real& lat2, real& lon2) const {
520
+ real t;
521
+ GenPosition(s12, LATITUDE | LONGITUDE, lat2, lon2, t);
522
+ }
523
+
524
+ /**
525
+ * The general position routine. RhumbLine::Position is defined in term so
526
+ * this function.
527
+ *
528
+ * @param[in] s12 distance between point 1 and point 2 (meters); it can be
529
+ * negative.
530
+ * @param[in] outmask a bitor'ed combination of RhumbLine::mask values
531
+ * specifying which of the following parameters should be set.
532
+ * @param[out] lat2 latitude of point 2 (degrees).
533
+ * @param[out] lon2 longitude of point 2 (degrees).
534
+ * @param[out] S12 area under the rhumb line (meters<sup>2</sup>).
535
+ *
536
+ * The RhumbLine::mask values possible for \e outmask are
537
+ * - \e outmask |= RhumbLine::LATITUDE for the latitude \e lat2;
538
+ * - \e outmask |= RhumbLine::LONGITUDE for the latitude \e lon2;
539
+ * - \e outmask |= RhumbLine::AREA for the area \e S12;
540
+ * - \e outmask |= RhumbLine::ALL for all of the above;
541
+ * - \e outmask |= RhumbLine::LONG_UNROLL to unroll \e lon2 instead of
542
+ * wrapping it into the range [&minus;180&deg;, 180&deg;).
543
+ * .
544
+ * With the RhumbLine::LONG_UNROLL bit set, the quantity \e lon2 &minus; \e
545
+ * lon1 indicates how many times and in what sense the rhumb line encircles
546
+ * the ellipsoid.
547
+ *
548
+ * If \e s12 is large enough that the rhumb line crosses a pole, the
549
+ * longitude of point 2 is indeterminate (a NaN is returned for \e lon2 and
550
+ * \e S12).
551
+ **********************************************************************/
552
+ void GenPosition(real s12, unsigned outmask,
553
+ real& lat2, real& lon2, real& S12) const;
554
+
555
+ /** \name Inspector functions
556
+ **********************************************************************/
557
+ ///@{
558
+
559
+ /**
560
+ * @return \e lat1 the latitude of point 1 (degrees).
561
+ **********************************************************************/
562
+ Math::real Latitude() const { return _lat1; }
563
+
564
+ /**
565
+ * @return \e lon1 the longitude of point 1 (degrees).
566
+ **********************************************************************/
567
+ Math::real Longitude() const { return _lon1; }
568
+
569
+ /**
570
+ * @return \e azi12 the azimuth of the rhumb line (degrees).
571
+ **********************************************************************/
572
+ Math::real Azimuth() const { return _azi12; }
573
+
574
+ /**
575
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
576
+ * the value inherited from the Rhumb object used in the constructor.
577
+ **********************************************************************/
578
+ Math::real MajorRadius() const { return _rh.MajorRadius(); }
579
+
580
+ /**
581
+ * @return \e f the flattening of the ellipsoid. This is the value
582
+ * inherited from the Rhumb object used in the constructor.
583
+ **********************************************************************/
584
+ Math::real Flattening() const { return _rh.Flattening(); }
585
+ };
586
+
587
+ } // namespace GeographicLib
588
+
589
+ #endif // GEOGRAPHICLIB_RHUMB_HPP