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