geographiclib 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +12 -0
  3. data/LICENSE +24 -0
  4. data/ext/geographiclib/Accumulator.cpp +23 -0
  5. data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
  6. data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
  7. data/ext/geographiclib/CassiniSoldner.cpp +89 -0
  8. data/ext/geographiclib/CircularEngine.cpp +96 -0
  9. data/ext/geographiclib/DMS.cpp +381 -0
  10. data/ext/geographiclib/Ellipsoid.cpp +125 -0
  11. data/ext/geographiclib/EllipticFunction.cpp +512 -0
  12. data/ext/geographiclib/GARS.cpp +122 -0
  13. data/ext/geographiclib/GeoCoords.cpp +175 -0
  14. data/ext/geographiclib/Geocentric.cpp +172 -0
  15. data/ext/geographiclib/Geodesic.cpp +1908 -0
  16. data/ext/geographiclib/GeodesicExact.cpp +927 -0
  17. data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
  18. data/ext/geographiclib/GeodesicLine.cpp +321 -0
  19. data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
  20. data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
  21. data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
  22. data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
  23. data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
  24. data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
  25. data/ext/geographiclib/GeographicLib/Config.h +12 -0
  26. data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
  27. data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
  28. data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
  29. data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
  30. data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
  31. data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
  32. data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
  33. data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
  34. data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
  35. data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
  36. data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
  37. data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
  38. data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
  39. data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
  40. data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
  41. data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
  42. data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
  43. data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
  44. data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
  45. data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
  46. data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
  47. data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
  48. data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
  49. data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
  50. data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
  51. data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
  52. data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
  53. data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
  54. data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
  55. data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
  56. data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
  57. data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
  58. data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
  59. data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
  60. data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
  61. data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
  62. data/ext/geographiclib/Geohash.cpp +102 -0
  63. data/ext/geographiclib/Geoid.cpp +509 -0
  64. data/ext/geographiclib/Georef.cpp +135 -0
  65. data/ext/geographiclib/Gnomonic.cpp +85 -0
  66. data/ext/geographiclib/GravityCircle.cpp +129 -0
  67. data/ext/geographiclib/GravityModel.cpp +360 -0
  68. data/ext/geographiclib/LambertConformalConic.cpp +456 -0
  69. data/ext/geographiclib/LocalCartesian.cpp +62 -0
  70. data/ext/geographiclib/MGRS.cpp +461 -0
  71. data/ext/geographiclib/MagneticCircle.cpp +52 -0
  72. data/ext/geographiclib/MagneticModel.cpp +269 -0
  73. data/ext/geographiclib/Math.cpp +63 -0
  74. data/ext/geographiclib/NormalGravity.cpp +262 -0
  75. data/ext/geographiclib/OSGB.cpp +167 -0
  76. data/ext/geographiclib/PolarStereographic.cpp +108 -0
  77. data/ext/geographiclib/PolygonArea.cpp +204 -0
  78. data/ext/geographiclib/Rhumb.cpp +383 -0
  79. data/ext/geographiclib/SphericalEngine.cpp +477 -0
  80. data/ext/geographiclib/TransverseMercator.cpp +603 -0
  81. data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
  82. data/ext/geographiclib/UTMUPS.cpp +296 -0
  83. data/ext/geographiclib/Utility.cpp +61 -0
  84. data/ext/geographiclib/extconf.rb +3 -0
  85. data/ext/geographiclib/geographiclib.cpp +62 -0
  86. data/lib/geographiclib.rb +20 -0
  87. metadata +140 -0
@@ -0,0 +1,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