]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGLocalWeatherDatabase.h
Update from JSBSim
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.h
1 /*****************************************************************************
2
3  Header:       FGLocalWeatherDatabase.h 
4  Author:       Christian Mayer
5  Date started: 28.05.99
6
7  -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  details.
18
19  You should have received a copy of the GNU General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Database for the local weather
29 This database is the only one that gets called from FG
30
31 HISTORY
32 ------------------------------------------------------------------------------
33 28.05.1999 Christian Mayer      Created
34 16.06.1999 Durk Talsma          Portability for Linux
35 20.06.1999 Christian Mayer      added lots of consts
36 30.06.1999 Christian Mayer      STL portability
37 11.10.1999 Christian Mayer      changed set<> to map<> on Bernie Bright's 
38                                 suggestion
39 19.10.1999 Christian Mayer      change to use PLIB's sg instead of Point[2/3]D
40                                 and lots of wee code cleaning
41 14.12.1999 Christian Mayer      Changed the internal structure to use Dave
42                                 Eberly's spherical interpolation code. This
43                                 stops our dependancy on the (ugly) voronoi
44                                 code and simplyfies the code structure a lot.
45 18.07.2001 Christian Mayer      Added the posibility to limit the amount of 
46                                 stations for a faster init.
47 *****************************************************************************/
48
49 /****************************************************************************/
50 /* SENTRY                                                                   */
51 /****************************************************************************/
52 #ifndef FGLocalWeatherDatabase_H
53 #define FGLocalWeatherDatabase_H
54
55 /****************************************************************************/
56 /* INCLUDES                                                                 */
57 /****************************************************************************/
58 #include <vector>
59 #include STL_STRING
60
61 #include <plib/sg.h>
62
63 #include "sphrintp.h"
64
65 #include "FGPhysicalProperties.h"
66 #include "FGPhysicalProperty.h"
67
68
69 #include "FGWeatherFeature.h"
70 #include "FGWeatherDefs.h"
71 #include "FGThunderstorm.h"
72
73 /****************************************************************************/
74 /* DEFINES                                                                  */
75 /****************************************************************************/
76 SG_USING_STD(vector);
77 SG_USING_STD(string);
78 SG_USING_NAMESPACE(std);
79
80 /****************************************************************************/
81 /* CLASS DECLARATION                                                        */
82 /****************************************************************************/
83 struct _FGLocalWeatherDatabaseCache
84 {
85     sgVec3             last_known_position;
86     //sgVec3             current_position;
87     SGPropertyNode     *latitude_deg;
88     SGPropertyNode     *longitude_deg;
89     SGPropertyNode     *altitude_ft;
90     FGPhysicalProperty last_known_property;
91 };
92
93 class FGLocalWeatherDatabase
94 {
95 private:
96 protected:
97     SphereInterpolate<FGPhysicalProperties> *database;
98
99     typedef vector<sgVec2>      pointVector;
100     typedef vector<pointVector> tileVector;
101
102     /************************************************************************/
103     /* make tiles out of points on a 2D plane                               */
104     /************************************************************************/
105     WeatherPrecision WeatherVisibility; //how far do I need to simulate the
106                                         //local weather? Unit: metres
107
108     _FGLocalWeatherDatabaseCache *cache;
109     inline void check_cache_for_update(void) const;
110
111     bool Thunderstorm;                  //is there a thunderstorm near by?
112     FGThunderstorm *theThunderstorm;    //pointer to the thunderstorm.
113
114 public:
115     /************************************************************************/
116     /* for tieing them to the property system                               */
117     /************************************************************************/
118     inline WeatherPrecision get_wind_north() const;
119     inline WeatherPrecision get_wind_east() const;
120     inline WeatherPrecision get_wind_up() const;
121     inline WeatherPrecision get_temperature() const;
122     inline WeatherPrecision get_air_pressure() const;
123     inline WeatherPrecision get_vapor_pressure() const;
124     inline WeatherPrecision get_air_density() const;
125
126     static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;  
127     
128     enum DatabaseWorkingType {
129         use_global,     //use global database for data !!obsolete!!
130         use_internet,   //use the weather data that came from the internet
131         manual,         //use only user inputs
132         distant,        //use distant information, e.g. like LAN when used in
133                         //a multiplayer environment
134         random,         //generate weather randomly
135         default_mode    //use only default values
136     };
137
138     DatabaseWorkingType DatabaseStatus;
139
140     void init( const WeatherPrecision visibility,
141                const DatabaseWorkingType type,
142                const string &root );
143
144     /************************************************************************/
145     /* Constructor and Destructor                                           */
146     /************************************************************************/
147     FGLocalWeatherDatabase(
148         const sgVec3&             position,
149         const string&             root,
150         const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
151         const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
152     {
153         cache = new _FGLocalWeatherDatabaseCache;
154         sgCopyVec3( cache->last_known_position, position );
155
156         init( visibility, type, root );
157
158         theFGLocalWeatherDatabase = this;
159     }
160
161     FGLocalWeatherDatabase(
162         const WeatherPrecision    position_lat,
163         const WeatherPrecision    position_lon,
164         const WeatherPrecision    position_alt,
165         const string&             root,
166         const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
167         const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
168     {
169         cache = new _FGLocalWeatherDatabaseCache;
170         sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
171
172         init( visibility, type, root );
173
174         theFGLocalWeatherDatabase = this;
175     }
176
177     ~FGLocalWeatherDatabase();
178
179     /************************************************************************/
180     /* reset the whole database                                             */
181     /************************************************************************/
182     void reset(const DatabaseWorkingType type = PREFERED_WORKING_TYPE);
183
184     /************************************************************************/
185     /* update the database. Since the last call we had dt seconds           */
186     /************************************************************************/
187     void update(const WeatherPrecision dt);                     //time has changed
188     void update(const sgVec3& p);                               //position has  changed
189     void update(const sgVec3& p, const WeatherPrecision dt);    //time and/or position has changed
190
191     /************************************************************************/
192     /* Get the physical properties on the specified point p                 */
193     /************************************************************************/
194 #ifdef macintosh
195     /* fix a problem with mw compilers in that they don't know the
196        difference between the next two methods. Since the first one
197        doesn't seem to be used anywhere, I commented it out. This is
198        supposed to be fixed in the forthcoming CodeWarrior Release
199        6. */
200 #else
201     FGPhysicalProperties get(const sgVec2& p) const;
202 #endif
203     FGPhysicalProperty   get(const sgVec3& p) const;
204
205     WeatherPrecision     getAirDensity(const sgVec3& p) const;
206     
207     /************************************************************************/
208     /* Add a weather feature at the point p and surrounding area            */
209     /************************************************************************/
210     // !! Adds aren't supported anymore !!
211
212     void setSnowRainIntensity   (const WeatherPrecision x, const sgVec2& p);
213     void setSnowRainType        (const SnowRainType x,     const sgVec2& p);
214     void setLightningProbability(const WeatherPrecision x, const sgVec2& p);
215
216     void setProperties(const FGPhysicalProperties2D& x);    //change a property
217
218     /************************************************************************/
219     /* get/set weather visibility                                           */
220     /************************************************************************/
221     void             setWeatherVisibility(const WeatherPrecision visibility);
222     WeatherPrecision getWeatherVisibility(void) const;
223
224     /************************************************************************/
225     /* figure out if there's a thunderstorm that has to be taken care of    */
226     /************************************************************************/
227     void updateThunderstorm(const float dt)
228     {
229         if (Thunderstorm == false)
230             return;
231
232         theThunderstorm->update( dt );
233     }
234 };
235
236 extern FGLocalWeatherDatabase *WeatherDatabase;
237 void fgUpdateWeatherDatabase(void);
238
239 /****************************************************************************/
240 /* get/set weather visibility                                               */
241 /****************************************************************************/
242 void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecision visibility)
243 {
244     if (visibility >= MINIMUM_WEATHER_VISIBILITY)
245         WeatherVisibility = visibility;
246     else
247         WeatherVisibility = MINIMUM_WEATHER_VISIBILITY;
248 }
249
250 WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
251 {
252     return WeatherVisibility;
253 }
254
255 inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
256 {
257   if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
258        ( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
259        ( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
260     return; //nothing to do 
261
262   sgVec3 position = { cache->latitude_deg->getFloatValue(), 
263                       cache->longitude_deg->getFloatValue(), 
264                       cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
265
266   sgCopyVec3(cache->last_known_position, position);
267   cache->last_known_property = get(position);
268 }
269
270 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
271 {
272   check_cache_for_update();
273
274   return cache->last_known_property.Wind[0];
275 }
276
277 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
278 {
279   check_cache_for_update();
280
281   return cache->last_known_property.Wind[1];
282 }
283
284 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
285 {
286   check_cache_for_update();
287
288   return cache->last_known_property.Wind[2];
289 }
290
291 inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
292 {
293   check_cache_for_update();
294
295   return cache->last_known_property.Temperature;
296 }
297
298 inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
299 {
300   check_cache_for_update();
301
302   return cache->last_known_property.AirPressure;
303 }
304
305 inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
306 {
307   check_cache_for_update();
308
309   return cache->last_known_property.VaporPressure;
310 }
311
312 inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
313 {
314   // check_for_update();
315   // not required, as the called functions will do that
316
317   return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
318          (get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
319 }
320
321
322 /****************************************************************************/
323 #endif /*FGLocalWeatherDatabase_H*/