geographiclib 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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