1 /*****************************************************************************
3 Header: FGLocalWeatherDatabase.h
4 Author: Christian Mayer
7 -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
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
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
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.
23 Further information about the GNU General Public License can also be found on
24 the world wide web at http://www.gnu.org.
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Database for the local weather
29 This database is the only one that gets called from FG
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
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 *****************************************************************************/
49 /****************************************************************************/
51 /****************************************************************************/
52 #ifndef FGLocalWeatherDatabase_H
53 #define FGLocalWeatherDatabase_H
55 /****************************************************************************/
57 /****************************************************************************/
63 #include <Main/fgfs.hxx>
65 #include <simgear/constants.h>
66 #include <simgear/misc/props.hxx>
70 #include "FGPhysicalProperties.h"
71 #include "FGPhysicalProperty.h"
73 #include "FGWeatherFeature.h"
74 #include "FGWeatherDefs.h"
75 #include "FGThunderstorm.h"
77 /****************************************************************************/
79 /****************************************************************************/
82 SG_USING_NAMESPACE(std);
84 /****************************************************************************/
85 /* CLASS DECLARATION */
86 /****************************************************************************/
87 struct _FGLocalWeatherDatabaseCache
89 sgVec3 last_known_position;
90 //sgVec3 current_position;
91 SGPropertyNode *latitude_deg;
92 SGPropertyNode *longitude_deg;
93 SGPropertyNode *altitude_ft;
94 FGPhysicalProperty last_known_property;
97 class FGLocalWeatherDatabase : public FGSubsystem
101 SphereInterpolate *database_logic;
102 vector<FGPhysicalProperties> database_data;
104 FGPhysicalProperties DatabaseEvaluate(const sgVec2& p) const
106 sgVec2 p_converted = {p[0]*(SGD_2PI/360.0),
107 p[1]*(SGD_2PI/360.0)};
108 EvaluateData d = database_logic->Evaluate(p_converted);
109 return database_data[d.index[0]]*d.percentage[0] +
110 database_data[d.index[1]]*d.percentage[1] +
111 database_data[d.index[2]]*d.percentage[2] ;
114 FGPhysicalProperties DatabaseEvaluate(const sgVec3& p) const
116 sgVec3 p_converted = {p[0]*(SGD_2PI/360.0),
117 p[1]*(SGD_2PI/360.0),
119 EvaluateData d = database_logic->Evaluate(p_converted);
120 return database_data[d.index[0]]*d.percentage[0] +
121 database_data[d.index[1]]*d.percentage[1] +
122 database_data[d.index[2]]*d.percentage[2] ;
125 typedef vector<sgVec2> pointVector;
126 typedef vector<pointVector> tileVector;
128 /************************************************************************/
129 /* make tiles out of points on a 2D plane */
130 /************************************************************************/
131 WeatherPrecision WeatherVisibility; //how far do I need to simulate the
132 //local weather? Unit: metres
134 _FGLocalWeatherDatabaseCache *cache;
135 inline void check_cache_for_update(void) const;
137 bool Thunderstorm; //is there a thunderstorm near by?
138 FGThunderstorm *theThunderstorm; //pointer to the thunderstorm.
141 /************************************************************************/
142 /* for tieing them to the property system */
143 /************************************************************************/
144 inline WeatherPrecision get_wind_north() const;
145 inline WeatherPrecision get_wind_east() const;
146 inline WeatherPrecision get_wind_up() const;
147 inline WeatherPrecision get_temperature() const;
148 inline WeatherPrecision get_air_pressure() const;
149 inline WeatherPrecision get_vapor_pressure() const;
150 inline WeatherPrecision get_air_density() const;
152 static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;
154 enum DatabaseWorkingType {
155 use_global, //use global database for data !!obsolete!!
156 use_internet, //use the weather data that came from the internet
157 manual, //use only user inputs
158 distant, //use distant information, e.g. like LAN when used in
159 //a multiplayer environment
160 random, //generate weather randomly
161 default_mode //use only default values
164 DatabaseWorkingType DatabaseStatus;
166 void init( const WeatherPrecision visibility,
167 const DatabaseWorkingType type,
168 const string &root );
170 /************************************************************************/
171 /* Constructor and Destructor */
172 /************************************************************************/
173 FGLocalWeatherDatabase(
174 const sgVec3& position,
176 const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
177 const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
179 cache = new _FGLocalWeatherDatabaseCache;
180 sgCopyVec3( cache->last_known_position, position );
182 init( visibility, type, root );
184 theFGLocalWeatherDatabase = this;
187 FGLocalWeatherDatabase(
188 const WeatherPrecision position_lat,
189 const WeatherPrecision position_lon,
190 const WeatherPrecision position_alt,
192 const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
193 const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
195 cache = new _FGLocalWeatherDatabaseCache;
196 sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
198 init( visibility, type, root );
200 theFGLocalWeatherDatabase = this;
203 ~FGLocalWeatherDatabase();
205 /************************************************************************/
206 /* reset the whole database */
207 /************************************************************************/
208 void reset(const DatabaseWorkingType type = PREFERED_WORKING_TYPE);
210 /************************************************************************/
211 /* update the database. Since the last call we had dt seconds */
212 /************************************************************************/
213 void update(const WeatherPrecision dt); //time has changed
214 void update(const sgVec3& p); //position has changed
215 void update(const sgVec3& p, const WeatherPrecision dt); //time and/or position has changed
217 /************************************************************************/
218 /* define methods requited for FGSubsystem */
219 /************************************************************************/
220 virtual void init () { /* do nothing; that's done in the constructor */ };
221 virtual void bind ();
222 virtual void unbind ();
223 virtual void update (int dt) { update((float) dt); };
225 /************************************************************************/
226 /* Get the physical properties on the specified point p */
227 /************************************************************************/
229 /* fix a problem with mw compilers in that they don't know the
230 difference between the next two methods. Since the first one
231 doesn't seem to be used anywhere, I commented it out. This is
232 supposed to be fixed in the forthcoming CodeWarrior Release
235 FGPhysicalProperties get(const sgVec2& p) const;
237 FGPhysicalProperty get(const sgVec3& p) const;
239 WeatherPrecision getAirDensity(const sgVec3& p) const;
241 /************************************************************************/
242 /* Add a weather feature at the point p and surrounding area */
243 /************************************************************************/
244 // !! Adds aren't supported anymore !!
246 void setSnowRainIntensity (const WeatherPrecision x, const sgVec2& p);
247 void setSnowRainType (const SnowRainType x, const sgVec2& p);
248 void setLightningProbability(const WeatherPrecision x, const sgVec2& p);
250 void setProperties(const FGPhysicalProperties2D& x); //change a property
252 /************************************************************************/
253 /* get/set weather visibility */
254 /************************************************************************/
255 void setWeatherVisibility(const WeatherPrecision visibility);
256 WeatherPrecision getWeatherVisibility(void) const;
258 /************************************************************************/
259 /* figure out if there's a thunderstorm that has to be taken care of */
260 /************************************************************************/
261 void updateThunderstorm(const float dt)
263 if (Thunderstorm == false)
266 theThunderstorm->update( dt );
270 extern FGLocalWeatherDatabase *WeatherDatabase;
271 void fgUpdateWeatherDatabase(void);
273 /****************************************************************************/
274 /* get/set weather visibility */
275 /****************************************************************************/
276 void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecision visibility)
278 if (visibility >= MINIMUM_WEATHER_VISIBILITY)
279 WeatherVisibility = visibility;
281 WeatherVisibility = MINIMUM_WEATHER_VISIBILITY;
284 WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
286 return WeatherVisibility;
289 inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
291 if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
292 ( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
293 ( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
294 return; //nothing to do
296 sgVec3 position = { cache->latitude_deg->getFloatValue(),
297 cache->longitude_deg->getFloatValue(),
298 cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
300 sgCopyVec3(cache->last_known_position, position);
301 cache->last_known_property = get(position);
304 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
306 check_cache_for_update();
308 return cache->last_known_property.Wind[0];
311 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
313 check_cache_for_update();
315 return cache->last_known_property.Wind[1];
318 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
320 check_cache_for_update();
322 return cache->last_known_property.Wind[2];
325 inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
327 check_cache_for_update();
329 return cache->last_known_property.Temperature;
332 inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
334 check_cache_for_update();
336 return cache->last_known_property.AirPressure;
339 inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
341 check_cache_for_update();
343 return cache->last_known_property.VaporPressure;
346 inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
348 // check_for_update();
349 // not required, as the called functions will do that
351 return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) /
352 (get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
356 /****************************************************************************/
357 #endif /*FGLocalWeatherDatabase_H*/