From a8be680c43cbc24cd02985cfef2d882c6a36ad06 Mon Sep 17 00:00:00 2001 From: curt Date: Mon, 23 Feb 2004 01:39:12 +0000 Subject: [PATCH] Enhance the FGMetarEnvironmentCtrl class to also do on the fly weather updates based on the "closest" airport with metar data available. Note that the web based query is in the main loop and causes brief sim pauses. Update rate (once per minute) needs to be tweaked with, but is a good value for testing. --- src/Environment/environment_ctrl.cxx | 111 ++++++++++++++++----------- src/Environment/environment_ctrl.hxx | 7 +- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/src/Environment/environment_ctrl.cxx b/src/Environment/environment_ctrl.cxx index b987a6b6d..c03afd61c 100644 --- a/src/Environment/environment_ctrl.cxx +++ b/src/Environment/environment_ctrl.cxx @@ -319,17 +319,14 @@ FGInterpolateEnvironmentCtrl::bucket::operator< (const bucket &b) const FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl () : env( new FGInterpolateEnvironmentCtrl ), - _icao( strdup( fgGetString("/sim/presets/airport-id") ) ) + _icao( fgGetString("/sim/presets/airport-id") ), + update_interval_sec( 60.0 ), + elapsed( 60.0 ) { } FGMetarEnvironmentCtrl::~FGMetarEnvironmentCtrl () { - if (_icao) { - free(_icao); - _icao = NULL; - } - delete env; env = NULL; } @@ -357,14 +354,8 @@ static void set_dewpoint_at_altitude( float dewpoint_degc, float altitude_ft ) { void -FGMetarEnvironmentCtrl::init () +FGMetarEnvironmentCtrl::update_env_config () { - if (_icao != NULL) { - free(_icao); - _icao = NULL; - } - - fetch_data(_icao); fgSetupWind( fgGetDouble("/environment/metar/base-wind-range-from"), fgGetDouble("/environment/metar/base-wind-range-to"), fgGetDouble("/environment/metar/base-wind-speed-kt"), @@ -378,33 +369,43 @@ FGMetarEnvironmentCtrl::init () station_elevation_ft ); fgDefaultWeatherValue( "pressure-sea-level-inhg", fgGetDouble("/environment/metar/pressure-inhg") ); +} - env->init(); +void +FGMetarEnvironmentCtrl::init () +{ + const SGPropertyNode *longitude + = fgGetNode( "/position/longitude-deg", true ); + const SGPropertyNode *latitude + = fgGetNode( "/position/latitude-deg", true ); + + bool found_metar = false; + while ( !found_metar ) { + FGAirport a = globals->get_airports() + ->search( longitude->getDoubleValue(), + latitude->getDoubleValue(), + true ); + if ( fetch_data( a.id ) ) { + cout << "closest station w/ metar = " << a.id << endl; + _icao = a.id; + elapsed = 0.0; + update_env_config(); + env->init(); + found_metar = true; + } else { + // mark as no metar so it doesn't show up in subsequent + // searches. + cout << "no metar at metar = " << a.id << endl; + globals->get_airports()->no_metar( a.id ); + } + } } void FGMetarEnvironmentCtrl::reinit () { #if 0 - if (_icao != NULL) { - free(_icao); - _icao = NULL; - } - - fetch_data(_icao); - fgSetupWind( fgGetDouble("/environment/metar/base-wind-range-from"), - fgGetDouble("/environment/metar/base-wind-range-to"), - fgGetDouble("/environment/metar/base-wind-speed-kt"), - fgGetDouble("/environment/metar/gust-wind-speed-kt") ); - - fgDefaultWeatherValue( "visibility-m", - fgGetDouble("/environment/metar/min-visibility-m") ); - set_temp_at_altitude( fgGetDouble("/environment/metar/temperature-degc"), - station_elevation_ft ); - set_dewpoint_at_altitude( fgGetDouble("/environment/metar/dewpoint-degc"), - station_elevation_ft ); - fgDefaultWeatherValue( "pressure-sea-level-inhg", - fgGetDouble("/environment/metar/pressure-inhg") ); + update_env_config(); #endif env->reinit(); @@ -413,6 +414,29 @@ FGMetarEnvironmentCtrl::reinit () void FGMetarEnvironmentCtrl::update(double delta_time_sec) { + const SGPropertyNode *longitude + = fgGetNode( "/position/longitude-deg", true ); + const SGPropertyNode *latitude + = fgGetNode( "/position/latitude-deg", true ); + elapsed += delta_time_sec; + if ( elapsed > update_interval_sec ) { + FGAirport a = globals->get_airports() + ->search( longitude->getDoubleValue(), + latitude->getDoubleValue(), + true ); + if ( fetch_data( a.id ) ) { + cout << "closest station w/ metar = " << a.id << endl; + _icao = a.id; + elapsed = 0.0; + update_env_config(); + env->init(); + } else { + // mark as no metar so it doesn't show up in subsequent + // searches. + cout << "no metar at metar = " << a.id << endl; + globals->get_airports()->no_metar( a.id ); + } + } env->update(delta_time_sec); } @@ -422,21 +446,18 @@ FGMetarEnvironmentCtrl::setEnvironment (FGEnvironment * environment) env->setEnvironment(environment); } -void -FGMetarEnvironmentCtrl::fetch_data (const char *icao) +bool +FGMetarEnvironmentCtrl::fetch_data (const string &icao) { char s[128]; double d, dt; int i; - if ((icao == NULL) && (_icao == NULL)) { - _icao = strdup( fgGetString("/sim/presets/airport-id") ); + if ((icao == "") && (_icao == "")) { + _icao = fgGetString("/sim/presets/airport-id"); - } else if (icao != NULL) { - if (_icao != NULL) - free(_icao); - - _icao = strdup(icao); + } else if (icao != "") { + _icao = icao; } // fetch station elevation if exists @@ -446,11 +467,11 @@ FGMetarEnvironmentCtrl::fetch_data (const char *icao) // fetch current metar data SGMetar *m; try { - m = new SGMetar(_icao); + m = new SGMetar( _icao.c_str() ); } catch (const sg_io_exception& e) { SG_LOG( SG_GENERAL, SG_WARN, "Error fetching live weather data: " << e.getFormattedMessage().c_str() ); - return; + return false; } d = m->getMinVisibility().getVisibility_m(); @@ -557,6 +578,8 @@ FGMetarEnvironmentCtrl::fetch_data (const char *icao) } delete m; + + return true; } diff --git a/src/Environment/environment_ctrl.hxx b/src/Environment/environment_ctrl.hxx index 343359ca9..61617a3fc 100644 --- a/src/Environment/environment_ctrl.hxx +++ b/src/Environment/environment_ctrl.hxx @@ -153,9 +153,12 @@ public: private: FGInterpolateEnvironmentCtrl *env; - char *_icao; + string _icao; float station_elevation_ft; - void fetch_data (const char *icao); + float update_interval_sec; + float elapsed; + bool fetch_data (const string &icao); + void update_env_config(); }; #endif // _ENVIRONMENT_CTRL_HXX