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,12 @@
1
+ // This will be overwritten by ./configure
2
+
3
+ #define GEOGRAPHICLIB_VERSION_STRING "1.46"
4
+ #define GEOGRAPHICLIB_VERSION_MAJOR 1
5
+ #define GEOGRAPHICLIB_VERSION_MINOR 46
6
+ #define GEOGRAPHICLIB_VERSION_PATCH 0
7
+
8
+ // Undefine HAVE_LONG_DOUBLE if this type is unknown to the compiler
9
+ #define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 1
10
+
11
+ // Define WORDS_BIGENDIAN to be 1 if your machine is big endian
12
+ /* #undef WORDS_BIGENDIAN */
@@ -0,0 +1,387 @@
1
+ /**
2
+ * \file Constants.hpp
3
+ * \brief Header for GeographicLib::Constants 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_CONSTANTS_HPP)
11
+ #define GEOGRAPHICLIB_CONSTANTS_HPP 1
12
+
13
+ #include <GeographicLib/Config.h>
14
+
15
+ /**
16
+ * @relates GeographicLib::Constants
17
+ * Pack the version components into a single integer. Users should not rely on
18
+ * this particular packing of the components of the version number; see the
19
+ * documentation for GEOGRAPHICLIB_VERSION, below.
20
+ **********************************************************************/
21
+ #define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c))
22
+
23
+ /**
24
+ * @relates GeographicLib::Constants
25
+ * The version of GeographicLib as a single integer, packed as MMmmmmpp where
26
+ * MM is the major version, mmmm is the minor version, and pp is the patch
27
+ * level. Users should not rely on this particular packing of the components
28
+ * of the version number. Instead they should use a test such as \code
29
+ #if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,37,0)
30
+ ...
31
+ #endif
32
+ * \endcode
33
+ **********************************************************************/
34
+ #define GEOGRAPHICLIB_VERSION \
35
+ GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \
36
+ GEOGRAPHICLIB_VERSION_MINOR, \
37
+ GEOGRAPHICLIB_VERSION_PATCH)
38
+
39
+ /**
40
+ * @relates GeographicLib::Constants
41
+ * Is the C++11 static_assert available?
42
+ **********************************************************************/
43
+ #if !defined(GEOGRAPHICLIB_HAS_STATIC_ASSERT)
44
+ # if __cplusplus >= 201103 || defined(__GXX_EXPERIMENTAL_CXX0X__)
45
+ # define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
46
+ # elif defined(_MSC_VER) && _MSC_VER >= 1600
47
+ // For reference, here is a table of Visual Studio and _MSC_VER
48
+ // correspondences:
49
+ //
50
+ // _MSC_VER Visual Studio
51
+ // 1100 vc5
52
+ // 1200 vc6
53
+ // 1300 vc7
54
+ // 1310 vc7.1 (2003)
55
+ // 1400 vc8 (2005)
56
+ // 1500 vc9 (2008)
57
+ // 1600 vc10 (2010)
58
+ // 1700 vc11 (2012)
59
+ // 1800 vc12 (2013)
60
+ // 1900 vc14 (2015)
61
+ # define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
62
+ # else
63
+ # define GEOGRAPHICLIB_HAS_STATIC_ASSERT 0
64
+ # endif
65
+ #endif
66
+
67
+ /**
68
+ * @relates GeographicLib::Constants
69
+ * A compile-time assert. Use C++11 static_assert, if available.
70
+ **********************************************************************/
71
+ #if !defined(GEOGRAPHICLIB_STATIC_ASSERT)
72
+ # if GEOGRAPHICLIB_HAS_STATIC_ASSERT
73
+ # define GEOGRAPHICLIB_STATIC_ASSERT static_assert
74
+ # else
75
+ # define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \
76
+ { enum{ GEOGRAPHICLIB_STATIC_ASSERT_ENUM = 1/int(cond) }; }
77
+ # endif
78
+ #endif
79
+
80
+ #if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \
81
+ GEOGRAPHICLIB_SHARED_LIB
82
+ # if GEOGRAPHICLIB_SHARED_LIB > 1
83
+ # error GEOGRAPHICLIB_SHARED_LIB must be 0 or 1
84
+ # elif defined(GeographicLib_EXPORTS)
85
+ # define GEOGRAPHICLIB_EXPORT __declspec(dllexport)
86
+ # else
87
+ # define GEOGRAPHICLIB_EXPORT __declspec(dllimport)
88
+ # endif
89
+ #else
90
+ # define GEOGRAPHICLIB_EXPORT
91
+ #endif
92
+
93
+ #include <stdexcept>
94
+ #include <string>
95
+ #include <GeographicLib/Math.hpp>
96
+
97
+ /**
98
+ * \brief Namespace for %GeographicLib
99
+ *
100
+ * All of %GeographicLib is defined within the GeographicLib namespace. In
101
+ * addition all the header files are included via %GeographicLib/Class.hpp.
102
+ * This minimizes the likelihood of conflicts with other packages.
103
+ **********************************************************************/
104
+ namespace GeographicLib {
105
+
106
+ /**
107
+ * \brief %Constants needed by %GeographicLib
108
+ *
109
+ * Define constants specifying the WGS84 ellipsoid, the UTM and UPS
110
+ * projections, and various unit conversions.
111
+ *
112
+ * Example of use:
113
+ * \include example-Constants.cpp
114
+ **********************************************************************/
115
+ class GEOGRAPHICLIB_EXPORT Constants {
116
+ private:
117
+ typedef Math::real real;
118
+ Constants(); // Disable constructor
119
+
120
+ public:
121
+ /**
122
+ * A synonym for Math::degree<real>().
123
+ **********************************************************************/
124
+ static inline Math::real degree() { return Math::degree(); }
125
+ /**
126
+ * @return the number of radians in an arcminute.
127
+ **********************************************************************/
128
+ static inline Math::real arcminute()
129
+ { return Math::degree() / 60; }
130
+ /**
131
+ * @return the number of radians in an arcsecond.
132
+ **********************************************************************/
133
+ static inline Math::real arcsecond()
134
+ { return Math::degree() / 3600; }
135
+
136
+ /** \name Ellipsoid parameters
137
+ **********************************************************************/
138
+ ///@{
139
+ /**
140
+ * @tparam T the type of the returned value.
141
+ * @return the equatorial radius of WGS84 ellipsoid (6378137 m).
142
+ **********************************************************************/
143
+ template<typename T> static inline T WGS84_a()
144
+ { return 6378137 * meter<T>(); }
145
+ /**
146
+ * A synonym for WGS84_a<real>().
147
+ **********************************************************************/
148
+ static inline Math::real WGS84_a() { return WGS84_a<real>(); }
149
+ /**
150
+ * @tparam T the type of the returned value.
151
+ * @return the flattening of WGS84 ellipsoid (1/298.257223563).
152
+ **********************************************************************/
153
+ template<typename T> static inline T WGS84_f() {
154
+ // Evaluating this as 1000000000 / T(298257223563LL) reduces the
155
+ // round-off error by about 10%. However, expressing the flattening as
156
+ // 1/298.257223563 is well ingrained.
157
+ return 1 / ( T(298257223563LL) / 1000000000 );
158
+ }
159
+ /**
160
+ * A synonym for WGS84_f<real>().
161
+ **********************************************************************/
162
+ static inline Math::real WGS84_f() { return WGS84_f<real>(); }
163
+ /**
164
+ * @tparam T the type of the returned value.
165
+ * @return the gravitational constant of the WGS84 ellipsoid, \e GM, in
166
+ * m<sup>3</sup> s<sup>&minus;2</sup>.
167
+ **********************************************************************/
168
+ template<typename T> static inline T WGS84_GM()
169
+ { return T(3986004) * 100000000 + 41800000; }
170
+ /**
171
+ * A synonym for WGS84_GM<real>().
172
+ **********************************************************************/
173
+ static inline Math::real WGS84_GM() { return WGS84_GM<real>(); }
174
+ /**
175
+ * @tparam T the type of the returned value.
176
+ * @return the angular velocity of the WGS84 ellipsoid, &omega;, in rad
177
+ * s<sup>&minus;1</sup>.
178
+ **********************************************************************/
179
+ template<typename T> static inline T WGS84_omega()
180
+ { return 7292115 / (T(1000000) * 100000); }
181
+ /**
182
+ * A synonym for WGS84_omega<real>().
183
+ **********************************************************************/
184
+ static inline Math::real WGS84_omega() { return WGS84_omega<real>(); }
185
+ /**
186
+ * @tparam T the type of the returned value.
187
+ * @return the equatorial radius of GRS80 ellipsoid, \e a, in m.
188
+ **********************************************************************/
189
+ template<typename T> static inline T GRS80_a()
190
+ { return 6378137 * meter<T>(); }
191
+ /**
192
+ * A synonym for GRS80_a<real>().
193
+ **********************************************************************/
194
+ static inline Math::real GRS80_a() { return GRS80_a<real>(); }
195
+ /**
196
+ * @tparam T the type of the returned value.
197
+ * @return the gravitational constant of the GRS80 ellipsoid, \e GM, in
198
+ * m<sup>3</sup> s<sup>&minus;2</sup>.
199
+ **********************************************************************/
200
+ template<typename T> static inline T GRS80_GM()
201
+ { return T(3986005) * 100000000; }
202
+ /**
203
+ * A synonym for GRS80_GM<real>().
204
+ **********************************************************************/
205
+ static inline Math::real GRS80_GM() { return GRS80_GM<real>(); }
206
+ /**
207
+ * @tparam T the type of the returned value.
208
+ * @return the angular velocity of the GRS80 ellipsoid, &omega;, in rad
209
+ * s<sup>&minus;1</sup>.
210
+ *
211
+ * This is about 2 &pi; 366.25 / (365.25 &times; 24 &times; 3600) rad
212
+ * s<sup>&minus;1</sup>. 365.25 is the number of days in a Julian year and
213
+ * 365.35/366.25 converts from solar days to sidereal days. Using the
214
+ * number of days in a Gregorian year (365.2425) results in a worse
215
+ * approximation (because the Gregorian year includes the precession of the
216
+ * earth's axis).
217
+ **********************************************************************/
218
+ template<typename T> static inline T GRS80_omega()
219
+ { return 7292115 / (T(1000000) * 100000); }
220
+ /**
221
+ * A synonym for GRS80_omega<real>().
222
+ **********************************************************************/
223
+ static inline Math::real GRS80_omega() { return GRS80_omega<real>(); }
224
+ /**
225
+ * @tparam T the type of the returned value.
226
+ * @return the dynamical form factor of the GRS80 ellipsoid,
227
+ * <i>J</i><sub>2</sub>.
228
+ **********************************************************************/
229
+ template<typename T> static inline T GRS80_J2()
230
+ { return T(108263) / 100000000; }
231
+ /**
232
+ * A synonym for GRS80_J2<real>().
233
+ **********************************************************************/
234
+ static inline Math::real GRS80_J2() { return GRS80_J2<real>(); }
235
+ /**
236
+ * @tparam T the type of the returned value.
237
+ * @return the central scale factor for UTM (0.9996).
238
+ **********************************************************************/
239
+ template<typename T> static inline T UTM_k0()
240
+ {return T(9996) / 10000; }
241
+ /**
242
+ * A synonym for UTM_k0<real>().
243
+ **********************************************************************/
244
+ static inline Math::real UTM_k0() { return UTM_k0<real>(); }
245
+ /**
246
+ * @tparam T the type of the returned value.
247
+ * @return the central scale factor for UPS (0.994).
248
+ **********************************************************************/
249
+ template<typename T> static inline T UPS_k0()
250
+ { return T(994) / 1000; }
251
+ /**
252
+ * A synonym for UPS_k0<real>().
253
+ **********************************************************************/
254
+ static inline Math::real UPS_k0() { return UPS_k0<real>(); }
255
+ ///@}
256
+
257
+ /** \name SI units
258
+ **********************************************************************/
259
+ ///@{
260
+ /**
261
+ * @tparam T the type of the returned value.
262
+ * @return the number of meters in a meter.
263
+ *
264
+ * This is unity, but this lets the internal system of units be changed if
265
+ * necessary.
266
+ **********************************************************************/
267
+ template<typename T> static inline T meter() { return T(1); }
268
+ /**
269
+ * A synonym for meter<real>().
270
+ **********************************************************************/
271
+ static inline Math::real meter() { return meter<real>(); }
272
+ /**
273
+ * @return the number of meters in a kilometer.
274
+ **********************************************************************/
275
+ static inline Math::real kilometer()
276
+ { return 1000 * meter<real>(); }
277
+ /**
278
+ * @return the number of meters in a nautical mile (approximately 1 arc
279
+ * minute)
280
+ **********************************************************************/
281
+ static inline Math::real nauticalmile()
282
+ { return 1852 * meter<real>(); }
283
+
284
+ /**
285
+ * @tparam T the type of the returned value.
286
+ * @return the number of square meters in a square meter.
287
+ *
288
+ * This is unity, but this lets the internal system of units be changed if
289
+ * necessary.
290
+ **********************************************************************/
291
+ template<typename T> static inline T square_meter()
292
+ { return meter<real>() * meter<real>(); }
293
+ /**
294
+ * A synonym for square_meter<real>().
295
+ **********************************************************************/
296
+ static inline Math::real square_meter()
297
+ { return square_meter<real>(); }
298
+ /**
299
+ * @return the number of square meters in a hectare.
300
+ **********************************************************************/
301
+ static inline Math::real hectare()
302
+ { return 10000 * square_meter<real>(); }
303
+ /**
304
+ * @return the number of square meters in a square kilometer.
305
+ **********************************************************************/
306
+ static inline Math::real square_kilometer()
307
+ { return kilometer() * kilometer(); }
308
+ /**
309
+ * @return the number of square meters in a square nautical mile.
310
+ **********************************************************************/
311
+ static inline Math::real square_nauticalmile()
312
+ { return nauticalmile() * nauticalmile(); }
313
+ ///@}
314
+
315
+ /** \name Anachronistic British units
316
+ **********************************************************************/
317
+ ///@{
318
+ /**
319
+ * @return the number of meters in an international foot.
320
+ **********************************************************************/
321
+ static inline Math::real foot()
322
+ { return real(254 * 12) / 10000 * meter<real>(); }
323
+ /**
324
+ * @return the number of meters in a yard.
325
+ **********************************************************************/
326
+ static inline Math::real yard() { return 3 * foot(); }
327
+ /**
328
+ * @return the number of meters in a fathom.
329
+ **********************************************************************/
330
+ static inline Math::real fathom() { return 2 * yard(); }
331
+ /**
332
+ * @return the number of meters in a chain.
333
+ **********************************************************************/
334
+ static inline Math::real chain() { return 22 * yard(); }
335
+ /**
336
+ * @return the number of meters in a furlong.
337
+ **********************************************************************/
338
+ static inline Math::real furlong() { return 10 * chain(); }
339
+ /**
340
+ * @return the number of meters in a statute mile.
341
+ **********************************************************************/
342
+ static inline Math::real mile() { return 8 * furlong(); }
343
+ /**
344
+ * @return the number of square meters in an acre.
345
+ **********************************************************************/
346
+ static inline Math::real acre() { return chain() * furlong(); }
347
+ /**
348
+ * @return the number of square meters in a square statute mile.
349
+ **********************************************************************/
350
+ static inline Math::real square_mile() { return mile() * mile(); }
351
+ ///@}
352
+
353
+ /** \name Anachronistic US units
354
+ **********************************************************************/
355
+ ///@{
356
+ /**
357
+ * @return the number of meters in a US survey foot.
358
+ **********************************************************************/
359
+ static inline Math::real surveyfoot()
360
+ { return real(1200) / 3937 * meter<real>(); }
361
+ ///@}
362
+ };
363
+
364
+ /**
365
+ * \brief Exception handling for %GeographicLib
366
+ *
367
+ * A class to handle exceptions. It's derived from std::runtime_error so it
368
+ * can be caught by the usual catch clauses.
369
+ *
370
+ * Example of use:
371
+ * \include example-GeographicErr.cpp
372
+ **********************************************************************/
373
+ class GeographicErr : public std::runtime_error {
374
+ public:
375
+
376
+ /**
377
+ * Constructor
378
+ *
379
+ * @param[in] msg a string message, which is accessible in the catch
380
+ * clause via what().
381
+ **********************************************************************/
382
+ GeographicErr(const std::string& msg) : std::runtime_error(msg) {}
383
+ };
384
+
385
+ } // namespace GeographicLib
386
+
387
+ #endif // GEOGRAPHICLIB_CONSTANTS_HPP
@@ -0,0 +1,370 @@
1
+ /**
2
+ * \file DMS.hpp
3
+ * \brief Header for GeographicLib::DMS 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_DMS_HPP)
11
+ #define GEOGRAPHICLIB_DMS_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+ #include <GeographicLib/Utility.hpp>
15
+
16
+ #if defined(_MSC_VER)
17
+ // Squelch warnings about dll vs vector and constant conditional expressions
18
+ # pragma warning (push)
19
+ # pragma warning (disable: 4251 4127)
20
+ #endif
21
+
22
+ namespace GeographicLib {
23
+
24
+ /**
25
+ * \brief Convert between degrees and the %DMS representation
26
+ *
27
+ * Parse a string representing degree, minutes, and seconds and return the
28
+ * angle in degrees and format an angle in degrees as degree, minutes, and
29
+ * seconds. In addition, handle NANs and infinities on input and output.
30
+ *
31
+ * Example of use:
32
+ * \include example-DMS.cpp
33
+ **********************************************************************/
34
+ class GEOGRAPHICLIB_EXPORT DMS {
35
+ public:
36
+
37
+ /**
38
+ * Indicator for presence of hemisphere indicator (N/S/E/W) on latitudes
39
+ * and longitudes.
40
+ **********************************************************************/
41
+ enum flag {
42
+ /**
43
+ * No indicator present.
44
+ * @hideinitializer
45
+ **********************************************************************/
46
+ NONE = 0,
47
+ /**
48
+ * Latitude indicator (N/S) present.
49
+ * @hideinitializer
50
+ **********************************************************************/
51
+ LATITUDE = 1,
52
+ /**
53
+ * Longitude indicator (E/W) present.
54
+ * @hideinitializer
55
+ **********************************************************************/
56
+ LONGITUDE = 2,
57
+ /**
58
+ * Used in Encode to indicate output of an azimuth in [000, 360) with no
59
+ * letter indicator.
60
+ * @hideinitializer
61
+ **********************************************************************/
62
+ AZIMUTH = 3,
63
+ /**
64
+ * Used in Encode to indicate output of a plain number.
65
+ * @hideinitializer
66
+ **********************************************************************/
67
+ NUMBER = 4,
68
+ };
69
+
70
+ /**
71
+ * Indicator for trailing units on an angle.
72
+ **********************************************************************/
73
+ enum component {
74
+ /**
75
+ * Trailing unit is degrees.
76
+ * @hideinitializer
77
+ **********************************************************************/
78
+ DEGREE = 0,
79
+ /**
80
+ * Trailing unit is arc minutes.
81
+ * @hideinitializer
82
+ **********************************************************************/
83
+ MINUTE = 1,
84
+ /**
85
+ * Trailing unit is arc seconds.
86
+ * @hideinitializer
87
+ **********************************************************************/
88
+ SECOND = 2,
89
+ };
90
+
91
+ private:
92
+ typedef Math::real real;
93
+ // Replace all occurrences of pat by c
94
+ static void replace(std::string& s, const std::string& pat, char c) {
95
+ std::string::size_type p = 0;
96
+ while (true) {
97
+ p = s.find(pat, p);
98
+ if (p == std::string::npos)
99
+ break;
100
+ s.replace(p, pat.length(), 1, c);
101
+ }
102
+ }
103
+ static const std::string hemispheres_;
104
+ static const std::string signs_;
105
+ static const std::string digits_;
106
+ static const std::string dmsindicators_;
107
+ static const std::string components_[3];
108
+ static Math::real NumMatch(const std::string& s);
109
+ static Math::real InternalDecode(const std::string& dmsa, flag& ind);
110
+ DMS(); // Disable constructor
111
+
112
+ public:
113
+
114
+ /**
115
+ * Convert a string in DMS to an angle.
116
+ *
117
+ * @param[in] dms string input.
118
+ * @param[out] ind a DMS::flag value signaling the presence of a
119
+ * hemisphere indicator.
120
+ * @exception GeographicErr if \e dms is malformed (see below).
121
+ * @return angle (degrees).
122
+ *
123
+ * Degrees, minutes, and seconds are indicated by the characters d, '
124
+ * (single quote), &quot; (double quote), and these components may only be
125
+ * given in this order. Any (but not all) components may be omitted and
126
+ * other symbols (e.g., the &deg; symbol for degrees and the unicode prime
127
+ * and double prime symbols for minutes and seconds) may be substituted;
128
+ * two single quotes can be used instead of &quot;. The last component
129
+ * indicator may be omitted and is assumed to be the next smallest unit
130
+ * (thus 33d10 is interpreted as 33d10'). The final component may be a
131
+ * decimal fraction but the non-final components must be integers. Instead
132
+ * of using d, ', and &quot; to indicate degrees, minutes, and seconds, :
133
+ * (colon) may be used to <i>separate</i> these components (numbers must
134
+ * appear before and after each colon); thus 50d30'10.3&quot; may be
135
+ * written as 50:30:10.3, 5.5' may be written 0:5.5, and so on. The
136
+ * integer parts of the minutes and seconds components must be less
137
+ * than 60. A single leading sign is permitted. A hemisphere designator
138
+ * (N, E, W, S) may be added to the beginning or end of the string. The
139
+ * result is multiplied by the implied sign of the hemisphere designator
140
+ * (negative for S and W). In addition \e ind is set to DMS::LATITUDE if N
141
+ * or S is present, to DMS::LONGITUDE if E or W is present, and to
142
+ * DMS::NONE otherwise. Throws an error on a malformed string. No check
143
+ * is performed on the range of the result. Examples of legal and illegal
144
+ * strings are
145
+ * - <i>LEGAL</i> (all the entries on each line are equivalent)
146
+ * - -20.51125, 20d30'40.5&quot;S, -20&deg;30'40.5, -20d30.675,
147
+ * N-20d30'40.5&quot;, -20:30:40.5
148
+ * - 4d0'9, 4d9&quot;, 4d9'', 4:0:9, 004:00:09, 4.0025, 4.0025d, 4d0.15,
149
+ * 04:.15
150
+ * - 4:59.99999999999999, 4:60.0, 4:59:59.9999999999999, 4:59:60.0, 5
151
+ * - <i>ILLEGAL</i> (the exception thrown explains the problem)
152
+ * - 4d5&quot;4', 4::5, 4:5:, :4:5, 4d4.5'4&quot;, -N20.5, 1.8e2d, 4:60,
153
+ * 4:59:60
154
+ *
155
+ * The decoding operation can also perform addition and subtraction
156
+ * operations. If the string includes <i>internal</i> signs (i.e., not at
157
+ * the beginning nor immediately after an initial hemisphere designator),
158
+ * then the string is split immediately before such signs and each piece is
159
+ * decoded according to the above rules and the results added; thus
160
+ * <code>S3-2.5+4.1N</code> is parsed as the sum of <code>S3</code>,
161
+ * <code>-2.5</code>, <code>+4.1N</code>. Any piece can include a
162
+ * hemisphere designator; however, if multiple designators are given, they
163
+ * must compatible; e.g., you cannot mix N and E. In addition, the
164
+ * designator can appear at the beginning or end of the first piece, but
165
+ * must be at the end of all subsequent pieces (a hemisphere designator is
166
+ * not allowed after the initial sign). Examples of legal and illegal
167
+ * combinations are
168
+ * - <i>LEGAL</i> (these are all equivalent)
169
+ * - 070:00:45, 70:01:15W+0:0.5, 70:01:15W-0:0:30W, W70:01:15+0:0:30E
170
+ * - <i>ILLEGAL</i> (the exception thrown explains the problem)
171
+ * - 70:01:15W+0:0:15N, W70:01:15+W0:0:15
172
+ *
173
+ * <b>WARNING:</b> "Exponential" notation is not recognized. Thus
174
+ * <code>7.0E1</code> is illegal, while <code>7.0E+1</code> is parsed as
175
+ * <code>(7.0E) + (+1)</code>, yielding the same result as
176
+ * <code>8.0E</code>.
177
+ *
178
+ * <b>NOTE:</b> At present, all the string handling in the C++
179
+ * implementation %GeographicLib is with 8-bit characters. The support for
180
+ * unicode symbols for degrees, minutes, and seconds is therefore via the
181
+ * <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding. (The
182
+ * JavaScript implementation of this class uses unicode natively, of
183
+ * course.)
184
+ *
185
+ * Here is the list of Unicode symbols supported for degrees, minutes,
186
+ * seconds, and the sign:
187
+ * - degrees:
188
+ * - d, D lower and upper case letters
189
+ * - U+00b0 degree symbol (&deg;)
190
+ * - U+00ba masculine ordinal indicator
191
+ * - U+2070 superscript zero
192
+ * - U+02da ring above
193
+ * - minutes:
194
+ * - ' apostrophe
195
+ * - U+2032 prime (&prime;)
196
+ * - U+00b4 acute accent
197
+ * - U+2019 right single quote (&rsquo;)
198
+ * - seconds:
199
+ * - &quot; quotation mark
200
+ * - U+2033 double prime (&Prime;)
201
+ * - U+201d right double quote (&rdquo;)
202
+ * - '&nbsp;' any two consecutive symbols for minutes
203
+ * - leading sign:
204
+ * - U+2212 minus sign (&minus;)
205
+ * .
206
+ * The codes with a leading zero byte, e.g., U+00b0, are accepted in their
207
+ * UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0.
208
+ **********************************************************************/
209
+ static Math::real Decode(const std::string& dms, flag& ind);
210
+
211
+ /**
212
+ * Convert DMS to an angle.
213
+ *
214
+ * @param[in] d degrees.
215
+ * @param[in] m arc minutes.
216
+ * @param[in] s arc seconds.
217
+ * @return angle (degrees)
218
+ *
219
+ * This does not propagate the sign on \e d to the other components,
220
+ * so -3d20' would need to be represented as - DMS::Decode(3.0, 20.0) or
221
+ * DMS::Decode(-3.0, -20.0).
222
+ **********************************************************************/
223
+ static Math::real Decode(real d, real m = 0, real s = 0)
224
+ { return d + (m + s / 60) / 60; }
225
+
226
+ /**
227
+ * Convert a pair of strings to latitude and longitude.
228
+ *
229
+ * @param[in] dmsa first string.
230
+ * @param[in] dmsb second string.
231
+ * @param[out] lat latitude (degrees).
232
+ * @param[out] lon longitude (degrees).
233
+ * @param[in] longfirst if true assume longitude is given before latitude
234
+ * in the absence of hemisphere designators (default false).
235
+ * @exception GeographicErr if \e dmsa or \e dmsb is malformed.
236
+ * @exception GeographicErr if \e dmsa and \e dmsb are both interpreted as
237
+ * latitudes.
238
+ * @exception GeographicErr if \e dmsa and \e dmsb are both interpreted as
239
+ * longitudes.
240
+ * @exception GeographicErr if decoded latitude is not in [&minus;90&deg;,
241
+ * 90&deg;].
242
+ *
243
+ * By default, the \e lat (resp., \e lon) is assigned to the results of
244
+ * decoding \e dmsa (resp., \e dmsb). However this is overridden if either
245
+ * \e dmsa or \e dmsb contain a latitude or longitude hemisphere designator
246
+ * (N, S, E, W). If an exception is thrown, \e lat and \e lon are
247
+ * unchanged.
248
+ **********************************************************************/
249
+ static void DecodeLatLon(const std::string& dmsa, const std::string& dmsb,
250
+ real& lat, real& lon,
251
+ bool longfirst = false);
252
+
253
+ /**
254
+ * Convert a string to an angle in degrees.
255
+ *
256
+ * @param[in] angstr input string.
257
+ * @exception GeographicErr if \e angstr is malformed.
258
+ * @exception GeographicErr if \e angstr includes a hemisphere designator.
259
+ * @return angle (degrees)
260
+ *
261
+ * No hemisphere designator is allowed and no check is done on the range of
262
+ * the result.
263
+ **********************************************************************/
264
+ static Math::real DecodeAngle(const std::string& angstr);
265
+
266
+ /**
267
+ * Convert a string to an azimuth in degrees.
268
+ *
269
+ * @param[in] azistr input string.
270
+ * @exception GeographicErr if \e azistr is malformed.
271
+ * @exception GeographicErr if \e azistr includes a N/S designator.
272
+ * @return azimuth (degrees) reduced to the range [&minus;180&deg;,
273
+ * 180&deg;).
274
+ *
275
+ * A hemisphere designator E/W can be used; the result is multiplied by
276
+ * &minus;1 if W is present.
277
+ **********************************************************************/
278
+ static Math::real DecodeAzimuth(const std::string& azistr);
279
+
280
+ /**
281
+ * Convert angle (in degrees) into a DMS string (using d, ', and &quot;).
282
+ *
283
+ * @param[in] angle input angle (degrees)
284
+ * @param[in] trailing DMS::component value indicating the trailing units
285
+ * of the string (this component is given as a decimal number if
286
+ * necessary).
287
+ * @param[in] prec the number of digits after the decimal point for the
288
+ * trailing component.
289
+ * @param[in] ind DMS::flag value indicating additional formatting.
290
+ * @param[in] dmssep if non-null, use as the DMS separator character
291
+ * (instead of d, ', &quot; delimiters).
292
+ * @exception std::bad_alloc if memory for the string can't be allocated.
293
+ * @return formatted string
294
+ *
295
+ * The interpretation of \e ind is as follows:
296
+ * - ind == DMS::NONE, signed result no leading zeros on degrees except in
297
+ * the units place, e.g., -8d03'.
298
+ * - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no sign,
299
+ * pad degrees to 2 digits, e.g., 08d03'S.
300
+ * - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no
301
+ * sign, pad degrees to 3 digits, e.g., 008d03'W.
302
+ * - ind == DMS::AZIMUTH, convert to the range [0, 360&deg;), no
303
+ * sign, pad degrees to 3 digits, e.g., 351d57'.
304
+ * .
305
+ * The integer parts of the minutes and seconds components are always given
306
+ * with 2 digits.
307
+ **********************************************************************/
308
+ static std::string Encode(real angle, component trailing, unsigned prec,
309
+ flag ind = NONE, char dmssep = char(0));
310
+
311
+ /**
312
+ * Convert angle into a DMS string (using d, ', and &quot;) selecting the
313
+ * trailing component based on the precision.
314
+ *
315
+ * @param[in] angle input angle (degrees)
316
+ * @param[in] prec the precision relative to 1 degree.
317
+ * @param[in] ind DMS::flag value indicated additional formatting.
318
+ * @param[in] dmssep if non-null, use as the DMS separator character
319
+ * (instead of d, ', &quot; delimiters).
320
+ * @exception std::bad_alloc if memory for the string can't be allocated.
321
+ * @return formatted string
322
+ *
323
+ * \e prec indicates the precision relative to 1 degree, e.g., \e prec = 3
324
+ * gives a result accurate to 0.1' and \e prec = 4 gives a result accurate
325
+ * to 1&quot;. \e ind is interpreted as in DMS::Encode with the additional
326
+ * facility that DMS::NUMBER represents \e angle as a number in fixed
327
+ * format with precision \e prec.
328
+ **********************************************************************/
329
+ static std::string Encode(real angle, unsigned prec, flag ind = NONE,
330
+ char dmssep = char(0)) {
331
+ return ind == NUMBER ? Utility::str(angle, int(prec)) :
332
+ Encode(angle,
333
+ prec < 2 ? DEGREE : (prec < 4 ? MINUTE : SECOND),
334
+ prec < 2 ? prec : (prec < 4 ? prec - 2 : prec - 4),
335
+ ind, dmssep);
336
+ }
337
+
338
+ /**
339
+ * Split angle into degrees and minutes
340
+ *
341
+ * @param[in] ang angle (degrees)
342
+ * @param[out] d degrees (an integer returned as a real)
343
+ * @param[out] m arc minutes.
344
+ **********************************************************************/
345
+ static void Encode(real ang, real& d, real& m) {
346
+ d = int(ang); m = 60 * (ang - d);
347
+ }
348
+
349
+ /**
350
+ * Split angle into degrees and minutes and seconds.
351
+ *
352
+ * @param[in] ang angle (degrees)
353
+ * @param[out] d degrees (an integer returned as a real)
354
+ * @param[out] m arc minutes (an integer returned as a real)
355
+ * @param[out] s arc seconds.
356
+ **********************************************************************/
357
+ static void Encode(real ang, real& d, real& m, real& s) {
358
+ d = int(ang); ang = 60 * (ang - d);
359
+ m = int(ang); s = 60 * (ang - m);
360
+ }
361
+
362
+ };
363
+
364
+ } // namespace GeographicLib
365
+
366
+ #if defined(_MSC_VER)
367
+ # pragma warning (pop)
368
+ #endif
369
+
370
+ #endif // GEOGRAPHICLIB_DMS_HPP