geographiclib 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +12 -0
- data/LICENSE +24 -0
- data/ext/geographiclib/Accumulator.cpp +23 -0
- data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
- data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
- data/ext/geographiclib/CassiniSoldner.cpp +89 -0
- data/ext/geographiclib/CircularEngine.cpp +96 -0
- data/ext/geographiclib/DMS.cpp +381 -0
- data/ext/geographiclib/Ellipsoid.cpp +125 -0
- data/ext/geographiclib/EllipticFunction.cpp +512 -0
- data/ext/geographiclib/GARS.cpp +122 -0
- data/ext/geographiclib/GeoCoords.cpp +175 -0
- data/ext/geographiclib/Geocentric.cpp +172 -0
- data/ext/geographiclib/Geodesic.cpp +1908 -0
- data/ext/geographiclib/GeodesicExact.cpp +927 -0
- data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
- data/ext/geographiclib/GeodesicLine.cpp +321 -0
- data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
- data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
- data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
- data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
- data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
- data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
- data/ext/geographiclib/GeographicLib/Config.h +12 -0
- data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
- data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
- data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
- data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
- data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
- data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
- data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
- data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
- data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
- data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
- data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
- data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
- data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
- data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
- data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
- data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
- data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
- data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
- data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
- data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
- data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
- data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
- data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
- data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
- data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
- data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
- data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
- data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
- data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
- data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
- data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
- data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
- data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
- data/ext/geographiclib/Geohash.cpp +102 -0
- data/ext/geographiclib/Geoid.cpp +509 -0
- data/ext/geographiclib/Georef.cpp +135 -0
- data/ext/geographiclib/Gnomonic.cpp +85 -0
- data/ext/geographiclib/GravityCircle.cpp +129 -0
- data/ext/geographiclib/GravityModel.cpp +360 -0
- data/ext/geographiclib/LambertConformalConic.cpp +456 -0
- data/ext/geographiclib/LocalCartesian.cpp +62 -0
- data/ext/geographiclib/MGRS.cpp +461 -0
- data/ext/geographiclib/MagneticCircle.cpp +52 -0
- data/ext/geographiclib/MagneticModel.cpp +269 -0
- data/ext/geographiclib/Math.cpp +63 -0
- data/ext/geographiclib/NormalGravity.cpp +262 -0
- data/ext/geographiclib/OSGB.cpp +167 -0
- data/ext/geographiclib/PolarStereographic.cpp +108 -0
- data/ext/geographiclib/PolygonArea.cpp +204 -0
- data/ext/geographiclib/Rhumb.cpp +383 -0
- data/ext/geographiclib/SphericalEngine.cpp +477 -0
- data/ext/geographiclib/TransverseMercator.cpp +603 -0
- data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
- data/ext/geographiclib/UTMUPS.cpp +296 -0
- data/ext/geographiclib/Utility.cpp +61 -0
- data/ext/geographiclib/extconf.rb +3 -0
- data/ext/geographiclib/geographiclib.cpp +62 -0
- data/lib/geographiclib.rb +20 -0
- 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 ⌊10<sup>6</sup> <i>x</i>⌋ 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 = −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
|
+
* - …
|
186
|
+
* - \e prec = 11 (max), 1 μ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 [−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 = −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 −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
|
+
* −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
|