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