]> git.mxchange.org Git - flightgear.git/commitdiff
Clean out FGAirportList - not quite obsolete yet, but the spatial queries are
authorjmt <jmt>
Fri, 26 Dec 2008 11:15:00 +0000 (11:15 +0000)
committerjmt <jmt>
Fri, 26 Dec 2008 11:15:00 +0000 (11:15 +0000)
gone. This is good news, since the old query was implemented as a linear
search, sorted by Manhattan distance, and with a warning not to use the logic
at runtime. Various systems (such as the Mk-VIII) do query such data often,
eg every second.

Also gets Point3D out of Airports/simple.hxx, as a precursor to removing it
completely.

src/ATCDCL/AIGAVFRTraffic.cxx
src/ATCDCL/AIMgr.cxx
src/Airports/apt_loader.cxx
src/Airports/simple.cxx
src/Airports/simple.hxx
src/Environment/environment_ctrl.cxx
src/Environment/environment_ctrl.hxx
src/Instrumentation/mk_viii.cxx
src/Instrumentation/mk_viii.hxx
src/Scripting/NasalSys.cxx

index 811002f23b1b4bbf9cc0ebe3e57d7ed16bc2644e..faaf41e643f29a3dcd21c9abc54f2975b65e33be 100644 (file)
@@ -38,6 +38,9 @@ using std::string;
 #include "ATCutils.hxx"
 #include "tower.hxx"
 
+// extern from Airports/simple.cxx
+extern Point3D fgGetAirportPos( const std::string& id );
+
 FGAIGAVFRTraffic::FGAIGAVFRTraffic() {
        ATC = globals->get_ATC_mgr();
        _towerContactedIncoming = false;
index 5d4da1d862370b8c93f46fa7a9c1ea4848e98d54..36a97783ee2d86763812d1c34efabdd80c773b93 100644 (file)
@@ -53,6 +53,9 @@ using std::cout;
 
 using namespace simgear;
 
+// extern from Airports/simple.cxx
+extern Point3D fgGetAirportPos( const std::string& id );
+
 FGAIMgr::FGAIMgr() {
        ATC = globals->get_ATC_mgr();
        initDone = false;
index 646aedc5cc6a5a833890734094221839adcb2a71..92495181a7ea5ec08fcbd277c8f9d5176f0a8899 100644 (file)
@@ -290,7 +290,7 @@ bool fgAirportDBLoad( FGAirportList *airports,
             metar_in >> skipeol;
         } else {
             const FGAirport* a = airports->search( ident );
-            if ( a ) airports->has_metar( ident );
+            if ( a ) const_cast<FGAirport*>(a)->setMetar(true);
         }
     }
 
index 944dfbb80cf1f47a97150f2a222a116ada8c7d3b..e7b9a48d88344448732bfdc53c8e55b932ab1f0d 100644 (file)
@@ -325,13 +325,9 @@ FGAirport* FGAirportList::add( const string &id, const SGGeod& location, const S
     // try and read in an auxilary file
 
     airports_array.push_back( a );
-    SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << location.getLongitudeDeg()
-            << ", " << location.getLatitudeDeg() << " elev = " << location.getElevationFt() );
-            
     return a;
 }
 
-
 // search for the specified id
 FGAirport* FGAirportList::search( const string& id)
 {
@@ -339,41 +335,6 @@ FGAirport* FGAirportList::search( const string& id)
     return (itr == airports_by_id.end() ? NULL : itr->second);
 }
 
-// search for the airport nearest the specified position
-FGAirport* FGAirportList::search(double lon_deg, double lat_deg, double max_range)
-{
-    static FGAirportSearchFilter accept_any;
-    return search(lon_deg, lat_deg, max_range, accept_any);
-}
-
-
-// search for the airport nearest the specified position and
-// passing the filter
-FGAirport* FGAirportList::search(double lon_deg, double lat_deg,
-        double max_range,
-        FGAirportSearchFilter& filter)
-{
-    double min_dist = max_range;
-
-    airport_list_iterator it = airports_array.begin();
-    airport_list_iterator end = airports_array.end();
-    airport_list_iterator closest = end;
-    for (; it != end; ++it) {
-        if (!filter.pass(*it))
-            continue;
-
-        // crude manhatten distance based on lat/lon difference
-        double d = fabs(lon_deg - (*it)->getLongitude())
-                + fabs(lat_deg - (*it)->getLatitude());
-        if (d < min_dist) {
-            closest = it;
-            min_dist = d;
-        }
-    }
-    return closest != end ? *closest : 0;
-}
-
-
 int
 FGAirportList::size () const
 {
@@ -390,29 +351,6 @@ const FGAirport *FGAirportList::getAirport( unsigned int index ) const
     }
 }
 
-
-/**
- * Mark the specified airport record as not having metar
- */
-void FGAirportList::no_metar( const string &id )
-{
-    if(airports_by_id.find(id) != airports_by_id.end()) {
-        airports_by_id[id]->setMetar(false);
-    }
-}
-
-
-/**
- * Mark the specified airport record as (yes) having metar
- */
-void FGAirportList::has_metar( const string &id )
-{
-    if(airports_by_id.find(id) != airports_by_id.end()) {
-        airports_by_id[id]->setMetar(true);
-    }
-}
-
-
 // find basic airport location info from airport database
 const FGAirport *fgFindAirportID( const string& id)
 {
index 9a295b251d6c3fc5b8c3745f0bdbd2f7e3ebcd23..8b2aaf10f30ab9c7ade17ed962c4da22f7e05250 100644 (file)
 
 #include <string>
 #include <map>
-#include <set>
 #include <vector>
 
-#include <simgear/math/point3d.hxx>
 #include "Navaids/positioned.hxx"
 
 // forward decls
@@ -139,14 +137,6 @@ private:
     std::vector<FGRunwayPtr> mTaxiways;
 };
 
-
-class FGAirportSearchFilter {
-public:
-    virtual ~FGAirportSearchFilter() {}
-    // all airports pass the filter by default
-    virtual bool pass(FGAirport*) { return true; }
-};
-
 typedef std::map < std::string, FGAirport* > airport_map;
 typedef airport_map::iterator airport_map_iterator;
 typedef airport_map::const_iterator const_airport_map_iterator;
@@ -178,14 +168,6 @@ public:
     // Returns NULL if unsucessfull.
     FGAirport* search( const std::string& id );
 
-    // search for the airport closest to the specified position
-    // (currently a linear inefficient search so it's probably not
-    // best to use this at runtime.)  An FGAirportSearchFilter class
-    // can be used to restrict the possible choices to a subtype.
-    // max_range limits search - specified as an arc distance, in degrees
-    FGAirport* search( double lon_deg, double lat_deg, double max_range );
-    FGAirport* search( double lon_deg, double lat_deg, double max_range, FGAirportSearchFilter& );
-
     /**
      * Return the number of airports in the list.
      */
@@ -196,16 +178,6 @@ public:
      */
     const FGAirport *getAirport( unsigned int index ) const;
 
-    /**
-     * Mark the specified airport record as not having metar
-     */
-    void no_metar( const std::string &id );
-
-    /**
-     * Mark the specified airport record as (yes) having metar
-     */
-    void has_metar( const std::string &id );
-
 };
 
 // find basic airport location info from airport database
@@ -214,9 +186,6 @@ const FGAirport *fgFindAirportID( const std::string& id);
 // get airport elevation
 double fgGetAirportElev( const std::string& id );
 
-// get airport position
-Point3D fgGetAirportPos( const std::string& id );
-
 #endif // _FG_SIMPLE_HXX
 
 
index 677969e705a0550dedb1b390b8d7c1a12543ba2e..e0844d81d068b205f2676d0f45ec18338c12a6fb 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 FGPositioned::Filter
+{
+public:
+  virtual bool pass(FGPositioned* aPos) const
+  {
+    if ((aPos->type() < FGPositioned::AIRPORT) || (aPos->type() > FGPositioned::SEAPORT)) {
+      return false;
+    }
+    
+    FGAirport* apt = static_cast<FGAirport*>(aPos);
+    return apt->getMetar();
+  }
+};
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGEnvironmentCtrl abstract base class.
@@ -645,10 +653,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;
@@ -659,33 +666,32 @@ 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;
+        FGPositionedRef a = FGPositioned::findClosest(pos, 10000.0, &filter);
+        if (!a) {
+          break;
         }
-    }
+        
+        FGMetarResult result = fetch_data(a->ident());
+        if ( result.m != NULL ) {
+            SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
+                    << a->ident());
+            last_apt = a;
+            _icao = a->ident();
+            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() );
+            static_cast<FGAirport*>(a.ptr())->setMetar(false);
+        }
+    } // of airprot-with-metar search iteration
+    
     metar_max_age->setLongValue(max_age);
 }
 
@@ -702,7 +708,6 @@ FGMetarEnvironmentCtrl::reinit ()
 void
 FGMetarEnvironmentCtrl::update(double delta_time_sec)
 {
-
     _dt += delta_time_sec;
     if (_error_count >= 3)
        return;
@@ -713,6 +718,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;
@@ -720,20 +728,17 @@ 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;
+        FGPositionedRef a = FGPositioned::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->ident() );
                 last_apt = a;
-                _icao = a->getId();
+                _icao = a->ident();
                 search_elapsed = 0.0;
                 fetch_elapsed = 0.0;
             } else {
@@ -741,8 +746,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 ) {
@@ -781,7 +787,8 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
             // 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 );
+            const FGAirport* apt = globals->get_airports()->search(result.icao);
+            const_cast<FGAirport*>(apt)->setMetar(false);
             search_elapsed = 9999.0;
         }
     }
index cc2449cae2c56b61af4aed1f1a1c9f9892d4a567..9538548ec746d8ee0612f7857b3ee6d7ec1e0a46 100644 (file)
 #ifndef _ENVIRONMENT_CTRL_HXX
 #define _ENVIRONMENT_CTRL_HXX
 
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
 #include <simgear/compiler.h>
 #include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/environment/metar.hxx>
 
 #if defined(ENABLE_THREADS)
 # include <OpenThreads/Thread>
 # include <simgear/threads/SGQueue.hxx>
 #endif
 
-#include <cmath>
 #include <queue>
 #include <vector>
 
-using std::queue;
-using std::vector;
+#include "Navaids/positioned.hxx"
+#include "Environment/environment.hxx"
 
+// forward decls
 class SGPropertyNode;
 class FGAirport;
+class FGMetar;
 
-#include "environment.hxx"
-#include "fgmetar.hxx"
-
-
-\f
 /**
  * Interface to control environment information for a specific location.
  */
@@ -133,20 +124,20 @@ private:
         static bool lessThan(bucket *a, bucket *b);
     };
 
-    void read_table (const SGPropertyNode * node, vector<bucket *> &table);
-    void do_interpolate (vector<bucket *> &table, double altitude_ft,
+    void read_table (const SGPropertyNode * node, std::vector<bucket *> &table);
+    void do_interpolate (std::vector<bucket *> &table, double altitude_ft,
                          FGEnvironment * environment);
 
     FGEnvironment env1, env2;   // temporaries
 
-    vector<bucket *> _boundary_table;
-    vector<bucket *> _aloft_table;
+    std::vector<bucket *> _boundary_table;
+    std::vector<bucket *> _aloft_table;
 };
 
 
 // A convenience wrapper around FGMetar
 struct FGMetarResult {
-    string icao;
+    std::string icao;
     FGMetar *m;
 };
 
@@ -169,7 +160,7 @@ public:
 private:
     FGInterpolateEnvironmentCtrl *env;
 
-    string _icao;
+    std::string _icao;
     bool metar_loaded;
     float station_elevation_ft;
     float search_interval_sec;
@@ -177,7 +168,7 @@ private:
     float search_elapsed;
     float fetch_elapsed;
     float interpolate_elapsed;
-    const FGAirport *last_apt;
+    FGPositionedRef last_apt;
     SGPropertyNode_ptr proxy_host;
     SGPropertyNode_ptr proxy_port;
     SGPropertyNode_ptr proxy_auth;
@@ -209,7 +200,7 @@ private:
     /**
      * FIFO queue which holds a pointer to the fetched metar data.
      */
-    SGBlockingQueue < string > request_queue;
+    SGBlockingQueue <std::string > request_queue;
 
     /**
      * FIFO queue which holds a pointer to the fetched metar data.
@@ -219,12 +210,12 @@ private:
     /**
      * FIFO queue which holds a pointer to the fetched metar data.
      */
-    queue < string > request_queue;
+    std::queue <std::string > request_queue;
 
     /**
      * FIFO queue which holds a pointer to the fetched metar data.
      */
-    queue < FGMetarResult > result_queue;
+    std::queue < FGMetarResult > result_queue;
 #endif
 
 #if defined(ENABLE_THREADS)
index a310297d63febeea6b0812bec4c10e7905a53c3d..8908078c9d347dfd986e80d9b9363f0a9b5bfe55 100755 (executable)
@@ -4254,9 +4254,14 @@ MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
   return false;
 }
 
-bool MK_VIII::Mode6Handler::AirportFilter::pass(FGAirport* a)
+bool MK_VIII::Mode6Handler::AirportFilter::pass(FGPositioned* a) const
 {
-  return self->test_airport(a);
+  if (a->type() != FGPositioned::AIRPORT) {
+    return false;
+  }
+    
+  bool ok = self->test_airport(static_cast<FGAirport*>(a));
+  return ok;
 }
 
 void
@@ -4269,20 +4274,19 @@ MK_VIII::Mode6Handler::update_runway ()
   }
 
   // Search for the closest runway threshold in range 5
-  // nm. Passing 0.5 degrees (approximatively 30 nm) to
+  // nm. Passing 30nm to
   // get_closest_airport() provides enough margin for large
   // airports, which may have a runway located far away from the
   // airport's reference point.
   AirportFilter filter(this);
-  const FGAirport *airport = globals->get_airports()->search(
-    mk_data(gps_latitude).get(), mk_data(gps_longitude).get(),
-                       0.5, filter);
-
-  if (airport) {
-    runway.elevation = airport->getElevation();
+  FGPositionedRef apt = FGPositioned::findClosest(
+    SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
+    30.0, &filter);
+  if (apt) {
+    runway.elevation = apt->elevation();
   }
   
-  has_runway.set(airport != NULL);
+  has_runway.set(apt != NULL);
 }
 
 void
@@ -4493,17 +4497,16 @@ MK_VIII::TCFHandler::select_runway (const FGAirport *airport)
   return _runway;
 }
 
-bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a)
+bool MK_VIII::TCFHandler::AirportFilter::pass(FGPositioned* aPos) const
 {
-  for (unsigned int r=0; r<a->numRunways(); ++r) {
-    if (a->getRunwayByIndex(r)->lengthFt() >= mk->conf.runway_database) {
-      return true;
-    }
+  if (aPos->type() != FGPositioned::AIRPORT) {
+    return false;
   }
-    
-  return false;
+  
+  FGAirport* apt = static_cast<FGAirport*>(aPos);
+  return apt->hasHardRunwayOfLengthFt(mk->conf.runway_database);
 }
-
+   
 void
 MK_VIII::TCFHandler::update_runway ()
 {
@@ -4513,25 +4516,25 @@ MK_VIII::TCFHandler::update_runway ()
   }
 
   // Search for the intended destination runway of the closest
-  // airport in range 15 nm. Passing 0.5 degrees (approximatively
-  // 30 nm) to get_closest_airport() provides enough margin for
+  // airport in range 15 nm. Passing 30nm to get_closest_airport() 
+  // provides enough margin for
   // large airports, which may have a runway located far away from
   // the airport's reference point.
   AirportFilter filter(mk);
-  const FGAirport *airport = globals->get_airports()->search(
-      mk_data(gps_longitude).get(), mk_data(gps_latitude).get(),
-                       0.5, filter);
-
-  if (!airport) return;
+  FGPositionedRef apt = FGPositioned::findClosest(
+    SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
+    30.0, &filter);
+      
+  if (!apt) return;
   
          has_runway = true;
 
-         FGRunway* _runway = select_runway(airport);
-
+         FGRunway* _runway = select_runway(static_cast<FGAirport*>(apt.ptr()));
+    
          runway.center.latitude = _runway->latitude();
          runway.center.longitude = _runway->longitude();
 
-         runway.elevation = airport->getElevation();
+         runway.elevation = apt->elevation();
 
          double half_length_m = _runway->lengthM() * 0.5;
          runway.half_length = half_length_m * SG_METER_TO_NM;
index f134084402af57568c91a782d95b9ba2241a277a..249bdf023c5c19d45fceee34911c4c815f79479b 100755 (executable)
@@ -1505,13 +1505,13 @@ private:
     unsigned int get_bank_angle_alerts ();
     void update_bank_angle ();
     
-    class AirportFilter : public FGAirportSearchFilter
+    class AirportFilter : public FGPositioned::Filter
     {
     public: 
       AirportFilter(Mode6Handler *s)
         : self(s) {}
         
-      virtual bool pass(FGAirport *a);
+      virtual bool pass(FGPositioned *a) const;
       
     private:
       Mode6Handler* self;
@@ -1578,13 +1578,13 @@ private:
     bool is_tcf ();
     bool is_rfcf ();
 
-    class AirportFilter : public FGAirportSearchFilter
+    class AirportFilter : public FGPositioned::Filter
     {
     public: 
       AirportFilter(MK_VIII *device)
         : mk(device) {}
         
-      virtual bool pass(FGAirport *a);
+      virtual bool pass(FGPositioned *a) const;
       
     private:
       MK_VIII* mk;
index 0a10317f94d0f6ebaa57e5f18d23d06b4eee4c55..61055ce4ebb6d475facaadb89fa9f51ca94f3a6a 100644 (file)
@@ -497,19 +497,23 @@ static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args)
 #undef HASHSET
 }
 
-
-class airport_filter : public FGAirportSearchFilter {
-    virtual bool pass(FGAirport *a) { return a->isAirport(); }
-} airport;
-class seaport_filter : public FGAirportSearchFilter {
-    virtual bool pass(FGAirport *a) { return a->isSeaport(); }
-} seaport;
-class heliport_filter : public FGAirportSearchFilter {
-    virtual bool pass(FGAirport *a) { return a->isHeliport(); }
-} heliport;
+class AirportInfoFilter : public FGPositioned::Filter
+{
+public:
+  AirportInfoFilter() :
+    type(FGPositioned::AIRPORT)
+  { }
+  
+  virtual bool pass(FGPositioned* aPos) const
+  {
+    return (aPos->type() == type);
+  }
+  
+  FGPositioned::Type type;
+};
 
 // Returns data hash for particular or nearest airport of a <type>, or nil
-// on error. Only one side of each runway is contained.
+// on error.
 //
 // airportinfo(<id>);                   e.g. "KSFO"
 // airportinfo(<type>);                 type := ("airport"|"seaport"|"heliport")
@@ -519,38 +523,50 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
 {
     static SGConstPropertyNode_ptr latn = fgGetNode("/position/latitude-deg", true);
     static SGConstPropertyNode_ptr lonn = fgGetNode("/position/longitude-deg", true);
-    double lat, lon;
-
-    FGAirportList *aptlst = globals->get_airports();
-    FGAirport *apt;
+    SGGeod pos;
+    FGPositionedRef ref;
+    
     if(argc >= 2 && naIsNum(args[0]) && naIsNum(args[1])) {
-        lat = args[0].num;
-        lon = args[1].num;
+        pos = SGGeod::fromDeg(args[1].num, args[0].num);
         args += 2;
         argc -= 2;
     } else {
-        lat = latn->getDoubleValue();
-        lon = lonn->getDoubleValue();
+        pos = SGGeod::fromDeg(lonn->getDoubleValue(), latn->getDoubleValue());
     }
 
-    double maxRange = 360.0; // expose this? or pick a smaller value?
+    double maxRange = 10000.0; // expose this? or pick a smaller value?
+
+    AirportInfoFilter filter; // defaults to airports only
 
     if(argc == 0) {
-        apt = aptlst->search(lon, lat, maxRange, airport);
+      // fine, just fall through and use AIRPORT
     } else if(argc == 1 && naIsString(args[0])) {
         const char *s = naStr_data(args[0]);
-        if(!strcmp(s, "airport")) apt = aptlst->search(lon, lat, maxRange, airport);
-        else if(!strcmp(s, "seaport")) apt = aptlst->search(lon, lat, maxRange, seaport);
-        else if(!strcmp(s, "heliport")) apt = aptlst->search(lon, lat, maxRange, heliport);
-        else apt = aptlst->search(s);
+        if (!strcmp(s, "airport")) filter.type = FGPositioned::AIRPORT;
+        else if(!strcmp(s, "seaport")) filter.type = FGPositioned::SEAPORT;
+        else if(!strcmp(s, "heliport")) filter.type = FGPositioned::HELIPORT;
+        else {
+            // user provided an <id>, hopefully
+            ref = globals->get_airports()->search(s);
+            if (!ref) {
+                naRuntimeError(c, "airportinfo() couldn't find airport:%s", s);
+                return naNil();
+            }
+        }
     } else {
         naRuntimeError(c, "airportinfo() with invalid function arguments");
         return naNil();
     }
-    if(!apt) return naNil();
-
-    string id = apt->getId();
-    string name = apt->getName();
+    
+    if (!ref) {
+        ref = FGPositioned::findClosest(pos, maxRange, &filter);
+    }
+    
+    if(!ref) return naNil();
+    FGAirport *apt = static_cast<FGAirport*>(ref.ptr());
+    
+    string id = apt->ident();
+    string name = apt->name();
 
     // set runway hash
     naRef rwys = naNewHash(c);