CM:
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:
parent
1de5373ed9
commit
20f50d349f
3 changed files with 199 additions and 35 deletions
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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*/
|
||||
|
|
Loading…
Add table
Reference in a new issue