]> git.mxchange.org Git - flightgear.git/blobdiff - src/WeatherCM/FGLocalWeatherDatabase.cpp
Continuing work on ssg-ifying the sky dome.
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.cpp
index f88e87b7e46e157d8a845d8fa0a2c469c545f4e8..ba4da125429df2b0e32de198b2c4044fed34f1b1 100644 (file)
@@ -38,69 +38,38 @@ HISTORY
                                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 <Include/compiler.h>
-#include <Include/fg_constants.h>
+#include <simgear/compiler.h>
+#include <simgear/constants.h>
 
 #include <Aircraft/aircraft.hxx>
 
 #include "FGLocalWeatherDatabase.h"
-#include "FGVoronoi.h"
 
+#include "FGWeatherParse.h"
 
 /****************************************************************************/
 /********************************** CODE ************************************/
 /****************************************************************************/
 
-/****************************************************************************/
-/* return the index (better: ID) of the area with point p                  */
-/****************************************************************************/
-unsigned int FGLocalWeatherDatabase::AreaWith(const sgVec2& p) const
-{
-    
-    for (FGMicroWeatherList::size_type i = 0; i != WeatherAreas.size(); i++)
-    {
-       if (WeatherAreas[i].hasPoint(p) == true)
-           return i+1;
-    }
-
-    return 0;  //nothing found
-}
-
-/****************************************************************************/
-/* make tiles out of points on a 2D plane                                  */
-/****************************************************************************/
-void FGLocalWeatherDatabase::tileLocalWeather(const FGPhysicalProperties2DVector& EntryList)
-{
-    FGVoronoiInputList input;
-
-    for (FGPhysicalProperties2DVectorConstIt 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 sgVec3& posititon, const WeatherPrecision 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);
     }
@@ -108,19 +77,53 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const sgVec3& posititon, const We
     setWeatherVisibility(visibility);
 
     DatabaseStatus = type;
-    global = 0;            //just get sure...
-    sgCopyVec3(last_known_position, posititon);
-
+    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<FGPhysicalProperties>(n, p, f);
+
+           //and free my allocations:
+           delete[] p;
+           delete[] f;
+           cerr << "Finished weather init.\n";
+
        }
        break;
 
@@ -131,8 +134,11 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const sgVec3& posititon, const We
     case manual:
     case default_mode:
        {
-           vector<sgVec2Wrap> 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<FGPhysicalProperties>(2,x,y,z,f);
        }
        break;
 
@@ -144,13 +150,7 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const sgVec3& posititon, const We
 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;
 }
 
 /****************************************************************************/
@@ -158,16 +158,7 @@ FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
 /****************************************************************************/
 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";
 }
 
 /****************************************************************************/
@@ -175,24 +166,29 @@ void FGLocalWeatherDatabase::reset(const DatabaseWorkingType type)
 /****************************************************************************/
 void FGLocalWeatherDatabase::update(const WeatherPrecision dt)
 {
-    if (DatabaseStatus==use_global)
-       global->update(dt);
+    //if (DatabaseStatus==use_global)
+    // global->update(dt);
 }
 
 void FGLocalWeatherDatabase::update(const sgVec3& p) //position has changed
 {
     sgCopyVec3(last_known_position, p);
-    //cerr << "****\nupdate inside\n";
-    //cerr << "Parameter: " << p << "\n";
-    //cerr << "****\n";
+
+    //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 sgVec3& p, const WeatherPrecision dt)   //time and/or position has changed
 {
     sgCopyVec3(last_known_position, p);
-
-    if (DatabaseStatus==use_global)
-       global->update(dt);
 }
 
 /****************************************************************************/
@@ -200,154 +196,54 @@ void FGLocalWeatherDatabase::update(const sgVec3& p, const WeatherPrecision dt)
 /****************************************************************************/
 FGPhysicalProperty FGLocalWeatherDatabase::get(const sgVec3& p) const
 {
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       return WeatherAreas[a-1].get(p[3]);
-    else    //point is outside => ask GlobalWeatherDatabase
-       return global->get(p);
+    return FGPhysicalProperty(database->Evaluate(p), p[3]);
 }
 
+#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
 {
-    sgVec3 temp;
-    sgSetVec3(temp, p[0], p[1], 0.0);
-
-    unsigned int a = AreaWith(temp);
-    if (a != 0)
-       return WeatherAreas[a-1].get();
-    else    //point is outside => ask GlobalWeatherDatabase
-       return global->get(p);
+    return database->Evaluate(p);
 }
+#endif
 
 WeatherPrecision FGLocalWeatherDatabase::getAirDensity(const sgVec3& p) const
 {
-    FGPhysicalProperty dummy;
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       dummy = WeatherAreas[a-1].get(p[3]);
-    else    //point is outside => ask GlobalWeatherDatabase
-       dummy = global->get(p);
+    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 WeatherPrecision alt, const sgVec3& x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addWind(alt, x);
-}
-
-void FGLocalWeatherDatabase::addTurbulence(const WeatherPrecision alt, const sgVec3& x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addTurbulence(alt, x);
-}
-
-void FGLocalWeatherDatabase::addTemperature(const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addTemperature(alt, x);
-}
-
-void FGLocalWeatherDatabase::addAirPressure(const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addAirPressure(alt, x);
-}
-
-void FGLocalWeatherDatabase::addVaporPressure(const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addVaporPressure(alt, x);
-}
-
-void FGLocalWeatherDatabase::addCloud(const WeatherPrecision alt, const FGCloudItem& x, const sgVec2& p)
-{
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].addCloud(alt, x);
-}
 
 void FGLocalWeatherDatabase::setSnowRainIntensity(const WeatherPrecision x, const sgVec2& p)
 {
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].setSnowRainIntensity(x);
+    /* not supported yet */
 }
 
 void FGLocalWeatherDatabase::setSnowRainType(const SnowRainType x, const sgVec2& p)
 {
-    unsigned int a = AreaWith(p);
-    if (a != 0)
-       WeatherAreas[a-1].setSnowRainType(x);
+    /* not supported yet */
 }
 
 void FGLocalWeatherDatabase::setLightningProbability(const WeatherPrecision x, const sgVec2& 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";
     sgVec3 position;
     sgSetVec3(position, 
        current_aircraft.fdm_state->get_Latitude(),