]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGGeod.hxx
Mathias Fröhlich:
[simgear.git] / simgear / math / SGGeod.hxx
1 #ifndef SGGeod_H
2 #define SGGeod_H
3
4 #include <simgear/constants.h>
5
6 // #define SG_GEOD_NATIVE_DEGREE
7
8 /// Class representing a geodetic location
9 class SGGeod {
10 public:
11   /// Default constructor, initializes the instance to lat = lon = elev = 0
12   SGGeod(void);
13   /// Initialize from a cartesian vector assumed to be in meters
14   /// Note that this conversion is relatively expensive to compute
15   SGGeod(const SGVec3<double>& cart);
16   /// Initialize from a geocentric position
17   /// Note that this conversion is relatively expensive to compute
18   SGGeod(const SGGeoc& geoc);
19
20   /// Factory from angular values in radians and elevation is 0
21   static SGGeod fromRad(double lon, double lat);
22   /// Factory from angular values in degrees and elevation is 0
23   static SGGeod fromDeg(double lon, double lat);
24   /// Factory from angular values in radians and elevation in ft
25   static SGGeod fromRadFt(double lon, double lat, double elevation);
26   /// Factory from angular values in degrees and elevation in ft
27   static SGGeod fromDegFt(double lon, double lat, double elevation);
28   /// Factory from angular values in radians and elevation in m
29   static SGGeod fromRadM(double lon, double lat, double elevation);
30   /// Factory from angular values in degrees and elevation in m
31   static SGGeod fromDegM(double lon, double lat, double elevation);
32
33   /// Return the geodetic longitude in radians
34   double getLongitudeRad(void) const;
35   /// Set the geodetic longitude from the argument given in radians
36   void setLongitudeRad(double lon);
37
38   /// Return the geodetic longitude in degrees
39   double getLongitudeDeg(void) const;
40   /// Set the geodetic longitude from the argument given in degrees
41   void setLongitudeDeg(double lon);
42
43   /// Return the geodetic latitude in radians
44   double getLatitudeRad(void) const;
45   /// Set the geodetic latitude from the argument given in radians
46   void setLatitudeRad(double lat);
47
48   /// Return the geodetic latitude in degrees
49   double getLatitudeDeg(void) const;
50   /// Set the geodetic latitude from the argument given in degrees
51   void setLatitudeDeg(double lat);
52
53   /// Return the geodetic elevation in meters
54   double getElevationM(void) const;
55   /// Set the geodetic elevation from the argument given in meters
56   void setElevationM(double elevation);
57
58   /// Return the geodetic elevation in feet
59   double getElevationFt(void) const;
60   /// Set the geodetic elevation from the argument given in feet
61   void setElevationFt(double elevation);
62
63 private:
64   /// This one is private since construction is not unique if you do
65   /// not know the units of the arguments. Use the factory methods for
66   /// that purpose
67   SGGeod(double lon, double lat, double elevation);
68
69   /// The actual data, angles in degree, elevation in meters
70   /// The rationale for storing the values in degrees is that most code places
71   /// in flightgear/terragear use degrees as a nativ input and output value.
72   /// The places where it makes sense to use radians is when we convert
73   /// to other representations or compute rotation matrices. But both tasks
74   /// are computionally intensive anyway and that additional 'toRadian'
75   /// conversion does not hurt too much
76   double _lon;
77   double _lat;
78   double _elevation;
79 };
80
81 inline
82 SGGeod::SGGeod(void) :
83   _lon(0), _lat(0), _elevation(0)
84 {
85 }
86
87 inline
88 SGGeod::SGGeod(double lon, double lat, double elevation) :
89   _lon(lon), _lat(lat), _elevation(elevation)
90 {
91 }
92
93 inline
94 SGGeod::SGGeod(const SGVec3<double>& cart)
95 {
96   SGGeodesy::SGCartToGeod(cart, *this);
97 }
98
99 inline
100 SGGeod::SGGeod(const SGGeoc& geoc)
101 {
102   SGVec3<double> cart;
103   SGGeodesy::SGGeocToCart(geoc, cart);
104   SGGeodesy::SGCartToGeod(cart, *this);
105 }
106
107 inline
108 SGGeod
109 SGGeod::fromRad(double lon, double lat)
110 {
111 #ifdef SG_GEOD_NATIVE_DEGREE
112   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES, 0);
113 #else
114   return SGGeod(lon, lat, 0);
115 #endif
116 }
117
118 inline
119 SGGeod
120 SGGeod::fromDeg(double lon, double lat)
121 {
122 #ifdef SG_GEOD_NATIVE_DEGREE
123   return SGGeod(lon, lat, 0);
124 #else
125   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0);
126 #endif
127 }
128
129 inline
130 SGGeod
131 SGGeod::fromRadFt(double lon, double lat, double elevation)
132 {
133 #ifdef SG_GEOD_NATIVE_DEGREE
134   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
135                 elevation*SG_FEET_TO_METER);
136 #else
137   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
138 #endif
139 }
140
141 inline
142 SGGeod
143 SGGeod::fromDegFt(double lon, double lat, double elevation)
144 {
145 #ifdef SG_GEOD_NATIVE_DEGREE
146   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
147 #else
148   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
149                 elevation*SG_FEET_TO_METER);
150 #endif
151 }
152
153 inline
154 SGGeod
155 SGGeod::fromRadM(double lon, double lat, double elevation)
156 {
157 #ifdef SG_GEOD_NATIVE_DEGREE
158   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
159                 elevation);
160 #else
161   return SGGeod(lon, lat, elevation);
162 #endif
163 }
164
165 inline
166 SGGeod
167 SGGeod::fromDegM(double lon, double lat, double elevation)
168 {
169 #ifdef SG_GEOD_NATIVE_DEGREE
170   return SGGeod(lon, lat, elevation);
171 #else
172   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
173                 elevation);
174 #endif
175 }
176
177 inline
178 double
179 SGGeod::getLongitudeRad(void) const
180 {
181 #ifdef SG_GEOD_NATIVE_DEGREE
182   return _lon*SGD_DEGREES_TO_RADIANS;
183 #else
184   return _lon;
185 #endif
186 }
187
188 inline
189 void
190 SGGeod::setLongitudeRad(double lon)
191 {
192 #ifdef SG_GEOD_NATIVE_DEGREE
193   _lon = lon*SGD_RADIANS_TO_DEGREES;
194 #else
195   _lon = lon;
196 #endif
197 }
198
199 inline
200 double
201 SGGeod::getLongitudeDeg(void) const
202 {
203 #ifdef SG_GEOD_NATIVE_DEGREE
204   return _lon;
205 #else
206   return _lon*SGD_RADIANS_TO_DEGREES;
207 #endif
208 }
209
210 inline
211 void
212 SGGeod::setLongitudeDeg(double lon)
213 {
214 #ifdef SG_GEOD_NATIVE_DEGREE
215   _lon = lon;
216 #else
217   _lon = lon*SGD_DEGREES_TO_RADIANS;
218 #endif
219 }
220
221 inline
222 double
223 SGGeod::getLatitudeRad(void) const
224 {
225 #ifdef SG_GEOD_NATIVE_DEGREE
226   return _lat*SGD_DEGREES_TO_RADIANS;
227 #else
228   return _lat;
229 #endif
230 }
231
232 inline
233 void
234 SGGeod::setLatitudeRad(double lat)
235 {
236 #ifdef SG_GEOD_NATIVE_DEGREE
237   _lat = lat*SGD_RADIANS_TO_DEGREES;
238 #else
239   _lat = lat;
240 #endif
241 }
242
243 inline
244 double
245 SGGeod::getLatitudeDeg(void) const
246 {
247 #ifdef SG_GEOD_NATIVE_DEGREE
248   return _lat;
249 #else
250   return _lat*SGD_RADIANS_TO_DEGREES;
251 #endif
252 }
253
254 inline
255 void
256 SGGeod::setLatitudeDeg(double lat)
257 {
258 #ifdef SG_GEOD_NATIVE_DEGREE
259   _lat = lat;
260 #else
261   _lat = lat*SGD_DEGREES_TO_RADIANS;
262 #endif
263 }
264
265 inline
266 double
267 SGGeod::getElevationM(void) const
268 {
269   return _elevation;
270 }
271
272 inline
273 void
274 SGGeod::setElevationM(double elevation)
275 {
276   _elevation = elevation;
277 }
278
279 inline
280 double
281 SGGeod::getElevationFt(void) const
282 {
283   return _elevation*SG_METER_TO_FEET;
284 }
285
286 inline
287 void
288 SGGeod::setElevationFt(double elevation)
289 {
290   _elevation = elevation*SG_FEET_TO_METER;
291 }
292
293 /// Output to an ostream
294 template<typename char_type, typename traits_type>
295 inline
296 std::basic_ostream<char_type, traits_type>&
297 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeod& g)
298 {
299   return s << "lon = " << g.getLongitudeDeg()
300            << "deg, lat = " << g.getLatitudeDeg()
301            << "deg, elev = " << g.getElevationM()
302            << "m";
303 }
304
305 #endif