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 <simgear/misc/props.hxx>
64 #include <simgear/constants.h>
68 #include "FGPhysicalProperties.h"
69 #include "FGPhysicalProperty.h"
71 #include "FGWeatherFeature.h"
72 #include "FGWeatherDefs.h"
73 #include "FGThunderstorm.h"
75 /****************************************************************************/
77 /****************************************************************************/
80 SG_USING_NAMESPACE(std);
82 /****************************************************************************/
83 /* CLASS DECLARATION */
84 /****************************************************************************/
85 struct _FGLocalWeatherDatabaseCache
87 sgVec3 last_known_position;
88 //sgVec3 current_position;
89 SGPropertyNode *latitude_deg;
90 SGPropertyNode *longitude_deg;
91 SGPropertyNode *altitude_ft;
92 FGPhysicalProperty last_known_property;
95 class FGLocalWeatherDatabase
99 SphereInterpolate<FGPhysicalProperties> *database;
101 typedef vector<sgVec2> pointVector;
102 typedef vector<pointVector> tileVector;
104 /************************************************************************/
105 /* make tiles out of points on a 2D plane */
106 /************************************************************************/
107 WeatherPrecision WeatherVisibility; //how far do I need to simulate the
108 //local weather? Unit: metres
110 _FGLocalWeatherDatabaseCache *cache;
111 inline void check_cache_for_update(void) const;
113 bool Thunderstorm; //is there a thunderstorm near by?
114 FGThunderstorm *theThunderstorm; //pointer to the thunderstorm.
117 /************************************************************************/
118 /* for tieing them to the property system */
119 /************************************************************************/
120 inline WeatherPrecision get_wind_north() const;
121 inline WeatherPrecision get_wind_east() const;
122 inline WeatherPrecision get_wind_up() const;
123 inline WeatherPrecision get_temperature() const;
124 inline WeatherPrecision get_air_pressure() const;
125 inline WeatherPrecision get_vapor_pressure() const;
126 inline WeatherPrecision get_air_density() const;
128 static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;
130 enum DatabaseWorkingType {
131 use_global, //use global database for data !!obsolete!!
132 use_internet, //use the weather data that came from the internet
133 manual, //use only user inputs
134 distant, //use distant information, e.g. like LAN when used in
135 //a multiplayer environment
136 random, //generate weather randomly
137 default_mode //use only default values
140 DatabaseWorkingType DatabaseStatus;
142 void init( const WeatherPrecision visibility,
143 const DatabaseWorkingType type,
144 const string &root );
146 /************************************************************************/
147 /* Constructor and Destructor */
148 /************************************************************************/
149 FGLocalWeatherDatabase(
150 const sgVec3& position,
152 const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
153 const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
155 cache = new _FGLocalWeatherDatabaseCache;
156 sgCopyVec3( cache->last_known_position, position );
158 init( visibility, type, root );
160 theFGLocalWeatherDatabase = this;
163 FGLocalWeatherDatabase(
164 const WeatherPrecision position_lat,
165 const WeatherPrecision position_lon,
166 const WeatherPrecision position_alt,
168 const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
169 const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
171 cache = new _FGLocalWeatherDatabaseCache;
172 sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
174 init( visibility, type, root );
176 theFGLocalWeatherDatabase = this;
179 ~FGLocalWeatherDatabase();
181 /************************************************************************/
182 /* reset the whole database */
183 /************************************************************************/
184 void reset(const DatabaseWorkingType type = PREFERED_WORKING_TYPE);
186 /************************************************************************/
187 /* update the database. Since the last call we had dt seconds */
188 /************************************************************************/
189 void update(const WeatherPrecision dt); //time has changed
190 void update(const sgVec3& p); //position has changed
191 void update(const sgVec3& p, const WeatherPrecision dt); //time and/or position has changed
193 /************************************************************************/
194 /* Get the physical properties on the specified point p */
195 /************************************************************************/
197 /* fix a problem with mw compilers in that they don't know the
198 difference between the next two methods. Since the first one
199 doesn't seem to be used anywhere, I commented it out. This is
200 supposed to be fixed in the forthcoming CodeWarrior Release
203 FGPhysicalProperties get(const sgVec2& p) const;
205 FGPhysicalProperty get(const sgVec3& p) const;
207 WeatherPrecision getAirDensity(const sgVec3& p) const;
209 /************************************************************************/
210 /* Add a weather feature at the point p and surrounding area */
211 /************************************************************************/
212 // !! Adds aren't supported anymore !!
214 void setSnowRainIntensity (const WeatherPrecision x, const sgVec2& p);
215 void setSnowRainType (const SnowRainType x, const sgVec2& p);
216 void setLightningProbability(const WeatherPrecision x, const sgVec2& p);
218 void setProperties(const FGPhysicalProperties2D& x); //change a property
220 /************************************************************************/
221 /* get/set weather visibility */
222 /************************************************************************/
223 void setWeatherVisibility(const WeatherPrecision visibility);
224 WeatherPrecision getWeatherVisibility(void) const;
226 /************************************************************************/
227 /* figure out if there's a thunderstorm that has to be taken care of */
228 /************************************************************************/
229 void updateThunderstorm(const float dt)
231 if (Thunderstorm == false)
234 theThunderstorm->update( dt );
238 extern FGLocalWeatherDatabase *WeatherDatabase;
239 void fgUpdateWeatherDatabase(void);
241 /****************************************************************************/
242 /* get/set weather visibility */
243 /****************************************************************************/
244 void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecision visibility)
246 if (visibility >= MINIMUM_WEATHER_VISIBILITY)
247 WeatherVisibility = visibility;
249 WeatherVisibility = MINIMUM_WEATHER_VISIBILITY;
252 WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
254 return WeatherVisibility;
257 inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
259 if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
260 ( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
261 ( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
262 return; //nothing to do
264 sgVec3 position = { cache->latitude_deg->getFloatValue(),
265 cache->longitude_deg->getFloatValue(),
266 cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
268 sgCopyVec3(cache->last_known_position, position);
269 cache->last_known_property = get(position);
272 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
274 check_cache_for_update();
276 return cache->last_known_property.Wind[0];
279 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
281 check_cache_for_update();
283 return cache->last_known_property.Wind[1];
286 inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
288 check_cache_for_update();
290 return cache->last_known_property.Wind[2];
293 inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
295 check_cache_for_update();
297 return cache->last_known_property.Temperature;
300 inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
302 check_cache_for_update();
304 return cache->last_known_property.AirPressure;
307 inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
309 check_cache_for_update();
311 return cache->last_known_property.VaporPressure;
314 inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
316 // check_for_update();
317 // not required, as the called functions will do that
319 return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) /
320 (get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
324 /****************************************************************************/
325 #endif /*FGLocalWeatherDatabase_H*/