]> git.mxchange.org Git - flightgear.git/blobdiff - src/WeatherCM/FGLocalWeatherDatabase.cpp
Code reorganization.
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.cpp
index 761c5e25cc80f5d510dd1d03a375c3e1362081a1..ba4da125429df2b0e32de198b2c4044fed34f1b1 100644 (file)
@@ -5,7 +5,7 @@
  Date started: 28.05.99
  Called by:    main program
 
  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
 
  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
 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                                                                */
 /****************************************************************************/
 *****************************************************************************/
 
 /****************************************************************************/
 /* INCLUDES                                                                */
 /****************************************************************************/
-#include "FGLocalWeatherDatabase.h"
-#include "FGVoronoi.h"
-#include "fg_constants.h"
+#include <simgear/compiler.h>
+#include <simgear/constants.h>
 
 #include <Aircraft/aircraft.hxx>
 
 #include <Aircraft/aircraft.hxx>
-#include <Include/fg_constants.h>
-
-/****************************************************************************/
-/********************************** 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::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)
     {
 {
     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);
        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:
        {
 
     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;
 
        }
        break;
 
@@ -125,8 +134,11 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const Point3D& posititon, const W
     case manual:
     case default_mode:
        {
     case manual:
     case default_mode:
        {
-           vector<Point2D> 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;
 
        }
        break;
 
@@ -138,228 +150,106 @@ FGLocalWeatherDatabase::FGLocalWeatherDatabase(const Point3D& posititon, const W
 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
 {
     //Tidying up:
 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                                                */
 /****************************************************************************/
 }
 
 /****************************************************************************/
 /* 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              */
 /****************************************************************************/
 }
 
 /****************************************************************************/
 /* 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 */
 /****************************************************************************/
 }
 
 /****************************************************************************/
 /* 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
 {
 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);
 }
 
 
     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)
 {
 }
 
 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)
 {
 }
 
 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_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 );
 }
 
 }