X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FWeatherCM%2FFGLocalWeatherDatabase.cpp;h=0ad64b9fa2a0587e266027d622b625fe26d77c0e;hb=a4e81f4ff075e6a3c0c2ea1b5a29c0bcdfdbc671;hp=e17d3ce67c469c473cf92b6cb5e5bea6d69bad1d;hpb=6ccc92a666d286ab5c979f7de9ce3955f74cc64f;p=flightgear.git diff --git a/src/WeatherCM/FGLocalWeatherDatabase.cpp b/src/WeatherCM/FGLocalWeatherDatabase.cpp index e17d3ce67..0ad64b9fa 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" @@ -85,7 +88,7 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility, setWeatherVisibility(visibility); DatabaseStatus = type; - database = 0; //just get sure... + database_logic = 0; //just get sure... Thunderstorm = false; //I don't need to set theThunderstorm as Thunderstorm == false @@ -102,30 +105,79 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility, case use_internet: { FGWeatherParse *parsed_data = new FGWeatherParse(); - - parsed_data->input( "weather/current.gz" ); + sgVec2 *p; + unsigned int *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 unsigned int[n]; + + // fill the database + for (unsigned int i = 0; i < n; i++) + { + f[i] = i; + database_data[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 unsigned int[m]; + + map::const_iterator ci; + ci = squared_distance.begin(); + + // fill the database + for ( i = 0; i < m; i++ ) + { + f[i] = i; + database_data.push_back( 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_logic = new SphereInterpolate(m, p, f); //and free my allocations: delete[] p; @@ -145,20 +197,134 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility, double x[2] = {0.0, 0.0}; //make an standard weather that's the same at the whole world double y[2] = {0.0, 0.0}; //make an standard weather that's the same at the whole world double z[2] = {1.0, -1.0}; //make an standard weather that's the same at the whole world - FGPhysicalProperties f[2]; //make an standard weather that's the same at the whole world - database = new SphereInterpolate(2,x,y,z,f); + unsigned int f[2] = {0, 0}; + database_data.push_back( FGPhysicalProperties() ); // == database_date[0] + database_logic = new SphereInterpolate(2,x,y,z,f); } break; 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" ); + +} + +void FGLocalWeatherDatabase::bind() +{ + 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); + + + SGPropertyNode * station_nodes = fgGetNode("/environment/weather"); + if (station_nodes == 0) { + cerr << "No weatherstations (/environment/weather)!!"; + return; + } + + int index = 0; + for(vector::iterator it = database_data.begin(); it != database_data.end(); it++) + { + SGPropertyNode * station = station_nodes->getNode("station", index, true); + + station -> tie("air-pressure-Pa", + SGRawValueMethods( + database_data[0].AirPressure, + &FGAirPressureItem::getValue, + &FGAirPressureItem::setValue) + ,false); + + int i; + for( i = 0; i < database_data[index].Wind.size(); i++) + { + SGPropertyNode * wind = station->getNode("wind", i, true); + wind -> tie("north-mps", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getWind_x, + &FGPhysicalProperties::setWind_x) + ,false); + wind -> tie("east-mps", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getWind_y, + &FGPhysicalProperties::setWind_y) + ,false); + wind -> tie("up-mps", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getWind_z, + &FGPhysicalProperties::setWind_z) + ,false); + wind -> tie("altitude-m", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getWind_a, + &FGPhysicalProperties::setWind_a) + ,false); + } + + for( i = 0; i < database_data[index].Temperature.size(); i++) + { + SGPropertyNode * temperature = station->getNode("temperature", i, true); + temperature -> tie("value-K", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getTemperature_x, + &FGPhysicalProperties::setTemperature_x) + ,false); + temperature -> tie("altitude-m", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getTemperature_a, + &FGPhysicalProperties::setTemperature_a) + ,false); + } + + for( i = 0; i < database_data[index].VaporPressure.size(); i++) + { + SGPropertyNode * vaporpressure = station->getNode("vapor-pressure", i, true); + vaporpressure -> tie("value-Pa", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getVaporPressure_x, + &FGPhysicalProperties::setVaporPressure_x) + ,false); + vaporpressure -> tie("altitude-m", + SGRawValueMethodsIndexed( + database_data[index], i, + &FGPhysicalProperties::getVaporPressure_a, + &FGPhysicalProperties::setVaporPressure_a) + ,false); + } + + index++; + } +} + +void FGLocalWeatherDatabase::unbind() +{ + fgUntie("/environment/weather/wind-north-mps"); + fgUntie("/environment/weather/wind-east-mps"); + fgUntie("/environment/weather/wind-up-mps"); + fgUntie("/environment/weather/temperature-K"); + fgUntie("/environment/weather/air-pressure-Pa"); + fgUntie("/environment/weather/vapor-pressure-Pa"); + fgUntie("/environment/weather/air-density"); } FGLocalWeatherDatabase::~FGLocalWeatherDatabase() { //Tidying up: - delete database; + delete database_logic; } /****************************************************************************/ @@ -180,14 +346,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"; */ @@ -196,7 +358,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); } /****************************************************************************/ @@ -204,7 +365,12 @@ void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) /****************************************************************************/ FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const { - return FGPhysicalProperty(database->Evaluate(p), p[2]); + // check for bogous altitudes. Dunno why, but FGFS want's to know the + // weather at an altitude of roughly -3000 meters... + if (p[2] < -500.0f) + return FGPhysicalProperty(DatabaseEvaluate(p), -500.0f); + + return FGPhysicalProperty(DatabaseEvaluate(p), p[2]); } #ifdef macintosh @@ -216,13 +382,13 @@ FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const #else FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const { - return database->Evaluate(p); + return DatabaseEvaluate(p); } #endif WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const { - FGPhysicalProperty dummy(database->Evaluate(p), p[2]); + FGPhysicalProperty dummy(DatabaseEvaluate(p), p[2]); return (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / @@ -253,13 +419,11 @@ void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x) void fgUpdateWeatherDatabase(void) { sgVec3 position; - sgVec3 wind; - sgSetVec3(position, current_aircraft.fdm_state->get_Latitude(), current_aircraft.fdm_state->get_Longitude(), - current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER); + current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER); WeatherDatabase->update( position );