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.
- checksums.yaml +7 -0
- data/AUTHORS +12 -0
- data/LICENSE +24 -0
- data/ext/geographiclib/Accumulator.cpp +23 -0
- data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
- data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
- data/ext/geographiclib/CassiniSoldner.cpp +89 -0
- data/ext/geographiclib/CircularEngine.cpp +96 -0
- data/ext/geographiclib/DMS.cpp +381 -0
- data/ext/geographiclib/Ellipsoid.cpp +125 -0
- data/ext/geographiclib/EllipticFunction.cpp +512 -0
- data/ext/geographiclib/GARS.cpp +122 -0
- data/ext/geographiclib/GeoCoords.cpp +175 -0
- data/ext/geographiclib/Geocentric.cpp +172 -0
- data/ext/geographiclib/Geodesic.cpp +1908 -0
- data/ext/geographiclib/GeodesicExact.cpp +927 -0
- data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
- data/ext/geographiclib/GeodesicLine.cpp +321 -0
- data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
- data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
- data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
- data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
- data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
- data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
- data/ext/geographiclib/GeographicLib/Config.h +12 -0
- data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
- data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
- data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
- data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
- data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
- data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
- data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
- data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
- data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
- data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
- data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
- data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
- data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
- data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
- data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
- data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
- data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
- data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
- data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
- data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
- data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
- data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
- data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
- data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
- data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
- data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
- data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
- data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
- data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
- data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
- data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
- data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
- data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
- data/ext/geographiclib/Geohash.cpp +102 -0
- data/ext/geographiclib/Geoid.cpp +509 -0
- data/ext/geographiclib/Georef.cpp +135 -0
- data/ext/geographiclib/Gnomonic.cpp +85 -0
- data/ext/geographiclib/GravityCircle.cpp +129 -0
- data/ext/geographiclib/GravityModel.cpp +360 -0
- data/ext/geographiclib/LambertConformalConic.cpp +456 -0
- data/ext/geographiclib/LocalCartesian.cpp +62 -0
- data/ext/geographiclib/MGRS.cpp +461 -0
- data/ext/geographiclib/MagneticCircle.cpp +52 -0
- data/ext/geographiclib/MagneticModel.cpp +269 -0
- data/ext/geographiclib/Math.cpp +63 -0
- data/ext/geographiclib/NormalGravity.cpp +262 -0
- data/ext/geographiclib/OSGB.cpp +167 -0
- data/ext/geographiclib/PolarStereographic.cpp +108 -0
- data/ext/geographiclib/PolygonArea.cpp +204 -0
- data/ext/geographiclib/Rhumb.cpp +383 -0
- data/ext/geographiclib/SphericalEngine.cpp +477 -0
- data/ext/geographiclib/TransverseMercator.cpp +603 -0
- data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
- data/ext/geographiclib/UTMUPS.cpp +296 -0
- data/ext/geographiclib/Utility.cpp +61 -0
- data/ext/geographiclib/extconf.rb +3 -0
- data/ext/geographiclib/geographiclib.cpp +62 -0
- data/lib/geographiclib.rb +20 -0
- 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 − \e f) \e a, or \e k0 is
|
|
143
|
+
* not positive.
|
|
144
|
+
* @exception GeographicErr if \e stdlat is not in [−90°,
|
|
145
|
+
* 90°].
|
|
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 − \e f) \e a, or \e k1 is
|
|
159
|
+
* not positive.
|
|
160
|
+
* @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
|
|
161
|
+
* [−90°, 90°], 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 − \e f) \e a, or \e k1 is
|
|
178
|
+
* not positive.
|
|
179
|
+
* @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
|
|
180
|
+
* [−90°, 90°], 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 −
|
|
187
|
+
* \e lat1) ≤ 160° and max(abs(\e lat1), abs(\e lat2)) ≤ 90
|
|
188
|
+
* − min(0.0002, 2.2 × 10<sup>−6</sup>(180 − \e
|
|
189
|
+
* dlat), 6 × 10<sup>−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
|
+
* × 10<sup>−14</sup>d and the relative error in the scale is
|
|
192
|
+
* less than 7 × 10<sup>−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 [−90°,
|
|
206
|
+
* 90°].
|
|
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
|
+
* [−90°, 90°]. 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 [−180°, 180°). 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 [−90°, 90°].
|
|
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 [−90°, 90°].
|
|
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 [−90°, 90°].
|
|
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 [−90°, 90°].
|
|
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 ⋅ \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 [−180°,
|
|
157
|
+
* 180°).
|
|
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> ⋅ \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
|