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