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,184 @@
1
+ /**
2
+ * \file Accumulator.hpp
3
+ * \brief Header for GeographicLib::Accumulator class
4
+ *
5
+ * Copyright (c) Charles Karney (2010-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_ACCUMULATOR_HPP)
11
+ #define GEOGRAPHICLIB_ACCUMULATOR_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ namespace GeographicLib {
16
+
17
+ /**
18
+ * \brief An accumulator for sums
19
+ *
20
+ * This allows many numbers of floating point type \e T to be added together
21
+ * with twice the normal precision. Thus if \e T is double, the effective
22
+ * precision of the sum is 106 bits or about 32 decimal places.
23
+ *
24
+ * The implementation follows J. R. Shewchuk,
25
+ * <a href="https://dx.doi.org/10.1007/PL00009321"> Adaptive Precision
26
+ * Floating-Point Arithmetic and Fast Robust Geometric Predicates</a>,
27
+ * Discrete & Computational Geometry 18(3) 305--363 (1997).
28
+ *
29
+ * Approximate timings (summing a vector<double>)
30
+ * - double: 2ns
31
+ * - Accumulator<double>: 23ns
32
+ *
33
+ * In the documentation of the member functions, \e sum stands for the value
34
+ * currently held in the accumulator.
35
+ *
36
+ * Example of use:
37
+ * \include example-Accumulator.cpp
38
+ **********************************************************************/
39
+ template<typename T = Math::real>
40
+ class GEOGRAPHICLIB_EXPORT Accumulator {
41
+ private:
42
+ // _s + _t accumulators for the sum.
43
+ T _s, _t;
44
+ // Same as Math::sum, but requires abs(u) >= abs(v). This isn't currently
45
+ // used.
46
+ static inline T fastsum(T u, T v, T& t) {
47
+ GEOGRAPHICLIB_VOLATILE T s = u + v;
48
+ GEOGRAPHICLIB_VOLATILE T vp = s - u;
49
+ t = v - vp;
50
+ return s;
51
+ }
52
+ void Add(T y) {
53
+ // Here's Shewchuk's solution...
54
+ T u; // hold exact sum as [s, t, u]
55
+ y = Math::sum(y, _t, u); // Accumulate starting at least significant end
56
+ _s = Math::sum(y, _s, _t);
57
+ // Start is _s, _t decreasing and non-adjacent. Sum is now (s + t + u)
58
+ // exactly with s, t, u non-adjacent and in decreasing order (except for
59
+ // possible zeros). The following code tries to normalize the result.
60
+ // Ideally, we want _s = round(s+t+u) and _u = round(s+t+u - _s). The
61
+ // following does an approximate job (and maintains the decreasing
62
+ // non-adjacent property). Here are two "failures" using 3-bit floats:
63
+ //
64
+ // Case 1: _s is not equal to round(s+t+u) -- off by 1 ulp
65
+ // [12, -1] - 8 -> [4, 0, -1] -> [4, -1] = 3 should be [3, 0] = 3
66
+ //
67
+ // Case 2: _s+_t is not as close to s+t+u as it shold be
68
+ // [64, 5] + 4 -> [64, 8, 1] -> [64, 8] = 72 (off by 1)
69
+ // should be [80, -7] = 73 (exact)
70
+ //
71
+ // "Fixing" these problems is probably not worth the expense. The
72
+ // representation inevitably leads to small errors in the accumulated
73
+ // values. The additional errors illustrated here amount to 1 ulp of the
74
+ // less significant word during each addition to the Accumulator and an
75
+ // additional possible error of 1 ulp in the reported sum.
76
+ //
77
+ // Incidentally, the "ideal" representation described above is not
78
+ // canonical, because _s = round(_s + _t) may not be true. For example,
79
+ // with 3-bit floats:
80
+ //
81
+ // [128, 16] + 1 -> [160, -16] -- 160 = round(145).
82
+ // But [160, 0] - 16 -> [128, 16] -- 128 = round(144).
83
+ //
84
+ if (_s == 0) // This implies t == 0,
85
+ _s = u; // so result is u
86
+ else
87
+ _t += u; // otherwise just accumulate u to t.
88
+ }
89
+ T Sum(T y) const {
90
+ Accumulator a(*this);
91
+ a.Add(y);
92
+ return a._s;
93
+ }
94
+ public:
95
+ /**
96
+ * Construct from a \e T. This is not declared explicit, so that you can
97
+ * write <code>Accumulator<double> a = 5;</code>.
98
+ *
99
+ * @param[in] y set \e sum = \e y.
100
+ **********************************************************************/
101
+ Accumulator(T y = T(0)) : _s(y), _t(0) {
102
+ GEOGRAPHICLIB_STATIC_ASSERT(!std::numeric_limits<T>::is_integer,
103
+ "Accumulator type is not floating point");
104
+ }
105
+ /**
106
+ * Set the accumulator to a number.
107
+ *
108
+ * @param[in] y set \e sum = \e y.
109
+ **********************************************************************/
110
+ Accumulator& operator=(T y) { _s = y; _t = 0; return *this; }
111
+ /**
112
+ * Return the value held in the accumulator.
113
+ *
114
+ * @return \e sum.
115
+ **********************************************************************/
116
+ T operator()() const { return _s; }
117
+ /**
118
+ * Return the result of adding a number to \e sum (but don't change \e sum).
119
+ *
120
+ * @param[in] y the number to be added to the sum.
121
+ * @return \e sum + \e y.
122
+ **********************************************************************/
123
+ T operator()(T y) const { return Sum(y); }
124
+ /**
125
+ * Add a number to the accumulator.
126
+ *
127
+ * @param[in] y set \e sum += \e y.
128
+ **********************************************************************/
129
+ Accumulator& operator+=(T y) { Add(y); return *this; }
130
+ /**
131
+ * Subtract a number from the accumulator.
132
+ *
133
+ * @param[in] y set \e sum -= \e y.
134
+ **********************************************************************/
135
+ Accumulator& operator-=(T y) { Add(-y); return *this; }
136
+ /**
137
+ * Multiply accumulator by an integer. To avoid loss of accuracy, use only
138
+ * integers such that \e n &times; \e T is exactly representable as a \e T
139
+ * (i.e., &plusmn; powers of two). Use \e n = &minus;1 to negate \e sum.
140
+ *
141
+ * @param[in] n set \e sum *= \e n.
142
+ **********************************************************************/
143
+ Accumulator& operator*=(int n) { _s *= n; _t *= n; return *this; }
144
+ /**
145
+ * Multiply accumulator by a number. The fma (fused multiply and add)
146
+ * instruction is used (if available) in order to maintain accuracy.
147
+ *
148
+ * @param[in] y set \e sum *= \e y.
149
+ **********************************************************************/
150
+ Accumulator& operator*=(T y) {
151
+ T d = _s; _s *= y;
152
+ d = Math::fma(y, d, -_s); // the error in the first multiplication
153
+ _t = Math::fma(y, _t, d); // add error to the second term
154
+ return *this;
155
+ }
156
+ /**
157
+ * Test equality of an Accumulator with a number.
158
+ **********************************************************************/
159
+ bool operator==(T y) const { return _s == y; }
160
+ /**
161
+ * Test inequality of an Accumulator with a number.
162
+ **********************************************************************/
163
+ bool operator!=(T y) const { return _s != y; }
164
+ /**
165
+ * Less operator on an Accumulator and a number.
166
+ **********************************************************************/
167
+ bool operator<(T y) const { return _s < y; }
168
+ /**
169
+ * Less or equal operator on an Accumulator and a number.
170
+ **********************************************************************/
171
+ bool operator<=(T y) const { return _s <= y; }
172
+ /**
173
+ * Greater operator on an Accumulator and a number.
174
+ **********************************************************************/
175
+ bool operator>(T y) const { return _s > y; }
176
+ /**
177
+ * Greater or equal operator on an Accumulator and a number.
178
+ **********************************************************************/
179
+ bool operator>=(T y) const { return _s >= y; }
180
+ };
181
+
182
+ } // namespace GeographicLib
183
+
184
+ #endif // GEOGRAPHICLIB_ACCUMULATOR_HPP
@@ -0,0 +1,312 @@
1
+ /**
2
+ * \file AlbersEqualArea.hpp
3
+ * \brief Header for GeographicLib::AlbersEqualArea class
4
+ *
5
+ * Copyright (c) Charles Karney (2010-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_ALBERSEQUALAREA_HPP)
11
+ #define GEOGRAPHICLIB_ALBERSEQUALAREA_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ namespace GeographicLib {
16
+
17
+ /**
18
+ * \brief Albers equal area conic projection
19
+ *
20
+ * Implementation taken from the report,
21
+ * - J. P. Snyder,
22
+ * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A
23
+ * Working Manual</a>, USGS Professional Paper 1395 (1987),
24
+ * pp. 101--102.
25
+ *
26
+ * This is a implementation of the equations in Snyder except that divided
27
+ * differences will be [have been] used to transform the expressions into
28
+ * ones which may be evaluated accurately. [In this implementation, the
29
+ * projection correctly becomes the cylindrical equal area or the azimuthal
30
+ * equal area projection when the standard latitude is the equator or a
31
+ * pole.]
32
+ *
33
+ * The ellipsoid parameters, the standard parallels, and the scale on the
34
+ * standard parallels are set in the constructor. Internally, the case with
35
+ * two standard parallels is converted into a single standard parallel, the
36
+ * latitude of minimum azimuthal scale, with an azimuthal scale specified on
37
+ * this parallel. This latitude is also used as the latitude of origin which
38
+ * is returned by AlbersEqualArea::OriginLatitude. The azimuthal scale on
39
+ * the latitude of origin is given by AlbersEqualArea::CentralScale. The
40
+ * case with two standard parallels at opposite poles is singular and is
41
+ * disallowed. The central meridian (which is a trivial shift of the
42
+ * longitude) is specified as the \e lon0 argument of the
43
+ * AlbersEqualArea::Forward and AlbersEqualArea::Reverse functions.
44
+ * AlbersEqualArea::Forward and AlbersEqualArea::Reverse also return the
45
+ * meridian convergence, &gamma;, and azimuthal scale, \e k. A small square
46
+ * aligned with the cardinal directions is projected to a rectangle with
47
+ * dimensions \e k (in the E-W direction) and 1/\e k (in the N-S direction).
48
+ * The E-W sides of the rectangle are oriented &gamma; degrees
49
+ * counter-clockwise from the \e x axis. There is no provision in this class
50
+ * for specifying a false easting or false northing or a different latitude
51
+ * of origin.
52
+ *
53
+ * Example of use:
54
+ * \include example-AlbersEqualArea.cpp
55
+ *
56
+ * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility
57
+ * providing access to the functionality of LambertConformalConic and
58
+ * AlbersEqualArea.
59
+ **********************************************************************/
60
+ class GEOGRAPHICLIB_EXPORT AlbersEqualArea {
61
+ private:
62
+ typedef Math::real real;
63
+ real eps_, epsx_, epsx2_, tol_, tol0_;
64
+ real _a, _f, _fm, _e2, _e, _e2m, _qZ, _qx;
65
+ real _sign, _lat0, _k0;
66
+ real _n0, _m02, _nrho0, _k2, _txi0, _scxi0, _sxi0;
67
+ static const int numit_ = 5; // Newton iterations in Reverse
68
+ static const int numit0_ = 20; // Newton iterations in Init
69
+ static inline real hyp(real x) { return Math::hypot(real(1), x); }
70
+ // atanh( e * x)/ e if f > 0
71
+ // atan (sqrt(-e2) * x)/sqrt(-e2) if f < 0
72
+ // x if f = 0
73
+ inline real atanhee(real x) const {
74
+ using std::atan2; using std::abs;
75
+ return _f > 0 ? Math::atanh(_e * x)/_e :
76
+ // We only invoke atanhee in txif for positive latitude. Then x is
77
+ // only negative for very prolate ellipsoids (_b/_a >= sqrt(2)) and we
78
+ // still need to return a positive result in this case; hence the need
79
+ // for the call to atan2.
80
+ (_f < 0 ? (atan2(_e * abs(x), x < 0 ? -1 : 1)/_e) : x);
81
+ }
82
+ // return atanh(sqrt(x))/sqrt(x) - 1, accurate for small x
83
+ static real atanhxm1(real x);
84
+
85
+ // Divided differences
86
+ // Definition: Df(x,y) = (f(x)-f(y))/(x-y)
87
+ // See:
88
+ // W. M. Kahan and R. J. Fateman,
89
+ // Symbolic computation of divided differences,
90
+ // SIGSAM Bull. 33(3), 7-28 (1999)
91
+ // https://dx.doi.org/10.1145/334714.334716
92
+ // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
93
+ //
94
+ // General rules
95
+ // h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y)
96
+ // h(x) = f(x)*g(x):
97
+ // Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y)
98
+ // = Df(x,y)*g(y) + Dg(x,y)*f(x)
99
+ // = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2
100
+ //
101
+ // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^2))
102
+ static inline real Dsn(real x, real y, real sx, real sy) {
103
+ // sx = x/hyp(x)
104
+ real t = x * y;
105
+ return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) :
106
+ (x - y != 0 ? (sx - sy) / (x - y) : 1);
107
+ }
108
+ // Datanhee(x,y) = atanhee((x-y)/(1-e^2*x*y))/(x-y)
109
+ inline real Datanhee(real x, real y) const {
110
+ real t = x - y, d = 1 - _e2 * x * y;
111
+ return t ? atanhee(t / d) / t : 1 / d;
112
+ }
113
+ // DDatanhee(x,y) = (Datanhee(1,y) - Datanhee(1,x))/(y-x)
114
+ real DDatanhee(real x, real y) const;
115
+ void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1);
116
+ real txif(real tphi) const;
117
+ real tphif(real txi) const;
118
+
119
+ friend class Ellipsoid; // For access to txif, tphif, etc.
120
+ public:
121
+
122
+ /**
123
+ * Constructor with a single standard parallel.
124
+ *
125
+ * @param[in] a equatorial radius of ellipsoid (meters).
126
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
127
+ * Negative \e f gives a prolate ellipsoid.
128
+ * @param[in] stdlat standard parallel (degrees), the circle of tangency.
129
+ * @param[in] k0 azimuthal scale on the standard parallel.
130
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k0 is
131
+ * not positive.
132
+ * @exception GeographicErr if \e stdlat is not in [&minus;90&deg;,
133
+ * 90&deg;].
134
+ **********************************************************************/
135
+ AlbersEqualArea(real a, real f, real stdlat, real k0);
136
+
137
+ /**
138
+ * Constructor with two standard parallels.
139
+ *
140
+ * @param[in] a equatorial radius of ellipsoid (meters).
141
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
142
+ * Negative \e f gives a prolate ellipsoid.
143
+ * @param[in] stdlat1 first standard parallel (degrees).
144
+ * @param[in] stdlat2 second standard parallel (degrees).
145
+ * @param[in] k1 azimuthal scale on the standard parallels.
146
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k1 is
147
+ * not positive.
148
+ * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
149
+ * [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
150
+ * opposite poles.
151
+ **********************************************************************/
152
+ AlbersEqualArea(real a, real f, real stdlat1, real stdlat2, real k1);
153
+
154
+ /**
155
+ * Constructor with two standard parallels specified by sines and cosines.
156
+ *
157
+ * @param[in] a equatorial radius of ellipsoid (meters).
158
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
159
+ * Negative \e f gives a prolate ellipsoid.
160
+ * @param[in] sinlat1 sine of first standard parallel.
161
+ * @param[in] coslat1 cosine of first standard parallel.
162
+ * @param[in] sinlat2 sine of second standard parallel.
163
+ * @param[in] coslat2 cosine of second standard parallel.
164
+ * @param[in] k1 azimuthal scale on the standard parallels.
165
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k1 is
166
+ * not positive.
167
+ * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
168
+ * [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
169
+ * opposite poles.
170
+ *
171
+ * This allows parallels close to the poles to be specified accurately.
172
+ * This routine computes the latitude of origin and the azimuthal scale at
173
+ * this latitude. If \e dlat = abs(\e lat2 &minus; \e lat1) &le; 160&deg;,
174
+ * then the error in the latitude of origin is less than 4.5 &times;
175
+ * 10<sup>&minus;14</sup>d;.
176
+ **********************************************************************/
177
+ AlbersEqualArea(real a, real f,
178
+ real sinlat1, real coslat1,
179
+ real sinlat2, real coslat2,
180
+ real k1);
181
+
182
+ /**
183
+ * Set the azimuthal scale for the projection.
184
+ *
185
+ * @param[in] lat (degrees).
186
+ * @param[in] k azimuthal scale at latitude \e lat (default 1).
187
+ * @exception GeographicErr \e k is not positive.
188
+ * @exception GeographicErr if \e lat is not in (&minus;90&deg;,
189
+ * 90&deg;).
190
+ *
191
+ * This allows a "latitude of conformality" to be specified.
192
+ **********************************************************************/
193
+ void SetScale(real lat, real k = real(1));
194
+
195
+ /**
196
+ * Forward projection, from geographic to Lambert conformal conic.
197
+ *
198
+ * @param[in] lon0 central meridian longitude (degrees).
199
+ * @param[in] lat latitude of point (degrees).
200
+ * @param[in] lon longitude of point (degrees).
201
+ * @param[out] x easting of point (meters).
202
+ * @param[out] y northing of point (meters).
203
+ * @param[out] gamma meridian convergence at point (degrees).
204
+ * @param[out] k azimuthal scale of projection at point; the radial
205
+ * scale is the 1/\e k.
206
+ *
207
+ * The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No
208
+ * false easting or northing is added and \e lat should be in the range
209
+ * [&minus;90&deg;, 90&deg;]. The values of \e x and \e y returned for
210
+ * points which project to infinity (i.e., one or both of the poles) will
211
+ * be large but finite.
212
+ **********************************************************************/
213
+ void Forward(real lon0, real lat, real lon,
214
+ real& x, real& y, real& gamma, real& k) const;
215
+
216
+ /**
217
+ * Reverse projection, from Lambert conformal conic to geographic.
218
+ *
219
+ * @param[in] lon0 central meridian longitude (degrees).
220
+ * @param[in] x easting of point (meters).
221
+ * @param[in] y northing of point (meters).
222
+ * @param[out] lat latitude of point (degrees).
223
+ * @param[out] lon longitude of point (degrees).
224
+ * @param[out] gamma meridian convergence at point (degrees).
225
+ * @param[out] k azimuthal scale of projection at point; the radial
226
+ * scale is the 1/\e k.
227
+ *
228
+ * The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No
229
+ * false easting or northing is added. The value of \e lon returned is in
230
+ * the range [&minus;180&deg;, 180&deg;). The value of \e lat returned is
231
+ * in the range [&minus;90&deg;, 90&deg;]. If the input point is outside
232
+ * the legal projected space the nearest pole is returned.
233
+ **********************************************************************/
234
+ void Reverse(real lon0, real x, real y,
235
+ real& lat, real& lon, real& gamma, real& k) const;
236
+
237
+ /**
238
+ * AlbersEqualArea::Forward without returning the convergence and
239
+ * scale.
240
+ **********************************************************************/
241
+ void Forward(real lon0, real lat, real lon,
242
+ real& x, real& y) const {
243
+ real gamma, k;
244
+ Forward(lon0, lat, lon, x, y, gamma, k);
245
+ }
246
+
247
+ /**
248
+ * AlbersEqualArea::Reverse without returning the convergence and
249
+ * scale.
250
+ **********************************************************************/
251
+ void Reverse(real lon0, real x, real y,
252
+ real& lat, real& lon) const {
253
+ real gamma, k;
254
+ Reverse(lon0, x, y, lat, lon, gamma, k);
255
+ }
256
+
257
+ /** \name Inspector functions
258
+ **********************************************************************/
259
+ ///@{
260
+ /**
261
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
262
+ * the value used in the constructor.
263
+ **********************************************************************/
264
+ Math::real MajorRadius() const { return _a; }
265
+
266
+ /**
267
+ * @return \e f the flattening of the ellipsoid. This is the value used in
268
+ * the constructor.
269
+ **********************************************************************/
270
+ Math::real Flattening() const { return _f; }
271
+
272
+ /**
273
+ * @return latitude of the origin for the projection (degrees).
274
+ *
275
+ * This is the latitude of minimum azimuthal scale and equals the \e stdlat
276
+ * in the 1-parallel constructor and lies between \e stdlat1 and \e stdlat2
277
+ * in the 2-parallel constructors.
278
+ **********************************************************************/
279
+ Math::real OriginLatitude() const { return _lat0; }
280
+
281
+ /**
282
+ * @return central scale for the projection. This is the azimuthal scale
283
+ * on the latitude of origin.
284
+ **********************************************************************/
285
+ Math::real CentralScale() const { return _k0; }
286
+ ///@}
287
+
288
+ /**
289
+ * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
290
+ * stdlat = 0, and \e k0 = 1. This degenerates to the cylindrical equal
291
+ * area projection.
292
+ **********************************************************************/
293
+ static const AlbersEqualArea& CylindricalEqualArea();
294
+
295
+ /**
296
+ * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
297
+ * stdlat = 90&deg;, and \e k0 = 1. This degenerates to the
298
+ * Lambert azimuthal equal area projection.
299
+ **********************************************************************/
300
+ static const AlbersEqualArea& AzimuthalEqualAreaNorth();
301
+
302
+ /**
303
+ * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
304
+ * stdlat = &minus;90&deg;, and \e k0 = 1. This degenerates to the
305
+ * Lambert azimuthal equal area projection.
306
+ **********************************************************************/
307
+ static const AlbersEqualArea& AzimuthalEqualAreaSouth();
308
+ };
309
+
310
+ } // namespace GeographicLib
311
+
312
+ #endif // GEOGRAPHICLIB_ALBERSEQUALAREA_HPP