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,355 @@
1
+ /**
2
+ * \file MGRS.hpp
3
+ * \brief Header for GeographicLib::MGRS 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_MGRS_HPP)
11
+ #define GEOGRAPHICLIB_MGRS_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+ #include <GeographicLib/UTMUPS.hpp>
15
+
16
+ #if defined(_MSC_VER)
17
+ // Squelch warnings about dll vs string
18
+ # pragma warning (push)
19
+ # pragma warning (disable: 4251)
20
+ #endif
21
+
22
+ namespace GeographicLib {
23
+
24
+ /**
25
+ * \brief Convert between UTM/UPS and %MGRS
26
+ *
27
+ * MGRS is defined in Chapter 3 of
28
+ * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill,
29
+ * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/TM8358_1.pdf">
30
+ * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>,
31
+ * Defense Mapping Agency, Technical Manual TM8358.1 (1990).
32
+ * .
33
+ * This document has been updated by the two NGA documents
34
+ * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_STND_0037_2_0_0_GRIDS/NGA.STND.0037_2.0.0_GRIDS.pdf">
35
+ * Universal Grids and Grid Reference Systems</a>,
36
+ * NGA.STND.0037_2.0.0_GRIDS (2014).
37
+ * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_SIG_0012_2_0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf">
38
+ * The Universal Grids and the Transverse Mercator and Polar Stereographic
39
+ * Map Projections</a>, NGA.SIG.0012_2.0.0_UTMUPS (2014).
40
+ *
41
+ * This implementation has the following properties:
42
+ * - The conversions are closed, i.e., output from Forward is legal input for
43
+ * Reverse and vice versa. Conversion in both directions preserve the
44
+ * UTM/UPS selection and the UTM zone.
45
+ * - Forward followed by Reverse and vice versa is approximately the
46
+ * identity. (This is affected in predictable ways by errors in
47
+ * determining the latitude band and by loss of precision in the MGRS
48
+ * coordinates.)
49
+ * - The trailing digits produced by Forward are consistent as the precision
50
+ * is varied. Specifically, the digits are obtained by operating on the
51
+ * easting with &lfloor;10<sup>6</sup> <i>x</i>&rfloor; and extracting the
52
+ * required digits from the resulting number (and similarly for the
53
+ * northing).
54
+ * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS
55
+ * coordinates with a legal 100 km block prefix are legal (even though the
56
+ * latitude band letter may now belong to a neighboring band).
57
+ * - The range of UTM/UPS coordinates allowed for conversion to MGRS
58
+ * coordinates is the maximum consistent with staying within the letter
59
+ * ranges of the MGRS scheme.
60
+ * - All the transformations are implemented as static methods in the MGRS
61
+ * class.
62
+ *
63
+ * The <a href="http://www.nga.mil">NGA</a> software package
64
+ * <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans</a>
65
+ * also provides conversions to and from MGRS. Version 3.0 (and earlier)
66
+ * suffers from some drawbacks:
67
+ * - Inconsistent rules are used to determine the whether a particular MGRS
68
+ * coordinate is legal. A more systematic approach is taken here.
69
+ * - The underlying projections are not very accurately implemented.
70
+ *
71
+ * Example of use:
72
+ * \include example-MGRS.cpp
73
+ **********************************************************************/
74
+ class GEOGRAPHICLIB_EXPORT MGRS {
75
+ private:
76
+ typedef Math::real real;
77
+ static const std::string hemispheres_;
78
+ static const std::string utmcols_[3];
79
+ static const std::string utmrow_;
80
+ static const std::string upscols_[4];
81
+ static const std::string upsrows_[2];
82
+ static const std::string latband_;
83
+ static const std::string upsband_;
84
+ static const std::string digits_;
85
+
86
+ static const int mineasting_[4];
87
+ static const int maxeasting_[4];
88
+ static const int minnorthing_[4];
89
+ static const int maxnorthing_[4];
90
+ enum {
91
+ base_ = 10,
92
+ // Top-level tiles are 10^5 m = 100 km on a side
93
+ tilelevel_ = 5,
94
+ // Period of UTM row letters
95
+ utmrowperiod_ = 20,
96
+ // Row letters are shifted by 5 for even zones
97
+ utmevenrowshift_ = 5,
98
+ // Maximum precision is um
99
+ maxprec_ = 5 + 6,
100
+ // For generating digits at maxprec
101
+ mult_ = 1000000,
102
+ };
103
+ static void CheckCoords(bool utmp, bool& northp, real& x, real& y);
104
+ static int UTMRow(int iband, int icol, int irow);
105
+
106
+ friend class UTMUPS; // UTMUPS::StandardZone calls LatitudeBand
107
+ // Return latitude band number [-10, 10) for the given latitude (degrees).
108
+ // The bands are reckoned in include their southern edges.
109
+ static int LatitudeBand(real lat) {
110
+ using std::floor;
111
+ int ilat = int(floor(lat));
112
+ return (std::max)(-10, (std::min)(9, (ilat + 80)/8 - 10));
113
+ }
114
+ // Return approximate latitude band number [-10, 10) for the given northing
115
+ // (meters). With this rule, each 100km tile would have a unique band
116
+ // letter corresponding to the latitude at the center of the tile. This
117
+ // function isn't currently used.
118
+ static int ApproxLatitudeBand(real y) {
119
+ // northing at tile center in units of tile = 100km
120
+ using std::floor; using std::abs;
121
+ real ya = floor( (std::min)(real(88), abs(y/tile_)) ) +
122
+ real(0.5);
123
+ // convert to lat (mult by 90/100) and then to band (divide by 8)
124
+ // the +1 fine tunes the boundary between bands 3 and 4
125
+ int b = int(floor( ((ya * 9 + 1) / 10) / 8 ));
126
+ // For the northern hemisphere we have
127
+ // band rows num
128
+ // N 0 0:8 9
129
+ // P 1 9:17 9
130
+ // Q 2 18:26 9
131
+ // R 3 27:34 8
132
+ // S 4 35:43 9
133
+ // T 5 44:52 9
134
+ // U 6 53:61 9
135
+ // V 7 62:70 9
136
+ // W 8 71:79 9
137
+ // X 9 80:94 15
138
+ return y >= 0 ? b : -(b + 1);
139
+ }
140
+ // UTMUPS access these enums
141
+ enum {
142
+ tile_ = 100000, // Size MGRS blocks
143
+ minutmcol_ = 1,
144
+ maxutmcol_ = 9,
145
+ minutmSrow_ = 10,
146
+ maxutmSrow_ = 100, // Also used for UTM S false northing
147
+ minutmNrow_ = 0, // Also used for UTM N false northing
148
+ maxutmNrow_ = 95,
149
+ minupsSind_ = 8, // These 4 ind's apply to easting and northing
150
+ maxupsSind_ = 32,
151
+ minupsNind_ = 13,
152
+ maxupsNind_ = 27,
153
+ upseasting_ = 20, // Also used for UPS false northing
154
+ utmeasting_ = 5, // UTM false easting
155
+ // Difference between S hemisphere northing and N hemisphere northing
156
+ utmNshift_ = (maxutmSrow_ - minutmNrow_) * tile_
157
+ };
158
+ MGRS(); // Disable constructor
159
+
160
+ public:
161
+
162
+ /**
163
+ * Convert UTM or UPS coordinate to an MGRS coordinate.
164
+ *
165
+ * @param[in] zone UTM zone (zero means UPS).
166
+ * @param[in] northp hemisphere (true means north, false means south).
167
+ * @param[in] x easting of point (meters).
168
+ * @param[in] y northing of point (meters).
169
+ * @param[in] prec precision relative to 100 km.
170
+ * @param[out] mgrs MGRS string.
171
+ * @exception GeographicErr if \e zone, \e x, or \e y is outside its
172
+ * allowed range.
173
+ * @exception GeographicErr if the memory for the MGRS string can't be
174
+ * allocated.
175
+ *
176
+ * \e prec specifies the precision of the MGRS string as follows:
177
+ * - \e prec = &minus;1 (min), only the grid zone is returned
178
+ * - \e prec = 0, 100 km
179
+ * - \e prec = 1, 10 km
180
+ * - \e prec = 2, 1 km
181
+ * - \e prec = 3, 100 m
182
+ * - \e prec = 4, 10 m
183
+ * - \e prec = 5, 1 m
184
+ * - \e prec = 6, 0.1 m
185
+ * - &hellip;
186
+ * - \e prec = 11 (max), 1 &mu;m
187
+ *
188
+ * UTM eastings are allowed to be in the range [100 km, 900 km], northings
189
+ * are allowed to be in in [0 km, 9500 km] for the northern hemisphere and
190
+ * in [1000 km, 10000 km] for the southern hemisphere. (However UTM
191
+ * northings can be continued across the equator. So the actual limits on
192
+ * the northings are [&minus;9000 km, 9500 km] for the "northern"
193
+ * hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.)
194
+ *
195
+ * UPS eastings/northings are allowed to be in the range [1300 km, 2700 km]
196
+ * in the northern hemisphere and in [800 km, 3200 km] in the southern
197
+ * hemisphere.
198
+ *
199
+ * The ranges are 100 km more restrictive than for the conversion between
200
+ * geographic coordinates and UTM and UPS given by UTMUPS. These
201
+ * restrictions are dictated by the allowed letters in MGRS coordinates.
202
+ * The choice of 9500 km for the maximum northing for northern hemisphere
203
+ * and of 1000 km as the minimum northing for southern hemisphere provide
204
+ * at least 0.5 degree extension into standard UPS zones. The upper ends
205
+ * of the ranges for the UPS coordinates is dictated by requiring symmetry
206
+ * about the meridians 0E and 90E.
207
+ *
208
+ * All allowed UTM and UPS coordinates may now be converted to legal MGRS
209
+ * coordinates with the proviso that eastings and northings on the upper
210
+ * boundaries are silently reduced by about 4 nm (4 nanometers) to place
211
+ * them \e within the allowed range. (This includes reducing a southern
212
+ * hemisphere northing of 10000 km by 4 nm so that it is placed in latitude
213
+ * band M.) The UTM or UPS coordinates are truncated to requested
214
+ * precision to determine the MGRS coordinate. Thus in UTM zone 38n, the
215
+ * square area with easting in [444 km, 445 km) and northing in [3688 km,
216
+ * 3689 km) maps to MGRS coordinate 38SMB4488 (at \e prec = 2, 1 km),
217
+ * Khulani Sq., Baghdad.
218
+ *
219
+ * The UTM/UPS selection and the UTM zone is preserved in the conversion to
220
+ * MGRS coordinate. Thus for \e zone > 0, the MGRS coordinate begins with
221
+ * the zone number followed by one of [C--M] for the southern
222
+ * hemisphere and [N--X] for the northern hemisphere. For \e zone =
223
+ * 0, the MGRS coordinates begins with one of [AB] for the southern
224
+ * hemisphere and [XY] for the northern hemisphere.
225
+ *
226
+ * The conversion to the MGRS is exact for prec in [0, 5] except that a
227
+ * neighboring latitude band letter may be given if the point is within 5nm
228
+ * of a band boundary. For prec in [6, 11], the conversion is accurate to
229
+ * roundoff.
230
+ *
231
+ * If \e prec = &minus;1, then the "grid zone designation", e.g., 18T, is
232
+ * returned. This consists of the UTM zone number (absent for UPS) and the
233
+ * first letter of the MGRS string which labels the latitude band for UTM
234
+ * and the hemisphere for UPS.
235
+ *
236
+ * If \e x or \e y is NaN or if \e zone is UTMUPS::INVALID, the returned
237
+ * MGRS string is "INVALID".
238
+ *
239
+ * Return the result via a reference argument to avoid the overhead of
240
+ * allocating a potentially large number of small strings. If an error is
241
+ * thrown, then \e mgrs is unchanged.
242
+ **********************************************************************/
243
+ static void Forward(int zone, bool northp, real x, real y,
244
+ int prec, std::string& mgrs);
245
+
246
+ /**
247
+ * Convert UTM or UPS coordinate to an MGRS coordinate when the latitude is
248
+ * known.
249
+ *
250
+ * @param[in] zone UTM zone (zero means UPS).
251
+ * @param[in] northp hemisphere (true means north, false means south).
252
+ * @param[in] x easting of point (meters).
253
+ * @param[in] y northing of point (meters).
254
+ * @param[in] lat latitude (degrees).
255
+ * @param[in] prec precision relative to 100 km.
256
+ * @param[out] mgrs MGRS string.
257
+ * @exception GeographicErr if \e zone, \e x, or \e y is outside its
258
+ * allowed range.
259
+ * @exception GeographicErr if \e lat is inconsistent with the given UTM
260
+ * coordinates.
261
+ * @exception std::bad_alloc if the memory for \e mgrs can't be allocated.
262
+ *
263
+ * The latitude is ignored for \e zone = 0 (UPS); otherwise the latitude is
264
+ * used to determine the latitude band and this is checked for consistency
265
+ * using the same tests as Reverse.
266
+ **********************************************************************/
267
+ static void Forward(int zone, bool northp, real x, real y, real lat,
268
+ int prec, std::string& mgrs);
269
+
270
+ /**
271
+ * Convert a MGRS coordinate to UTM or UPS coordinates.
272
+ *
273
+ * @param[in] mgrs MGRS string.
274
+ * @param[out] zone UTM zone (zero means UPS).
275
+ * @param[out] northp hemisphere (true means north, false means south).
276
+ * @param[out] x easting of point (meters).
277
+ * @param[out] y northing of point (meters).
278
+ * @param[out] prec precision relative to 100 km.
279
+ * @param[in] centerp if true (default), return center of the MGRS square,
280
+ * else return SW (lower left) corner.
281
+ * @exception GeographicErr if \e mgrs is illegal.
282
+ *
283
+ * All conversions from MGRS to UTM/UPS are permitted provided the MGRS
284
+ * coordinate is a possible result of a conversion in the other direction.
285
+ * (The leading 0 may be dropped from an input MGRS coordinate for UTM
286
+ * zones 1--9.) In addition, MGRS coordinates with a neighboring
287
+ * latitude band letter are permitted provided that some portion of the
288
+ * 100 km block is within the given latitude band. Thus
289
+ * - 38VLS and 38WLS are allowed (latitude 64N intersects the square
290
+ * 38[VW]LS); but 38VMS is not permitted (all of 38WMS is north of 64N)
291
+ * - 38MPE and 38NPF are permitted (they straddle the equator); but 38NPE
292
+ * and 38MPF are not permitted (the equator does not intersect either
293
+ * block).
294
+ * - Similarly ZAB and YZB are permitted (they straddle the prime
295
+ * meridian); but YAB and ZZB are not (the prime meridian does not
296
+ * intersect either block).
297
+ *
298
+ * The UTM/UPS selection and the UTM zone is preserved in the conversion
299
+ * from MGRS coordinate. The conversion is exact for prec in [0, 5]. With
300
+ * \e centerp = true, the conversion from MGRS to geographic and back is
301
+ * stable. This is not assured if \e centerp = false.
302
+ *
303
+ * If a "grid zone designation" (for example, 18T or A) is given, then some
304
+ * suitable (but essentially arbitrary) point within that grid zone is
305
+ * returned. The main utility of the conversion is to allow \e zone and \e
306
+ * northp to be determined. In this case, the \e centerp parameter is
307
+ * ignored and \e prec is set to &minus;1.
308
+ *
309
+ * If the first 3 characters of \e mgrs are "INV", then \e x and \e y are
310
+ * set to NaN, \e zone is set to UTMUPS::INVALID, and \e prec is set to
311
+ * &minus;2.
312
+ *
313
+ * If an exception is thrown, then the arguments are unchanged.
314
+ **********************************************************************/
315
+ static void Reverse(const std::string& mgrs,
316
+ int& zone, bool& northp, real& x, real& y,
317
+ int& prec, bool centerp = true);
318
+
319
+ /** \name Inspector functions
320
+ **********************************************************************/
321
+ ///@{
322
+ /**
323
+ * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
324
+ *
325
+ * (The WGS84 value is returned because the UTM and UPS projections are
326
+ * based on this ellipsoid.)
327
+ **********************************************************************/
328
+ static Math::real MajorRadius() { return UTMUPS::MajorRadius(); }
329
+
330
+ /**
331
+ * @return \e f the flattening of the WGS84 ellipsoid.
332
+ *
333
+ * (The WGS84 value is returned because the UTM and UPS projections are
334
+ * based on this ellipsoid.)
335
+ **********************************************************************/
336
+ static Math::real Flattening() { return UTMUPS::Flattening(); }
337
+ ///@}
338
+
339
+ /**
340
+ * Perform some checks on the UTMUPS coordinates on this ellipsoid. Throw
341
+ * an error if any of the assumptions made in the MGRS class is not true.
342
+ * This check needs to be carried out if the ellipsoid parameters (or the
343
+ * UTM/UPS scales) are ever changed.
344
+ **********************************************************************/
345
+ static void Check();
346
+
347
+ };
348
+
349
+ } // namespace GeographicLib
350
+
351
+ #if defined(_MSC_VER)
352
+ # pragma warning (pop)
353
+ #endif
354
+
355
+ #endif // GEOGRAPHICLIB_MGRS_HPP
@@ -0,0 +1,178 @@
1
+ /**
2
+ * \file MagneticCircle.hpp
3
+ * \brief Header for GeographicLib::MagneticCircle class
4
+ *
5
+ * Copyright (c) Charles Karney (2011-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_MAGNETICCIRCLE_HPP)
11
+ #define GEOGRAPHICLIB_MAGNETICCIRCLE_HPP 1
12
+
13
+ #include <vector>
14
+ #include <GeographicLib/Constants.hpp>
15
+ #include <GeographicLib/CircularEngine.hpp>
16
+
17
+ namespace GeographicLib {
18
+
19
+ /**
20
+ * \brief Geomagnetic field on a circle of latitude
21
+ *
22
+ * Evaluate the earth's magnetic field on a circle of constant height and
23
+ * latitude. This uses a CircularEngine to pre-evaluate the inner sum of the
24
+ * spherical harmonic sum, allowing the values of the field at several
25
+ * different longitudes to be evaluated rapidly.
26
+ *
27
+ * Use MagneticModel::Circle to create a MagneticCircle object. (The
28
+ * constructor for this class is private.)
29
+ *
30
+ * Example of use:
31
+ * \include example-MagneticCircle.cpp
32
+ *
33
+ * <a href="MagneticField.1.html">MagneticField</a> is a command-line utility
34
+ * providing access to the functionality of MagneticModel and MagneticCircle.
35
+ **********************************************************************/
36
+
37
+ class GEOGRAPHICLIB_EXPORT MagneticCircle {
38
+ private:
39
+ typedef Math::real real;
40
+
41
+ real _a, _f, _lat, _h, _t, _cphi, _sphi, _t1, _dt0;
42
+ bool _interpolate, _constterm;
43
+ CircularEngine _circ0, _circ1, _circ2;
44
+
45
+ MagneticCircle(real a, real f, real lat, real h, real t,
46
+ real cphi, real sphi, real t1, real dt0,
47
+ bool interpolate,
48
+ const CircularEngine& circ0, const CircularEngine& circ1)
49
+ : _a(a)
50
+ , _f(f)
51
+ , _lat(Math::LatFix(lat))
52
+ , _h(h)
53
+ , _t(t)
54
+ , _cphi(cphi)
55
+ , _sphi(sphi)
56
+ , _t1(t1)
57
+ , _dt0(dt0)
58
+ , _interpolate(interpolate)
59
+ , _constterm(false)
60
+ , _circ0(circ0)
61
+ , _circ1(circ1)
62
+ {}
63
+
64
+ MagneticCircle(real a, real f, real lat, real h, real t,
65
+ real cphi, real sphi, real t1, real dt0,
66
+ bool interpolate,
67
+ const CircularEngine& circ0, const CircularEngine& circ1,
68
+ const CircularEngine& circ2)
69
+ : _a(a)
70
+ , _f(f)
71
+ , _lat(lat)
72
+ , _h(h)
73
+ , _t(t)
74
+ , _cphi(cphi)
75
+ , _sphi(sphi)
76
+ , _t1(t1)
77
+ , _dt0(dt0)
78
+ , _interpolate(interpolate)
79
+ , _constterm(true)
80
+ , _circ0(circ0)
81
+ , _circ1(circ1)
82
+ , _circ2(circ2)
83
+ {}
84
+
85
+ void Field(real lon, bool diffp,
86
+ real& Bx, real& By, real& Bz,
87
+ real& Bxt, real& Byt, real& Bzt) const;
88
+
89
+ friend class MagneticModel; // MagneticModel calls the private constructor
90
+
91
+ public:
92
+
93
+ /**
94
+ * A default constructor for the normal gravity. This sets up an
95
+ * uninitialized object which can be later replaced by the
96
+ * MagneticModel::Circle.
97
+ **********************************************************************/
98
+ MagneticCircle() : _a(-1) {}
99
+
100
+ /** \name Compute the magnetic field
101
+ **********************************************************************/
102
+ ///@{
103
+ /**
104
+ * Evaluate the components of the geomagnetic field at a particular
105
+ * longitude.
106
+ *
107
+ * @param[in] lon longitude of the point (degrees).
108
+ * @param[out] Bx the easterly component of the magnetic field (nanotesla).
109
+ * @param[out] By the northerly component of the magnetic field (nanotesla).
110
+ * @param[out] Bz the vertical (up) component of the magnetic field
111
+ * (nanotesla).
112
+ **********************************************************************/
113
+ void operator()(real lon, real& Bx, real& By, real& Bz) const {
114
+ real dummy;
115
+ Field(lon, false, Bx, By, Bz, dummy, dummy, dummy);
116
+ }
117
+
118
+ /**
119
+ * Evaluate the components of the geomagnetic field and their time
120
+ * derivatives at a particular longitude.
121
+ *
122
+ * @param[in] lon longitude of the point (degrees).
123
+ * @param[out] Bx the easterly component of the magnetic field (nanotesla).
124
+ * @param[out] By the northerly component of the magnetic field (nanotesla).
125
+ * @param[out] Bz the vertical (up) component of the magnetic field
126
+ * (nanotesla).
127
+ * @param[out] Bxt the rate of change of \e Bx (nT/yr).
128
+ * @param[out] Byt the rate of change of \e By (nT/yr).
129
+ * @param[out] Bzt the rate of change of \e Bz (nT/yr).
130
+ **********************************************************************/
131
+ void operator()(real lon, real& Bx, real& By, real& Bz,
132
+ real& Bxt, real& Byt, real& Bzt) const {
133
+ Field(lon, true, Bx, By, Bz, Bxt, Byt, Bzt);
134
+ }
135
+ ///@}
136
+
137
+ /** \name Inspector functions
138
+ **********************************************************************/
139
+ ///@{
140
+ /**
141
+ * @return true if the object has been initialized.
142
+ **********************************************************************/
143
+ bool Init() const { return _a > 0; }
144
+ /**
145
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
146
+ * the value inherited from the MagneticModel object used in the
147
+ * constructor.
148
+ **********************************************************************/
149
+ Math::real MajorRadius() const
150
+ { return Init() ? _a : Math::NaN(); }
151
+ /**
152
+ * @return \e f the flattening of the ellipsoid. This is the value
153
+ * inherited from the MagneticModel object used in the constructor.
154
+ **********************************************************************/
155
+ Math::real Flattening() const
156
+ { return Init() ? _f : Math::NaN(); }
157
+ /**
158
+ * @return the latitude of the circle (degrees).
159
+ **********************************************************************/
160
+ Math::real Latitude() const
161
+ { return Init() ? _lat : Math::NaN(); }
162
+ /**
163
+ * @return the height of the circle (meters).
164
+ **********************************************************************/
165
+ Math::real Height() const
166
+ { return Init() ? _h : Math::NaN(); }
167
+ /**
168
+ * @return the time (fractional years).
169
+ **********************************************************************/
170
+ Math::real Time() const
171
+ { return Init() ? _t : Math::NaN(); }
172
+
173
+ ///@}
174
+ };
175
+
176
+ } // namespace GeographicLib
177
+
178
+ #endif // GEOGRAPHICLIB_MAGNETICCIRCLE_HPP