]> git.mxchange.org Git - flightgear.git/blobdiff - src/Environment/environment_ctrl.cxx
Development for two new features:
[flightgear.git] / src / Environment / environment_ctrl.cxx
index 5d4494b051da8a7030c5f5b6e94f9d7599382ee9..cf9c6505faefd68dff5f2cdfabb23f86666f19d2 100644 (file)
@@ -24,8 +24,6 @@
 #  include "config.h"
 #endif
 
-#include <stdlib.h>
-#include <math.h>
 #include <algorithm>
 
 #include <simgear/debug/logstream.hxx>
 #include <Main/fg_props.hxx>
 #include <Main/util.hxx>
 
+#include "Environment/fgmetar.hxx"
 #include "environment_mgr.hxx"
 #include "environment_ctrl.hxx"
 
 using std::sort;
 
-class metar_filter : public FGAirportSearchFilter {
-    virtual bool pass(FGAirport *a) { return a->getMetar(); }
-} metar_only;
-
+class AirportWithMetar : public FGAirport::AirportFilter
+{
+public:
+  virtual bool passAirport(FGAirport* aApt) const
+  {
+    return aApt->getMetar();
+  }
+};
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGEnvironmentCtrl abstract base class.
@@ -328,7 +331,6 @@ FGInterpolateEnvironmentCtrl::bucket::lessThan(bucket *a, bucket *b)
 
 FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl ()
     : env( new FGInterpolateEnvironmentCtrl ),
-      _icao( "" ),
       metar_loaded( false ),
       search_interval_sec( 60.0 ),        // 1 minute
       same_station_interval_sec( 900.0 ), // 15 minutes
@@ -649,10 +651,9 @@ double FGMetarEnvironmentCtrl::interpolate_val(double currentval,
 void
 FGMetarEnvironmentCtrl::init ()
 {
-    const SGPropertyNode *longitude
-        = fgGetNode( "/position/longitude-deg", true );
-    const SGPropertyNode *latitude
-        = fgGetNode( "/position/latitude-deg", true );
+    SGGeod pos = SGGeod::fromDeg(
+      fgGetDouble("/position/longitude-deg", true), 
+      fgGetDouble( "/position/latitude-deg", true));
 
     metar_loaded = false;
     bool found_metar = false;
@@ -663,33 +664,31 @@ FGMetarEnvironmentCtrl::init ()
     metar_max_age->setLongValue(0);
 
     while ( !found_metar && (_error_count < 3) ) {
-        const FGAirport* a = globals->get_airports()
-                   ->search( longitude->getDoubleValue(),
-                             latitude->getDoubleValue(),
-                             360.0,
-                             metar_only );
-        if ( a ) {  
-            FGMetarResult result = fetch_data( a->getId() );
-            if ( result.m != NULL ) {
-                SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
-                        << a->getId());
-                last_apt = a;
-                _icao = a->getId();
-                search_elapsed = 0.0;
-                fetch_elapsed = 0.0;
-                update_metar_properties( result.m );
-                update_env_config();
-                env->init();
-                found_metar = true;
-            } else {
-                // mark as no metar so it doesn't show up in subsequent
-                // searches.
-                SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = "
-                        << a->getId() );
-                globals->get_airports()->no_metar( a->getId() );
-            }
+        AirportWithMetar filter;
+        FGAirport* a = FGAirport::findClosest(pos, 10000.0, &filter);
+        if (!a) {
+          break;
         }
-    }
+        
+        FGMetarResult result = fetch_data(a);
+        if ( result.m != NULL ) {
+            SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
+                    << a->ident());
+            last_apt = a;
+            search_elapsed = 0.0;
+            fetch_elapsed = 0.0;
+            update_metar_properties( result.m );
+            update_env_config();
+            env->init();
+            found_metar = true;
+        } else {
+            // mark as no metar so it doesn't show up in subsequent
+            // searches.
+            SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a->ident() );
+            a->setMetar(false);
+        }
+    } // of airprot-with-metar search iteration
+    
     metar_max_age->setLongValue(max_age);
 }
 
@@ -706,7 +705,6 @@ FGMetarEnvironmentCtrl::reinit ()
 void
 FGMetarEnvironmentCtrl::update(double delta_time_sec)
 {
-
     _dt += delta_time_sec;
     if (_error_count >= 3)
        return;
@@ -717,6 +715,9 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
         = fgGetNode( "/position/longitude-deg", true );
     static const SGPropertyNode *latitude
         = fgGetNode( "/position/latitude-deg", true );
+    SGGeod pos = SGGeod::fromDeg(longitude->getDoubleValue(), 
+      latitude->getDoubleValue());
+        
     search_elapsed += delta_time_sec;
     fetch_elapsed += delta_time_sec;
     interpolate_elapsed += delta_time_sec;
@@ -724,20 +725,16 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
     // if time for a new search request, push it onto the request
     // queue
     if ( search_elapsed > search_interval_sec ) {
-        const FGAirport* a = globals->get_airports()
-                   ->search( longitude->getDoubleValue(),
-                             latitude->getDoubleValue(),
-                             360.0,
-                             metar_only );
-        if ( a ) {
-            if ( !last_apt || last_apt->getId() != a->getId()
+        AirportWithMetar filter;
+        FGAirport* a = FGAirport::findClosest(pos, 10000.0, &filter);
+        if (a) {
+          if ( !last_apt || last_apt->ident() != a->ident()
                  || fetch_elapsed > same_station_interval_sec )
             {
                 SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
-                        << a->getId());
-                request_queue.push( a->getId() );
+                        << a->ident());
+                request_queue.push(a);
                 last_apt = a;
-                _icao = a->getId();
                 search_elapsed = 0.0;
                 fetch_elapsed = 0.0;
             } else {
@@ -745,8 +742,9 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
                 SG_LOG( SG_GENERAL, SG_INFO, "same station, waiting = "
                         << same_station_interval_sec - fetch_elapsed );
             }
+
         } else {
-            SG_LOG( SG_GENERAL, SG_WARN,
+          SG_LOG( SG_GENERAL, SG_WARN,
                     "Unable to find any airports with metar" );
         }
     } else if ( interpolate_elapsed > EnvironmentUpdatePeriodSec ) {
@@ -758,15 +756,15 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
 
 #if !defined(ENABLE_THREADS)
     // No loader thread running so manually fetch the data
-    string id = "";
+    FGAirport* apt = NULL;
     while ( !request_queue.empty() ) {
-        id = request_queue.front();
+        apt = request_queue.front();
         request_queue.pop();
     }
 
-    if ( !id.empty() ) {
-        SG_LOG( SG_GENERAL, SG_INFO, "inline fetching = " << id );
-        result = fetch_data( id );
+    if (apt) {
+        SG_LOG( SG_GENERAL, SG_INFO, "inline fetching = " << apt->ident() );
+        result = fetch_data( apt );
         result_queue.push( result );
     }
 #endif // ENABLE_THREADS
@@ -784,8 +782,8 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
             // mark as no metar so it doesn't show up in subsequent
             // searches, and signal an immediate re-search.
             SG_LOG( SG_GENERAL, SG_WARN,
-                    "no metar at station = " << result.icao );
-            globals->get_airports()->no_metar( result.icao );
+                    "no metar at station = " << result.airport->ident() );
+            result.airport->setMetar(false);
             search_elapsed = 9999.0;
         }
     }
@@ -801,10 +799,10 @@ FGMetarEnvironmentCtrl::setEnvironment (FGEnvironment * environment)
 }
 
 FGMetarResult
-FGMetarEnvironmentCtrl::fetch_data( const string &icao )
+FGMetarEnvironmentCtrl::fetch_data(FGAirport* apt)
 {
     FGMetarResult result;
-    result.icao = icao;
+    result.airport = apt;
 
     // if the last error was more than three seconds ago,
     // then pretent nothing happened.
@@ -816,18 +814,14 @@ FGMetarEnvironmentCtrl::fetch_data( const string &icao )
         _error_count = 0;
     }
 
-    // fetch station elevation if exists
-    const FGAirport* a = globals->get_airports()->search( icao );
-    if ( a ) {
-        station_elevation_ft = a->getElevation();
-    }
+    station_elevation_ft = apt->getElevation();
 
     // fetch current metar data
     try {
         string host = proxy_host->getStringValue();
         string auth = proxy_auth->getStringValue();
         string port = proxy_port->getStringValue();
-        result.m = new FGMetar( icao, host, port, auth);
+        result.m = new FGMetar( apt->ident(), host, port, auth);
 
         long max_age = metar_max_age->getLongValue();
         long age = result.m->getAge_min();
@@ -969,7 +963,7 @@ FGMetarEnvironmentCtrl::update_metar_properties( const FGMetar *m )
 void
 FGMetarEnvironmentCtrl::thread_stop()
 {
-    request_queue.push( string() );    // ask thread to terminate
+    request_queue.push(NULL);  // ask thread to terminate
     thread->join();
 }
 
@@ -978,11 +972,11 @@ FGMetarEnvironmentCtrl::MetarThread::run()
 {
     while ( true )
     {
-        string icao = fetcher->request_queue.pop();
-        if (icao.empty())
+        FGAirport* apt = fetcher->request_queue.pop();
+        if (!apt)
             return;
-        SG_LOG( SG_GENERAL, SG_INFO, "Thread: fetch metar data = " << icao );
-        FGMetarResult result = fetcher->fetch_data( icao );
+        SG_LOG( SG_GENERAL, SG_INFO, "Thread: fetch metar data = " << apt->ident() );
+        FGMetarResult result = fetcher->fetch_data( apt );
         fetcher->result_queue.push( result );
     }
 }