]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGGeod.hxx
Add project.* to MSVC project files
[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 #ifndef NO_OPENSCENEGRAPH_INTERFACE
24 #include <osg/Matrix>
25 #endif
26
27 // #define SG_GEOD_NATIVE_DEGREE
28
29 /// Class representing a geodetic location
30 class SGGeod {
31 public:
32   /// Default constructor, initializes the instance to lat = lon = elev = 0
33   SGGeod(void);
34
35   /// Factory from angular values in radians and elevation is 0
36   static SGGeod fromRad(double lon, double lat);
37   /// Factory from angular values in degrees and elevation is 0
38   static SGGeod fromDeg(double lon, double lat);
39   /// Factory from angular values in radians and elevation in ft
40   static SGGeod fromRadFt(double lon, double lat, double elevation);
41   /// Factory from angular values in degrees and elevation in ft
42   static SGGeod fromDegFt(double lon, double lat, double elevation);
43   /// Factory from angular values in radians and elevation in m
44   static SGGeod fromRadM(double lon, double lat, double elevation);
45   /// Factory from angular values in degrees and elevation in m
46   static SGGeod fromDegM(double lon, double lat, double elevation);
47   /// Factory from an other SGGeod and a different elevation in m
48   static SGGeod fromGeodM(const SGGeod& geod, double elevation);
49   /// Factory from an other SGGeod and a different elevation in ft
50   static SGGeod fromGeodFt(const SGGeod& geod, double elevation);
51   /// Factory to convert position from a cartesian position assumed to be
52   /// in wgs84 measured in meters
53   /// Note that this conversion is relatively expensive to compute
54   static SGGeod fromCart(const SGVec3<double>& cart);
55   /// Factory to convert position from a geocentric position
56   /// Note that this conversion is relatively expensive to compute
57   static SGGeod fromGeoc(const SGGeoc& geoc);
58
59   /// Return the geodetic longitude in radians
60   double getLongitudeRad(void) const;
61   /// Set the geodetic longitude from the argument given in radians
62   void setLongitudeRad(double lon);
63
64   /// Return the geodetic longitude in degrees
65   double getLongitudeDeg(void) const;
66   /// Set the geodetic longitude from the argument given in degrees
67   void setLongitudeDeg(double lon);
68
69   /// Return the geodetic latitude in radians
70   double getLatitudeRad(void) const;
71   /// Set the geodetic latitude from the argument given in radians
72   void setLatitudeRad(double lat);
73
74   /// Return the geodetic latitude in degrees
75   double getLatitudeDeg(void) const;
76   /// Set the geodetic latitude from the argument given in degrees
77   void setLatitudeDeg(double lat);
78
79   /// Return the geodetic elevation in meters
80   double getElevationM(void) const;
81   /// Set the geodetic elevation from the argument given in meters
82   void setElevationM(double elevation);
83
84   /// Return the geodetic elevation in feet
85   double getElevationFt(void) const;
86   /// Set the geodetic elevation from the argument given in feet
87   void setElevationFt(double elevation);
88
89   // Compare two geodetic positions for equality
90   bool operator == ( const SGGeod & other ) const;
91
92 #ifndef NO_OPENSCENEGRAPH_INTERFACE
93   // Create a local coordinate frame in the earth-centered frame of
94   // reference. X points north, Z points down.
95   // makeSimulationFrameRelative() only includes rotation.
96   osg::Matrix makeSimulationFrameRelative() const;
97   osg::Matrix makeSimulationFrame() const;
98
99   // Create a Z-up local coordinate frame in the earth-centered frame
100   // of reference. This is what scenery models, etc. expect.
101   // makeZUpFrameRelative() only includes rotation.
102   osg::Matrix makeZUpFrameRelative() const;
103   osg::Matrix makeZUpFrame() const;
104 #endif
105 private:
106   /// This one is private since construction is not unique if you do
107   /// not know the units of the arguments. Use the factory methods for
108   /// that purpose
109   SGGeod(double lon, double lat, double elevation);
110
111   //// FIXME: wrong comment!
112   /// The actual data, angles in degrees, elevation in meters
113   /// The rationale for storing the values in degrees is that most code places
114   /// in flightgear/terragear use degrees as a nativ input and output value.
115   /// The places where it makes sense to use radians is when we convert
116   /// to other representations or compute rotation matrices. But both tasks
117   /// are computionally intensive anyway and that additional 'toRadian'
118   /// conversion does not hurt too much
119   double _lon;
120   double _lat;
121   double _elevation;
122 };
123
124 inline
125 SGGeod::SGGeod(void) :
126   _lon(0), _lat(0), _elevation(0)
127 {
128 }
129
130 inline
131 SGGeod::SGGeod(double lon, double lat, double elevation) :
132   _lon(lon), _lat(lat), _elevation(elevation)
133 {
134 }
135
136 inline
137 SGGeod
138 SGGeod::fromRad(double lon, double lat)
139 {
140 #ifdef SG_GEOD_NATIVE_DEGREE
141   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES, 0);
142 #else
143   return SGGeod(lon, lat, 0);
144 #endif
145 }
146
147 inline
148 SGGeod
149 SGGeod::fromDeg(double lon, double lat)
150 {
151 #ifdef SG_GEOD_NATIVE_DEGREE
152   return SGGeod(lon, lat, 0);
153 #else
154   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0);
155 #endif
156 }
157
158 inline
159 SGGeod
160 SGGeod::fromRadFt(double lon, double lat, double elevation)
161 {
162 #ifdef SG_GEOD_NATIVE_DEGREE
163   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
164                 elevation*SG_FEET_TO_METER);
165 #else
166   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
167 #endif
168 }
169
170 inline
171 SGGeod
172 SGGeod::fromDegFt(double lon, double lat, double elevation)
173 {
174 #ifdef SG_GEOD_NATIVE_DEGREE
175   return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
176 #else
177   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
178                 elevation*SG_FEET_TO_METER);
179 #endif
180 }
181
182 inline
183 SGGeod
184 SGGeod::fromRadM(double lon, double lat, double elevation)
185 {
186 #ifdef SG_GEOD_NATIVE_DEGREE
187   return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
188                 elevation);
189 #else
190   return SGGeod(lon, lat, elevation);
191 #endif
192 }
193
194 inline
195 SGGeod
196 SGGeod::fromDegM(double lon, double lat, double elevation)
197 {
198 #ifdef SG_GEOD_NATIVE_DEGREE
199   return SGGeod(lon, lat, elevation);
200 #else
201   return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
202                 elevation);
203 #endif
204 }
205
206 inline
207 SGGeod
208 SGGeod::fromGeodM(const SGGeod& geod, double elevation)
209 {
210   return SGGeod(geod._lon, geod._lat, elevation);
211 }
212
213 inline
214 SGGeod
215 SGGeod::fromGeodFt(const SGGeod& geod, double elevation)
216 {
217   return SGGeod(geod._lon, geod._lat, elevation*SG_FEET_TO_METER);
218 }
219
220 inline
221 SGGeod
222 SGGeod::fromCart(const SGVec3<double>& cart)
223 {
224   SGGeod geod;
225   SGGeodesy::SGCartToGeod(cart, geod);
226   return geod;
227 }
228
229 inline
230 SGGeod
231 SGGeod::fromGeoc(const SGGeoc& geoc)
232 {
233   SGVec3<double> cart;
234   SGGeodesy::SGGeocToCart(geoc, cart);
235   SGGeod geod;
236   SGGeodesy::SGCartToGeod(cart, geod);
237   return geod;
238 }
239
240 inline
241 double
242 SGGeod::getLongitudeRad(void) const
243 {
244 #ifdef SG_GEOD_NATIVE_DEGREE
245   return _lon*SGD_DEGREES_TO_RADIANS;
246 #else
247   return _lon;
248 #endif
249 }
250
251 inline
252 void
253 SGGeod::setLongitudeRad(double lon)
254 {
255 #ifdef SG_GEOD_NATIVE_DEGREE
256   _lon = lon*SGD_RADIANS_TO_DEGREES;
257 #else
258   _lon = lon;
259 #endif
260 }
261
262 inline
263 double
264 SGGeod::getLongitudeDeg(void) const
265 {
266 #ifdef SG_GEOD_NATIVE_DEGREE
267   return _lon;
268 #else
269   return _lon*SGD_RADIANS_TO_DEGREES;
270 #endif
271 }
272
273 inline
274 void
275 SGGeod::setLongitudeDeg(double lon)
276 {
277 #ifdef SG_GEOD_NATIVE_DEGREE
278   _lon = lon;
279 #else
280   _lon = lon*SGD_DEGREES_TO_RADIANS;
281 #endif
282 }
283
284 inline
285 double
286 SGGeod::getLatitudeRad(void) const
287 {
288 #ifdef SG_GEOD_NATIVE_DEGREE
289   return _lat*SGD_DEGREES_TO_RADIANS;
290 #else
291   return _lat;
292 #endif
293 }
294
295 inline
296 void
297 SGGeod::setLatitudeRad(double lat)
298 {
299 #ifdef SG_GEOD_NATIVE_DEGREE
300   _lat = lat*SGD_RADIANS_TO_DEGREES;
301 #else
302   _lat = lat;
303 #endif
304 }
305
306 inline
307 double
308 SGGeod::getLatitudeDeg(void) const
309 {
310 #ifdef SG_GEOD_NATIVE_DEGREE
311   return _lat;
312 #else
313   return _lat*SGD_RADIANS_TO_DEGREES;
314 #endif
315 }
316
317 inline
318 void
319 SGGeod::setLatitudeDeg(double lat)
320 {
321 #ifdef SG_GEOD_NATIVE_DEGREE
322   _lat = lat;
323 #else
324   _lat = lat*SGD_DEGREES_TO_RADIANS;
325 #endif
326 }
327
328 inline
329 double
330 SGGeod::getElevationM(void) const
331 {
332   return _elevation;
333 }
334
335 inline
336 void
337 SGGeod::setElevationM(double elevation)
338 {
339   _elevation = elevation;
340 }
341
342 inline
343 double
344 SGGeod::getElevationFt(void) const
345 {
346   return _elevation*SG_METER_TO_FEET;
347 }
348
349 inline
350 void
351 SGGeod::setElevationFt(double elevation)
352 {
353   _elevation = elevation*SG_FEET_TO_METER;
354 }
355
356 inline
357 bool
358 SGGeod::operator == ( const SGGeod & other ) const
359 {
360   return _lon == other._lon &&
361          _lat == other._lat &&
362          _elevation == other._elevation;
363 }
364
365 /// Output to an ostream
366 template<typename char_type, typename traits_type>
367 inline
368 std::basic_ostream<char_type, traits_type>&
369 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeod& g)
370 {
371   return s << "lon = " << g.getLongitudeDeg()
372            << "deg, lat = " << g.getLatitudeDeg()
373            << "deg, elev = " << g.getElevationM()
374            << "m";
375 }
376
377 #endif