]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGGeod.hxx
Boolean uniforms are now updatable by properties
[simgear.git] / simgear / math / SGGeod.hxx
1 // Copyright (C) 2006  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef SGGeod_H
19 #define SGGeod_H
20
21 #include <simgear/constants.h>
22
23 // #define SG_GEOD_NATIVE_DEGREE
24
25 /// Class representing a geodetic location
26 class SGGeod {
27 public:
28   /// Default constructor, initializes the instance to lat = lon = elev = 0
29   SGGeod(void);
30
31   /// Factory from angular values in radians and elevation is 0
32   static SGGeod fromRad(double lon, double lat);
33   /// Factory from angular values in degrees and elevation is 0
34   static SGGeod fromDeg(double lon, double lat);
35   /// Factory from angular values in radians and elevation in ft
36   static SGGeod fromRadFt(double lon, double lat, double elevation);
37   /// Factory from angular values in degrees and elevation in ft
38   static SGGeod fromDegFt(double lon, double lat, double elevation);
39   /// Factory from angular values in radians and elevation in m
40   static SGGeod fromRadM(double lon, double lat, double elevation);
41   /// Factory from angular values in degrees and elevation in m
42   static SGGeod fromDegM(double lon, double lat, double elevation);
43   /// Factory from an other SGGeod and a different elevation in m
44   static SGGeod fromGeodM(const SGGeod& geod, double elevation);
45   /// Factory from an other SGGeod and a different elevation in ft
46   static SGGeod fromGeodFt(const SGGeod& geod, double elevation);
47   /// Factory to convert position from a cartesian position assumed to be
48   /// in wgs84 measured in meters
49   /// Note that this conversion is relatively expensive to compute
50   static SGGeod fromCart(const SGVec3<double>& cart);
51   /// Factory to convert position from a geocentric position
52   /// Note that this conversion is relatively expensive to compute
53   static SGGeod fromGeoc(const SGGeoc& geoc);
54
55   /// Return the geodetic longitude in radians
56   double getLongitudeRad(void) const;
57   /// Set the geodetic longitude from the argument given in radians
58   void setLongitudeRad(double lon);
59
60   /// Return the geodetic longitude in degrees
61   double getLongitudeDeg(void) const;
62   /// Set the geodetic longitude from the argument given in degrees
63   void setLongitudeDeg(double lon);
64
65   /// Return the geodetic latitude in radians
66   double getLatitudeRad(void) const;
67   /// Set the geodetic latitude from the argument given in radians
68   void setLatitudeRad(double lat);
69
70   /// Return the geodetic latitude in degrees
71   double getLatitudeDeg(void) const;
72   /// Set the geodetic latitude from the argument given in degrees
73   void setLatitudeDeg(double lat);
74
75   /// Return the geodetic elevation in meters
76   double getElevationM(void) const;
77   /// Set the geodetic elevation from the argument given in meters
78   void setElevationM(double elevation);
79
80   /// Return the geodetic elevation in feet
81   double getElevationFt(void) const;
82   /// Set the geodetic elevation from the argument given in feet
83   void setElevationFt(double elevation);
84
85   // Compare two geodetic positions for equality
86   bool operator == ( const SGGeod & other ) const;
87
88 private:
89   /// This one is private since construction is not unique if you do
90   /// not know the units of the arguments. Use the factory methods for
91   /// that purpose
92   SGGeod(double lon, double lat, double elevation);
93
94   //// FIXME: wrong comment!
95   /// The actual data, angles in degrees, elevation in meters
96   /// The rationale for storing the values in degrees is that most code places
97   /// in flightgear/terragear use degrees as a nativ input and output value.
98   /// The places where it makes sense to use radians is when we convert
99   /// to other representations or compute rotation matrices. But both tasks
100   /// are computionally intensive anyway and that additional 'toRadian'
101   /// conversion does not hurt too much
102   double _lon;
103   double _lat;
104   double _elevation;
105 };
106
107 inline
108 SGGeod::SGGeod(void) :
109   _lon(0), _lat(0), _elevation(0)
110 {
111 }
112
113 inline
114 SGGeod::SGGeod(double lon, double lat, double elevation) :
115   _lon(lon), _lat(lat), _elevation(elevation)
116 {
117 }
118
119 inline
120 SGGeod
121 SGGeod::fromRad(double lon, double lat)
122 {
123 #ifdef SG_GEOD_NATIVE_DEGREE
124   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES, 0);
125 #else
126   return SGGeod(lon, lat, 0);
127 #endif
128 }
129
130 inline
131 SGGeod
132 SGGeod::fromDeg(double lon, double lat)
133 {
134 #ifdef SG_GEOD_NATIVE_DEGREE
135   return SGGeod(lon, lat, 0);
136 #else
137   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0);
138 #endif
139 }
140
141 inline
142 SGGeod
143 SGGeod::fromRadFt(double lon, double lat, double elevation)
144 {
145 #ifdef SG_GEOD_NATIVE_DEGREE
146   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
147                 elevation*SG_FEET_TO_METER);
148 #else
149   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
150 #endif
151 }
152
153 inline
154 SGGeod
155 SGGeod::fromDegFt(double lon, double lat, double elevation)
156 {
157 #ifdef SG_GEOD_NATIVE_DEGREE
158   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
159 #else
160   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
161                 elevation*SG_FEET_TO_METER);
162 #endif
163 }
164
165 inline
166 SGGeod
167 SGGeod::fromRadM(double lon, double lat, double elevation)
168 {
169 #ifdef SG_GEOD_NATIVE_DEGREE
170   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
171                 elevation);
172 #else
173   return SGGeod(lon, lat, elevation);
174 #endif
175 }
176
177 inline
178 SGGeod
179 SGGeod::fromDegM(double lon, double lat, double elevation)
180 {
181 #ifdef SG_GEOD_NATIVE_DEGREE
182   return SGGeod(lon, lat, elevation);
183 #else
184   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
185                 elevation);
186 #endif
187 }
188
189 inline
190 SGGeod
191 SGGeod::fromGeodM(const SGGeod& geod, double elevation)
192 {
193   return SGGeod(geod._lon, geod._lat, elevation);
194 }
195
196 inline
197 SGGeod
198 SGGeod::fromGeodFt(const SGGeod& geod, double elevation)
199 {
200   return SGGeod(geod._lon, geod._lat, elevation*SG_FEET_TO_METER);
201 }
202
203 inline
204 SGGeod
205 SGGeod::fromCart(const SGVec3<double>& cart)
206 {
207   SGGeod geod;
208   SGGeodesy::SGCartToGeod(cart, geod);
209   return geod;
210 }
211
212 inline
213 SGGeod
214 SGGeod::fromGeoc(const SGGeoc& geoc)
215 {
216   SGVec3<double> cart;
217   SGGeodesy::SGGeocToCart(geoc, cart);
218   SGGeod geod;
219   SGGeodesy::SGCartToGeod(cart, geod);
220   return geod;
221 }
222
223 inline
224 double
225 SGGeod::getLongitudeRad(void) const
226 {
227 #ifdef SG_GEOD_NATIVE_DEGREE
228   return _lon*SGD_DEGREES_TO_RADIANS;
229 #else
230   return _lon;
231 #endif
232 }
233
234 inline
235 void
236 SGGeod::setLongitudeRad(double lon)
237 {
238 #ifdef SG_GEOD_NATIVE_DEGREE
239   _lon = lon*SGD_RADIANS_TO_DEGREES;
240 #else
241   _lon = lon;
242 #endif
243 }
244
245 inline
246 double
247 SGGeod::getLongitudeDeg(void) const
248 {
249 #ifdef SG_GEOD_NATIVE_DEGREE
250   return _lon;
251 #else
252   return _lon*SGD_RADIANS_TO_DEGREES;
253 #endif
254 }
255
256 inline
257 void
258 SGGeod::setLongitudeDeg(double lon)
259 {
260 #ifdef SG_GEOD_NATIVE_DEGREE
261   _lon = lon;
262 #else
263   _lon = lon*SGD_DEGREES_TO_RADIANS;
264 #endif
265 }
266
267 inline
268 double
269 SGGeod::getLatitudeRad(void) const
270 {
271 #ifdef SG_GEOD_NATIVE_DEGREE
272   return _lat*SGD_DEGREES_TO_RADIANS;
273 #else
274   return _lat;
275 #endif
276 }
277
278 inline
279 void
280 SGGeod::setLatitudeRad(double lat)
281 {
282 #ifdef SG_GEOD_NATIVE_DEGREE
283   _lat = lat*SGD_RADIANS_TO_DEGREES;
284 #else
285   _lat = lat;
286 #endif
287 }
288
289 inline
290 double
291 SGGeod::getLatitudeDeg(void) const
292 {
293 #ifdef SG_GEOD_NATIVE_DEGREE
294   return _lat;
295 #else
296   return _lat*SGD_RADIANS_TO_DEGREES;
297 #endif
298 }
299
300 inline
301 void
302 SGGeod::setLatitudeDeg(double lat)
303 {
304 #ifdef SG_GEOD_NATIVE_DEGREE
305   _lat = lat;
306 #else
307   _lat = lat*SGD_DEGREES_TO_RADIANS;
308 #endif
309 }
310
311 inline
312 double
313 SGGeod::getElevationM(void) const
314 {
315   return _elevation;
316 }
317
318 inline
319 void
320 SGGeod::setElevationM(double elevation)
321 {
322   _elevation = elevation;
323 }
324
325 inline
326 double
327 SGGeod::getElevationFt(void) const
328 {
329   return _elevation*SG_METER_TO_FEET;
330 }
331
332 inline
333 void
334 SGGeod::setElevationFt(double elevation)
335 {
336   _elevation = elevation*SG_FEET_TO_METER;
337 }
338
339 inline
340 bool
341 SGGeod::operator == ( const SGGeod & other ) const
342 {
343   return _lon == other._lon &&
344          _lat == other._lat &&
345          _elevation == other._elevation;
346 }
347
348 /// Output to an ostream
349 template<typename char_type, typename traits_type>
350 inline
351 std::basic_ostream<char_type, traits_type>&
352 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeod& g)
353 {
354   return s << "lon = " << g.getLongitudeDeg()
355            << "deg, lat = " << g.getLatitudeDeg()
356            << "deg, elev = " << g.getElevationM()
357            << "m";
358 }
359
360 #endif