/********************************** CODE ************************************/
/****************************************************************************/
-/****************************************************************************/
-/* Interpolate p which lies inside the triangle x1, x2, x3 */
-/* */
-/* x3\ Do this by calulating q and linear interpolate its */
-/* |\ \ value as it's laying between x1 and x2. */
-/* | \ \ Then interpolate p as it lays between p and x3 */
-/* | \ \ */
-/* | p \ Advantages: p has exactly the value of a corner */
-/* | \ \ when it's laying on it. */
-/* | \ \ If p isn't in the triangle the algoritm */
-/* x1------q------x2 extrapolates it's value */
-/****************************************************************************/
template<class V>
V triangle_interpolate(const sgVec2& x1, const V& v1, const sgVec2& x2, const V& v2, const sgVec2& x3, const V& v3, const sgVec2& p)
{
- sgVec2 q;
- V q_value;
-
- //q = x1 + (x2 - x1)*( ((x3-x1).x()*(x1-x2).y() - (x1-x2).x()*(x3-x1).y())/((p-x3).x()*(x2-x1).y() - (x2-x1).x()*(p-x3).y()) );
-
- sgSubVec2 (q, x2, x1);
- sgScaleVec2(q, (x3[0]-x1[0])*(x1[1]-x2[1]) - (x1[0]-x2[0])*(x3[1]-x1[1]) );
- sgScaleVec2(q, 1.0 / ( (p [0]-x3[0])*(x2[1]-x1[1]) - (x2[0]-x1[0])*(p [1]-x3[1]) ) );
- sgAddVec2 (q, x1);
+ /************************************************************************/
+ /* First I have to solve the two equations. Rewritten they look like: */
+ /* */
+ /* a11 * x1 + a12 * x2 = b1 */
+ /* a21 * x1 + a22 * x2 = b2 */
+ /* */
+ /* with */
+ /* */
+ /* a11 = x2[0] - x1[0] a12 = x3[0] - x1[0] b1 = p[0] - x1[0] */
+ /* a21 = x2[1] - x1[1] a22 = x3[1] - x1[1] b2 = p[1] - x1[1] */
+ /* */
+ /* So I can easily get the solution by saying: */
+ /* */
+ /* | a11 a12 | */
+ /* D = | | */
+ /* | a21 a22 | */
+ /* */
+ /* | b1 a12 | | a11 b1 | */
+ /* | | | | */
+ /* | b2 a22 | | a21 b2 | */
+ /* x1 = ----------- x2 = ----------- */
+ /* D D */
+ /* */
+ /* I just need to take care then that D != 0 or I would get no */
+ /* solution or an infinite amount. Both wouildn't be good... */
+ /************************************************************************/
- q_value = v1 + (v2 - v1) * ( sgDistanceVec2(x1, q) / sgDistanceVec2(x1, x2) );
-
- return q_value + (v3 - q_value) * ( sgDistanceVec2(q, p) / sgDistanceVec2(q, x3));
+ float D = (x2[0] - x1[0]) * (x3[1] - x1[1]) - (x2[1] - x1[1]) * (x3[0] - x1[0]);
+
+ if (D == 0.0)
+ return v1; //BAD THING HAPPENED!!! I should throw an exeption
+
+ float x = ( (p [0] - x1[0]) * (x3[1] - x1[1]) - (p [1] - x1[1]) * (x3[0] - x1[0]) ) / D;
+ float y = ( (x2[0] - x1[0]) * (p [1] - x1[1]) - (x2[1] - x1[1]) * (p [0] - x1[0]) ) / D;
+
+ return v1 + x * (v2 - v1) + y * (v3 - v1);
}
/****************************************************************************/
for (FGPhysicalProperties2DVectorConstIt it=database.begin(); it!=database.end(); it++)
{ //go through the whole database
- d = sgScalarProductVec2(it->p, p);
+ d = sgDistanceVec2(it->p, p);
if (d<distance[0])
{
distance[2] = distance[1]; distance[1] = distance[0]; distance[0] = d;
iterator[2] = iterator[1]; iterator[1] = iterator[0]; iterator[0] = it;
- //NOTE: The last line causes a warning that an unitialiced variable
+ //NOTE: The last line causes a warning that an unitialized variable
//is used. You can ignore this warning here.
}
else if (d<distance[1])
//now I've got the closest entry in xx[0], the 2nd closest in xx[1] and the
//3rd in xx[2];
-
+
//interpolate now:
return triangle_interpolate(
iterator[0]->p, (FGPhysicalProperties)*iterator[0],
#include "FGLocalWeatherDatabase.h"
#include "FGVoronoi.h"
+#include "FGWeatherParse.h"
/****************************************************************************/
/********************************** CODE ************************************/
WeatherAreas.push_back(FGMicroWeather(it2->value, it2->boundary));
}
-/****************************************************************************/
-/* Constructor and Destructor */
-/****************************************************************************/
FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0;
FGLocalWeatherDatabase *WeatherDatabase;
-FGLocalWeatherDatabase::FGLocalWeatherDatabase(const sgVec3& position, const WeatherPrecision visibility, const DatabaseWorkingType type)
+void FGLocalWeatherDatabase::init(const WeatherPrecision visibility, const DatabaseWorkingType type)
{
cerr << "Initializing FGLocalWeatherDatabase\n";
cerr << "-----------------------------------\n";
DatabaseStatus = type;
global = 0; //just get sure...
- sgCopyVec3(last_known_position, position);
-
- theFGLocalWeatherDatabase = this;
+ Thunderstorm = false;
+ //I don't need to set theThunderstorm as Thunderstorm == false
switch(DatabaseStatus)
{
{
global = new FGGlobalWeatherDatabase; //initialize GlobalDatabase
global->setDatabaseStatus(FGGlobalWeatherDatabase_working);
- tileLocalWeather(global->getAll(position, WeatherVisibility, 3));
+ tileLocalWeather(global->getAll(last_known_position, WeatherVisibility, 3));
+ }
+ break;
+
+ case use_internet:
+ {
+ FGWeatherParse parsed_data;
+
+ parsed_data.input( "weather/current.gz" );
+ global = new FGGlobalWeatherDatabase; //initialize GlobalDatabase
+ global->setDatabaseStatus(FGGlobalWeatherDatabase_working);
+
+ // fill the database
+ for (unsigned int i = 0; i != parsed_data.stored_stations(); i++)
+ {
+ global->add( parsed_data.getFGPhysicalProperties2D(i) );
+ //cerr << parsed_data.getFGPhysicalProperties2D(i);
+
+ if ( (i%100) == 0)
+ cerr << ".";
+ }
+ cerr << "\n";
+
+ //and finally tile it
+ tileLocalWeather(global->getAll(last_known_position, WeatherVisibility, 3));
+ cerr << "Finished weather init.\n";
+
}
break;
case manual:
case default_mode:
{
+
vector<sgVec2Wrap> emptyList;
WeatherAreas.push_back(FGMicroWeather(FGPhysicalProperties2D(), emptyList)); //in these cases I've only got one tile
}
void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
{
sgCopyVec3(last_known_position, p);
- //cerr << "****\nupdate inside\n";
- //cerr << "Parameter: " << p << "\n";
- //cerr << "****\n";
+
+ if ( AreaWith(p) == 0 )
+ { //I have moved out of my local area...
+
+ //now I should erase all my areas and get the new ones
+ //but that takes too long :-( I have to take care about that soon
+ }
+
+ //uncomment this when you are using the GlobalDatabase
+ /*
+ cerr << "****\nupdate(p) inside\n";
+ cerr << "Parameter: " << p[0] << "/" << p[1] << "/" << p[2] << "\n";
+ sgVec2 p2d;
+ sgSetVec2( p2d, p[0], p[1] );
+ cerr << FGPhysicalProperties2D(global->get(p2d), p2d);
+ cerr << "****\n";
+ */
}
void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) //time and/or position has changed
{
sgCopyVec3(last_known_position, p);
+ if ( AreaWith(p) == 0 )
+ { //I have moved out of my local area...
+
+ //now I should erase all my areas and get the new ones
+ //but that takes too long :-( I have to take care about that soon
+ }
+
if (DatabaseStatus==use_global)
global->update(dt);
}
//BAD, BAD, BAD thing I'm doing here: I'm adding to the global database a point that
//changes my voronoi diagram but I don't update it! instead I'm changing one local value
//that could be anywhere!!
- //This only *might* work when the plane moves so far so fast that the diagram gets new
+ //This only *might* work when the plane moves so far so fast that the diagram gets newly
//calculated soon...
unsigned int a = AreaWith(x.p);
if (a != 0)
#include "FGMicroWeather.h"
#include "FGWeatherFeature.h"
#include "FGWeatherDefs.h"
+#include "FGThunderstorm.h"
/****************************************************************************/
/* DEFINES */
//local weather? Unit: metres
sgVec3 last_known_position;
+ bool Thunderstorm; //is there a thunderstorm near by?
+ FGThunderstorm *theThunderstorm; //pointer to the thunderstorm.
/************************************************************************/
/* return the index of the area with point p */
enum DatabaseWorkingType {
use_global, //use global database for data
+ use_internet, //use the weather data that came from the internet
manual, //use only user inputs
distant, //use distant information, e.g. like LAN when used in
//a multiplayer environment
DatabaseWorkingType DatabaseStatus;
+ void init( const WeatherPrecision visibility, const DatabaseWorkingType type );
+
/************************************************************************/
/* Constructor and Destructor */
/************************************************************************/
FGLocalWeatherDatabase(
const sgVec3& position,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY,
- const DatabaseWorkingType type = PREFERED_WORKING_TYPE);
+ const DatabaseWorkingType type = PREFERED_WORKING_TYPE)
+ {
+ sgCopyVec3( last_known_position, position );
+
+ init( visibility, type );
+
+ theFGLocalWeatherDatabase = this;
+ }
FGLocalWeatherDatabase(
const WeatherPrecision position_lat,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY,
const DatabaseWorkingType type = PREFERED_WORKING_TYPE)
{
- cout << "This constructor is broken and should *NOT* be used!" << endl;
- exit(-1);
-
- sgVec3 position;
- sgSetVec3( position, position_lat, position_lon, position_alt );
+ sgSetVec3( last_known_position, position_lat, position_lon, position_alt );
- // Christian: the following line does not do what you intend.
- // It just creates a new FGLocalWeatherDatabase which isn't
- // assigned to anything so it is immediately discared.
+ init( visibility, type );
- /* BAD --> */ FGLocalWeatherDatabase( position, visibility, type );
+ theFGLocalWeatherDatabase = this;
}
~FGLocalWeatherDatabase();
/************************************************************************/
void setWeatherVisibility(const WeatherPrecision visibility);
WeatherPrecision getWeatherVisibility(void) const;
+
+ /************************************************************************/
+ /* figure out if there's a thunderstorm that has to be taken care of */
+ /************************************************************************/
+ void updateThunderstorm(const float dt)
+ {
+ if (Thunderstorm == false)
+ return;
+
+ theThunderstorm->update( dt );
+ }
};
extern FGLocalWeatherDatabase *WeatherDatabase;
#include "FGPhysicalProperties.h"
#include "FGWeatherDefs.h"
+#include "FGWeatherUtils.h"
+
/****************************************************************************/
/********************************** CODE ************************************/
/****************************************************************************/
return CloudsIt->second;
}
-
+ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
+{
+ typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
+ typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
+ typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
+
+ out << "Position: (" << p.p[0] << ", " << p.p[1] << ", " << p.p[2] << ")\n";
+
+ out << "Stored Wind: ";
+ for (wind_iterator WindIt = p.Wind.begin();
+ WindIt != p.Wind.end();
+ WindIt++)
+ out << "(" << WindIt->second.x() << ", " << WindIt->second.y() << ", " << WindIt->second.z() << ") m/s at (" << WindIt->first << ") m; ";
+ out << "\n";
+
+ out << "Stored Turbulence: ";
+ for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
+ TurbulenceIt != p.Turbulence.end();
+ TurbulenceIt++)
+ out << "(" << TurbulenceIt->second.x() << ", " << TurbulenceIt->second.y() << ", " << TurbulenceIt->second.z() << ") m/s at (" << TurbulenceIt->first << ") m; ";
+ out << "\n";
+
+ out << "Stored Temperature: ";
+ for (scalar_iterator TemperatureIt = p.Temperature.begin();
+ TemperatureIt != p.Temperature.end();
+ TemperatureIt++)
+ out << Kelvin2Celsius(TemperatureIt->second) << " degC at " << TemperatureIt->first << "m; ";
+ out << "\n";
+
+ out << "Stored AirPressure: ";
+ out << p.AirPressure.getValue(0)/100.0 << " hPa at " << 0.0 << "m; ";
+ out << "\n";
+
+ out << "Stored VaporPressure: ";
+ for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
+ VaporPressureIt != p.VaporPressure.end();
+ VaporPressureIt++)
+ out << VaporPressureIt->second/100.0 << " hPa at " << VaporPressureIt->first << "m; ";
+ out << "\n";
+
+ return out << "\n";
+}
map<Altitude,FGCloudItem> Clouds; //amount of covering and type
- WeatherPrecision SnowRainIntensity; //this also stands for hail, snow,...
+ WeatherPrecision SnowRainIntensity; //this also stands for hail, snow,...
SnowRainType snowRainType;
- WeatherPrecision LightningProbability;
+ WeatherPrecision LightningProbability; //in lightnings per second
FGPhysicalProperties(); //consructor to fill it with FG standart weather
typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
-inline ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
-{
- typedef map<FGPhysicalProperties::Altitude, FGWindItem >::const_iterator wind_iterator;
- typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
- typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
-
- out << "Position: (" << p.p[0] << ", " << p.p[1] << ", " << p.p[2] << ")\n";
-
- out << "Stored Wind: ";
- for (wind_iterator WindIt = p.Wind.begin();
- WindIt != p.Wind.end();
- WindIt++)
- out << "(" << WindIt->first << ") at (" << WindIt->second.x() << ", " << WindIt->second.y() << ", " << WindIt->second.z() << ") m; ";
- out << "\n";
-
- out << "Stored Turbulence: ";
- for (turbulence_iterator TurbulenceIt = p.Turbulence.begin();
- TurbulenceIt != p.Turbulence.end();
- TurbulenceIt++)
- out << "(" << TurbulenceIt->first << ") at (" << TurbulenceIt->second.x() << ", " << TurbulenceIt->second.y() << ", " << TurbulenceIt->second.z() << ") m; ";
- out << "\n";
-
- out << "Stored Temperature: ";
- for (scalar_iterator TemperatureIt = p.Temperature.begin();
- TemperatureIt != p.Temperature.end();
- TemperatureIt++)
- out << TemperatureIt->first << " at " << TemperatureIt->second << "m; ";
- out << "\n";
-
- out << "Stored AirPressure: ";
- out << p.AirPressure.getValue(0) << " at " << 0.0 << "m; ";
- out << "\n";
-
- out << "Stored VaporPressure: ";
- for (scalar_iterator VaporPressureIt = p.VaporPressure.begin();
- VaporPressureIt != p.VaporPressure.end();
- VaporPressureIt++)
- out << VaporPressureIt->first << " at " << VaporPressureIt->second << "m; ";
- out << "\n";
-
- return out << "\n";
-}
inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
--- /dev/null
+/*****************************************************************************
+
+ Module: FGThunderstorm.cpp
+ Author: Christian Mayer
+ Date started: 02.11.99
+
+ -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+------------------------------------------------------------------------------
+Function that calls other parts of fg when a lightning has happened
+
+HISTORY
+------------------------------------------------------------------------------
+02.11.1999 Christian Mayer Created
+*****************************************************************************/
+
+/****************************************************************************/
+/* INCLUDES */
+/****************************************************************************/
+#include <stdlib.h>
+#include <time.h>
+
+#include <sg.h>
+
+#include "FGThunderstorm.h"
+
+/****************************************************************************/
+/********************************** CODE ************************************/
+/****************************************************************************/
+FGThunderstorm::FGThunderstorm(const float n, const float e, const float s, const float w, const float p, const unsigned int seed)
+{
+ northBorder = n;
+ eastBorder = e;
+ southBorder = s;
+ westBorder = w;
+
+ lightningProbability = p;
+ currentProbability = 0.0;
+
+ switch(seed)
+ {
+ case 0:
+ //a seed of 0 means that I have to initialize the seed myself
+ srand( (unsigned)time( NULL ) );
+ break;
+
+ case 1:
+ //a seed of 1 means that I must not initialize the seed
+ break;
+
+ default:
+ //any other seed means that I have to initialize with that seed
+ srand( seed );
+ }
+}
+
+FGThunderstorm::~FGThunderstorm(void)
+{
+ //I don't need to do anything
+}
+
+void FGThunderstorm::update(const float dt)
+{
+ //increase currentProbability by a value x that's 0.5 dt <= x <= 1.5 dt
+ currentProbability += dt * ( 0.5 - (float(rand())/RAND_MAX) );
+
+ if (currentProbability > lightningProbability)
+ { //ok, I've got a lightning now
+
+ //figure out where the lightning is:
+ sgVec2 lightningPosition;
+ sgSetVec2(
+ lightningPosition,
+ southBorder + (northBorder - southBorder)*(float(rand())/RAND_MAX),
+ westBorder + (eastBorder - westBorder )*(float(rand())/RAND_MAX)
+ );
+
+ //call OpenGl:
+ /* ... */
+
+ //call Sound:
+ /* ... */
+
+ //call Radio module:
+ /* ... */
+
+ currentProbability = 0.0; //and begin again
+ }
+}
+
+
+
+
--- /dev/null
+/*****************************************************************************
+
+ Header: FGThunderstorm.h
+ Author: Christian Mayer
+ Date started: 02.11.99
+
+ -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+------------------------------------------------------------------------------
+Header for the thunderstom class
+
+HISTORY
+------------------------------------------------------------------------------
+02.11.1999 Christian Mayer Created
+*****************************************************************************/
+
+/****************************************************************************/
+/* SENTRY */
+/****************************************************************************/
+#ifndef FGThunderstorm_H
+#define FGThunderstorm_H
+
+/****************************************************************************/
+/* INCLUDES */
+/****************************************************************************/
+
+/****************************************************************************/
+/* DEFINES */
+/****************************************************************************/
+
+/****************************************************************************/
+/* CLASS DECLARATION */
+/****************************************************************************/
+class FGThunderstorm
+{
+private:
+protected:
+ float northBorder;
+ float eastBorder;
+ float southBorder;
+ float westBorder;
+
+ float lightningProbability; //in lightnings per second
+ float currentProbability; //=0.0 directly after a lightning stroke and
+ //gets increased over the time until it's
+ //bigger than lightningProbability. When that
+ //happens we've got a new lightning
+
+public:
+ FGThunderstorm(const float n, const float e, const float s, const float w, const float p, const unsigned int seed = 0);
+ ~FGThunderstorm(void);
+
+ void update(const float dt);
+};
+
+/****************************************************************************/
+#endif /*FGThunderstorm_H*/
+
+
+
+
+
+
--- /dev/null
+/*****************************************************************************
+
+ Module: FGWeatherParse.cpp
+ Author: Christian Mayer
+ Date started: 28.05.99
+ Called by: FGMicroWeather
+
+ -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+------------------------------------------------------------------------------
+Parse the weather that can be downloaded from
+
+ http://129.13.102.67/out/flight/yymmddhhdata.txt.gz
+
+where yy stands for the year, mm for the month, dd for the day and hh for the
+hour.
+The columns are explained at
+
+ http://129.13.102.67/out/flight/kopf.txt
+
+and a list of the stations can be found at
+
+ http://129.13.102.67/out/flight/wmoconv.txt.gz
+
+Many thanks to Georg Mueller (Georg.Mueller@imk.fzk.de) of the
+
+ Institut fuer Meteorologie und Klimaforschung, Universitaet Karlsruhe
+
+for makeking such a service aviable.
+You can also visit his homepage at http://www.wetterzentrale.de
+
+HISTORY
+------------------------------------------------------------------------------
+18.10.1999 Christian Mayer Created
+*****************************************************************************/
+
+/****************************************************************************/
+/* INCLUDES */
+/****************************************************************************/
+#include "Include/fg_constants.h"
+
+#include "FGWeatherParse.h"
+#include "FGWeatherUtils.h"
+
+/****************************************************************************/
+/********************************** CODE ************************************/
+/****************************************************************************/
+
+FGWeatherParse::FGWeatherParse()
+{
+}
+
+FGWeatherParse::~FGWeatherParse()
+{
+}
+
+void FGWeatherParse::input(const char *file)
+{
+ unsigned int nr = 0;
+
+ fg_gzifstream in;
+
+ cerr << "Parsing \"" << file << "\" for weather datas:\n";
+
+ in.open( file );
+
+ while ( in )
+ {
+ entry temp;
+
+ in >> temp.year;
+ in >> temp.month;
+ in >> temp.day;
+ in >> temp.hour;
+ in >> temp.station_number;
+ in >> temp.lat;
+ in >> temp.lon;
+ in >> temp.x_wind;
+ in >> temp.y_wind;
+ in >> temp.temperature;
+ in >> temp.dewpoint;
+ in >> temp.airpressure;
+ in >> temp.airpressure_history[0];
+ in >> temp.airpressure_history[1];
+ in >> temp.airpressure_history[2];
+ in >> temp.airpressure_history[3];
+
+ weather_station.push_back( temp );
+
+ // output a point to ease the waiting
+ if ( ((nr++)%100) == 0 )
+ cerr << ".";
+ }
+
+ cerr << "\n" << nr << " stations read\n";
+}
+
+FGPhysicalProperties2D FGWeatherParse::getFGPhysicalProperties2D(const unsigned int nr) const
+{
+ FGPhysicalProperties2D ret_val;
+
+ //chache this entry
+ entry this_entry = weather_station[nr];
+
+ //set the position of the station
+ sgSetVec2( ret_val.p, this_entry.lat * DEG_TO_RAD, this_entry.lon * DEG_TO_RAD );
+
+ ret_val.Wind[-1000.0] = FGWindItem(this_entry.x_wind, this_entry.y_wind, 0.0);
+ ret_val.Wind[10000.0] = FGWindItem(this_entry.x_wind, this_entry.y_wind, 0.0);
+ ret_val.Temperature[0.0] = Celsius( this_entry.temperature );
+ ret_val.AirPressure = FGAirPressureItem( this_entry.airpressure * 10.0 ); //*10 to go from 10 hPa to Pa
+
+ //I have the dewpoint and the temperature, so I can get the vapor pressure
+ ret_val.VaporPressure[-1000.0] = sat_vp( this_entry.dewpoint );
+ ret_val.VaporPressure[10000.0] = sat_vp( this_entry.dewpoint );
+
+ //I've got no ideas about clouds...
+ //ret_val.Clouds[0] = 0.0;
+
+ return ret_val;
+}
+
+
+
+
--- /dev/null
+/*****************************************************************************
+
+ Header: FGWeatherParse.h
+ Author: Christian Mayer
+ Date started: 28.05.99
+
+ -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Further information about the GNU General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+------------------------------------------------------------------------------
+Parse the weather that can be downloaded from
+
+ http://129.13.102.67/out/flight/yymmddhhdata.txt.gz
+
+where yy stands for the year, mm for the month, dd for the day and hh for the
+hour.
+The columns are explained at
+
+ http://129.13.102.67/out/flight/kopf.txt
+
+and a list of the stations can be found at
+
+ http://129.13.102.67/out/flight/wmoconv.txt.gz
+
+Many thanks to Georg Mueller (Georg.Mueller@imk.fzk.de) of the
+
+ Institut fuer Meteorologie und Klimaforschung, Universitaet Karlsruhe
+
+for makeking such a service aviable.
+You can also visit his homepage at http://www.wetterzentrale.de
+
+HISTORY
+------------------------------------------------------------------------------
+18.10.1999 Christian Mayer Created
+*****************************************************************************/
+
+/****************************************************************************/
+/* SENTRY */
+/****************************************************************************/
+#ifndef FGWeatherParse_H
+#define FGWeatherParse_H
+
+/****************************************************************************/
+/* INCLUDES */
+/****************************************************************************/
+#include <Include/compiler.h>
+#include <vector>
+
+#include <Misc/fgstream.hxx>
+
+#include "FGPhysicalProperties.h"
+
+/****************************************************************************/
+/* DEFINES */
+/****************************************************************************/
+FG_USING_STD(vector);
+
+/****************************************************************************/
+/* CLASS DECLARATION */
+/****************************************************************************/
+class FGWeatherParse
+{
+public:
+ struct entry;
+
+private:
+ vector<entry> weather_station;
+
+protected:
+public:
+ /************************************************************************/
+ /* A line (i.e. entry) in the data file looks like: */
+ /* yyyy mm dd hh XXXXX BBBBB LLLLLL UUUUU VVVVV TTTTT DDDDD PPPPP pppp */
+ /************************************************************************/
+ struct entry
+ {
+ int year; // The yyyy
+ int month; // The mm
+ int day; // The dd
+ int hour; // The hh
+ unsigned int station_number; // The XXXXX
+ float lat; // The BBBBBB negative = south
+ float lon; // The LLLLLLL negative = west
+ float x_wind; // The UUUUU negative = to the weat
+ float y_wind; // The VVVVV negative = to the south
+ float temperature; // The TTTTT in degC
+ float dewpoint; // The DDDDD in degC
+ float airpressure; // The PPPPP in hPa
+ float airpressure_history[4]; // The pppp in hPa
+ };
+
+ FGWeatherParse();
+ ~FGWeatherParse();
+
+ void input(const char *file);
+
+ unsigned int stored_stations(void) const
+ {
+ return weather_station.size();
+ }
+
+ entry getEntry(const unsigned int nr) const
+ {
+ return weather_station[nr];
+ }
+
+ FGPhysicalProperties2D getFGPhysicalProperties2D(const unsigned int nr) const;
+};
+
+/****************************************************************************/
+#endif /*FGWeatherParse_H*/
public:
FGWindItem(const sgVec3& v) { sgCopyVec3(value, v); }
+ FGWindItem(const WeatherPrecision x, const WeatherPrecision y, const WeatherPrecision z)
+ { sgSetVec3 (value, x, y, z); }
FGWindItem() { sgZeroVec3(value); }
void getValue(sgVec3 ret) const { sgCopyVec3(ret, value); };
FGPhysicalProperty.cpp FGPhysicalProperty.h \
FGSnowRain.h \
FGTemperatureItem.cpp FGTemperatureItem.h \
+ FGThunderstorm.cpp FGThunderstorm.h \
FGTurbulenceItem.cpp FGTurbulenceItem.h \
FGVaporPressureItem.cpp FGVaporPressureItem.h \
FGVoronoi.cpp FGVoronoi.h \
FGWeatherDefs.h FGWeatherFeature.h FGWeatherUtils.h \
+ FGWeatherParse.cpp FGWeatherParse.h \
FGWeatherVectorWrap.h \
FGWindItem.cpp FGWindItem.h