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