]> git.mxchange.org Git - flightgear.git/commitdiff
CM:
authorcurt <curt>
Thu, 19 Jul 2001 22:10:14 +0000 (22:10 +0000)
committercurt <curt>
Thu, 19 Jul 2001 22:10:14 +0000 (22:10 +0000)
I've updated the WeatherDatabase to be able to use only the n closest
stations. This can speed up the initalization dramatically.

To take a benefit from that you need:

- http://129.13.102.67/out/flight/current.txt.gz in
  FG_ROOT/weather/current.txt.gz
- --prop:/environment/weather/working-type=internet
- --prop:/environment/weather/max-stations=what_ever_you_want

The WeatherCM stuff now publishes its data in the property system.

    /environment/weather/wind-north-mps
    /environment/weather/wind-east-mps
    /environment/weather/wind-up-mps
    /environment/weather/temperature-K
    /environment/weather/air-pressure-Pa
    /environment/weather/vapor-pressure-Pa
    /environment/weather/air-density

are the new properties.

src/Main/fg_init.cxx
src/WeatherCM/FGLocalWeatherDatabase.cpp
src/WeatherCM/FGLocalWeatherDatabase.h

index e69190122c481476acc28229186fa6d985979ba9..90c2edd194df841c80189c22ae616a5f4e8f3ed5 100644 (file)
@@ -661,19 +661,35 @@ bool fgInitSubsystems( void ) {
     sgSetVec3( position, current_aircraft.fdm_state->get_Latitude(),
               current_aircraft.fdm_state->get_Longitude(),
               current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER );
-    FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 
+    double init_vis = fgGetDouble("/environment/visibility-m");
+
+    FGLocalWeatherDatabase::DatabaseWorkingType working_type;
+
+    if (fgGetString("/environment/weather/working-type") == "internet")
+    {
+      working_type = FGLocalWeatherDatabase::use_internet;
+    } else {
+      working_type = FGLocalWeatherDatabase::default_mode;
+    }
+    
+    if ( init_vis > 0 ) {
+      FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 
        new FGLocalWeatherDatabase( position,
-                                   globals->get_fg_root() );
+                                   globals->get_fg_root(),
+                                    working_type,
+                                    init_vis );
+    } else {
+      FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 
+       new FGLocalWeatherDatabase( position,
+                                   globals->get_fg_root(),
+                                    working_type );
+    }
+
     // cout << theFGLocalWeatherDatabase << endl;
     // cout << "visibility = " 
     //      << theFGLocalWeatherDatabase->getWeatherVisibility() << endl;
 
     WeatherDatabase = FGLocalWeatherDatabase::theFGLocalWeatherDatabase;
-    
-    double init_vis = fgGetDouble("/environment/visibility-m");
-    if ( init_vis > 0 ) {
-       WeatherDatabase->setWeatherVisibility( init_vis );
-    }
 
     // register the periodic update of the weather
     global_events.Register( "weather update", fgUpdateWeatherDatabase,
index 36e13f5b5ec7149db18efbd2f2be09ba7d7ddbd1..262414451d3f80d581e0dd51cbbea35d16199291 100644 (file)
@@ -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 <simgear/constants.h>
 
 #include <Aircraft/aircraft.hxx>
+#include <Main/fg_props.hxx>
 
 #include "FGLocalWeatherDatabase.h"
 
@@ -104,30 +107,77 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
     case use_internet:
        {
            FGWeatherParse *parsed_data = new FGWeatherParse();
-
-           parsed_data->input( "weather/current.gz" );
+           sgVec2               *p;
+           FGPhysicalProperties *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 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 << ".";
+               }
+            }
+            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<float, unsigned int> 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 FGPhysicalProperties[m];
+
+                map<float, unsigned int>::const_iterator ci;
+                ci = squared_distance.begin();
+
+               // fill the database
+               for ( i = 0; i < m; i++ ) 
+                { 
+                   f[i] = 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<FGPhysicalProperties>(n, p, f);
+           cerr << "\nInitialiating Interpolation. (2-3 minutes on a PII-350 for ca. 3500 stations)\n";
+           database = new SphereInterpolate<FGPhysicalProperties>(m, p, f);
 
            //and free my allocations:
            delete[] p;
@@ -154,6 +204,18 @@ void FGLocalWeatherDatabase::init( const WeatherPrecision visibility,
     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"  );
+
+    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);
 }
 
 FGLocalWeatherDatabase::~FGLocalWeatherDatabase()
@@ -181,14 +243,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";
     */
@@ -197,7 +255,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);
 }
 
 /****************************************************************************/
@@ -254,8 +311,6 @@ void FGLocalWeatherDatabase::setProperties(const FGPhysicalProperties2D& x)
 void fgUpdateWeatherDatabase(void)
 {
     sgVec3 position;
-    sgVec3 wind;
-    
     
     sgSetVec3(position, 
         current_aircraft.fdm_state->get_Latitude(),
index a779a861a2366e735d6691673b4c3bf04c21f7ba..c3d5d1a3ccd26de7436e35e48f0e5f05437f6003 100644 (file)
@@ -42,6 +42,8 @@ HISTORY
                                 Eberly's spherical interpolation code. This
                                stops our dependancy on the (ugly) voronoi
                                code and simplyfies the code structure a lot.
+18.07.2001 Christian Mayer      Added the posibility to limit the amount of 
+                                stations for a faster init.
 *****************************************************************************/
 
 /****************************************************************************/
@@ -78,6 +80,16 @@ SG_USING_NAMESPACE(std);
 /****************************************************************************/
 /* CLASS DECLARATION                                                       */
 /****************************************************************************/
+struct _FGLocalWeatherDatabaseCache
+{
+    sgVec3             last_known_position;
+    //sgVec3             current_position;
+    SGPropertyNode     *latitude_deg;
+    SGPropertyNode     *longitude_deg;
+    SGPropertyNode     *altitude_ft;
+    FGPhysicalProperty last_known_property;
+};
+
 class FGLocalWeatherDatabase
 {
 private:
@@ -92,12 +104,25 @@ protected:
     /************************************************************************/
     WeatherPrecision WeatherVisibility;        //how far do I need to simulate the
                                        //local weather? Unit: metres
-    sgVec3 last_known_position;
+
+    _FGLocalWeatherDatabaseCache *cache;
+    inline void check_cache_for_update(void) const;
 
     bool Thunderstorm;                 //is there a thunderstorm near by?
     FGThunderstorm *theThunderstorm;   //pointer to the thunderstorm.
 
 public:
+    /************************************************************************/
+    /* for tieing them to the property system                              */
+    /************************************************************************/
+    inline WeatherPrecision get_wind_north() const;
+    inline WeatherPrecision get_wind_east() const;
+    inline WeatherPrecision get_wind_up() const;
+    inline WeatherPrecision get_temperature() const;
+    inline WeatherPrecision get_air_pressure() const;
+    inline WeatherPrecision get_vapor_pressure() const;
+    inline WeatherPrecision get_air_density() const;
+
     static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;  
     
     enum DatabaseWorkingType {
@@ -122,10 +147,11 @@ public:
     FGLocalWeatherDatabase(
        const sgVec3&             position,
        const string&             root,
-       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY,
-       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE)
+       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
+       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
     {
-       sgCopyVec3( last_known_position, position );
+        cache = new _FGLocalWeatherDatabaseCache;
+       sgCopyVec3( cache->last_known_position, position );
 
        init( visibility, type, root );
 
@@ -137,10 +163,11 @@ public:
        const WeatherPrecision    position_lon,
        const WeatherPrecision    position_alt,
        const string&             root,
-       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY,
-       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE)
+       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
+       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
     {
-       sgSetVec3( last_known_position, position_lat, position_lon, position_alt );
+        cache = new _FGLocalWeatherDatabaseCache;
+       sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
 
        init( visibility, type, root );
 
@@ -225,6 +252,72 @@ WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
     return WeatherVisibility;
 }
 
+inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
+{
+  if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
+       ( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
+       ( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
+    return; //nothing to do 
+
+  sgVec3 position = { cache->latitude_deg->getFloatValue(), 
+                      cache->longitude_deg->getFloatValue(), 
+                      cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
+
+  sgCopyVec3(cache->last_known_position, position);
+  cache->last_known_property = get(position);
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[0];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[1];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[2];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Temperature;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.AirPressure;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.VaporPressure;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
+{
+  // check_for_update();
+  // not required, as the called functions will do that
+
+  return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
+        (get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
+}
+
 
 /****************************************************************************/
 #endif /*FGLocalWeatherDatabase_H*/