1
0
Fork 0
I've updated the WeatherDatabase to be able to use only the n closest
stations. This can speed up the initalization dramatically.

To take a benefit from that you need:

- http://129.13.102.67/out/flight/current.txt.gz in
  FG_ROOT/weather/current.txt.gz
- --prop:/environment/weather/working-type=internet
- --prop:/environment/weather/max-stations=what_ever_you_want

The WeatherCM stuff now publishes its data in the property system.

    /environment/weather/wind-north-mps
    /environment/weather/wind-east-mps
    /environment/weather/wind-up-mps
    /environment/weather/temperature-K
    /environment/weather/air-pressure-Pa
    /environment/weather/vapor-pressure-Pa
    /environment/weather/air-density

are the new properties.
This commit is contained in:
curt 2001-07-19 22:10:14 +00:00
parent 1de5373ed9
commit 20f50d349f
3 changed files with 199 additions and 35 deletions

View file

@ -661,19 +661,35 @@ bool fgInitSubsystems( void ) {
sgSetVec3( position, current_aircraft.fdm_state->get_Latitude(),
current_aircraft.fdm_state->get_Longitude(),
current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER );
FGLocalWeatherDatabase::theFGLocalWeatherDatabase =
double init_vis = fgGetDouble("/environment/visibility-m");
FGLocalWeatherDatabase::DatabaseWorkingType working_type;
if (fgGetString("/environment/weather/working-type") == "internet")
{
working_type = FGLocalWeatherDatabase::use_internet;
} else {
working_type = FGLocalWeatherDatabase::default_mode;
}
if ( init_vis > 0 ) {
FGLocalWeatherDatabase::theFGLocalWeatherDatabase =
new FGLocalWeatherDatabase( position,
globals->get_fg_root() );
globals->get_fg_root(),
working_type,
init_vis );
} else {
FGLocalWeatherDatabase::theFGLocalWeatherDatabase =
new FGLocalWeatherDatabase( position,
globals->get_fg_root(),
working_type );
}
// cout << theFGLocalWeatherDatabase << endl;
// cout << "visibility = "
// << theFGLocalWeatherDatabase->getWeatherVisibility() << endl;
WeatherDatabase = FGLocalWeatherDatabase::theFGLocalWeatherDatabase;
double init_vis = fgGetDouble("/environment/visibility-m");
if ( init_vis > 0 ) {
WeatherDatabase->setWeatherVisibility( init_vis );
}
// register the periodic update of the weather
global_events.Register( "weather update", fgUpdateWeatherDatabase,

View file

@ -46,6 +46,8 @@ HISTORY
on 'the bus'
18.05.2000 Christian Mayer Minor clean-ups. Changed the code to use
FGWeatherUtils.h for unit conversion
18.07.2001 Christian Mayer Added the posibility to limit the amount of
stations for a faster init.
*****************************************************************************/
/****************************************************************************/
@ -55,6 +57,7 @@ HISTORY
#include <simgear/constants.h>
#include <Aircraft/aircraft.hxx>
#include <Main/fg_props.hxx>
#include "FGLocalWeatherDatabase.h"
@ -104,30 +107,77 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
case use_internet:
{
FGWeatherParse *parsed_data = new FGWeatherParse();
parsed_data->input( "weather/current.gz" );
sgVec2 *p;
FGPhysicalProperties *f;
string path_to_weather = root + "/weather/current.txt.gz";
parsed_data->input( path_to_weather.c_str() );
unsigned int n = parsed_data->stored_stations();
int m = fgGetInt("/environment/weather/max-stations", -1);
sgVec2 *p = new sgVec2 [n];
FGPhysicalProperties *f = new FGPhysicalProperties[n];
if ( ( m < 0 ) || ( m > n ) )
{
m = n;
// fill the database
for (unsigned int i = 0; i < n; i++)
{
f[i] = parsed_data->getFGPhysicalProperties(i);
parsed_data->getPosition(i, p[i]);
p = new sgVec2 [n];
f = new FGPhysicalProperties[n];
if ( (i%100) == 0)
cerr << ".";
}
// fill the database
for (unsigned int i = 0; i < n; i++)
{
f[i] = parsed_data->getFGPhysicalProperties(i);
parsed_data->getPosition(i, p[i]);
if ( (i%100) == 0)
cerr << ".";
}
}
else
{ // we have to limit the amount of stations
//store the "distance" between the station and the current
//position. As the distance is calculated from the lat/lon
//values it's not worth much - but it's good enough for
//comparison
map<float, unsigned int> squared_distance;
sgVec2 cur_pos;
cur_pos[0] = cache->last_known_position[0];
cur_pos[1] = cache->last_known_position[1];
unsigned int i;
for( i = 0; i < n; i++ )
{
sgVec2 pos;
parsed_data->getPosition(i, pos);
squared_distance[sgDistanceSquaredVec2(cur_pos, pos)] = i;
}
p = new sgVec2 [m];
f = new FGPhysicalProperties[m];
map<float, unsigned int>::const_iterator ci;
ci = squared_distance.begin();
// fill the database
for ( i = 0; i < m; i++ )
{
f[i] = parsed_data->getFGPhysicalProperties(ci->second);
parsed_data->getPosition(ci->second, p[i]);
if ( (i%100) == 0)
cerr << ".";
ci++;
}
}
// free the memory of the parsed data to ease the required memory
// for the very memory consuming spherical interpolation
delete parsed_data;
//and finally init the interpolation
cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350)\n";
database = new SphereInterpolate<FGPhysicalProperties>(n, p, f);
cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350 for ca. 3500 stations)\n";
database = new SphereInterpolate<FGPhysicalProperties>(m, p, f);
//and free my allocations:
delete[] p;
@ -154,6 +204,18 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
default:
cerr << "FGLocalWeatherDatabase error: Unknown database type specified!\n";
};
cache->latitude_deg = fgGetNode("/position/latitude-deg" );
cache->longitude_deg = fgGetNode("/position/longitude-deg");
cache->altitude_ft = fgGetNode("/position/altitude-ft" );
fgTie("/environment/weather/wind-north-mps", this, &FGLocalWeatherDatabase::get_wind_north);
fgTie("/environment/weather/wind-east-mps", this, &FGLocalWeatherDatabase::get_wind_east);
fgTie("/environment/weather/wind-up-mps", this, &FGLocalWeatherDatabase::get_wind_up);
fgTie("/environment/weather/temperature-K", this, &FGLocalWeatherDatabase::get_temperature);
fgTie("/environment/weather/air-pressure-Pa", this, &FGLocalWeatherDatabase::get_air_pressure);
fgTie("/environment/weather/vapor-pressure-Pa", this, &FGLocalWeatherDatabase::get_vapor_pressure);
fgTie("/environment/weather/air-density", this, &FGLocalWeatherDatabase::get_air_density);
}
FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
@ -181,14 +243,10 @@ void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
{
sgCopyVec3(last_known_position, p);
//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(get(p2d), p2d);
cerr << "****\n";
*/
@ -197,7 +255,6 @@ void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) //time and/or position has changed
{
sgCopyVec3(last_known_position, p);
}
/****************************************************************************/
@ -254,8 +311,6 @@ void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
void fgUpdateWeatherDatabase(void)
{
sgVec3 position;
sgVec3 wind;
sgSetVec3(position,
current_aircraft.fdm_state->get_Latitude(),

View file

@ -42,6 +42,8 @@ HISTORY
Eberly's spherical interpolation code. This
stops our dependancy on the (ugly) voronoi
code and simplyfies the code structure a lot.
18.07.2001 Christian Mayer Added the posibility to limit the amount of
stations for a faster init.
*****************************************************************************/
/****************************************************************************/
@ -78,6 +80,16 @@ SG_USING_NAMESPACE(std);
/****************************************************************************/
/* CLASS DECLARATION */
/****************************************************************************/
struct _FGLocalWeatherDatabaseCache
{
sgVec3 last_known_position;
//sgVec3 current_position;
SGPropertyNode *latitude_deg;
SGPropertyNode *longitude_deg;
SGPropertyNode *altitude_ft;
FGPhysicalProperty last_known_property;
};
class FGLocalWeatherDatabase
{
private:
@ -92,12 +104,25 @@ protected:
/************************************************************************/
WeatherPrecision WeatherVisibility; //how far do I need to simulate the
//local weather? Unit: metres
sgVec3 last_known_position;
_FGLocalWeatherDatabaseCache *cache;
inline void check_cache_for_update(void) const;
bool Thunderstorm; //is there a thunderstorm near by?
FGThunderstorm *theThunderstorm; //pointer to the thunderstorm.
public:
/************************************************************************/
/* for tieing them to the property system */
/************************************************************************/
inline WeatherPrecision get_wind_north() const;
inline WeatherPrecision get_wind_east() const;
inline WeatherPrecision get_wind_up() const;
inline WeatherPrecision get_temperature() const;
inline WeatherPrecision get_air_pressure() const;
inline WeatherPrecision get_vapor_pressure() const;
inline WeatherPrecision get_air_density() const;
static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;
enum DatabaseWorkingType {
@ -122,10 +147,11 @@ public:
FGLocalWeatherDatabase(
const sgVec3& position,
const string& root,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY,
const DatabaseWorkingType type = PREFERED_WORKING_TYPE)
const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
{
sgCopyVec3( last_known_position, position );
cache = new _FGLocalWeatherDatabaseCache;
sgCopyVec3( cache->last_known_position, position );
init( visibility, type, root );
@ -137,10 +163,11 @@ public:
const WeatherPrecision position_lon,
const WeatherPrecision position_alt,
const string& root,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY,
const DatabaseWorkingType type = PREFERED_WORKING_TYPE)
const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
{
sgSetVec3( last_known_position, position_lat, position_lon, position_alt );
cache = new _FGLocalWeatherDatabaseCache;
sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
init( visibility, type, root );
@ -225,6 +252,72 @@ WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
return WeatherVisibility;
}
inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
{
if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
return; //nothing to do
sgVec3 position = { cache->latitude_deg->getFloatValue(),
cache->longitude_deg->getFloatValue(),
cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
sgCopyVec3(cache->last_known_position, position);
cache->last_known_property = get(position);
}
inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
{
check_cache_for_update();
return cache->last_known_property.Wind[0];
}
inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
{
check_cache_for_update();
return cache->last_known_property.Wind[1];
}
inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
{
check_cache_for_update();
return cache->last_known_property.Wind[2];
}
inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
{
check_cache_for_update();
return cache->last_known_property.Temperature;
}
inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
{
check_cache_for_update();
return cache->last_known_property.AirPressure;
}
inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
{
check_cache_for_update();
return cache->last_known_property.VaporPressure;
}
inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
{
// check_for_update();
// not required, as the called functions will do that
return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) /
(get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
}
/****************************************************************************/
#endif /*FGLocalWeatherDatabase_H*/