4 #include <simgear/constants.h>
6 // #define SG_GEOD_NATIVE_DEGREE
8 /// Class representing a geodetic location
11 /// Default constructor, initializes the instance to lat = lon = elev = 0
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);
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);
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);
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);
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);
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);
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);
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);
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
67 SGGeod(double lon, double lat, double elevation);
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
82 SGGeod::SGGeod(void) :
83 _lon(0), _lat(0), _elevation(0)
88 SGGeod::SGGeod(double lon, double lat, double elevation) :
89 _lon(lon), _lat(lat), _elevation(elevation)
94 SGGeod::SGGeod(const SGVec3<double>& cart)
96 SGGeodesy::SGCartToGeod(cart, *this);
100 SGGeod::SGGeod(const SGGeoc& geoc)
103 SGGeodesy::SGGeocToCart(geoc, cart);
104 SGGeodesy::SGCartToGeod(cart, *this);
109 SGGeod::fromRad(double lon, double lat)
111 #ifdef SG_GEOD_NATIVE_DEGREE
112 return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES, 0);
114 return SGGeod(lon, lat, 0);
120 SGGeod::fromDeg(double lon, double lat)
122 #ifdef SG_GEOD_NATIVE_DEGREE
123 return SGGeod(lon, lat, 0);
125 return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0);
131 SGGeod::fromRadFt(double lon, double lat, double elevation)
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);
137 return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
143 SGGeod::fromDegFt(double lon, double lat, double elevation)
145 #ifdef SG_GEOD_NATIVE_DEGREE
146 return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
148 return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
149 elevation*SG_FEET_TO_METER);
155 SGGeod::fromRadM(double lon, double lat, double elevation)
157 #ifdef SG_GEOD_NATIVE_DEGREE
158 return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
161 return SGGeod(lon, lat, elevation);
167 SGGeod::fromDegM(double lon, double lat, double elevation)
169 #ifdef SG_GEOD_NATIVE_DEGREE
170 return SGGeod(lon, lat, elevation);
172 return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
179 SGGeod::getLongitudeRad(void) const
181 #ifdef SG_GEOD_NATIVE_DEGREE
182 return _lon*SGD_DEGREES_TO_RADIANS;
190 SGGeod::setLongitudeRad(double lon)
192 #ifdef SG_GEOD_NATIVE_DEGREE
193 _lon = lon*SGD_RADIANS_TO_DEGREES;
201 SGGeod::getLongitudeDeg(void) const
203 #ifdef SG_GEOD_NATIVE_DEGREE
206 return _lon*SGD_RADIANS_TO_DEGREES;
212 SGGeod::setLongitudeDeg(double lon)
214 #ifdef SG_GEOD_NATIVE_DEGREE
217 _lon = lon*SGD_DEGREES_TO_RADIANS;
223 SGGeod::getLatitudeRad(void) const
225 #ifdef SG_GEOD_NATIVE_DEGREE
226 return _lat*SGD_DEGREES_TO_RADIANS;
234 SGGeod::setLatitudeRad(double lat)
236 #ifdef SG_GEOD_NATIVE_DEGREE
237 _lat = lat*SGD_RADIANS_TO_DEGREES;
245 SGGeod::getLatitudeDeg(void) const
247 #ifdef SG_GEOD_NATIVE_DEGREE
250 return _lat*SGD_RADIANS_TO_DEGREES;
256 SGGeod::setLatitudeDeg(double lat)
258 #ifdef SG_GEOD_NATIVE_DEGREE
261 _lat = lat*SGD_DEGREES_TO_RADIANS;
267 SGGeod::getElevationM(void) const
274 SGGeod::setElevationM(double elevation)
276 _elevation = elevation;
281 SGGeod::getElevationFt(void) const
283 return _elevation*SG_METER_TO_FEET;
288 SGGeod::setElevationFt(double elevation)
290 _elevation = elevation*SG_FEET_TO_METER;
293 /// Output to an ostream
294 template<typename char_type, typename traits_type>
296 std::basic_ostream<char_type, traits_type>&
297 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeod& g)
299 return s << "lon = " << g.getLongitudeDeg()
300 << "deg, lat = " << g.getLatitudeDeg()
301 << "deg, elev = " << g.getElevationM()