GeographicLib  2.1.1
LocalCartesian.hpp
Go to the documentation of this file.
1 /**
2  * \file LocalCartesian.hpp
3  * \brief Header for GeographicLib::LocalCartesian class
4  *
5  * Copyright (c) Charles Karney (2008-2022) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * https://geographiclib.sourceforge.io/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_LOCALCARTESIAN_HPP)
11 #define GEOGRAPHICLIB_LOCALCARTESIAN_HPP 1
12 
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 
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  * In general, there are multiple solutions and the result which minimizes
157  * |<i>h</i> |is returned, i.e., (<i>lat</i>, <i>lon</i>) corresponds to
158  * the closest point on the ellipsoid. The value of \e lon returned is in
159  * the range [&minus;180&deg;, 180&deg;].
160  **********************************************************************/
161  void Reverse(real x, real y, real z, real& lat, real& lon, real& h)
162  const {
163  IntReverse(x, y, z, lat, lon, h, NULL);
164  }
165 
166  /**
167  * Convert from local cartesian to geodetic coordinates and return rotation
168  * matrix.
169  *
170  * @param[in] x local cartesian coordinate (meters).
171  * @param[in] y local cartesian coordinate (meters).
172  * @param[in] z local cartesian coordinate (meters).
173  * @param[out] lat latitude of point (degrees).
174  * @param[out] lon longitude of point (degrees).
175  * @param[out] h height of point above the ellipsoid (meters).
176  * @param[out] M if the length of the vector is 9, fill with the rotation
177  * matrix in row-major order.
178  *
179  * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
180  * express \e v as \e column vectors in one of two ways
181  * - in east, north, up coordinates (where the components are relative to a
182  * local coordinate system at (\e lat, \e lon, \e h)); call this
183  * representation \e v1.
184  * - in \e x, \e y, \e z coordinates (where the components are relative to
185  * the local coordinate system at (\e lat0, \e lon0, \e h0)); call this
186  * representation \e v0.
187  * .
188  * Then we have \e v1 = <i>M</i><sup>T</sup> &sdot; \e v0, where
189  * <i>M</i><sup>T</sup> is the transpose of \e M.
190  **********************************************************************/
191  void Reverse(real x, real y, real z, real& lat, real& lon, real& h,
192  std::vector<real>& M)
193  const {
194  if (M.end() == M.begin() + dim2_) {
195  real t[dim2_];
196  IntReverse(x, y, z, lat, lon, h, t);
197  std::copy(t, t + dim2_, M.begin());
198  } else
199  IntReverse(x, y, z, lat, lon, h, NULL);
200  }
201 
202  /** \name Inspector functions
203  **********************************************************************/
204  ///@{
205  /**
206  * @return latitude of the origin (degrees).
207  **********************************************************************/
208  Math::real LatitudeOrigin() const { return _lat0; }
209 
210  /**
211  * @return longitude of the origin (degrees).
212  **********************************************************************/
213  Math::real LongitudeOrigin() const { return _lon0; }
214 
215  /**
216  * @return height of the origin (meters).
217  **********************************************************************/
218  Math::real HeightOrigin() const { return _h0; }
219 
220  /**
221  * @return \e a the equatorial radius of the ellipsoid (meters). This is
222  * the value of \e a inherited from the Geocentric object used in the
223  * constructor.
224  **********************************************************************/
225  Math::real EquatorialRadius() const { return _earth.EquatorialRadius(); }
226 
227  /**
228  * @return \e f the flattening of the ellipsoid. This is the value
229  * inherited from the Geocentric object used in the constructor.
230  **********************************************************************/
231  Math::real Flattening() const { return _earth.Flattening(); }
232  ///@}
233 
234  };
235 
236 } // namespace GeographicLib
237 
238 #endif // GEOGRAPHICLIB_LOCALCARTESIAN_HPP
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
Header for GeographicLib::Geocentric class.
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
Geocentric coordinates
Definition: Geocentric.hpp:67
Math::real Flattening() const
Definition: Geocentric.hpp:255
Math::real EquatorialRadius() const
Definition: Geocentric.hpp:248
static const Geocentric & WGS84()
Definition: Geocentric.cpp:31
Local cartesian coordinates.
void Reverse(real x, real y, real z, real &lat, real &lon, real &h) const
void Forward(real lat, real lon, real h, real &x, real &y, real &z, std::vector< real > &M) const
Math::real LatitudeOrigin() const
void Reverse(real x, real y, real z, real &lat, real &lon, real &h, std::vector< real > &M) const
void Forward(real lat, real lon, real h, real &x, real &y, real &z) const
LocalCartesian(real lat0, real lon0, real h0=0, const Geocentric &earth=Geocentric::WGS84())
Math::real LongitudeOrigin() const
Math::real EquatorialRadius() const
LocalCartesian(const Geocentric &earth=Geocentric::WGS84())
Namespace for GeographicLib.
Definition: Accumulator.cpp:12