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,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