From: curt Date: Thu, 19 Jul 2001 22:10:14 +0000 (+0000) Subject: CM: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=20f50d349f6011439ea5559a134abc7bd6a9ecf3;p=flightgear.git 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. --- diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index e69190122..90c2edd19 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -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, diff --git a/src/WeatherCM/FGLocalWeatherDatabase.cpp b/src/WeatherCM/FGLocalWeatherDatabase.cpp index 36e13f5b5..262414451 100644 --- a/src/WeatherCM/FGLocalWeatherDatabase.cpp +++ b/src/WeatherCM/FGLocalWeatherDatabase.cpp @@ -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 #include +#include
#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(); - - sgVec2 *p = new sgVec2 [n]; - FGPhysicalProperties *f = new FGPhysicalProperties[n]; - - // 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 << "."; - } + int m = fgGetInt("/environment/weather/max-stations", -1); + + if ( ( m < 0 ) || ( m > n ) ) + { + m = n; + + p = new sgVec2 [n]; + f = new FGPhysicalProperties[n]; + + // 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 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::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(n, p, f); + cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350 for ca. 3500 stations)\n"; + database = new SphereInterpolate(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(), diff --git a/src/WeatherCM/FGLocalWeatherDatabase.h b/src/WeatherCM/FGLocalWeatherDatabase.h index a779a861a..c3d5d1a3c 100644 --- a/src/WeatherCM/FGLocalWeatherDatabase.h +++ b/src/WeatherCM/FGLocalWeatherDatabase.h @@ -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*/