X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FWeatherCM%2FFGLocalWeatherDatabase.cpp;h=ba4da125429df2b0e32de198b2c4044fed34f1b1;hb=485230b443de22c97d5c4ddfda98598fb52ce98a;hp=761c5e25cc80f5d510dd1d03a375c3e1362081a1;hpb=a0aee5d8666c654dbe9b9076c2b8ab39ac9ed8a6;p=flightgear.git diff --git a/src/WeatherCM/FGLocalWeatherDatabase.cpp b/src/WeatherCM/FGLocalWeatherDatabase.cpp index 761c5e25c..ba4da1254 100644 --- a/src/WeatherCM/FGLocalWeatherDatabase.cpp +++ b/src/WeatherCM/FGLocalWeatherDatabase.cpp @@ -5,7 +5,7 @@ Date started: 28.05.99 Called by: main program - ---------- Copyright (C) 1999 Christian Mayer (vader@t-online.de) ---------- + -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) -------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -34,87 +34,96 @@ HISTORY 28.05.1999 Christian Mayer Created 16.06.1999 Durk Talsma Portability for Linux 20.06.1999 Christian Mayer added lots of consts +11.10.1999 Christian Mayer changed set<> to map<> on Bernie Bright's + suggestion +19.10.1999 Christian Mayer change to use PLIB's sg instead of Point[2/3]D + and lots of wee code cleaning +14.12.1999 Christian Mayer Changed the internal structure to use Dave + Eberly's spherical interpolation code. This + stops our dependancy on the (ugly) voronoi + code and simplyfies the code structure a lot. *****************************************************************************/ /****************************************************************************/ /* INCLUDES */ /****************************************************************************/ -#include "FGLocalWeatherDatabase.h" -#include "FGVoronoi.h" -#include "fg_constants.h" +#include +#include #include -#include - -/****************************************************************************/ -/********************************** CODE ************************************/ -/****************************************************************************/ -/****************************************************************************/ -/* return the index (better: ID) of the area with point p */ -/****************************************************************************/ -unsigned int FGLocalWeatherDatabase::AreaWith(const Point2D& p) const -{ - - for (FGMicroWeatherList::size_type i = 0; i != WeatherAreas.size(); i++) - { - if (WeatherAreas[i].hasPoint(p) == true) - return i+1; - } +#include "FGLocalWeatherDatabase.h" - return 0; //nothing found -} +#include "FGWeatherParse.h" /****************************************************************************/ -/* make tiles out of points on a 2D plane */ +/********************************** CODE ************************************/ /****************************************************************************/ -void FGLocalWeatherDatabase::tileLocalWeather(const FGPhysicalProperties2DVector& EntryList) -{ - FGVoronoiInputList input; - - for (FGPhysicalProperties2DVector::const_iterator it1 = EntryList.begin(); it1 != EntryList.end(); it1++) - input.push_back(FGVoronoiInput(it1->p, *it1)); - FGVoronoiOutputList output = Voronoiate(input); - - for (FGVoronoiOutputList::iterator it2 = output.begin(); it2 != output.end(); it2++) - WeatherAreas.push_back(FGMicroWeather(it2->value, it2->boundary)); -} - -/****************************************************************************/ -/* Constructor and Destructor */ -/****************************************************************************/ FGLocalWeatherDatabase* FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 0; FGLocalWeatherDatabase *WeatherDatabase; -FGLocalWeatherDatabase::FGLocalWeatherDatabase(const Point3D& posititon, const WeatherPrecition& visibility, const DatabaseWorkingType& type) +void FGLocalWeatherDatabase::init(const WeatherPrecision visibility, const DatabaseWorkingType type) { cerr << "Initializing FGLocalWeatherDatabase\n"; cerr << "-----------------------------------\n"; if (theFGLocalWeatherDatabase) { - //FG_LOG( FG_GENERAL, FG_ALERT, "Error: only one local weather allowed" ); cerr << "Error: only one local weather allowed"; exit(-1); } setWeatherVisibility(visibility); - //WeatherVisibility = visibility; - DatabaseStatus = type; - global = 0; //just get sure... - last_known_position = posititon; + DatabaseStatus = type; + database = 0; //just get sure... - theFGLocalWeatherDatabase = this; + Thunderstorm = false; + //I don't need to set theThunderstorm as Thunderstorm == false switch(DatabaseStatus) { case use_global: { - global = new FGGlobalWeatherDatabase; //initialize GlobalDatabase - global->setDatabaseStatus(FGGlobalWeatherDatabase_working); - tileLocalWeather(global->getAll(posititon, WeatherVisibility, 3)); + cerr << "Error: there's no global database anymore!\n"; + exit(-1); + } + break; + + case use_internet: + { + FGWeatherParse *parsed_data = new FGWeatherParse(); + + parsed_data->input( "weather/current.gz" ); + 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 << "."; + } + + // 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); + + //and free my allocations: + delete[] p; + delete[] f; + cerr << "Finished weather init.\n"; + } break; @@ -125,8 +134,11 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const Point3D& posititon, const W case manual: case default_mode: { - vector emptyList; - WeatherAreas.push_back(FGMicroWeather(FGPhysicalProperties2D(), emptyList)); //in these cases I've only got one tile + 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); } break; @@ -138,228 +150,106 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const Point3D& posititon, const W FGLocalWeatherDatabase::~FGLocalWeatherDatabase() { //Tidying up: - - //delete every stored area - WeatherAreas.erase(WeatherAreas.begin(), WeatherAreas.end()); - - //delete global database if necessary - if (DatabaseStatus == use_global) - delete global; + delete database; } /****************************************************************************/ /* reset the whole database */ /****************************************************************************/ -void FGLocalWeatherDatabase::reset(const DatabaseWorkingType& type) +void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type) { - //delete global database if necessary - if ((DatabaseStatus == use_global) && (type != use_global)) - delete global; - - DatabaseStatus = type; - if (DatabaseStatus == use_global) - tileLocalWeather(global->getAll(last_known_position, WeatherVisibility, 3)); - - //delete every stored area - WeatherAreas.erase(WeatherAreas.begin(), WeatherAreas.end()); + cerr << "FGLocalWeatherDatabase::reset isn't supported yet\n"; } /****************************************************************************/ /* update the database. Since the last call we had dt seconds */ /****************************************************************************/ -void FGLocalWeatherDatabase::update(const WeatherPrecition& dt) +void FGLocalWeatherDatabase::update(const WeatherPrecision dt) { - if (DatabaseStatus==use_global) - global->update(dt); + //if (DatabaseStatus==use_global) + // global->update(dt); } -void FGLocalWeatherDatabase::update(const Point3D& p) //position has changed +void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed { - last_known_position = p; - //cerr << "****\nupdate inside\n"; - //cerr << "Parameter: " << p << "\n"; - //cerr << "****\n"; + 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"; + */ + } -void FGLocalWeatherDatabase::update(const Point3D& p, const WeatherPrecition& dt) //time and/or position has changed +void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt) //time and/or position has changed { - last_known_position = p; - - if (DatabaseStatus==use_global) - global->update(dt); + sgCopyVec3(last_known_position, p); } /****************************************************************************/ /* Get the physical properties on the specified point p out of the database */ /****************************************************************************/ -FGPhysicalProperty FGLocalWeatherDatabase::get(const Point3D& p) const -{ - unsigned int a = AreaWith(p); - if (a != 0) - return WeatherAreas[a-1].get(p.elev()); - else //point is outside => ask GlobalWeatherDatabase - return global->get(p); -} - FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const { - Point3D temp(p[0], p[1], p[2]); - - unsigned int a = AreaWith(temp); - if (a != 0) - return WeatherAreas[a-1].get(temp.elev()); - else //point is outside => ask GlobalWeatherDatabase - return global->get(temp); + return FGPhysicalProperty(database->Evaluate(p), p[3]); } -WeatherPrecition FGLocalWeatherDatabase::getAirDensity(const Point3D& p) const +#ifdef MACOS + /* fix a problem with mw compilers in that they don't know the + difference between the next two methods. Since the first one + doesn't seem to be used anywhere, I commented it out. This is + supposed to be fixed in the forthcoming CodeWarrior Release + 6. */ +#else +FGPhysicalProperties FGLocalWeatherDatabase::get(const sgVec2& p) const { - FGPhysicalProperty dummy; - unsigned int a = AreaWith(p); - if (a != 0) - dummy = WeatherAreas[a-1].get(p.elev()); - else //point is outside => ask GlobalWeatherDatabase - dummy = global->get(p); - - return - (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / - (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE); + return database->Evaluate(p); } +#endif -WeatherPrecition FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const +WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const { - Point3D temp(p[0], p[1], p[2]); - - FGPhysicalProperty dummy; - unsigned int a = AreaWith(temp); - if (a != 0) - dummy = WeatherAreas[a-1].get(temp.elev()); - else //point is outside => ask GlobalWeatherDatabase - dummy = global->get(temp); + FGPhysicalProperty dummy(database->Evaluate(p), p[3]); return (dummy.AirPressure*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / (dummy.Temperature*FG_WEATHER_DEFAULT_AIRPRESSURE); } -/****************************************************************************/ -/* Add a weather feature at the point p and surrounding area */ -/****************************************************************************/ -void FGLocalWeatherDatabase::addWind(const FGWindItem& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addWind(x); -} - -void FGLocalWeatherDatabase::addTurbulence(const FGTurbulenceItem& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addTurbulence(x); -} -void FGLocalWeatherDatabase::addTemperature(const FGTemperatureItem& x, const Point2D& p) +void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p) { - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addTemperature(x); + /* not supported yet */ } -void FGLocalWeatherDatabase::addAirPressure(const FGAirPressureItem& x, const Point2D& p) +void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p) { - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addAirPressure(x); + /* not supported yet */ } -void FGLocalWeatherDatabase::addVaporPressure(const FGVaporPressureItem& x, const Point2D& p) +void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& p) { - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addVaporPressure(x); -} - -void FGLocalWeatherDatabase::addCloud(const FGCloudItem& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].addCloud(x); -} - -void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecition& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].setSnowRainIntensity(x); -} - -void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].setSnowRainType(x); -} - -void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecition& x, const Point2D& p) -{ - unsigned int a = AreaWith(p); - if (a != 0) - WeatherAreas[a-1].setLightningProbability(x); -} - -void FGLocalWeatherDatabase::addProperties(const FGPhysicalProperties2D& x) -{ - if (DatabaseStatus==use_global) - { - global->add(x); - - //BAD, BAD, BAD thing I'm doing here: I'm adding to the global database a point that - //changes my voronoi diagram but I don't update it! instead I'm changing one local value - //that could be anywhere!! - //This only *might* work when the plane moves so far so fast that the diagram gets new - //calculated soon... - unsigned int a = AreaWith(x.p); - if (a != 0) - WeatherAreas[a-1].setStoredWeather(x); - } - else - { - unsigned int a = AreaWith(x.p); - if (a != 0) - WeatherAreas[a-1].setStoredWeather(x); - } + /* not supported yet */ } void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x) { - if (DatabaseStatus==use_global) - { - global->change(x); - - //BAD, BAD, BAD thing I'm doing here: I'm adding to the global database a point that - //changes my voronoi diagram but I don't update it! Instead I'm changing one local value - //that could be anywhere!! - //This only *might* work when the plane moves so far so fast that the diagram gets newly - //calculated soon... - unsigned int a = AreaWith(x.p); - if (a != 0) - WeatherAreas[a-1].setStoredWeather(x); - } - else - { - unsigned int a = AreaWith(x.p); - if (a != 0) - WeatherAreas[a-1].setStoredWeather(x); - } + /* not supported yet */ } void fgUpdateWeatherDatabase(void) { - //cerr << "FGLocalWeatherDatabase::update()\n"; - WeatherDatabase->update( Point3D( + sgVec3 position; + 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() * FEET_TO_METER); + + WeatherDatabase->update( position ); }