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,196 @@
1
+ /**
2
+ * \file TransverseMercator.hpp
3
+ * \brief Header for GeographicLib::TransverseMercator 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_TRANSVERSEMERCATOR_HPP)
11
+ #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER)
16
+ /**
17
+ * The order of the series approximation used in TransverseMercator.
18
+ * GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER can be set to any integer in [4, 8].
19
+ **********************************************************************/
20
+ # define GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER \
21
+ (GEOGRAPHICLIB_PRECISION == 2 ? 6 : \
22
+ (GEOGRAPHICLIB_PRECISION == 1 ? 4 : 8))
23
+ #endif
24
+
25
+ namespace GeographicLib {
26
+
27
+ /**
28
+ * \brief Transverse Mercator projection
29
+ *
30
+ * This uses Kr&uuml;ger's method which evaluates the projection and its
31
+ * inverse in terms of a series. See
32
+ * - L. Kr&uuml;ger,
33
+ * <a href="https://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme
34
+ * Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the
35
+ * ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New
36
+ * Series 52, 172 pp. (1912).
37
+ * - C. F. F. Karney,
38
+ * <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
39
+ * Transverse Mercator with an accuracy of a few nanometers,</a>
40
+ * J. Geodesy 85(8), 475--485 (Aug. 2011);
41
+ * preprint
42
+ * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>.
43
+ *
44
+ * Kr&uuml;ger's method has been extended from 4th to 6th order. The maximum
45
+ * error is 5 nm (5 nanometers), ground distance, for all positions within 35
46
+ * degrees of the central meridian. The error in the convergence is 2
47
+ * &times; 10<sup>&minus;15</sup>&quot; and the relative error in the scale
48
+ * is 6 &times; 10<sup>&minus;12</sup>%%. See Sec. 4 of
49
+ * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for details.
50
+ * The speed penalty in going to 6th order is only about 1%.
51
+ *
52
+ * There's a singularity in the projection at &phi; = 0&deg;, &lambda;
53
+ * &minus; &lambda;<sub>0</sub> = &plusmn;(1 &minus; \e e)90&deg; (&asymp;
54
+ * &plusmn;82.6&deg; for the WGS84 ellipsoid), where \e e is the
55
+ * eccentricity. Beyond this point, the series ceases to converge and the
56
+ * results from this method will be garbage. To be on the safe side, don't
57
+ * use this method if the angular distance from the central meridian exceeds
58
+ * (1 &minus; 2e)90&deg; (&asymp; 75&deg; for the WGS84 ellipsoid)
59
+ *
60
+ * TransverseMercatorExact is an alternative implementation of the projection
61
+ * using exact formulas which yield accurate (to 8 nm) results over the
62
+ * entire ellipsoid.
63
+ *
64
+ * The ellipsoid parameters and the central scale are set in the constructor.
65
+ * The central meridian (which is a trivial shift of the longitude) is
66
+ * specified as the \e lon0 argument of the TransverseMercator::Forward and
67
+ * TransverseMercator::Reverse functions. The latitude of origin is taken to
68
+ * be the equator. There is no provision in this class for specifying a
69
+ * false easting or false northing or a different latitude of origin.
70
+ * However these are can be simply included by the calling function. For
71
+ * example, the UTMUPS class applies the false easting and false northing for
72
+ * the UTM projections. A more complicated example is the British National
73
+ * Grid (<a href="http://www.spatialreference.org/ref/epsg/7405/">
74
+ * EPSG:7405</a>) which requires the use of a latitude of origin. This is
75
+ * implemented by the GeographicLib::OSGB class.
76
+ *
77
+ * See TransverseMercator.cpp for more information on the implementation.
78
+ *
79
+ * See \ref transversemercator for a discussion of this projection.
80
+ *
81
+ * Example of use:
82
+ * \include example-TransverseMercator.cpp
83
+ *
84
+ * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is a
85
+ * command-line utility providing access to the functionality of
86
+ * TransverseMercator and TransverseMercatorExact.
87
+ **********************************************************************/
88
+
89
+ class GEOGRAPHICLIB_EXPORT TransverseMercator {
90
+ private:
91
+ typedef Math::real real;
92
+ static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
93
+ static const int numit_ = 5;
94
+ real _a, _f, _k0, _e2, _es, _e2m, _c, _n;
95
+ // _alp[0] and _bet[0] unused
96
+ real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1];
97
+ friend class Ellipsoid; // For access to taupf, tauf.
98
+ public:
99
+
100
+ /**
101
+ * Constructor for a ellipsoid with
102
+ *
103
+ * @param[in] a equatorial radius (meters).
104
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
105
+ * Negative \e f gives a prolate ellipsoid.
106
+ * @param[in] k0 central scale factor.
107
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k0 is
108
+ * not positive.
109
+ **********************************************************************/
110
+ TransverseMercator(real a, real f, real k0);
111
+
112
+ /**
113
+ * Forward projection, from geographic to transverse Mercator.
114
+ *
115
+ * @param[in] lon0 central meridian of the projection (degrees).
116
+ * @param[in] lat latitude of point (degrees).
117
+ * @param[in] lon longitude of point (degrees).
118
+ * @param[out] x easting of point (meters).
119
+ * @param[out] y northing of point (meters).
120
+ * @param[out] gamma meridian convergence at point (degrees).
121
+ * @param[out] k scale of projection at point.
122
+ *
123
+ * No false easting or northing is added. \e lat should be in the range
124
+ * [&minus;90&deg;, 90&deg;].
125
+ **********************************************************************/
126
+ void Forward(real lon0, real lat, real lon,
127
+ real& x, real& y, real& gamma, real& k) const;
128
+
129
+ /**
130
+ * Reverse projection, from transverse Mercator to geographic.
131
+ *
132
+ * @param[in] lon0 central meridian of the projection (degrees).
133
+ * @param[in] x easting of point (meters).
134
+ * @param[in] y northing of point (meters).
135
+ * @param[out] lat latitude of point (degrees).
136
+ * @param[out] lon longitude of point (degrees).
137
+ * @param[out] gamma meridian convergence at point (degrees).
138
+ * @param[out] k scale of projection at point.
139
+ *
140
+ * No false easting or northing is added. The value of \e lon returned is
141
+ * in the range [&minus;180&deg;, 180&deg;).
142
+ **********************************************************************/
143
+ void Reverse(real lon0, real x, real y,
144
+ real& lat, real& lon, real& gamma, real& k) const;
145
+
146
+ /**
147
+ * TransverseMercator::Forward without returning the convergence and scale.
148
+ **********************************************************************/
149
+ void Forward(real lon0, real lat, real lon,
150
+ real& x, real& y) const {
151
+ real gamma, k;
152
+ Forward(lon0, lat, lon, x, y, gamma, k);
153
+ }
154
+
155
+ /**
156
+ * TransverseMercator::Reverse without returning the convergence and scale.
157
+ **********************************************************************/
158
+ void Reverse(real lon0, real x, real y,
159
+ real& lat, real& lon) const {
160
+ real gamma, k;
161
+ Reverse(lon0, x, y, lat, lon, gamma, k);
162
+ }
163
+
164
+ /** \name Inspector functions
165
+ **********************************************************************/
166
+ ///@{
167
+ /**
168
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
169
+ * the value used in the constructor.
170
+ **********************************************************************/
171
+ Math::real MajorRadius() const { return _a; }
172
+
173
+ /**
174
+ * @return \e f the flattening of the ellipsoid. This is the value used in
175
+ * the constructor.
176
+ **********************************************************************/
177
+ Math::real Flattening() const { return _f; }
178
+
179
+ /**
180
+ * @return \e k0 central scale for the projection. This is the value of \e
181
+ * k0 used in the constructor and is the scale on the central meridian.
182
+ **********************************************************************/
183
+ Math::real CentralScale() const { return _k0; }
184
+ ///@}
185
+
186
+ /**
187
+ * A global instantiation of TransverseMercator with the WGS84 ellipsoid
188
+ * and the UTM scale factor. However, unlike UTM, no false easting or
189
+ * northing is added.
190
+ **********************************************************************/
191
+ static const TransverseMercator& UTM();
192
+ };
193
+
194
+ } // namespace GeographicLib
195
+
196
+ #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP
@@ -0,0 +1,254 @@
1
+ /**
2
+ * \file TransverseMercatorExact.hpp
3
+ * \brief Header for GeographicLib::TransverseMercatorExact 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_TRANSVERSEMERCATOREXACT_HPP)
11
+ #define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+ #include <GeographicLib/EllipticFunction.hpp>
15
+
16
+ namespace GeographicLib {
17
+
18
+ /**
19
+ * \brief An exact implementation of the transverse Mercator projection
20
+ *
21
+ * Implementation of the Transverse Mercator Projection given in
22
+ * - L. P. Lee,
23
+ * <a href="https://dx.doi.org/10.3138/X687-1574-4325-WM62"> Conformal
24
+ * Projections Based On Jacobian Elliptic Functions</a>, Part V of
25
+ * Conformal Projections Based on Elliptic Functions,
26
+ * (B. V. Gutsell, Toronto, 1976), 128pp.,
27
+ * ISBN: 0919870163
28
+ * (also appeared as:
29
+ * Monograph 16, Suppl. No. 1 to Canadian Cartographer, Vol 13).
30
+ * - C. F. F. Karney,
31
+ * <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
32
+ * Transverse Mercator with an accuracy of a few nanometers,</a>
33
+ * J. Geodesy 85(8), 475--485 (Aug. 2011);
34
+ * preprint
35
+ * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>.
36
+ *
37
+ * Lee gives the correct results for forward and reverse transformations
38
+ * subject to the branch cut rules (see the description of the \e extendp
39
+ * argument to the constructor). The maximum error is about 8 nm (8
40
+ * nanometers), ground distance, for the forward and reverse transformations.
41
+ * The error in the convergence is 2 &times; 10<sup>&minus;15</sup>&quot;,
42
+ * the relative error in the scale is 7 &times; 10<sup>&minus;12</sup>%%.
43
+ * See Sec. 3 of
44
+ * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for details.
45
+ * The method is "exact" in the sense that the errors are close to the
46
+ * round-off limit and that no changes are needed in the algorithms for them
47
+ * to be used with reals of a higher precision. Thus the errors using long
48
+ * double (with a 64-bit fraction) are about 2000 times smaller than using
49
+ * double (with a 53-bit fraction).
50
+ *
51
+ * This algorithm is about 4.5 times slower than the 6th-order Kr&uuml;ger
52
+ * method, TransverseMercator, taking about 11 us for a combined forward and
53
+ * reverse projection on a 2.66 GHz Intel machine (g++, version 4.3.0, -O3).
54
+ *
55
+ * The ellipsoid parameters and the central scale are set in the constructor.
56
+ * The central meridian (which is a trivial shift of the longitude) is
57
+ * specified as the \e lon0 argument of the TransverseMercatorExact::Forward
58
+ * and TransverseMercatorExact::Reverse functions. The latitude of origin is
59
+ * taken to be the equator. See the documentation on TransverseMercator for
60
+ * how to include a false easting, false northing, or a latitude of origin.
61
+ *
62
+ * See <a href="http://geographiclib.sourceforge.net/tm-grid.kmz"
63
+ * type="application/vnd.google-earth.kmz"> tm-grid.kmz</a>, for an
64
+ * illustration of the transverse Mercator grid in Google Earth.
65
+ *
66
+ * See TransverseMercatorExact.cpp for more information on the
67
+ * implementation.
68
+ *
69
+ * See \ref transversemercator for a discussion of this projection.
70
+ *
71
+ * Example of use:
72
+ * \include example-TransverseMercatorExact.cpp
73
+ *
74
+ * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is a
75
+ * command-line utility providing access to the functionality of
76
+ * TransverseMercator and TransverseMercatorExact.
77
+ **********************************************************************/
78
+
79
+ class GEOGRAPHICLIB_EXPORT TransverseMercatorExact {
80
+ private:
81
+ typedef Math::real real;
82
+ static const int numit_ = 10;
83
+ real tol_, tol1_, tol2_, taytol_;
84
+ real _a, _f, _k0, _mu, _mv, _e;
85
+ bool _extendp;
86
+ EllipticFunction _Eu, _Ev;
87
+
88
+ void zeta(real u, real snu, real cnu, real dnu,
89
+ real v, real snv, real cnv, real dnv,
90
+ real& taup, real& lam) const;
91
+
92
+ void dwdzeta(real u, real snu, real cnu, real dnu,
93
+ real v, real snv, real cnv, real dnv,
94
+ real& du, real& dv) const;
95
+
96
+ bool zetainv0(real psi, real lam, real& u, real& v) const;
97
+ void zetainv(real taup, real lam, real& u, real& v) const;
98
+
99
+ void sigma(real u, real snu, real cnu, real dnu,
100
+ real v, real snv, real cnv, real dnv,
101
+ real& xi, real& eta) const;
102
+
103
+ void dwdsigma(real u, real snu, real cnu, real dnu,
104
+ real v, real snv, real cnv, real dnv,
105
+ real& du, real& dv) const;
106
+
107
+ bool sigmainv0(real xi, real eta, real& u, real& v) const;
108
+ void sigmainv(real xi, real eta, real& u, real& v) const;
109
+
110
+ void Scale(real tau, real lam,
111
+ real snu, real cnu, real dnu,
112
+ real snv, real cnv, real dnv,
113
+ real& gamma, real& k) const;
114
+
115
+ public:
116
+
117
+ /**
118
+ * Constructor for a ellipsoid with
119
+ *
120
+ * @param[in] a equatorial radius (meters).
121
+ * @param[in] f flattening of ellipsoid.
122
+ * @param[in] k0 central scale factor.
123
+ * @param[in] extendp use extended domain.
124
+ * @exception GeographicErr if \e a, \e f, or \e k0 is not positive.
125
+ *
126
+ * The transverse Mercator projection has a branch point singularity at \e
127
+ * lat = 0 and \e lon &minus; \e lon0 = 90 (1 &minus; \e e) or (for
128
+ * TransverseMercatorExact::UTM) x = 18381 km, y = 0m. The \e extendp
129
+ * argument governs where the branch cut is placed. With \e extendp =
130
+ * false, the "standard" convention is followed, namely the cut is placed
131
+ * along \e x > 18381 km, \e y = 0m. Forward can be called with any \e lat
132
+ * and \e lon then produces the transformation shown in Lee, Fig 46.
133
+ * Reverse analytically continues this in the &plusmn; \e x direction. As
134
+ * a consequence, Reverse may map multiple points to the same geographic
135
+ * location; for example, for TransverseMercatorExact::UTM, \e x =
136
+ * 22051449.037349 m, \e y = &minus;7131237.022729 m and \e x =
137
+ * 29735142.378357 m, \e y = 4235043.607933 m both map to \e lat =
138
+ * &minus;2&deg;, \e lon = 88&deg;.
139
+ *
140
+ * With \e extendp = true, the branch cut is moved to the lower left
141
+ * quadrant. The various symmetries of the transverse Mercator projection
142
+ * can be used to explore the projection on any sheet. In this mode the
143
+ * domains of \e lat, \e lon, \e x, and \e y are restricted to
144
+ * - the union of
145
+ * - \e lat in [0, 90] and \e lon &minus; \e lon0 in [0, 90]
146
+ * - \e lat in (-90, 0] and \e lon &minus; \e lon0 in [90 (1 &minus; \e
147
+ e), 90]
148
+ * - the union of
149
+ * - <i>x</i>/(\e k0 \e a) in [0, &infin;) and
150
+ * <i>y</i>/(\e k0 \e a) in [0, E(<i>e</i><sup>2</sup>)]
151
+ * - <i>x</i>/(\e k0 \e a) in [K(1 &minus; <i>e</i><sup>2</sup>) &minus;
152
+ * E(1 &minus; <i>e</i><sup>2</sup>), &infin;) and <i>y</i>/(\e k0 \e
153
+ * a) in (&minus;&infin;, 0]
154
+ * .
155
+ * See Sec. 5 of
156
+ * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for a full
157
+ * discussion of the treatment of the branch cut.
158
+ *
159
+ * The method will work for all ellipsoids used in terrestrial geodesy.
160
+ * The method cannot be applied directly to the case of a sphere (\e f = 0)
161
+ * because some the constants characterizing this method diverge in that
162
+ * limit, and in practice, \e f should be larger than about
163
+ * numeric_limits<real>::epsilon(). However, TransverseMercator treats the
164
+ * sphere exactly.
165
+ **********************************************************************/
166
+ TransverseMercatorExact(real a, real f, real k0, bool extendp = false);
167
+
168
+ /**
169
+ * Forward projection, from geographic to transverse Mercator.
170
+ *
171
+ * @param[in] lon0 central meridian of the projection (degrees).
172
+ * @param[in] lat latitude of point (degrees).
173
+ * @param[in] lon longitude of point (degrees).
174
+ * @param[out] x easting of point (meters).
175
+ * @param[out] y northing of point (meters).
176
+ * @param[out] gamma meridian convergence at point (degrees).
177
+ * @param[out] k scale of projection at point.
178
+ *
179
+ * No false easting or northing is added. \e lat should be in the range
180
+ * [&minus;90&deg;, 90&deg;].
181
+ **********************************************************************/
182
+ void Forward(real lon0, real lat, real lon,
183
+ real& x, real& y, real& gamma, real& k) const;
184
+
185
+ /**
186
+ * Reverse projection, from transverse Mercator to geographic.
187
+ *
188
+ * @param[in] lon0 central meridian of the projection (degrees).
189
+ * @param[in] x easting of point (meters).
190
+ * @param[in] y northing of point (meters).
191
+ * @param[out] lat latitude of point (degrees).
192
+ * @param[out] lon longitude of point (degrees).
193
+ * @param[out] gamma meridian convergence at point (degrees).
194
+ * @param[out] k scale of projection at point.
195
+ *
196
+ * No false easting or northing is added. The value of \e lon returned is
197
+ * in the range [&minus;180&deg;, 180&deg;).
198
+ **********************************************************************/
199
+ void Reverse(real lon0, real x, real y,
200
+ real& lat, real& lon, real& gamma, real& k) const;
201
+
202
+ /**
203
+ * TransverseMercatorExact::Forward without returning the convergence and
204
+ * scale.
205
+ **********************************************************************/
206
+ void Forward(real lon0, real lat, real lon,
207
+ real& x, real& y) const {
208
+ real gamma, k;
209
+ Forward(lon0, lat, lon, x, y, gamma, k);
210
+ }
211
+
212
+ /**
213
+ * TransverseMercatorExact::Reverse without returning the convergence and
214
+ * scale.
215
+ **********************************************************************/
216
+ void Reverse(real lon0, real x, real y,
217
+ real& lat, real& lon) const {
218
+ real gamma, k;
219
+ Reverse(lon0, x, y, lat, lon, gamma, k);
220
+ }
221
+
222
+ /** \name Inspector functions
223
+ **********************************************************************/
224
+ ///@{
225
+ /**
226
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
227
+ * the value used in the constructor.
228
+ **********************************************************************/
229
+ Math::real MajorRadius() const { return _a; }
230
+
231
+ /**
232
+ * @return \e f the flattening of the ellipsoid. This is the value used in
233
+ * the constructor.
234
+ **********************************************************************/
235
+ Math::real Flattening() const { return _f; }
236
+
237
+ /**
238
+ * @return \e k0 central scale for the projection. This is the value of \e
239
+ * k0 used in the constructor and is the scale on the central meridian.
240
+ **********************************************************************/
241
+ Math::real CentralScale() const { return _k0; }
242
+ ///@}
243
+
244
+ /**
245
+ * A global instantiation of TransverseMercatorExact with the WGS84
246
+ * ellipsoid and the UTM scale factor. However, unlike UTM, no false
247
+ * easting or northing is added.
248
+ **********************************************************************/
249
+ static const TransverseMercatorExact& UTM();
250
+ };
251
+
252
+ } // namespace GeographicLib
253
+
254
+ #endif // GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP
@@ -0,0 +1,421 @@
1
+ /**
2
+ * \file UTMUPS.hpp
3
+ * \brief Header for GeographicLib::UTMUPS 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_UTMUPS_HPP)
11
+ #define GEOGRAPHICLIB_UTMUPS_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ namespace GeographicLib {
16
+
17
+ /**
18
+ * \brief Convert between geographic coordinates and UTM/UPS
19
+ *
20
+ * UTM and UPS are defined
21
+ * - J. W. Hager, J. F. Behensky, and B. W. Drew,
22
+ * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.2/TM8358_2.pdf">
23
+ * The Universal Grids: Universal Transverse Mercator (UTM) and Universal
24
+ * Polar Stereographic (UPS)</a>, Defense Mapping Agency, Technical Manual
25
+ * TM8358.2 (1989).
26
+ * .
27
+ * Section 2-3 defines UTM and section 3-2.4 defines UPS. This document also
28
+ * includes approximate algorithms for the computation of the underlying
29
+ * transverse Mercator and polar stereographic projections. Here we
30
+ * substitute much more accurate algorithms given by
31
+ * GeographicLib:TransverseMercator and GeographicLib:PolarStereographic.
32
+ * These are the algorithms recommended by the NGA document
33
+ * - <a href="http://earth-info.nga.mil/GandG/publications/NGA_SIG_0012_2_0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf">
34
+ * The Universal Grids and the Transverse Mercator and Polar Stereographic
35
+ * Map Projections</a>, NGA.SIG.0012_2.0.0_UTMUPS (2014).
36
+ *
37
+ * In this implementation, the conversions are closed, i.e., output from
38
+ * Forward is legal input for Reverse and vice versa. The error is about 5nm
39
+ * in each direction. However, the conversion from legal UTM/UPS coordinates
40
+ * to geographic coordinates and back might throw an error if the initial
41
+ * point is within 5nm of the edge of the allowed range for the UTM/UPS
42
+ * coordinates.
43
+ *
44
+ * The simplest way to guarantee the closed property is to define allowed
45
+ * ranges for the eastings and northings for UTM and UPS coordinates. The
46
+ * UTM boundaries are the same for all zones. (The only place the
47
+ * exceptional nature of the zone boundaries is evident is when converting to
48
+ * UTM/UPS coordinates requesting the standard zone.) The MGRS lettering
49
+ * scheme imposes natural limits on UTM/UPS coordinates which may be
50
+ * converted into MGRS coordinates. For the conversion to/from geographic
51
+ * coordinates these ranges have been extended by 100km in order to provide a
52
+ * generous overlap between UTM and UPS and between UTM zones.
53
+ *
54
+ * The <a href="http://www.nga.mil">NGA</a> software package
55
+ * <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans</a>
56
+ * also provides conversions to and from UTM and UPS. Version 2.4.2 (and
57
+ * earlier) suffers from some drawbacks:
58
+ * - Inconsistent rules are used to determine the whether a particular UTM or
59
+ * UPS coordinate is legal. A more systematic approach is taken here.
60
+ * - The underlying projections are not very accurately implemented.
61
+ *
62
+ * The GeographicLib::UTMUPS::EncodeZone encodes the UTM zone and hemisphere
63
+ * to allow UTM/UPS coordinated to be displayed as, for example, "38N 444500
64
+ * 3688500". According to NGA.SIG.0012_2.0.0_UTMUPS the use of "N" to denote
65
+ * "north" in the context is not allowed (since a upper case letter in this
66
+ * context denotes the MGRS latitude band). Consequently, as of version
67
+ * 1.36, EncodeZone uses the lower case letters "n" and "s" to denote the
68
+ * hemisphere. In addition EncodeZone accepts an optional final argument \e
69
+ * abbrev, which, if false, results in the hemisphere being spelled out as in
70
+ * "38north".
71
+ *
72
+ * Example of use:
73
+ * \include example-UTMUPS.cpp
74
+ **********************************************************************/
75
+ class GEOGRAPHICLIB_EXPORT UTMUPS {
76
+ private:
77
+ typedef Math::real real;
78
+ static const int falseeasting_[4];
79
+ static const int falsenorthing_[4];
80
+ static const int mineasting_[4];
81
+ static const int maxeasting_[4];
82
+ static const int minnorthing_[4];
83
+ static const int maxnorthing_[4];
84
+ static const int epsg01N = 32601; // EPSG code for UTM 01N
85
+ static const int epsg60N = 32660; // EPSG code for UTM 60N
86
+ static const int epsgN = 32661; // EPSG code for UPS N
87
+ static const int epsg01S = 32701; // EPSG code for UTM 01S
88
+ static const int epsg60S = 32760; // EPSG code for UTM 60S
89
+ static const int epsgS = 32761; // EPSG code for UPS S
90
+ static real CentralMeridian(int zone)
91
+ { return real(6 * zone - 183); }
92
+ // Throw an error if easting or northing are outside standard ranges. If
93
+ // throwp = false, return bool instead.
94
+ static bool CheckCoords(bool utmp, bool northp, real x, real y,
95
+ bool msgrlimits = false, bool throwp = true);
96
+ UTMUPS(); // Disable constructor
97
+
98
+ public:
99
+
100
+ /**
101
+ * In this class we bring together the UTM and UPS coordinates systems.
102
+ * The UTM divides the earth between latitudes &minus;80&deg; and 84&deg;
103
+ * into 60 zones numbered 1 thru 60. Zone assign zone number 0 to the UPS
104
+ * regions, covering the two poles. Within UTMUPS, non-negative zone
105
+ * numbers refer to one of the "physical" zones, 0 for UPS and [1, 60] for
106
+ * UTM. Negative "pseudo-zone" numbers are used to select one of the
107
+ * physical zones.
108
+ **********************************************************************/
109
+ enum zonespec {
110
+ /**
111
+ * The smallest pseudo-zone number.
112
+ **********************************************************************/
113
+ MINPSEUDOZONE = -4,
114
+ /**
115
+ * A marker for an undefined or invalid zone. Equivalent to NaN.
116
+ **********************************************************************/
117
+ INVALID = -4,
118
+ /**
119
+ * If a coordinate already include zone information (e.g., it is an MGRS
120
+ * coordinate), use that, otherwise apply the UTMUPS::STANDARD rules.
121
+ **********************************************************************/
122
+ MATCH = -3,
123
+ /**
124
+ * Apply the standard rules for UTM zone assigment extending the UTM zone
125
+ * to each pole to give a zone number in [1, 60]. For example, use UTM
126
+ * zone 38 for longitude in [42&deg;, 48&deg;). The rules include the
127
+ * Norway and Svalbard exceptions.
128
+ **********************************************************************/
129
+ UTM = -2,
130
+ /**
131
+ * Apply the standard rules for zone assignment to give a zone number in
132
+ * [0, 60]. If the latitude is not in [&minus;80&deg;, 84&deg;), then
133
+ * use UTMUPS::UPS = 0, otherwise apply the rules for UTMUPS::UTM. The
134
+ * tests on latitudes and longitudes are all closed on the lower end open
135
+ * on the upper. Thus for UTM zone 38, latitude is in [&minus;80&deg;,
136
+ * 84&deg;) and longitude is in [42&deg;, 48&deg;).
137
+ **********************************************************************/
138
+ STANDARD = -1,
139
+ /**
140
+ * The largest pseudo-zone number.
141
+ **********************************************************************/
142
+ MAXPSEUDOZONE = -1,
143
+ /**
144
+ * The smallest physical zone number.
145
+ **********************************************************************/
146
+ MINZONE = 0,
147
+ /**
148
+ * The zone number used for UPS
149
+ **********************************************************************/
150
+ UPS = 0,
151
+ /**
152
+ * The smallest UTM zone number.
153
+ **********************************************************************/
154
+ MINUTMZONE = 1,
155
+ /**
156
+ * The largest UTM zone number.
157
+ **********************************************************************/
158
+ MAXUTMZONE = 60,
159
+ /**
160
+ * The largest physical zone number.
161
+ **********************************************************************/
162
+ MAXZONE = 60,
163
+ };
164
+
165
+ /**
166
+ * The standard zone.
167
+ *
168
+ * @param[in] lat latitude (degrees).
169
+ * @param[in] lon longitude (degrees).
170
+ * @param[in] setzone zone override (optional). If omitted, use the
171
+ * standard rules for picking the zone. If \e setzone is given then use
172
+ * that zone if it is non-negative, otherwise apply the rules given in
173
+ * UTMUPS::zonespec.
174
+ * @exception GeographicErr if \e setzone is outside the range
175
+ * [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE] = [&minus;4, 60].
176
+ *
177
+ * This is exact.
178
+ **********************************************************************/
179
+ static int StandardZone(real lat, real lon, int setzone = STANDARD);
180
+
181
+ /**
182
+ * Forward projection, from geographic to UTM/UPS.
183
+ *
184
+ * @param[in] lat latitude of point (degrees).
185
+ * @param[in] lon longitude of point (degrees).
186
+ * @param[out] zone the UTM zone (zero means UPS).
187
+ * @param[out] northp hemisphere (true means north, false means south).
188
+ * @param[out] x easting of point (meters).
189
+ * @param[out] y northing of point (meters).
190
+ * @param[out] gamma meridian convergence at point (degrees).
191
+ * @param[out] k scale of projection at point.
192
+ * @param[in] setzone zone override (optional).
193
+ * @param[in] mgrslimits if true enforce the stricter MGRS limits on the
194
+ * coordinates (default = false).
195
+ * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
196
+ * 90&deg;].
197
+ * @exception GeographicErr if the resulting \e x or \e y is out of allowed
198
+ * range (see Reverse); in this case, these arguments are unchanged.
199
+ *
200
+ * If \e setzone is omitted, use the standard rules for picking the zone.
201
+ * If \e setzone is given then use that zone if it is non-negative,
202
+ * otherwise apply the rules given in UTMUPS::zonespec. The accuracy of
203
+ * the conversion is about 5nm.
204
+ *
205
+ * The northing \e y jumps by UTMUPS::UTMShift() when crossing the equator
206
+ * in the southerly direction. Sometimes it is useful to remove this
207
+ * discontinuity in \e y by extending the "northern" hemisphere using
208
+ * UTMUPS::Transfer:
209
+ * \code
210
+ double lat = -1, lon = 123;
211
+ int zone;
212
+ bool northp;
213
+ double x, y, gamma, k;
214
+ GeographicLib::UTMUPS::Forward(lat, lon, zone, northp, x, y, gamma, k);
215
+ GeographicLib::UTMUPS::Transfer(zone, northp, x, y,
216
+ zone, true, x, y, zone);
217
+ northp = true;
218
+ \endcode
219
+ **********************************************************************/
220
+ static void Forward(real lat, real lon,
221
+ int& zone, bool& northp, real& x, real& y,
222
+ real& gamma, real& k,
223
+ int setzone = STANDARD, bool mgrslimits = false);
224
+
225
+ /**
226
+ * Reverse projection, from UTM/UPS to geographic.
227
+ *
228
+ * @param[in] zone the UTM zone (zero means UPS).
229
+ * @param[in] northp hemisphere (true means north, false means south).
230
+ * @param[in] x easting of point (meters).
231
+ * @param[in] y northing of point (meters).
232
+ * @param[out] lat latitude of point (degrees).
233
+ * @param[out] lon longitude of point (degrees).
234
+ * @param[out] gamma meridian convergence at point (degrees).
235
+ * @param[out] k scale of projection at point.
236
+ * @param[in] mgrslimits if true enforce the stricter MGRS limits on the
237
+ * coordinates (default = false).
238
+ * @exception GeographicErr if \e zone, \e x, or \e y is out of allowed
239
+ * range; this this case the arguments are unchanged.
240
+ *
241
+ * The accuracy of the conversion is about 5nm.
242
+ *
243
+ * UTM eastings are allowed to be in the range [0km, 1000km], northings are
244
+ * allowed to be in in [0km, 9600km] for the northern hemisphere and in
245
+ * [900km, 10000km] for the southern hemisphere. However UTM northings
246
+ * can be continued across the equator. So the actual limits on the
247
+ * northings are [-9100km, 9600km] for the "northern" hemisphere and
248
+ * [900km, 19600km] for the "southern" hemisphere.
249
+ *
250
+ * UPS eastings and northings are allowed to be in the range [1200km,
251
+ * 2800km] in the northern hemisphere and in [700km, 3300km] in the
252
+ * southern hemisphere.
253
+ *
254
+ * These ranges are 100km larger than allowed for the conversions to MGRS.
255
+ * (100km is the maximum extra padding consistent with eastings remaining
256
+ * non-negative.) This allows generous overlaps between zones and UTM and
257
+ * UPS. If \e mgrslimits = true, then all the ranges are shrunk by 100km
258
+ * so that they agree with the stricter MGRS ranges. No checks are
259
+ * performed besides these (e.g., to limit the distance outside the
260
+ * standard zone boundaries).
261
+ **********************************************************************/
262
+ static void Reverse(int zone, bool northp, real x, real y,
263
+ real& lat, real& lon, real& gamma, real& k,
264
+ bool mgrslimits = false);
265
+
266
+ /**
267
+ * UTMUPS::Forward without returning convergence and scale.
268
+ **********************************************************************/
269
+ static void Forward(real lat, real lon,
270
+ int& zone, bool& northp, real& x, real& y,
271
+ int setzone = STANDARD, bool mgrslimits = false) {
272
+ real gamma, k;
273
+ Forward(lat, lon, zone, northp, x, y, gamma, k, setzone, mgrslimits);
274
+ }
275
+
276
+ /**
277
+ * UTMUPS::Reverse without returning convergence and scale.
278
+ **********************************************************************/
279
+ static void Reverse(int zone, bool northp, real x, real y,
280
+ real& lat, real& lon, bool mgrslimits = false) {
281
+ real gamma, k;
282
+ Reverse(zone, northp, x, y, lat, lon, gamma, k, mgrslimits);
283
+ }
284
+
285
+ /**
286
+ * Transfer UTM/UPS coordinated from one zone to another.
287
+ *
288
+ * @param[in] zonein the UTM zone for \e xin and \e yin (or zero for UPS).
289
+ * @param[in] northpin hemisphere for \e xin and \e yin (true means north,
290
+ * false means south).
291
+ * @param[in] xin easting of point (meters) in \e zonein.
292
+ * @param[in] yin northing of point (meters) in \e zonein.
293
+ * @param[in] zoneout the requested UTM zone for \e xout and \e yout (or
294
+ * zero for UPS).
295
+ * @param[in] northpout hemisphere for \e xout output and \e yout.
296
+ * @param[out] xout easting of point (meters) in \e zoneout.
297
+ * @param[out] yout northing of point (meters) in \e zoneout.
298
+ * @param[out] zone the actual UTM zone for \e xout and \e yout (or zero
299
+ * for UPS); this equals \e zoneout if \e zoneout &ge; 0.
300
+ * @exception GeographicErr if \e zonein is out of range (see below).
301
+ * @exception GeographicErr if \e zoneout is out of range (see below).
302
+ * @exception GeographicErr if \e xin or \e yin fall outside their allowed
303
+ * ranges (see UTMUPS::Reverse).
304
+ * @exception GeographicErr if \e xout or \e yout fall outside their
305
+ * allowed ranges (see UTMUPS::Reverse).
306
+ *
307
+ * \e zonein must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0,
308
+ * 60] with \e zonein = UTMUPS::UPS, 0, indicating UPS. \e zonein may
309
+ * also be UTMUPS::INVALID.
310
+ *
311
+ * \e zoneout must be in the range [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE]
312
+ * = [-4, 60]. If \e zoneout &lt; UTMUPS::MINZONE then the rules give in
313
+ * the documentation of UTMUPS::zonespec are applied, and \e zone is set to
314
+ * the actual zone used for output.
315
+ *
316
+ * (\e xout, \e yout) can overlap with (\e xin, \e yin).
317
+ **********************************************************************/
318
+ static void Transfer(int zonein, bool northpin, real xin, real yin,
319
+ int zoneout, bool northpout, real& xout, real& yout,
320
+ int& zone);
321
+
322
+ /**
323
+ * Decode a UTM/UPS zone string.
324
+ *
325
+ * @param[in] zonestr string representation of zone and hemisphere.
326
+ * @param[out] zone the UTM zone (zero means UPS).
327
+ * @param[out] northp hemisphere (true means north, false means south).
328
+ * @exception GeographicErr if \e zonestr is malformed.
329
+ *
330
+ * For UTM, \e zonestr has the form of a zone number in the range
331
+ * [UTMUPS::MINUTMZONE, UTMUPS::MAXUTMZONE] = [1, 60] followed by a
332
+ * hemisphere letter, n or s (or "north" or "south" spelled out). For UPS,
333
+ * it consists just of the hemisphere letter (or the spelled out
334
+ * hemisphere). The returned value of \e zone is UTMUPS::UPS = 0 for UPS.
335
+ * Note well that "38s" indicates the southern hemisphere of zone 38 and
336
+ * not latitude band S, 32&deg; &le; \e lat &lt; 40&deg;. n, 01s, 2n, 38s,
337
+ * south, 3north are legal. 0n, 001s, +3n, 61n, 38P are illegal. INV is a
338
+ * special value for which the returned value of \e is UTMUPS::INVALID.
339
+ **********************************************************************/
340
+ static void DecodeZone(const std::string& zonestr, int& zone, bool& northp);
341
+
342
+ /**
343
+ * Encode a UTM/UPS zone string.
344
+ *
345
+ * @param[in] zone the UTM zone (zero means UPS).
346
+ * @param[in] northp hemisphere (true means north, false means south).
347
+ * @param[in] abbrev if true (the default) use abbreviated (n/s) notation
348
+ * for hemisphere; otherwise spell out the hemisphere (north/south)
349
+ * @exception GeographicErr if \e zone is out of range (see below).
350
+ * @exception std::bad_alloc if memoy for the string can't be allocated.
351
+ * @return string representation of zone and hemisphere.
352
+ *
353
+ * \e zone must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0,
354
+ * 60] with \e zone = UTMUPS::UPS, 0, indicating UPS (but the resulting
355
+ * string does not contain "0"). \e zone may also be UTMUPS::INVALID, in
356
+ * which case the returned string is "inv". This reverses
357
+ * UTMUPS::DecodeZone.
358
+ **********************************************************************/
359
+ static std::string EncodeZone(int zone, bool northp, bool abbrev = true);
360
+
361
+ /**
362
+ * Decode EPSG.
363
+ *
364
+ * @param[in] epsg the EPSG code.
365
+ * @param[out] zone the UTM zone (zero means UPS).
366
+ * @param[out] northp hemisphere (true means north, false means south).
367
+ *
368
+ * EPSG (European Petroleum Survery Group) codes are a way to refer to many
369
+ * different projections. DecodeEPSG decodes those refering to UTM or UPS
370
+ * projections for the WGS84 ellipsoid. If the code does not refer to one
371
+ * of these projections, \e zone is set to UTMUPS::INVALID. See
372
+ * http://spatialreference.org/ref/epsg/
373
+ **********************************************************************/
374
+ static void DecodeEPSG(int epsg, int& zone, bool& northp);
375
+
376
+ /**
377
+ * Encode zone as EPSG.
378
+ *
379
+ * @param[in] zone the UTM zone (zero means UPS).
380
+ * @param[in] northp hemisphere (true means north, false means south).
381
+ * @return EPSG code (or -1 if \e zone is not in the range
382
+ * [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0, 60])
383
+ *
384
+ * Convert \e zone and \e northp to the corresponding EPSG (European
385
+ * Petroleum Survery Group) codes
386
+ **********************************************************************/
387
+ static int EncodeEPSG(int zone, bool northp);
388
+
389
+ /**
390
+ * @return shift (meters) necessary to align north and south halves of a
391
+ * UTM zone (10<sup>7</sup>).
392
+ **********************************************************************/
393
+ static Math::real UTMShift();
394
+
395
+ /** \name Inspector functions
396
+ **********************************************************************/
397
+ ///@{
398
+ /**
399
+ * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
400
+ *
401
+ * (The WGS84 value is returned because the UTM and UPS projections are
402
+ * based on this ellipsoid.)
403
+ **********************************************************************/
404
+ static Math::real MajorRadius()
405
+ { return Constants::WGS84_a(); }
406
+
407
+ /**
408
+ * @return \e f the flattening of the WGS84 ellipsoid.
409
+ *
410
+ * (The WGS84 value is returned because the UTM and UPS projections are
411
+ * based on this ellipsoid.)
412
+ **********************************************************************/
413
+ static Math::real Flattening()
414
+ { return Constants::WGS84_f(); }
415
+ ///@}
416
+
417
+ };
418
+
419
+ } // namespace GeographicLib
420
+
421
+ #endif // GEOGRAPHICLIB_UTMUPS_HPP