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,313 @@
1
+ /**
2
+ * \file LambertConformalConic.hpp
3
+ * \brief Header for GeographicLib::LambertConformalConic 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_LAMBERTCONFORMALCONIC_HPP)
11
+ #define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP 1
12
+
13
+ #include <GeographicLib/Constants.hpp>
14
+
15
+ namespace GeographicLib {
16
+
17
+ /**
18
+ * \brief Lambert conformal 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. 107--109.
25
+ *
26
+ * This is a implementation of the equations in Snyder except that divided
27
+ * differences have been used to transform the expressions into ones which
28
+ * may be evaluated accurately and that Newton's method is used to invert the
29
+ * projection. In this implementation, the projection correctly becomes the
30
+ * Mercator projection or the polar stereographic projection when the
31
+ * standard latitude is the equator or a pole. The accuracy of the
32
+ * projections is about 10 nm (10 nanometers).
33
+ *
34
+ * The ellipsoid parameters, the standard parallels, and the scale on the
35
+ * standard parallels are set in the constructor. Internally, the case with
36
+ * two standard parallels is converted into a single standard parallel, the
37
+ * latitude of tangency (also the latitude of minimum scale), with a scale
38
+ * specified on this parallel. This latitude is also used as the latitude of
39
+ * origin which is returned by LambertConformalConic::OriginLatitude. The
40
+ * scale on the latitude of origin is given by
41
+ * LambertConformalConic::CentralScale. The case with two distinct standard
42
+ * parallels where one is a pole is singular and is disallowed. The central
43
+ * meridian (which is a trivial shift of the longitude) is specified as the
44
+ * \e lon0 argument of the LambertConformalConic::Forward and
45
+ * LambertConformalConic::Reverse functions. There is no provision in this
46
+ * class for specifying a false easting or false northing or a different
47
+ * latitude of origin. However these are can be simply included by the
48
+ * calling function. For example the Pennsylvania South state coordinate
49
+ * system (<a href="http://www.spatialreference.org/ref/epsg/3364/">
50
+ * EPSG:3364</a>) is obtained by:
51
+ * \include example-LambertConformalConic.cpp
52
+ *
53
+ * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility
54
+ * providing access to the functionality of LambertConformalConic and
55
+ * AlbersEqualArea.
56
+ **********************************************************************/
57
+ class GEOGRAPHICLIB_EXPORT LambertConformalConic {
58
+ private:
59
+ typedef Math::real real;
60
+ real eps_, epsx_, ahypover_;
61
+ real _a, _f, _fm, _e2, _es;
62
+ real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0;
63
+ real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax;
64
+ static const int numit_ = 5;
65
+ static inline real hyp(real x) { return Math::hypot(real(1), x); }
66
+ // Divided differences
67
+ // Definition: Df(x,y) = (f(x)-f(y))/(x-y)
68
+ // See:
69
+ // W. M. Kahan and R. J. Fateman,
70
+ // Symbolic computation of divided differences,
71
+ // SIGSAM Bull. 33(3), 7-28 (1999)
72
+ // https://dx.doi.org/10.1145/334714.334716
73
+ // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
74
+ //
75
+ // General rules
76
+ // h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y)
77
+ // h(x) = f(x)*g(x):
78
+ // Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y)
79
+ // = Df(x,y)*g(y) + Dg(x,y)*f(x)
80
+ // = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2
81
+ //
82
+ // hyp(x) = sqrt(1+x^2): Dhyp(x,y) = (x+y)/(hyp(x)+hyp(y))
83
+ static inline real Dhyp(real x, real y, real hx, real hy)
84
+ // hx = hyp(x)
85
+ { return (x + y) / (hx + hy); }
86
+ // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^2))
87
+ static inline real Dsn(real x, real y, real sx, real sy) {
88
+ // sx = x/hyp(x)
89
+ real t = x * y;
90
+ return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) :
91
+ (x - y != 0 ? (sx - sy) / (x - y) : 1);
92
+ }
93
+ // Dlog1p(x,y) = log1p((x-y)/(1+y))/(x-y)
94
+ static inline real Dlog1p(real x, real y) {
95
+ real t = x - y; if (t < 0) { t = -t; y = x; }
96
+ return t ? Math::log1p(t / (1 + y)) / t : 1 / (1 + x);
97
+ }
98
+ // Dexp(x,y) = exp((x+y)/2) * 2*sinh((x-y)/2)/(x-y)
99
+ static inline real Dexp(real x, real y) {
100
+ using std::sinh; using std::exp;
101
+ real t = (x - y)/2;
102
+ return (t ? sinh(t)/t : 1) * exp((x + y)/2);
103
+ }
104
+ // Dsinh(x,y) = 2*sinh((x-y)/2)/(x-y) * cosh((x+y)/2)
105
+ // cosh((x+y)/2) = (c+sinh(x)*sinh(y)/c)/2
106
+ // c=sqrt((1+cosh(x))*(1+cosh(y)))
107
+ // cosh((x+y)/2) = sqrt( (sinh(x)*sinh(y) + cosh(x)*cosh(y) + 1)/2 )
108
+ static inline real Dsinh(real x, real y, real sx, real sy, real cx, real cy)
109
+ // sx = sinh(x), cx = cosh(x)
110
+ {
111
+ // real t = (x - y)/2, c = sqrt((1 + cx) * (1 + cy));
112
+ // return (t ? sinh(t)/t : real(1)) * (c + sx * sy / c) /2;
113
+ using std::sinh; using std::sqrt;
114
+ real t = (x - y)/2;
115
+ return (t ? sinh(t)/t : 1) * sqrt((sx * sy + cx * cy + 1) /2);
116
+ }
117
+ // Dasinh(x,y) = asinh((x-y)*(x+y)/(x*sqrt(1+y^2)+y*sqrt(1+x^2)))/(x-y)
118
+ // = asinh((x*sqrt(1+y^2)-y*sqrt(1+x^2)))/(x-y)
119
+ static inline real Dasinh(real x, real y, real hx, real hy) {
120
+ // hx = hyp(x)
121
+ real t = x - y;
122
+ return t ?
123
+ Math::asinh(x*y > 0 ? t * (x+y) / (x*hy + y*hx) : x*hy - y*hx) / t :
124
+ 1/hx;
125
+ }
126
+ // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
127
+ inline real Deatanhe(real x, real y) const {
128
+ real t = x - y, d = 1 - _e2 * x * y;
129
+ return t ? Math::eatanhe(t / d, _es) / t : _e2 / d;
130
+ }
131
+ void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1);
132
+ public:
133
+
134
+ /**
135
+ * Constructor with a single standard parallel.
136
+ *
137
+ * @param[in] a equatorial radius of ellipsoid (meters).
138
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
139
+ * Negative \e f gives a prolate ellipsoid.
140
+ * @param[in] stdlat standard parallel (degrees), the circle of tangency.
141
+ * @param[in] k0 scale on the standard parallel.
142
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k0 is
143
+ * not positive.
144
+ * @exception GeographicErr if \e stdlat is not in [&minus;90&deg;,
145
+ * 90&deg;].
146
+ **********************************************************************/
147
+ LambertConformalConic(real a, real f, real stdlat, real k0);
148
+
149
+ /**
150
+ * Constructor with two standard parallels.
151
+ *
152
+ * @param[in] a equatorial radius of ellipsoid (meters).
153
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
154
+ * Negative \e f gives a prolate ellipsoid.
155
+ * @param[in] stdlat1 first standard parallel (degrees).
156
+ * @param[in] stdlat2 second standard parallel (degrees).
157
+ * @param[in] k1 scale on the standard parallels.
158
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k1 is
159
+ * not positive.
160
+ * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
161
+ * [&minus;90&deg;, 90&deg;], or if either \e stdlat1 or \e
162
+ * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2.
163
+ **********************************************************************/
164
+ LambertConformalConic(real a, real f, real stdlat1, real stdlat2, real k1);
165
+
166
+ /**
167
+ * Constructor with two standard parallels specified by sines and cosines.
168
+ *
169
+ * @param[in] a equatorial radius of ellipsoid (meters).
170
+ * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
171
+ * Negative \e f gives a prolate ellipsoid.
172
+ * @param[in] sinlat1 sine of first standard parallel.
173
+ * @param[in] coslat1 cosine of first standard parallel.
174
+ * @param[in] sinlat2 sine of second standard parallel.
175
+ * @param[in] coslat2 cosine of second standard parallel.
176
+ * @param[in] k1 scale on the standard parallels.
177
+ * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k1 is
178
+ * not positive.
179
+ * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
180
+ * [&minus;90&deg;, 90&deg;], or if either \e stdlat1 or \e
181
+ * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2.
182
+ *
183
+ * This allows parallels close to the poles to be specified accurately.
184
+ * This routine computes the latitude of origin and the scale at this
185
+ * latitude. In the case where \e lat1 and \e lat2 are different, the
186
+ * errors in this routines are as follows: if \e dlat = abs(\e lat2 &minus;
187
+ * \e lat1) &le; 160&deg; and max(abs(\e lat1), abs(\e lat2)) &le; 90
188
+ * &minus; min(0.0002, 2.2 &times; 10<sup>&minus;6</sup>(180 &minus; \e
189
+ * dlat), 6 &times 10<sup>&minus;8</sup> <i>dlat</i><sup>2</sup>) (in
190
+ * degrees), then the error in the latitude of origin is less than 4.5
191
+ * &times; 10<sup>&minus;14</sup>d and the relative error in the scale is
192
+ * less than 7 &times; 10<sup>&minus;15</sup>.
193
+ **********************************************************************/
194
+ LambertConformalConic(real a, real f,
195
+ real sinlat1, real coslat1,
196
+ real sinlat2, real coslat2,
197
+ real k1);
198
+
199
+ /**
200
+ * Set the scale for the projection.
201
+ *
202
+ * @param[in] lat (degrees).
203
+ * @param[in] k scale at latitude \e lat (default 1).
204
+ * @exception GeographicErr \e k is not positive.
205
+ * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
206
+ * 90&deg;].
207
+ **********************************************************************/
208
+ void SetScale(real lat, real k = real(1));
209
+
210
+ /**
211
+ * Forward projection, from geographic to Lambert conformal conic.
212
+ *
213
+ * @param[in] lon0 central meridian longitude (degrees).
214
+ * @param[in] lat latitude of point (degrees).
215
+ * @param[in] lon longitude of point (degrees).
216
+ * @param[out] x easting of point (meters).
217
+ * @param[out] y northing of point (meters).
218
+ * @param[out] gamma meridian convergence at point (degrees).
219
+ * @param[out] k scale of projection at point.
220
+ *
221
+ * The latitude origin is given by LambertConformalConic::LatitudeOrigin().
222
+ * No false easting or northing is added and \e lat should be in the range
223
+ * [&minus;90&deg;, 90&deg;]. The error in the projection is less than
224
+ * about 10 nm (10 nanometers), true distance, and the errors in the
225
+ * meridian convergence and scale are consistent with this. The values of
226
+ * \e x and \e y returned for points which project to infinity (i.e., one
227
+ * or both of the poles) will be large but finite.
228
+ **********************************************************************/
229
+ void Forward(real lon0, real lat, real lon,
230
+ real& x, real& y, real& gamma, real& k) const;
231
+
232
+ /**
233
+ * Reverse projection, from Lambert conformal conic to geographic.
234
+ *
235
+ * @param[in] lon0 central meridian longitude (degrees).
236
+ * @param[in] x easting of point (meters).
237
+ * @param[in] y northing of point (meters).
238
+ * @param[out] lat latitude of point (degrees).
239
+ * @param[out] lon longitude of point (degrees).
240
+ * @param[out] gamma meridian convergence at point (degrees).
241
+ * @param[out] k scale of projection at point.
242
+ *
243
+ * The latitude origin is given by LambertConformalConic::LatitudeOrigin().
244
+ * No false easting or northing is added. The value of \e lon returned is
245
+ * in the range [&minus;180&deg;, 180&deg;). The error in the projection
246
+ * is less than about 10 nm (10 nanometers), true distance, and the errors
247
+ * in the meridian convergence and scale are consistent with this.
248
+ **********************************************************************/
249
+ void Reverse(real lon0, real x, real y,
250
+ real& lat, real& lon, real& gamma, real& k) const;
251
+
252
+ /**
253
+ * LambertConformalConic::Forward without returning the convergence and
254
+ * scale.
255
+ **********************************************************************/
256
+ void Forward(real lon0, real lat, real lon,
257
+ real& x, real& y) const {
258
+ real gamma, k;
259
+ Forward(lon0, lat, lon, x, y, gamma, k);
260
+ }
261
+
262
+ /**
263
+ * LambertConformalConic::Reverse without returning the convergence and
264
+ * scale.
265
+ **********************************************************************/
266
+ void Reverse(real lon0, real x, real y,
267
+ real& lat, real& lon) const {
268
+ real gamma, k;
269
+ Reverse(lon0, x, y, lat, lon, gamma, k);
270
+ }
271
+
272
+ /** \name Inspector functions
273
+ **********************************************************************/
274
+ ///@{
275
+ /**
276
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
277
+ * the value used in the constructor.
278
+ **********************************************************************/
279
+ Math::real MajorRadius() const { return _a; }
280
+
281
+ /**
282
+ * @return \e f the flattening of the ellipsoid. This is the
283
+ * value used in the constructor.
284
+ **********************************************************************/
285
+ Math::real Flattening() const { return _f; }
286
+
287
+ /**
288
+ * @return latitude of the origin for the projection (degrees).
289
+ *
290
+ * This is the latitude of minimum scale and equals the \e stdlat in the
291
+ * 1-parallel constructor and lies between \e stdlat1 and \e stdlat2 in the
292
+ * 2-parallel constructors.
293
+ **********************************************************************/
294
+ Math::real OriginLatitude() const { return _lat0; }
295
+
296
+ /**
297
+ * @return central scale for the projection. This is the scale on the
298
+ * latitude of origin.
299
+ **********************************************************************/
300
+ Math::real CentralScale() const { return _k0; }
301
+ ///@}
302
+
303
+ /**
304
+ * A global instantiation of LambertConformalConic with the WGS84
305
+ * ellipsoid, \e stdlat = 0, and \e k0 = 1. This degenerates to the
306
+ * Mercator projection.
307
+ **********************************************************************/
308
+ static const LambertConformalConic& Mercator();
309
+ };
310
+
311
+ } // namespace GeographicLib
312
+
313
+ #endif // GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP
@@ -0,0 +1,236 @@
1
+ /**
2
+ * \file LocalCartesian.hpp
3
+ * \brief Header for GeographicLib::LocalCartesian 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_LOCALCARTESIAN_HPP)
11
+ #define GEOGRAPHICLIB_LOCALCARTESIAN_HPP 1
12
+
13
+ #include <GeographicLib/Geocentric.hpp>
14
+ #include <GeographicLib/Constants.hpp>
15
+
16
+ namespace GeographicLib {
17
+
18
+ /**
19
+ * \brief Local cartesian coordinates
20
+ *
21
+ * Convert between geodetic coordinates latitude = \e lat, longitude = \e
22
+ * lon, height = \e h (measured vertically from the surface of the ellipsoid)
23
+ * to local cartesian coordinates (\e x, \e y, \e z). The origin of local
24
+ * cartesian coordinate system is at \e lat = \e lat0, \e lon = \e lon0, \e h
25
+ * = \e h0. The \e z axis is normal to the ellipsoid; the \e y axis points
26
+ * due north. The plane \e z = - \e h0 is tangent to the ellipsoid.
27
+ *
28
+ * The conversions all take place via geocentric coordinates using a
29
+ * Geocentric object (by default Geocentric::WGS84()).
30
+ *
31
+ * Example of use:
32
+ * \include example-LocalCartesian.cpp
33
+ *
34
+ * <a href="CartConvert.1.html">CartConvert</a> is a command-line utility
35
+ * providing access to the functionality of Geocentric and LocalCartesian.
36
+ **********************************************************************/
37
+
38
+ class GEOGRAPHICLIB_EXPORT LocalCartesian {
39
+ private:
40
+ typedef Math::real real;
41
+ static const size_t dim_ = 3;
42
+ static const size_t dim2_ = dim_ * dim_;
43
+ Geocentric _earth;
44
+ real _lat0, _lon0, _h0;
45
+ real _x0, _y0, _z0, _r[dim2_];
46
+ void IntForward(real lat, real lon, real h, real& x, real& y, real& z,
47
+ real M[dim2_]) const;
48
+ void IntReverse(real x, real y, real z, real& lat, real& lon, real& h,
49
+ real M[dim2_]) const;
50
+ void MatrixMultiply(real M[dim2_]) const;
51
+ public:
52
+
53
+ /**
54
+ * Constructor setting the origin.
55
+ *
56
+ * @param[in] lat0 latitude at origin (degrees).
57
+ * @param[in] lon0 longitude at origin (degrees).
58
+ * @param[in] h0 height above ellipsoid at origin (meters); default 0.
59
+ * @param[in] earth Geocentric object for the transformation; default
60
+ * Geocentric::WGS84().
61
+ *
62
+ * \e lat0 should be in the range [&minus;90&deg;, 90&deg;].
63
+ **********************************************************************/
64
+ LocalCartesian(real lat0, real lon0, real h0 = 0,
65
+ const Geocentric& earth = Geocentric::WGS84())
66
+ : _earth(earth)
67
+ { Reset(lat0, lon0, h0); }
68
+
69
+ /**
70
+ * Default constructor.
71
+ *
72
+ * @param[in] earth Geocentric object for the transformation; default
73
+ * Geocentric::WGS84().
74
+ *
75
+ * Sets \e lat0 = 0, \e lon0 = 0, \e h0 = 0.
76
+ **********************************************************************/
77
+ explicit LocalCartesian(const Geocentric& earth = Geocentric::WGS84())
78
+ : _earth(earth)
79
+ { Reset(real(0), real(0), real(0)); }
80
+
81
+ /**
82
+ * Reset the origin.
83
+ *
84
+ * @param[in] lat0 latitude at origin (degrees).
85
+ * @param[in] lon0 longitude at origin (degrees).
86
+ * @param[in] h0 height above ellipsoid at origin (meters); default 0.
87
+ *
88
+ * \e lat0 should be in the range [&minus;90&deg;, 90&deg;].
89
+ **********************************************************************/
90
+ void Reset(real lat0, real lon0, real h0 = 0);
91
+
92
+ /**
93
+ * Convert from geodetic to local cartesian coordinates.
94
+ *
95
+ * @param[in] lat latitude of point (degrees).
96
+ * @param[in] lon longitude of point (degrees).
97
+ * @param[in] h height of point above the ellipsoid (meters).
98
+ * @param[out] x local cartesian coordinate (meters).
99
+ * @param[out] y local cartesian coordinate (meters).
100
+ * @param[out] z local cartesian coordinate (meters).
101
+ *
102
+ * \e lat should be in the range [&minus;90&deg;, 90&deg;].
103
+ **********************************************************************/
104
+ void Forward(real lat, real lon, real h, real& x, real& y, real& z)
105
+ const {
106
+ IntForward(lat, lon, h, x, y, z, NULL);
107
+ }
108
+
109
+ /**
110
+ * Convert from geodetic to local cartesian coordinates and return rotation
111
+ * matrix.
112
+ *
113
+ * @param[in] lat latitude of point (degrees).
114
+ * @param[in] lon longitude of point (degrees).
115
+ * @param[in] h height of point above the ellipsoid (meters).
116
+ * @param[out] x local cartesian coordinate (meters).
117
+ * @param[out] y local cartesian coordinate (meters).
118
+ * @param[out] z local cartesian coordinate (meters).
119
+ * @param[out] M if the length of the vector is 9, fill with the rotation
120
+ * matrix in row-major order.
121
+ *
122
+ * \e lat should be in the range [&minus;90&deg;, 90&deg;].
123
+ *
124
+ * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
125
+ * express \e v as \e column vectors in one of two ways
126
+ * - in east, north, up coordinates (where the components are relative to a
127
+ * local coordinate system at (\e lat, \e lon, \e h)); call this
128
+ * representation \e v1.
129
+ * - in \e x, \e y, \e z coordinates (where the components are relative to
130
+ * the local coordinate system at (\e lat0, \e lon0, \e h0)); call this
131
+ * representation \e v0.
132
+ * .
133
+ * Then we have \e v0 = \e M &sdot; \e v1.
134
+ **********************************************************************/
135
+ void Forward(real lat, real lon, real h, real& x, real& y, real& z,
136
+ std::vector<real>& M)
137
+ const {
138
+ if (M.end() == M.begin() + dim2_) {
139
+ real t[dim2_];
140
+ IntForward(lat, lon, h, x, y, z, t);
141
+ std::copy(t, t + dim2_, M.begin());
142
+ } else
143
+ IntForward(lat, lon, h, x, y, z, NULL);
144
+ }
145
+
146
+ /**
147
+ * Convert from local cartesian to geodetic coordinates.
148
+ *
149
+ * @param[in] x local cartesian coordinate (meters).
150
+ * @param[in] y local cartesian coordinate (meters).
151
+ * @param[in] z local cartesian coordinate (meters).
152
+ * @param[out] lat latitude of point (degrees).
153
+ * @param[out] lon longitude of point (degrees).
154
+ * @param[out] h height of point above the ellipsoid (meters).
155
+ *
156
+ * The value of \e lon returned is in the range [&minus;180&deg;,
157
+ * 180&deg;).
158
+ **********************************************************************/
159
+ void Reverse(real x, real y, real z, real& lat, real& lon, real& h)
160
+ const {
161
+ IntReverse(x, y, z, lat, lon, h, NULL);
162
+ }
163
+
164
+ /**
165
+ * Convert from local cartesian to geodetic coordinates and return rotation
166
+ * matrix.
167
+ *
168
+ * @param[in] x local cartesian coordinate (meters).
169
+ * @param[in] y local cartesian coordinate (meters).
170
+ * @param[in] z local cartesian coordinate (meters).
171
+ * @param[out] lat latitude of point (degrees).
172
+ * @param[out] lon longitude of point (degrees).
173
+ * @param[out] h height of point above the ellipsoid (meters).
174
+ * @param[out] M if the length of the vector is 9, fill with the rotation
175
+ * matrix in row-major order.
176
+ *
177
+ * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
178
+ * express \e v as \e column vectors in one of two ways
179
+ * - in east, north, up coordinates (where the components are relative to a
180
+ * local coordinate system at (\e lat, \e lon, \e h)); call this
181
+ * representation \e v1.
182
+ * - in \e x, \e y, \e z coordinates (where the components are relative to
183
+ * the local coordinate system at (\e lat0, \e lon0, \e h0)); call this
184
+ * representation \e v0.
185
+ * .
186
+ * Then we have \e v1 = <i>M</i><sup>T</sup> &sdot; \e v0, where
187
+ * <i>M</i><sup>T</sup> is the transpose of \e M.
188
+ **********************************************************************/
189
+ void Reverse(real x, real y, real z, real& lat, real& lon, real& h,
190
+ std::vector<real>& M)
191
+ const {
192
+ if (M.end() == M.begin() + dim2_) {
193
+ real t[dim2_];
194
+ IntReverse(x, y, z, lat, lon, h, t);
195
+ std::copy(t, t + dim2_, M.begin());
196
+ } else
197
+ IntReverse(x, y, z, lat, lon, h, NULL);
198
+ }
199
+
200
+ /** \name Inspector functions
201
+ **********************************************************************/
202
+ ///@{
203
+ /**
204
+ * @return latitude of the origin (degrees).
205
+ **********************************************************************/
206
+ Math::real LatitudeOrigin() const { return _lat0; }
207
+
208
+ /**
209
+ * @return longitude of the origin (degrees).
210
+ **********************************************************************/
211
+ Math::real LongitudeOrigin() const { return _lon0; }
212
+
213
+ /**
214
+ * @return height of the origin (meters).
215
+ **********************************************************************/
216
+ Math::real HeightOrigin() const { return _h0; }
217
+
218
+ /**
219
+ * @return \e a the equatorial radius of the ellipsoid (meters). This is
220
+ * the value of \e a inherited from the Geocentric object used in the
221
+ * constructor.
222
+ **********************************************************************/
223
+ Math::real MajorRadius() const { return _earth.MajorRadius(); }
224
+
225
+ /**
226
+ * @return \e f the flattening of the ellipsoid. This is the value
227
+ * inherited from the Geocentric object used in the constructor.
228
+ **********************************************************************/
229
+ Math::real Flattening() const { return _earth.Flattening(); }
230
+ ///@}
231
+
232
+ };
233
+
234
+ } // namespace GeographicLib
235
+
236
+ #endif // GEOGRAPHICLIB_LOCALCARTESIAN_HPP