]> git.mxchange.org Git - flightgear.git/commitdiff
Remove all name and spatial queries from FGNavList. All remaining queries are
authorjmt <jmt>
Thu, 25 Dec 2008 23:11:43 +0000 (23:11 +0000)
committerjmt <jmt>
Thu, 25 Dec 2008 23:11:43 +0000 (23:11 +0000)
by frequency (which makes sense), and use the FGPositioned spatial data if
required. As a result, the marker beacon list is gone (since beacons are only
searched spatially). In the process, clean up various minor things - most
notably, all the 'airport-related' navaids (ILS, GS, LOC, and the beacons) now
store a FGRunway* instead of an airport id string. This is more precise, and
saves string allocations.

21 files changed:
src/Airports/runways.hxx
src/Airports/simple.hxx
src/Instrumentation/KLN89/kln89_page_ndb.cxx
src/Instrumentation/KLN89/kln89_page_vor.cxx
src/Instrumentation/adf.cxx
src/Instrumentation/dme.cxx
src/Instrumentation/kr_87.cxx
src/Instrumentation/marker_beacon.cxx
src/Instrumentation/navradio.cxx
src/Instrumentation/tacan.cxx
src/Main/fg_init.cxx
src/Main/globals.cxx
src/Main/globals.hxx
src/Navaids/navdb.cxx
src/Navaids/navdb.hxx
src/Navaids/navlist.cxx
src/Navaids/navlist.hxx
src/Navaids/navrecord.cxx
src/Navaids/navrecord.hxx
src/Navaids/positioned.cxx
src/Navaids/positioned.hxx

index 7bb21b6b4532d688c2817a1ee07232e1fec5f6ea..8e40f9e76936a1c48837b3cd1ba81b8c001ec199 100644 (file)
@@ -44,6 +44,10 @@ class FGRunway : public FGPositioned
   double _width;
   double _displ_thresh;
   double _stopway;
+  
+  /** surface, as defined by:
+   * http://www.x-plane.org/home/robinp/Apt810.htm#RwySfcCodes
+   */
   int _surface_code;
   
 public:
index 7c7445947059da143acae7c8ca3974ee6e13e0bc..9a295b251d6c3fc5b8c3745f0bdbd2f7e3ebcd23 100644 (file)
@@ -71,6 +71,9 @@ public:
     bool   isSeaport()    const;
     bool   isHeliport()   const;
 
+    virtual const std::string& name() const
+    { return _name; }
+
     const SGGeod& getTowerLocation() const { return _tower_location; }
 
     void setMetar(bool value) { _has_metar = value; }
index 7bc6f2848a931a784599e85a99709dd27792f82f..d118e5abbc0d4a467e0bf422e4e1f0680bce6890 100644 (file)
@@ -90,7 +90,7 @@ void KLN89NDBPage::Update(double dt) {
                }
                if(_subPage == 0) {
                        // TODO - trim VOR-DME from the name, convert to uppercase, abbreviate, etc
-                       _kln89->DrawText(np->get_name(), 2, 0, 2);
+                       _kln89->DrawText(np->name(), 2, 0, 2);
                        _kln89->DrawLatitude(np->get_lat(), 2, 3, 1);
                        _kln89->DrawLongitude(np->get_lon(), 2, 3, 0);
                } else {
index 1b9fb0ace4ac329faff6106460b39694221fc19c..c0caaba722929a532baffab36fdb25eb8c8e31ad 100644 (file)
@@ -92,7 +92,7 @@ void KLN89VorPage::Update(double dt) {
                        //// TODO - will almost certainly have to process freq below for FG
                        _kln89->DrawFreq(np->get_freq(), 2, 9, 3);
                        // TODO - trim VOR-DME from the name, convert to uppercase, abbreviate, etc
-                       _kln89->DrawText(np->get_name(), 2, 0, 2);
+                       _kln89->DrawText(np->name(), 2, 0, 2);
                        //cout << np->lat << "... ";
                        _kln89->DrawLatitude(np->get_lat(), 2, 3, 1);
                        _kln89->DrawLongitude(np->get_lon(), 2, 3, 0);
index e8c20710f9c84ec68084f2f7466dbfee013d3f57..053812a0df61c6a4845a545458b3fc03c3f72074 100644 (file)
@@ -217,16 +217,15 @@ ADF::search (double frequency_khz, double longitude_rad,
     _time_before_search_sec = 1.0;
 
                                 // try the ILS list first
-    FGNavRecord *nav =
-        globals->get_navlist()->findByFreq(frequency_khz, longitude_rad,
-                                           latitude_rad, altitude_m);
+    FGNavRecord *nav = globals->get_navlist()->findByFreq(frequency_khz,
+      SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m));
 
     _transmitter_valid = (nav != NULL);
     if ( _transmitter_valid ) {
         ident = nav->get_trans_ident();
         if ( ident != _last_ident ) {
-            _transmitter_pos = nav->get_pos();
-            _transmitter_cart = nav->get_cart();
+            _transmitter_pos = nav->geod();
+            _transmitter_cart = nav->cart();
             _transmitter_range_nm = nav->get_range();
         }
     }
index f12b4f80e6938ea39670c2cc0b61d5123a35ce95..5685dbabec606efc20f7d21e2429efd58cc1b8a1 100644 (file)
@@ -165,14 +165,14 @@ DME::search (double frequency_mhz, double longitude_rad,
     _time_before_search_sec = 1.0;
 
     // try the ILS list first
-    FGNavRecord *dme
-        = globals->get_dmelist()->findByFreq( frequency_mhz, longitude_rad,
-                                              latitude_rad, altitude_m);
+    
+    FGNavRecord *dme = globals->get_dmelist()->findByFreq( frequency_mhz,
+      SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m));
 
     _transmitter_valid = (dme != NULL);
 
     if ( _transmitter_valid ) {
-        _transmitter = dme->get_cart();
+        _transmitter = dme->cart();
         _transmitter_elevation_ft = dme->get_elev_ft();
         _transmitter_range_nm = dme->get_range();
         _transmitter_bias = dme->get_multiuse();
index 2188c08c9e3e7d8c49b3505e7af52b69751d2aad..6683f8f935b563f3d784eb6991051836cba7fa23 100644 (file)
@@ -494,10 +494,9 @@ void FGKR_87::update( double dt_sec ) {
 
 // Update current nav/adf radio stations based on current postition
 void FGKR_87::search() {
-    double acft_lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double acft_lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double acft_elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
-
+  SGGeod pos = SGGeod::fromDegFt(lon_node->getDoubleValue(), 
+    lat_node->getDoubleValue(), alt_node->getDoubleValue());
+  
                                // FIXME: the panel should handle this
     static string last_ident = "";
 
@@ -508,9 +507,8 @@ void FGKR_87::search() {
     // ADF.
     ////////////////////////////////////////////////////////////////////////
 
-    FGNavRecord *adf
-        = globals->get_navlist()->findByFreq( freq, acft_lon, acft_lat,
-                                              acft_elev );
+  
+    FGNavRecord *adf = globals->get_navlist()->findByFreq( freq, pos);
     if ( adf != NULL ) {
        char sfreq[128];
        snprintf( sfreq, 10, "%d", freq );
@@ -526,8 +524,8 @@ void FGKR_87::search() {
            stn_lat = adf->get_lat();
            stn_elev = adf->get_elev_ft();
            range = adf->get_range();
-           effective_range = kludgeRange(stn_elev, acft_elev, range);
-           xyz = adf->get_cart();
+           effective_range = kludgeRange(stn_elev, pos.getElevationM(), range);
+           xyz = adf->cart();
 
            if ( globals->get_soundmgr()->exists( "adf-ident" ) ) {
                globals->get_soundmgr()->remove( "adf-ident" );
index 822ef4e3d8588778c80542d4f20b95aca8e4713e..e636704fb90ef686a7307f4bd9ec35ab074ce7dc 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <simgear/compiler.h>
 #include <simgear/math/sg_random.h>
+#include <simgear/misc/sg_path.hxx>
 
 #include <Aircraft/aircraft.hxx>
 #include <Navaids/navlist.hxx>
@@ -210,20 +211,20 @@ FGMarkerBeacon::update(double dt)
 
 
 static bool check_beacon_range( const SGGeod& pos,
-                                FGNavRecord *b )
+                                FGPositioned *b )
 {
-    double d = distSqr(b->get_cart(), SGVec3d::fromGeod(pos));
+    double d = distSqr(b->cart(), SGVec3d::fromGeod(pos));
     // cout << "  distance = " << d << " ("
     //      << FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
     //         * FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
     //      << ")" << endl;
 
-    // cout << "  range = " << sqrt(d) << endl;
+    //std::cout << "  range = " << sqrt(d) << std::endl;
 
     // cout << "elev = " << elev * SG_METER_TO_FEET
     //      << " current->get_elev() = " << current->get_elev() << endl;
     double elev_ft = pos.getElevationFt();
-    double delev = elev_ft - b->get_elev_ft();
+    double delev = elev_ft - b->elevation();
 
     // max range is the area under r = 2.4 * alt or r^2 = 4000^2 - alt^2
     // whichever is smaller.  The intersection point is 1538 ...
@@ -236,7 +237,7 @@ static bool check_beacon_range( const SGGeod& pos,
         maxrange2 = 0.0;
     }
     maxrange2 *= SG_FEET_TO_METER * SG_FEET_TO_METER; // convert to meter^2
-    // cout << "delev = " << delev << " maxrange = " << maxrange << endl;
+    //std::cout << "delev = " << delev << " maxrange = " << sqrt(maxrange2) << std::endl;
 
     // match up to twice the published range so we can model
     // reduced signal strength
@@ -247,10 +248,18 @@ static bool check_beacon_range( const SGGeod& pos,
     }
 }
 
+class BeaconFilter : public FGPositioned::Filter
+{
+public:
+  virtual bool pass(FGPositioned* aPos) const
+  {
+    return (aPos->type() >= FGPositioned::OM) && (aPos->type() <= FGPositioned::IM);
+  }
+};
+
 // Update current nav/adf radio stations based on current postition
 void FGMarkerBeacon::search()
 {
-
     // reset search time
     _time_before_search_sec = 1.0;
 
@@ -264,14 +273,10 @@ void FGMarkerBeacon::search()
     // Beacons.
     ////////////////////////////////////////////////////////////////////////
 
-    // get closest marker beacon
-    FGNavRecord *b
-      = globals->get_mkrlist()->findClosest( pos.getLongitudeRad(),
-                                             pos.getLatitudeRad(),
-                                             pos.getElevationM() );
-
-    // cout << "marker beacon = " << b << " (" << b->get_type() << ")" << endl;
-
+    // get closest marker beacon - within a 1nm cutoff
+    BeaconFilter filter;
+    FGPositionedRef b = FGPositioned::findClosest(pos, 1.0, &filter);
+     
     fgMkrBeacType beacon_type = NOBEACON;
     bool inrange = false;
     if ( b != NULL ) {
@@ -282,8 +287,7 @@ void FGMarkerBeacon::search()
         } else if ( b->type() == FGPositioned::IM ) {
             beacon_type = INNER;
         }
-        inrange = check_beacon_range( pos, b );
-        // cout << "  inrange = " << inrange << endl;
+        inrange = check_beacon_range( pos, b.ptr() );
     }
 
     outer_marker = middle_marker = inner_marker = false;
index 1b870dd1a40a9f0754f1f20c6a6671c2b3463a8f..b4455be10013b15952ecf0d3823739e4c52e19a8 100644 (file)
@@ -31,6 +31,7 @@
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/math/vector.hxx>
 #include <simgear/math/sg_random.h>
+#include <simgear/misc/sg_path.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/structure/exception.hxx>
 
@@ -764,10 +765,8 @@ void FGNavRadio::search()
     _time_before_search_sec = 1.0;
 
     // cache values locally for speed
-    double lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
-
+    SGGeod pos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
+      lat_node->getDoubleValue(), alt_node->getDoubleValue());
     FGNavRecord *nav = NULL;
     FGNavRecord *loc = NULL;
     FGNavRecord *dme = NULL;
@@ -778,11 +777,11 @@ void FGNavRadio::search()
     ////////////////////////////////////////////////////////////////////////
 
     double freq = freq_node->getDoubleValue();
-    nav = globals->get_navlist()->findByFreq(freq, lon, lat, elev);
-    dme = globals->get_dmelist()->findByFreq(freq, lon, lat, elev);
+    nav = globals->get_navlist()->findByFreq(freq, pos);
+    dme = globals->get_dmelist()->findByFreq(freq, pos);
     if ( nav == NULL ) {
-        loc = globals->get_loclist()->findByFreq(freq, lon, lat, elev);
-        gs = globals->get_gslist()->findByFreq(freq, lon, lat, elev);
+        loc = globals->get_loclist()->findByFreq(freq, pos);
+        gs = globals->get_gslist()->findByFreq(freq, pos);
     }
 
     string nav_id = "";
@@ -799,7 +798,7 @@ void FGNavRadio::search()
            while ( target_radial > 360.0 ) { target_radial -= 360.0; }
            loc_lon = loc->get_lon();
            loc_lat = loc->get_lat();
-           nav_xyz = loc->get_cart();
+           nav_xyz = loc->cart();
            last_nav_id = nav_id;
            last_nav_vor = false;
            loc_node->setBoolValue( true );
@@ -811,7 +810,7 @@ void FGNavRadio::search()
                 nav_elev = gs->get_elev_ft();
                 int tmp = (int)(gs->get_multiuse() / 1000.0);
                 target_gs = (double)tmp / 100.0;
-                gs_xyz = gs->get_cart();
+                gs_xyz = gs->cart();
 
                 // derive GS baseline (perpendicular to the runay
                 // along the ground)
@@ -884,10 +883,10 @@ void FGNavRadio::search()
            nav_elev = nav->get_elev_ft();
            twist = nav->get_multiuse();
            range = nav->get_range();
-           effective_range = adjustNavRange(nav_elev, elev, range);
+           effective_range = adjustNavRange(nav_elev, pos.getElevationM(), range);
            target_gs = 0.0;
            target_radial = sel_radial_node->getDoubleValue();
-           nav_xyz = nav->get_cart();
+           nav_xyz = nav->cart();
 
            if ( globals->get_soundmgr()->exists( nav_fx_name ) ) {
                globals->get_soundmgr()->remove( nav_fx_name );
index 59066c4539bf634910e3163c6f7e586a59480c91..92bb7df0edff6473607339a0fb1f78db7ad1e7b8 100755 (executable)
@@ -293,7 +293,7 @@ TACAN::search (double frequency_mhz, double longitude_rad,
 
     if ( freq_valid ) {
 
-        string str1( mobile_tacan->get_name() );
+        string str1( mobile_tacan->name() );
 
         SGPropertyNode * branch = fgGetNode("ai/models", true);
         vector<SGPropertyNode_ptr> carrier = branch->getChildren("carrier");
@@ -315,7 +315,7 @@ TACAN::search (double frequency_mhz, double longitude_rad,
                     _mobile_elevation_ft = mobile_tacan->get_elev_ft();
                     _mobile_range_nm = mobile_tacan->get_range();
                     _mobile_bias = mobile_tacan->get_multiuse();
-                    _mobile_name = mobile_tacan->get_name();
+                    _mobile_name = mobile_tacan->name();
                     _mobile_ident = mobile_tacan->get_trans_ident();
                     _mobile_valid = true;
                     SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter valid " << _mobile_valid );
@@ -353,7 +353,7 @@ TACAN::search (double frequency_mhz, double longitude_rad,
                     _mobile_elevation_ft = tanker[i]->getDoubleValue("position/altitude-ft");
                     _mobile_range_nm = mobile_tacan->get_range();
                     _mobile_bias = mobile_tacan->get_multiuse();
-                    _mobile_name = mobile_tacan->get_name();
+                    _mobile_name = mobile_tacan->name();
                     _mobile_ident = mobile_tacan->get_trans_ident();
                     _mobile_valid = true;
                     SG_LOG( SG_INSTR, SG_DEBUG, " tanker transmitter valid " << _mobile_valid );
@@ -392,7 +392,7 @@ TACAN::search (double frequency_mhz, double longitude_rad,
                     _mobile_elevation_ft = mp_tanker[i]->getDoubleValue("position/altitude-ft");
                     _mobile_range_nm = mobile_tacan->get_range();
                     _mobile_bias = mobile_tacan->get_multiuse();
-                    _mobile_name = mobile_tacan->get_name();
+                    _mobile_name = mobile_tacan->name();
                     _mobile_ident = mobile_tacan->get_trans_ident();
                     _mobile_valid = true;
 
@@ -415,19 +415,18 @@ TACAN::search (double frequency_mhz, double longitude_rad,
     }
 
     // try the TACAN/VORTAC list next
-    FGNavRecord *tacan
-        = globals->get_tacanlist()->findByFreq( frequency_mhz, longitude_rad,
-                                                latitude_rad, altitude_m);
+    FGNavRecord *tacan = globals->get_tacanlist()->findByFreq( frequency_mhz,
+      SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m));
 
     _transmitter_valid = (tacan != NULL);
 
     if ( _transmitter_valid ) {
         SG_LOG( SG_INSTR, SG_DEBUG, "transmitter valid " << _transmitter_valid );
 
-        _transmitter_pos = tacan->get_pos();
+        _transmitter_pos = tacan->geod();
         _transmitter_range_nm = tacan->get_range();
         _transmitter_bias = tacan->get_multiuse();
-        _transmitter_name = tacan->get_name();
+        _transmitter_name = tacan->name();
         _name_node->setStringValue(_transmitter_name.c_str());
         _transmitter_ident = tacan->get_trans_ident();
         _ident_node->setStringValue(_transmitter_ident.c_str());
index 4dd8fdcf82a64bd3cc60a14c0abdff07b690f3ce..2bb9b477eb600b4cdd644a5a7fdb4bcef3ed8f6d 100644 (file)
 #include <Navaids/navdb.hxx>
 #include <Navaids/navlist.hxx>
 #include <Navaids/fix.hxx>
+#include <Navaids/fixlist.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
 #include <Scripting/NasalSys.hxx>
@@ -974,7 +975,6 @@ fgInitNav ()
     FGNavList *loclist = new FGNavList;
     FGNavList *gslist = new FGNavList;
     FGNavList *dmelist = new FGNavList;
-    FGNavList *mkrlist = new FGNavList;
     FGNavList *tacanlist = new FGNavList;
     FGNavList *carrierlist = new FGNavList;
     FGTACANList *channellist = new FGTACANList;
@@ -983,12 +983,11 @@ fgInitNav ()
     globals->set_loclist( loclist );
     globals->set_gslist( gslist );
     globals->set_dmelist( dmelist );
-    globals->set_mkrlist( mkrlist );
     globals->set_tacanlist( tacanlist );
     globals->set_carrierlist( carrierlist );
     globals->set_channellist( channellist );
 
-    if ( !fgNavDBInit(navlist, loclist, gslist, dmelist, mkrlist, tacanlist, carrierlist, channellist) ) {
+    if ( !fgNavDBInit(navlist, loclist, gslist, dmelist, tacanlist, carrierlist, channellist) ) {
         SG_LOG( SG_GENERAL, SG_ALERT,
                 "Problems loading one or more navigational database" );
     }
index 8cf9d171d0741c3cdec7f8cbe86ed69104c86e9e..1bcbbea678ea03b71e8fb53953e7ff8f04ae0b62 100644 (file)
@@ -104,7 +104,6 @@ FGGlobals::FGGlobals() :
     loclist( NULL ),
     gslist( NULL ),
     dmelist( NULL ),
-    mkrlist( NULL ),
     tacanlist( NULL ),
     carrierlist( NULL ),
     channellist( NULL ),
@@ -155,7 +154,6 @@ FGGlobals::~FGGlobals()
     delete loclist;
     delete gslist;
     delete dmelist;
-    delete mkrlist;
     delete tacanlist;
     delete carrierlist;
     delete channellist;
index 64291971f697b92ff8533a88e860b93762a97f1a..4b21c77f8b402887deaaed165ca06adb7eedeac5 100644 (file)
@@ -183,7 +183,6 @@ private:
     FGNavList *loclist;
     FGNavList *gslist;
     FGNavList *dmelist;
-    FGNavList *mkrlist;
     FGNavList *tacanlist;
     FGNavList *carrierlist;
     FGTACANList *channellist;
@@ -331,8 +330,6 @@ public:
     inline void set_tacanlist( FGNavList *n ) { tacanlist = n; }
     inline FGNavList *get_carrierlist() const { return carrierlist; }
     inline void set_carrierlist( FGNavList *n ) { carrierlist = n; }
-    inline FGNavList *get_mkrlist() const { return mkrlist; }
-    inline void set_mkrlist( FGNavList *n ) { mkrlist = n; }
     inline FGTACANList *get_channellist() const { return channellist; }
     inline void set_channellist( FGTACANList *c ) { channellist = c; }
 
index dc95774e4b171b507f15a90979e807b1d765dfba..40f487c5c22ea9b5699615cd23f9231a90749857 100644 (file)
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/misc/strutils.hxx>
+#include <simgear/misc/sg_path.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/misc/sgstream.hxx>
 
 #include "navrecord.hxx"
+#include "navlist.hxx"
 #include "navdb.hxx"
 #include "Main/globals.hxx"
 
@@ -43,7 +45,7 @@ using std::string;
 
 // load and initialize the navigational databases
 bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
-                  FGNavList *dmelist, FGNavList *mkrlist, 
+                  FGNavList *dmelist, 
                   FGNavList *tacanlist, FGNavList *carrierlist,
                   FGTACANList *channellist)
 {
@@ -97,14 +99,14 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
       case FGPositioned::OM:
       case FGPositioned::MM:
       case FGPositioned::IM:
-        mkrlist->add(r);
+        // no need to add this to a list, never searched by frequency
         break;
       
       case FGPositioned::DME:
       {
         dmelist->add(r);
-        string::size_type loc1= r->get_name().find( "TACAN", 0 );
-        string::size_type loc2 = r->get_name().find( "VORTAC", 0 );
+        string::size_type loc1= r->name().find( "TACAN", 0 );
+        string::size_type loc2 = r->name().find( "VORTAC", 0 );
                        
         if( loc1 != string::npos || loc2 != string::npos) {
           tacanlist->add(r);
index cd524300f951dd5af5756991fa3914ba80716322..87e510825b2f228d616e9393edcc558ff0a49cf8 100644 (file)
 
 
 #include <simgear/compiler.h>
-#include <simgear/misc/sg_path.hxx>
 
-#include "navlist.hxx"
-#include "fixlist.hxx"
+class FGNavList;
+class FGTACANList;
 
 // load and initialize the navigational databases
 bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
-                  FGNavList *dmelist, FGNavList *mkrbeacons,
+                  FGNavList *dmelist,
                   FGNavList *tacanlist, FGNavList *carrierlist,
                   FGTACANList *channellist );
 
index eb2ef38ef5d46c4f6c8766e34517ff243b657a8b..66d990d5cd987f0cda3aa54c03a4fe5c37595b13 100644 (file)
 #endif
 
 #include <simgear/debug/logstream.hxx>
-#include <simgear/misc/sgstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/sg_inlines.h>
 
 #include "navlist.hxx"
 
-
-// Return true if the nav record matches the type
-static bool isTypeMatch(const FGNavRecord* n, fg_nav_types type)
-{
-  if (type == FG_NAV_ANY) return true;
-  return type == n->type();
-}
-
-
+using std::string;
 
 // FGNavList ------------------------------------------------------------------
 
@@ -50,7 +42,6 @@ FGNavList::FGNavList( void )
 
 FGNavList::~FGNavList( void )
 {
-    navaids_by_tile.erase( navaids_by_tile.begin(), navaids_by_tile.end() );
     nav_list_type navlist = navaids.begin()->second;
     navaids.erase( navaids.begin(), navaids.end() );
 }
@@ -63,133 +54,55 @@ bool FGNavList::init()
     // since we're using an SGSharedPointer
     nav_list_type navlist = navaids.begin()->second;
     navaids.erase( navaids.begin(), navaids.end() );
-    navaids_by_tile.erase( navaids_by_tile.begin(), navaids_by_tile.end() );
-    ident_navaids.erase( ident_navaids.begin(), ident_navaids.end() );
-
     return true;
 }
 
-
-// real add a marker beacon
-static void real_add( nav_map_type &navmap, const int master_index,
-                      FGNavRecord *n )
-{
-    navmap[master_index].push_back( n );
-}
-
-
-// front end for add a marker beacon
-static void tile_add( nav_map_type &navmap, FGNavRecord *n )
-{
-    double diff = 0;
-
-    double lon = n->get_lon();
-    double lat = n->get_lat();
-
-    int lonidx = (int)lon;
-    diff = lon - (double)lonidx;
-    if ( (lon < 0.0) && (fabs(diff) > SG_EPSILON) ) {
-        lonidx -= 1;
-    }
-    double lonfrac = lon - (double)lonidx;
-    lonidx += 180;
-
-    int latidx = (int)lat;
-    diff = lat - (double)latidx;
-    if ( (lat < 0.0) && (fabs(diff) > SG_EPSILON) ) {
-        latidx -= 1;
-    }
-    double latfrac = lat - (double)latidx;
-    latidx += 90;
-
-    int master_index = lonidx * 1000 + latidx;
-    // cout << "lonidx = " << lonidx << " latidx = " << latidx << "  ";
-    // cout << "Master index = " << master_index << endl;
-
-    // add to the actual bucket
-    real_add( navmap, master_index, n );
-
-    // if we are close to the edge, add to adjacent buckets so we only
-    // have to search one bucket at run time
-
-    // there are 8 cases since there are 8 adjacent tiles
-
-    if ( lonfrac < 0.2 ) {
-        real_add( navmap, master_index - 1000, n );
-        if ( latfrac < 0.2 ) {
-            real_add( navmap, master_index - 1000 - 1, n );
-        } else if ( latfrac > 0.8 ) {
-            real_add( navmap, master_index - 1000 + 1, n );
-        }
-    } else if ( lonfrac > 0.8 ) {
-        real_add( navmap, master_index + 1000, n );
-        if ( latfrac < 0.2 ) {
-            real_add( navmap, master_index + 1000 - 1, n );
-        } else if ( latfrac > 0.8 ) {
-            real_add( navmap, master_index + 1000 + 1, n );
-        }
-    } else if ( latfrac < 0.2 ) {
-        real_add( navmap, master_index - 1, n );
-    } else if ( latfrac > 0.8 ) {
-        real_add( navmap, master_index + 1, n );
-    }
-}
-
-
 // add an entry to the lists
 bool FGNavList::add( FGNavRecord *n )
 {
     navaids[n->get_freq()].push_back(n);
-    ident_navaids[n->get_ident()].push_back(n);
-    tile_add( navaids_by_tile, n );
     return true;
 }
 
-FGNavRecord *FGNavList::findByFreq( double freq, double lon, double lat, double elev )
+FGNavRecord *FGNavList::findByFreq( double freq, const SGGeod& position)
 {
     const nav_list_type& stations = navaids[(int)(freq*100.0 + 0.5)];
-
-    SGGeod geod = SGGeod::fromRadM(lon, lat, elev);
-    SGVec3d aircraft = SGVec3d::fromGeod(geod);
     SG_LOG( SG_INSTR, SG_DEBUG, "findbyFreq " << freq << " size " << stations.size()  );
-
-    return findNavFromList( aircraft, stations );
+    return findNavFromList( position, stations );
 }
 
-
-FGNavRecord *FGNavList::findByIdent( const char* ident,
-                               const double lon, const double lat )
+class VORNDBFilter : public FGPositioned::Filter
 {
-    const nav_list_type& stations = ident_navaids[ident];
-    SGGeod geod = SGGeod::fromRad(lon, lat);
-    SGVec3d aircraft = SGVec3d::fromGeod(geod);
-    return findNavFromList( aircraft, stations );
-}
-
-
-
+public:
+  virtual bool pass(FGPositioned* aPos) const
+  {
+    return (aPos->type() == FGPositioned::VOR) || (aPos->type() == FGPositioned::NDB);
+  }
+};
 
 // Given an Ident and optional freqency, return the first matching
 // station.
-FGNavRecord *FGNavList::findByIdentAndFreq( const char* ident, const double freq )
+FGNavRecord *FGNavList::findByIdentAndFreq(const string& ident, const double freq )
 {
-    nav_list_type stations = ident_navaids[ident];
-    SG_LOG( SG_INSTR, SG_DEBUG, "findByIdent " << ident<< " size " << stations.size()  );
-    if ( freq > 0.0 ) {
-        // sometimes there can be duplicated idents.  If a freq is
-        // specified, use it to refine the search.
-        int f = (int)(freq*100.0 + 0.5);
-        nav_list_const_iterator it, end = stations.end();
-        for ( it = stations.begin(); it != end; ++it ) {
-            if ( f == (*it)->get_freq() ) {
-                return (*it);
-            }
-        }
-    } else if (!stations.empty()) {
-        return stations[0];
+  FGPositionedRef cur;
+  VORNDBFilter filter;
+  cur = FGPositioned::findNextWithPartialId(cur, ident, &filter);
+  
+  if (freq <= 0.0) {
+    return static_cast<FGNavRecord*>(cur.ptr()); // might be null
+  }
+  
+  int f = (int)(freq*100.0 + 0.5);
+  while (cur) {
+    FGNavRecord* nav = static_cast<FGNavRecord*>(cur.ptr());
+    if (nav->get_freq() == f) {
+      return nav;
     }
+    
+    cur = FGPositioned::findNextWithPartialId(cur, ident, &filter);
+  }
 
-    return NULL;
+  return NULL;
 }
 
 // LOC, ILS, GS, and DME antenna's could potentially be
@@ -203,7 +116,7 @@ FGNavRecord *FGNavList::findByIdentAndFreq( const char* ident, const double freq
 // directional atennas and only when there is a chance it is
 // the closest station.)
 
-static bool penaltyForNav(FGNavRecord* aNav, const SGVec3d &aPos)
+static bool penaltyForNav(FGNavRecord* aNav, const SGGeod &aGeod)
 {
   switch (aNav->type()) {
   case FGPositioned::ILS:
@@ -224,34 +137,31 @@ static bool penaltyForNav(FGNavRecord* aNav, const SGVec3d &aPos)
     hdg_deg = aNav->get_multiuse();
   }
   
-  double az1 = 0.0, az2 = 0.0, s = 0.0;
-  SGGeod geod = SGGeod::fromCart(aPos);
-  geo_inverse_wgs_84( geod, aNav->geod(), &az1, &az2, &s);
+  double az1, az2, s;
+  SGGeodesy::inverse(aGeod, aNav->geod(), az1, az2, s);
   az1 = az1 - hdg_deg;
-  
-  if ( az1 >  180.0) az1 -= 360.0;
-  if ( az1 < -180.0) az1 += 360.0;
-  
+  SG_NORMALIZE_RANGE(az1, -180.0, 180.0);
   return fabs(az1) > 90.0;
 }
 
 // Given a point and a list of stations, return the closest one to the
 // specified point.
-FGNavRecord *FGNavList::findNavFromList( const SGVec3d &aircraft,
+FGNavRecord *FGNavList::findNavFromList( const SGGeod &aircraft,
                                          const nav_list_type &stations )
 {
     FGNavRecord *nav = NULL;
     double d2;                  // in meters squared
     double min_dist
         = FG_NAV_MAX_RANGE*SG_NM_TO_METER*FG_NAV_MAX_RANGE*SG_NM_TO_METER;
-
+    SGVec3d aircraftCart = SGVec3d::fromGeod(aircraft);
+    
     nav_list_const_iterator it;
     nav_list_const_iterator end = stations.end();
     // find the closest station within a sensible range (FG_NAV_MAX_RANGE)
     for ( it = stations.begin(); it != end; ++it ) {
         FGNavRecord *station = *it;
         // cout << "testing " << current->get_ident() << endl;
-        d2 = distSqr(station->get_cart(), aircraft);
+        d2 = distSqr(station->cart(), aircraftCart);
         if ( d2 < min_dist && penaltyForNav(station, aircraft))
         {
           double dist = sqrt(d2);
@@ -267,69 +177,6 @@ FGNavRecord *FGNavList::findNavFromList( const SGVec3d &aircraft,
     return nav;
 }
 
-
-// returns the closest entry to the give lon/lat/elev
-FGNavRecord *FGNavList::findClosest( double lon_rad, double lat_rad,
-                                     double elev_m, fg_nav_types type)
-{
-    FGNavRecord *result = NULL;
-    double diff;
-
-    double lon_deg = lon_rad * SG_RADIANS_TO_DEGREES;
-    double lat_deg = lat_rad * SG_RADIANS_TO_DEGREES;
-    int lonidx = (int)lon_deg;
-    diff = lon_deg - (double)lonidx;
-    if ( (lon_deg < 0.0) && (fabs(diff) > SG_EPSILON) ) {
-        lonidx -= 1;
-    }
-    lonidx += 180;
-
-    int latidx = (int)lat_deg;
-    diff = lat_deg - (double)latidx;
-    if ( (lat_deg < 0.0) && (fabs(diff) > SG_EPSILON) ) {
-        latidx -= 1;
-    }
-    latidx += 90;
-
-    int master_index = lonidx * 1000 + latidx;
-
-    const nav_list_type& navs = navaids_by_tile[ master_index ];
-    // cout << "Master index = " << master_index << endl;
-    // cout << "beacon search length = " << beacons.size() << endl;
-
-    nav_list_const_iterator current = navs.begin();
-    nav_list_const_iterator last = navs.end();
-
-    SGGeod geod = SGGeod::fromRadM(lon_rad, lat_rad, elev_m);
-    SGVec3d aircraft = SGVec3d::fromGeod(geod);
-
-    double min_dist = 999999999.0;
-
-    for ( ; current != last ; ++current ) {
-        if(isTypeMatch(*current, type)) {
-            // cout << "  testing " << (*current)->get_ident() << endl;
-
-            double d = distSqr((*current)->get_cart(), aircraft);
-            // cout << "  distance = " << d << " ("
-            //      << FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
-            //         * FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
-            //      << ")" << endl;
-
-            // cout << "  range = " << sqrt(d) << endl;
-
-            if ( d < min_dist ) {
-                min_dist = d;
-                result = (*current);
-            }
-        }
-    }
-
-    // cout << "lon = " << lon << " lat = " << lat
-    //      << "  closest beacon = " << sqrt( min_dist ) << endl;
-
-    return result;
-}
-
 // Given a frequency, return the first matching station.
 FGNavRecord *FGNavList::findStationByFreq( double freq )
 {
index 4f2bc52552a89af4b30e282cc7fbd86d9f10ed62..f54e5db9320433dff00b90f96d33bb0c93959af9 100644 (file)
@@ -26,9 +26,8 @@
 
 
 #include <simgear/compiler.h>
-#include <simgear/misc/sg_path.hxx>
+
 #include <simgear/structure/SGSharedPtr.hxx>
-#include <simgear/structure/SGReferenced.hxx>
 
 #include <map>
 #include <vector>
 
 #include "navrecord.hxx"
 
-using std::map;
-using std::vector;
-using std::string;
-
-
+// forward decls
+class SGGeod;
 
 // FGNavList ------------------------------------------------------------------
 
 typedef SGSharedPtr<FGNavRecord> nav_rec_ptr;
-typedef vector < nav_rec_ptr > nav_list_type;
+typedef std::vector < nav_rec_ptr > nav_list_type;
 typedef nav_list_type::iterator nav_list_iterator;
 typedef nav_list_type::const_iterator nav_list_const_iterator;
 
-typedef map < int, nav_list_type > nav_map_type;
+typedef std::map < int, nav_list_type > nav_map_type;
 typedef nav_map_type::iterator nav_map_iterator;
 typedef nav_map_type::const_iterator nav_map_const_iterator;
 
-typedef map < string, nav_list_type > nav_ident_map_type;
-typedef nav_ident_map_type::iterator nav_ident_map_iterator;
-
-
 class FGNavList {
 
     nav_list_type carrierlist;
     nav_map_type navaids;
-    nav_map_type navaids_by_tile;
-    nav_ident_map_type ident_navaids;
 
     // Given a point and a list of stations, return the closest one to
     // the specified point.
-    FGNavRecord *findNavFromList( const SGVec3d &aircraft,
+    FGNavRecord *findNavFromList( const SGGeod &aircraft,
                                   const nav_list_type &stations );
 
 public:
@@ -82,27 +72,17 @@ public:
 
     /** Query the database for the specified station.  It is assumed
       * that there will be multiple stations with matching frequencies
-      * so a position must be specified.  Lon and lat are in radians,
-      * elev is in meters.
+      * so a position must be specified.
       */
-    FGNavRecord *findByFreq( double freq, double lon, double lat, double elev );
-
-    // locate closest item in the DB matching the requested ident
-    FGNavRecord *findByIdent( const char* ident, const double lon, const double lat );
+    FGNavRecord *findByFreq( double freq, const SGGeod& position);
 
     // Given an Ident and optional freqency, return the first matching
     // station.
-    FGNavRecord *findByIdentAndFreq( const char* ident,
+    FGNavRecord *findByIdentAndFreq( const std::string& ident,
                                      const double freq = 0.0 );
 
-    // returns the closest entry to the give lon/lat/elev
-    FGNavRecord *findClosest( double lon_rad, double lat_rad, double elev_m, 
-      FGPositioned::Type type = FG_NAV_ANY );
-
     // given a frequency returns the first matching entry
     FGNavRecord *findStationByFreq( double frequency );
-
-    inline const nav_map_type& get_navaids() const { return navaids; }
 };
 
 
@@ -112,10 +92,9 @@ public:
 
 
 typedef SGSharedPtr<FGTACANRecord> tacan_rec_ptr;
-typedef vector < tacan_rec_ptr > tacan_list_type;
-typedef map < int, tacan_list_type > tacan_map_type;
-typedef map < string, tacan_list_type > tacan_ident_map_type;
-
+typedef std::vector < tacan_rec_ptr > tacan_list_type;
+typedef std::map < int, tacan_list_type > tacan_map_type;
+typedef std::map < std::string, tacan_list_type > tacan_ident_map_type;
 
 class FGTACANList {
 
@@ -135,7 +114,7 @@ public:
     bool add( FGTACANRecord *r );
 
     // Given a TACAN Channel, return the appropriate frequency.
-    FGTACANRecord *findByChannel( const string& channel );
+    FGTACANRecord *findByChannel( const std::string& channel );
 
 
 };
index e85c43c4fcd6b5e1ad790ffc71fedf60ff0076fb..1e3800ae4aae01ff51ab840fed808085af0534bf 100644 (file)
@@ -43,7 +43,7 @@ FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent,
   freq(aFreq),
   range(aRange),
   multiuse(aMultiuse),
-  name(aName),
+  _name(aName),
   serviceable(true),
   trans_ident(aIdent)
 { 
@@ -77,12 +77,6 @@ FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent,
   
 }
 
-SGVec3d FGNavRecord::get_cart() const
-{
-  return SGVec3d::fromGeod(geod());
-}
-
-
 static FGPositioned::Type
 mapRobinTypeToFGPType(int aTy)
 {
@@ -100,7 +94,7 @@ mapRobinTypeToFGPType(int aTy)
   case 13: return FGPositioned::DME;
   case 99: return FGPositioned::INVALID; // end-of-file code
   default:
-    throw sg_range_exception("Got a nav.dat type we don't recgonize", "FGNavRecord::createFromStream");
+    throw sg_range_exception("Got a nav.dat type we don't recognize", "FGNavRecord::createFromStream");
   }
 }
 
@@ -117,7 +111,7 @@ FGNavRecord* FGNavRecord::createFromStream(std::istream& aStream)
   
   double lat, lon, elev_ft, multiuse;
   int freq, range;
-  std::string apt_id, name, ident;
+  std::string name, ident;
   aStream >> lat >> lon >> elev_ft >> freq >> range >> multiuse >> ident;
   getline(aStream, name);
   
@@ -127,6 +121,12 @@ FGNavRecord* FGNavRecord::createFromStream(std::istream& aStream)
     freq *= 100;
   }
   
+  // ensure marker beacons are anonymous, so they don't get added to the
+  // name index
+  if ((type >= OM) && (type <= IM)) {
+    ident.clear();
+  }
+  
   FGNavRecord* result = new FGNavRecord(type, ident,
     simgear::strutils::strip(name), SGGeod::fromDegFt(lon, lat, elev_ft),
     freq, range, multiuse);
@@ -136,19 +136,29 @@ FGNavRecord* FGNavRecord::createFromStream(std::istream& aStream)
 
 void FGNavRecord::initAirportRelation()
 {
-  if (type() < ILS || type() > IM) {
+  if ((type() < ILS) || (type() > IM)) {
     return; // not airport-located
   }
   
-  vector<string> parts = simgear::strutils::split(name);
-  apt_id = parts[0];
-  const FGAirport* apt = fgFindAirportID(apt_id);
+  vector<string> parts = simgear::strutils::split(_name);
+  if (parts.size() < 2) {
+    SG_LOG(SG_GENERAL, SG_WARN, "navaid has malformed name:" << _name);
+    return;
+  }
+  
+  const FGAirport* apt = fgFindAirportID(parts[0]);
   
   if (!apt) {
-    SG_LOG(SG_GENERAL, SG_WARN, "navaid " << ident() << " associated with bogus airport ID:" << apt_id);
+    SG_LOG(SG_GENERAL, SG_WARN, "navaid " << _name << " associated with bogus airport ID:" << parts[0]);
     return;
   }
   
+  runway = apt->getRunwayByIdent(parts[1]);
+  if (!runway) {
+    SG_LOG(SG_GENERAL, SG_WARN, "navaid " << _name << " associated with bogus runway ID:" << parts[1]);
+    return;
+  }
+    
   // fudge elevation to the field elevation if it's not specified
   if (fabs(elevation()) < 0.01) {
     mPosition.setElevationFt(apt->getElevation());
@@ -160,16 +170,8 @@ void FGNavRecord::initAirportRelation()
       return;
     }
     
-    if (parts.size() < 2) {
-      SG_LOG(SG_GENERAL, SG_ALERT, "can't parse navaid " << ident() 
-              << " name for airport/runway:" << name);
-      return;
-    }
-    
-     double threshold
-            = fgGetDouble( "/sim/navdb/localizers/auto-align-threshold-deg",
-                           5.0 );
-    FGRunway* runway = apt->getRunwayByIdent(parts[1]);
+   double threshold 
+     = fgGetDouble( "/sim/navdb/localizers/auto-align-threshold-deg", 5.0 );
     alignLocaliserWithRunway(runway, threshold);
   }
 }
index 55a02af7ee20ebbe790c2eec1529ac36bdc07c4c..57c199d6cea225f17e5ad2bacc81c57fb9898619 100644 (file)
@@ -53,9 +53,8 @@ class FGNavRecord : public FGPositioned
                                 // (degrees) or localizer heading
                                 // (degrees) or dme bias (nm)
 
-    std::string name;                // verbose name in nav database
-    std::string apt_id;              // corresponding airport id
-
+    std::string _name;                // verbose name in nav database
+    FGRunway* runway;
 
     bool serviceable;          // for failure modeling
     std::string trans_ident;         // for failure modeling
@@ -78,23 +77,18 @@ public:
     inline double get_lon() const { return longitude(); } // degrees
     inline double get_lat() const { return latitude(); } // degrees
     inline double get_elev_ft() const { return elevation(); }
-
-    const SGGeod& get_pos() const { return geod(); }
-    SGVec3d get_cart() const;
-    
-    Type get_fg_type() const { return type(); }
-    
+        
     inline int get_freq() const { return freq; }
     inline int get_range() const { return range; }
     inline double get_multiuse() const { return multiuse; }
     inline void set_multiuse( double m ) { multiuse = m; }
     inline const char *get_ident() const { return ident().c_str(); }
-    inline const std::string& get_name() const { return name; }
-    inline const std::string& get_apt_id() const { return apt_id; }
+
     inline bool get_serviceable() const { return serviceable; }
     inline const char *get_trans_ident() const { return trans_ident.c_str(); }
 
-  
+  virtual const std::string& name() const
+  { return _name; }
 };
 
 class FGTACANRecord : public SGReferenced {
index 1f3575c9e6d7bb1832a3a1157d88670b81fd64f9..54bc57c4eb6ffa84ee7d623d78a5a3dd1d5f44a5 100644 (file)
@@ -26,6 +26,8 @@
 #include <set>
 #include <algorithm>
 
+#include <iostream>
+
 #include <simgear/math/sg_geodesy.hxx>
 
 #include "positioned.hxx"
@@ -199,20 +201,19 @@ class RangePredictate
 {
 public:
   RangePredictate(const SGGeod& aOrigin, double aRange) :
-    mOrigin(aOrigin),
-    mRange(aRange)
+    mOrigin(SGVec3d::fromGeod(aOrigin)),
+    mRangeSqr(aRange * aRange)
   { ; }
   
   bool operator()(const FGPositionedRef& aPos)
   {
-    double d, az1, az2;
-    SGGeodesy::inverse(aPos->geod(), mOrigin, az1, az2, d);
-    return (d > mRange);
+    double dSqr = distSqr(aPos->cart(), mOrigin);
+    return (dSqr > mRangeSqr);
   }
   
 private:
-  SGGeod mOrigin;
-  double mRange;
+  SGVec3d mOrigin;
+  double mRangeSqr;
 };
 
 static void
@@ -228,19 +229,18 @@ class DistanceOrdering
 {
 public:
   DistanceOrdering(const SGGeod& aPos) :
-    mPos(aPos)
+    mPos(SGVec3d::fromGeod(aPos))
   { }
   
   bool operator()(const FGPositionedRef& a, const FGPositionedRef& b) const
   {
-    double dA, dB, az1, az2;
-    SGGeodesy::inverse(mPos, a->geod(), az1, az2, dA);
-    SGGeodesy::inverse(mPos, b->geod(), az1, az2, dB);
+    double dA = distSqr(a->cart(), mPos),
+      dB = distSqr(b->cart(), mPos);
     return dA < dB;
   }
 
 private:
-  SGGeod mPos;
+  SGVec3d mPos;
 };
 
 static void
@@ -273,17 +273,17 @@ namedFindClosest(const std::string& aIdent, const SGGeod& aOrigin, FGPositioned:
   double minDist = HUGE_VAL;
   FGPositionedRef result;
   NamedPositionedIndex::const_iterator it = range.first;
-    
+  SGVec3d cartOrigin(SGVec3d::fromGeod(aOrigin));
+  
   for (; it != range.second; ++it) {
     if (aFilter && !aFilter->pass(range.first->second)) {
       continue;
     }
     
   // find distance
-    double d, az1, az2;
-    SGGeodesy::inverse(aOrigin, it->second->geod(), az1, az2, d);
-    if (d < minDist) {
-      minDist = d;
+    double d2 = distSqr(cartOrigin, it->second->cart());
+    if (d2 < minDist) {
+      minDist = d2;
       result = it->second;
     }
   }
@@ -328,11 +328,11 @@ spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, FGPosit
     result.insert(result.end(), hits.begin(), hits.end()); // append
   } // of outer loop
   
+  sortByDistance(aPos, result);
   if (result.size() > aN) {
     result.resize(aN); // truncate at requested number of matches
   }
   
-  sortByDistance(aPos, result);
   return result;
 }
 
@@ -353,6 +353,7 @@ FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPo
 
 FGPositioned::~FGPositioned()
 {
+  //std::cout << "destroying:" << mIdent << "/" << nameForType(mType) << std::endl;
   removeFromIndices(this);
 }
 
@@ -362,12 +363,24 @@ FGPositioned::bucket() const
   return SGBucket(mPosition);
 }
 
+SGVec3d
+FGPositioned::cart() const
+{
+  return SGVec3d::fromGeod(mPosition);
+}
+
 const char* FGPositioned::nameForType(Type aTy)
 {
  switch (aTy) {
+ case RUNWAY: return "runway";
+ case TAXIWAY: return "taxiway";
+ case PARK_STAND: return "parking stand";
  case FIX: return "fix";
  case VOR: return "VOR";
  case NDB: return "NDB";
+ case ILS: return "ILS";
+ case LOC: return "localiser";
+ case GS: return "glideslope";
  case OM: return "outer-marker";
  case MM: return "middle-marker";
  case IM: return "inner-marker";
@@ -375,6 +388,8 @@ const char* FGPositioned::nameForType(Type aTy)
  case HELIPORT: return "heliport";
  case SEAPORT: return "seaport";
  case WAYPOINT: return "waypoint";
+ case DME: return "dme";
+ case TACAN: return "tacan";
  default:
   return "unknown";
  }
index ff3666290f927c2032debfcc3273a7137d725b78..1c275dcf4db30ddcefe52340fcd23d5247394dad 100644 (file)
@@ -82,6 +82,11 @@ public:
   const SGGeod& geod() const
   { return mPosition; }
 
+  /**
+   * Compute the cartesian position associated with this object
+   */
+  SGVec3d cart() const;
+
   SGBucket bucket() const;
   
   double latitude() const