]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGLocalWeatherDatabase.cpp
Updated so load/save will work.
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.cpp
1 /*****************************************************************************
2
3  Module:       FGLocalWeatherDatabase.cpp
4  Author:       Christian Mayer
5  Date started: 28.05.99
6  Called by:    main program
7
8  -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  details.
19
20  You should have received a copy of the GNU General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 FUNCTIONAL DESCRIPTION
28 ------------------------------------------------------------------------------
29 Database for the local weather
30 This database is the only one that gets called from FG
31
32 HISTORY
33 ------------------------------------------------------------------------------
34 28.05.1999 Christian Mayer      Created
35 16.06.1999 Durk Talsma          Portability for Linux
36 20.06.1999 Christian Mayer      added lots of consts
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 07.05.2000 Tony Peden           Added functionality to get the weather data
46                                 on 'the bus'
47 18.05.2000 Christian Mayer      Minor clean-ups. Changed the code to use 
48                                 FGWeatherUtils.h for unit conversion
49 *****************************************************************************/
50
51 /****************************************************************************/
52 /* INCLUDES                                                                 */
53 /****************************************************************************/
54 #include <simgear/compiler.h>
55 #include <simgear/constants.h>
56
57 #include <Aircraft/aircraft.hxx>
58
59 #include "FGLocalWeatherDatabase.h"
60
61 #include "FGWeatherParse.h"
62
63 #include "FGWeatherUtils.h"
64
65 /****************************************************************************/
66 /********************************** CODE ************************************/
67 /****************************************************************************/
68
69 FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
70 FGLocalWeatherDatabase *WeatherDatabase;
71
72 void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
73                                    const DatabaseWorkingType type,
74                                    const string &root )
75 {
76     FGPhysicalProperties f[2];  //make an standard weather that's the same at the whole world
77
78     cerr << "Initializing FGLocalWeatherDatabase\n";
79     cerr << "-----------------------------------\n";
80
81     if (theFGLocalWeatherDatabase)
82     {
83         cerr << "Error: only one local weather allowed";
84         exit(-1);
85     }
86
87     setWeatherVisibility(visibility);
88
89     DatabaseStatus = type;
90     database = 0;           //just get sure...
91
92     Thunderstorm = false;
93     //I don't need to set theThunderstorm as Thunderstorm == false
94
95     switch(DatabaseStatus)
96     {
97     case use_global:
98         {
99             cerr << "Error: there's no global database anymore!\n";
100             exit(-1);
101         }
102         break;
103
104     case use_internet:
105         {
106             FGWeatherParse *parsed_data = new FGWeatherParse();
107
108             parsed_data->input( "weather/current.gz" );
109             unsigned int n = parsed_data->stored_stations();
110
111             sgVec2               *p = new sgVec2              [n];
112             FGPhysicalProperties *f = new FGPhysicalProperties[n];
113
114             // fill the database
115             for (unsigned int i = 0; i < n; i++) 
116             {
117                 f[i] = parsed_data->getFGPhysicalProperties(i);
118                 parsed_data->getPosition(i, p[i]);
119
120                 if ( (i%100) == 0)
121                     cerr << ".";
122             }
123
124             // free the memory of the parsed data to ease the required memory
125             // for the very memory consuming spherical interpolation
126             delete parsed_data;
127
128             //and finally init the interpolation
129             cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350)\n";
130             database = new SphereInterpolate<FGPhysicalProperties>(n, p, f);
131
132             //and free my allocations:
133             delete[] p;
134             delete[] f;
135             cerr << "Finished weather init.\n";
136
137         }
138         break;
139
140     case distant:
141         cerr << "FGLocalWeatherDatabase error: Distant database isn't implemented yet!\n";
142         cerr << "  using random mode instead!\n";
143     case random:
144     case manual:
145     case default_mode:
146         {
147             double x[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
148             double y[2] = {0.0,  0.0};  //make an standard weather that's the same at the whole world
149             double z[2] = {1.0, -1.0};  //make an standard weather that's the same at the whole world
150             database = new SphereInterpolate<FGPhysicalProperties>(2,x,y,z,f);
151         }
152         break;
153
154     default:
155         cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
156     };
157 }
158
159 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
160 {
161     //Tidying up:
162     delete database;
163 }
164
165 /****************************************************************************/
166 /* reset the whole database                                                 */
167 /****************************************************************************/
168 void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
169 {
170     cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n";
171 }
172
173 /****************************************************************************/
174 /* update the database. Since the last call we had dt seconds               */
175 /****************************************************************************/
176 void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
177 {
178     //if (DatabaseStatus==use_global)
179     //  global->update(dt);
180 }
181
182 void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
183 {
184     sgCopyVec3(last_known_position, p);
185
186     //uncomment this when you are using the GlobalDatabase
187     /*
188     cerr << "****\nupdate(p) inside\n";
189     cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
190     sgVec2 p2d;
191     sgSetVec2( p2d, p[0], p[1] );
192     cerr << FGPhysicalProperties2D(get(p2d), p2d);
193     cerr << "****\n";
194     */
195     
196 }
197
198 void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt)   //time and/or position has changed
199 {
200     sgCopyVec3(last_known_position, p);
201 }
202
203 /****************************************************************************/
204 /* Get the physical properties on the specified point p out of the database */
205 /****************************************************************************/
206 FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
207 {
208     return FGPhysicalProperty(database->Evaluate(p), p[2]);
209 }
210
211 #ifdef macintosh
212     /* fix a problem with mw compilers in that they don't know the
213        difference between the next two methods. Since the first one
214        doesn't seem to be used anywhere, I commented it out. This is
215        supposed to be fixed in the forthcoming CodeWarrior Release
216        6. */
217 #else
218 FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const
219 {
220     return database->Evaluate(p);
221 }
222 #endif
223
224 WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
225 {
226     FGPhysicalProperty dummy(database->Evaluate(p), p[2]);
227
228     return 
229         (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
230         (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE);
231 }
232
233
234 void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
235 {
236     /* not supported yet */
237 }
238
239 void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
240 {
241     /* not supported yet */
242 }
243
244 void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p)
245 {
246     /* not supported yet */
247 }
248
249 void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
250 {
251     /* not supported yet */
252 }
253
254 void fgUpdateWeatherDatabase(void)
255 {
256     sgVec3 position;
257     sgVec3 wind;
258     
259     
260     sgSetVec3(position, 
261         current_aircraft.fdm_state->get_Latitude(),
262         current_aircraft.fdm_state->get_Longitude(),
263         current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER);
264     
265     WeatherDatabase->update( position );
266        
267     // get the data on 'the bus' for the FDM
268
269    /*  FGPhysicalProperty porperty = WeatherDatabase->get(position);
270
271     current_aircraft.fdm_state->set_Static_temperature( Kelvin2Rankine(porperty.Temperature) );
272     current_aircraft.fdm_state->set_Static_pressure( Pascal2psf(porperty.AirPressure) );
273
274     current_aircraft.fdm_state->set_Density( SIdensity2JSBsim( Density(porperty.AirPressure, porperty.Temperature) ) );
275     
276 #define MSTOFPS  3.2808 //m/s to ft/s
277     current_aircraft.fdm_state->set_Velocities_Local_Airmass(porperty.Wind[1]*MSTOFPS,
278         porperty.Wind[0]*MSTOFPS,
279         porperty.Wind[2]*MSTOFPS); */
280
281     
282 }
283