]> git.mxchange.org Git - flightgear.git/commitdiff
Refactored some of the navlist code and removed the built in "fail to find"
authorcurt <curt>
Sat, 25 Jan 2003 20:45:39 +0000 (20:45 +0000)
committercurt <curt>
Sat, 25 Jan 2003 20:45:39 +0000 (20:45 +0000)
if the station is too far away.  Instead, simply return the closest station.
All the code that searches navaids does it's own range checking anyway.
This will make the navlist query functions a bit more useful for other
types of functionality where you may need to lookup a station without
consideration of range (i.e. presetting your position relative to a navaid.)

src/Cockpit/dme.cxx
src/Cockpit/kr_87.cxx
src/Cockpit/navcom.cxx
src/Main/fg_init.cxx
src/Navaids/nav.hxx
src/Navaids/navlist.cxx
src/Navaids/navlist.hxx
src/Navaids/testnavs.cxx

index bc00b0f51b4e66111f783ff7bfa3b02ea86119c7..e9a10b21c23c49993a17af6c1fa53efcae7e0d96 100644 (file)
@@ -218,7 +218,7 @@ void FGDME::search()
     }
 
     FGILS ils;
-    FGNav nav;
+    FGNav *nav;
 
     if ( current_ilslist->query( lon, lat, elev, freq, &ils ) ) {
         if (ils.get_has_dme()) {
@@ -232,17 +232,17 @@ void FGDME::search()
             y = ils.get_dme_y();
             z = ils.get_dme_z();
         }
-    } else if ( current_navlist->query( lon, lat, elev, freq, &nav ) ) {
-        if (nav.get_has_dme()) {
+    } else if ( (nav = current_navlist->findByFreq(freq, lon, lat, elev)) != NULL ) {
+        if (nav->get_has_dme()) {
             valid = true;
-            lon = nav.get_lon();
-            lat = nav.get_lat();
-            elev = nav.get_elev();
-            range = nav.get_range();
+            lon = nav->get_lon();
+            lat = nav->get_lat();
+            elev = nav->get_elev();
+            range = nav->get_range();
             effective_range = kludgeRange(elev, elev, range);
-            x = nav.get_x();
-            y = nav.get_y();
-            z = nav.get_z();
+            x = nav->get_x();
+            y = nav->get_y();
+            z = nav->get_z();
         }
     } else {
         valid = false;
index da6cde50bf44fac723a0a2749bf81e032d1d9762..9c06f9a491968290c22d87464032793af1e714c6 100644 (file)
@@ -482,33 +482,34 @@ void FGKR_87::search() {
     double acft_elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
 
                                // FIXME: the panel should handle this
-    FGNav nav;
-
     static string last_ident = "";
 
     ////////////////////////////////////////////////////////////////////////
     // ADF.
     ////////////////////////////////////////////////////////////////////////
 
-    if ( current_navlist->query( acft_lon, acft_lat, acft_elev, freq, &nav ) ) {
+    FGNav *nav
+        = current_navlist->findByFreq(freq, acft_lon, acft_lat, acft_elev);
+
+    if ( nav != NULL ) {
        char sfreq[128];
        snprintf( sfreq, 10, "%.0f", freq );
        ident = sfreq;
-       ident += nav.get_ident();
-//     cout << "adf ident = " << ident << endl;
+       ident += nav->get_ident();
+        // cout << "adf ident = " << ident << endl;
        valid = true;
        if ( last_ident != ident ) {
            last_ident = ident;
 
-           trans_ident = nav.get_trans_ident();
-           stn_lon = nav.get_lon();
-           stn_lat = nav.get_lat();
-           stn_elev = nav.get_elev();
-           range = nav.get_range();
+           trans_ident = nav->get_trans_ident();
+           stn_lon = nav->get_lon();
+           stn_lat = nav->get_lat();
+           stn_elev = nav->get_elev();
+           range = nav->get_range();
            effective_range = kludgeRange(stn_elev, acft_elev, range);
-           x = nav.get_x();
-           y = nav.get_y();
-           z = nav.get_z();
+           x = nav->get_x();
+           y = nav->get_y();
+           z = nav->get_z();
 
            if ( globals->get_soundmgr()->exists( "adf-ident" ) ) {
                globals->get_soundmgr()->remove( "adf-ident" );
@@ -528,7 +529,7 @@ void FGKR_87::search() {
            //      << globals->get_time_params()->get_cur_time() << endl;
 
            // cout << "Found an adf station in range" << endl;
-           // cout << " id = " << nav.get_ident() << endl;
+           // cout << " id = " << nav->get_ident() << endl;
        }
     } else {
        valid = false;
index e621ddbf28cdb5dc725d56c4531d3e22f4819df1..bf2e522ca83ccf500b2f225cfa70192c6d5a7919 100644 (file)
@@ -451,7 +451,7 @@ void FGNavCom::search()
     double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
 
     FGILS ils;
-    FGNav nav;
+    FGNav *nav;
 
     ////////////////////////////////////////////////////////////////////////
     // Nav.
@@ -515,27 +515,27 @@ void FGNavCom::search()
            // cout << "Found an ils station in range" << endl;
            // cout << " id = " << ils.get_locident() << endl;
        }
-    } else if ( current_navlist->query( lon, lat, elev, nav_freq, &nav ) ) {
-       nav_id = nav.get_ident();
+    } else if ( (nav = current_navlist->findByFreq(nav_freq, lon, lat, elev)) != NULL ) {
+       nav_id = nav->get_ident();
        nav_valid = true;
        if ( last_nav_id != nav_id || !last_nav_vor ) {
            last_nav_id = nav_id;
            last_nav_vor = true;
-           nav_trans_ident = nav.get_trans_ident();
+           nav_trans_ident = nav->get_trans_ident();
            nav_loc = false;
-           nav_has_dme = nav.get_has_dme();
+           nav_has_dme = nav->get_has_dme();
            nav_has_gs = false;
-           nav_loclon = nav.get_lon();
-           nav_loclat = nav.get_lat();
-           nav_elev = nav.get_elev();
-           nav_magvar = nav.get_magvar();
-           nav_range = nav.get_range();
+           nav_loclon = nav->get_lon();
+           nav_loclat = nav->get_lat();
+           nav_elev = nav->get_elev();
+           nav_magvar = nav->get_magvar();
+           nav_range = nav->get_range();
            nav_effective_range = adjustNavRange(nav_elev, elev, nav_range);
            nav_target_gs = 0.0;
            nav_radial = nav_sel_radial;
-           nav_x = nav.get_x();
-           nav_y = nav.get_y();
-           nav_z = nav.get_z();
+           nav_x = nav->get_x();
+           nav_y = nav->get_y();
+           nav_z = nav->get_z();
 
            if ( globals->get_soundmgr()->exists( nav_fx_name ) ) {
                globals->get_soundmgr()->remove( nav_fx_name );
@@ -566,7 +566,7 @@ void FGNavCom::search()
            //      << globals->get_time_params()->get_cur_time() << endl;
 
            // cout << "Found a vor station in range" << endl;
-           // cout << " id = " << nav.get_ident() << endl;
+           // cout << " id = " << nav->get_ident() << endl;
        }
     } else {
        nav_valid = false;
index 842509c5421d77468437206131ef06403a4a12b5..57c5904899491c1e6a07394561d69b035506db5d 100644 (file)
@@ -960,15 +960,15 @@ static void fgSetDistOrAltFromGlideSlope() {
 
 // Set current_options lon/lat given an airport id and heading (degrees)
 static bool fgSetPosFromNAV( const string& id, const double& freq ) {
-    FGNav nav;
+    FGNav *nav = current_navlist->findByIdentAndFreq( id.c_str(), freq );
 
     // set initial position from runway and heading
-    if ( current_navlist->findByIdentAndFreq( id.c_str(), freq, &nav ) ) {
+    if ( nav != NULL ) {
         SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
                 << id << ":" << freq );
 
-        double lon = nav.get_lon();
-        double lat = nav.get_lat();
+        double lon = nav->get_lon();
+        double lat = nav->get_lat();
 
         if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
         {
index 478c47e1eebe2ec1e84be151c722a092d4c8ad68..2bfff9f1e85db8b3e641841201191b3d46e33887 100644 (file)
@@ -79,15 +79,6 @@ public:
     inline string get_trans_ident() { return trans_ident; }
     inline double get_magvar () const { return magvar; }
 
-    /* inline void set_type( char t ) { type = t; }
-    inline void set_lon( double l ) { lon = l; }
-    inline void set_lat( double l ) { lat = l; }
-    inline void set_elev( double e ) { elev = e; }
-    inline void set_freq( int f ) { freq = f; }
-    inline void set_range( int r ) { range = r; }
-    inline void set_dme( bool b ) { dme = b; }
-    inline void set_ident( char *i ) { strncpy( ident, i, 5 ); } */
-
     friend istream& operator>> ( istream&, FGNav& );
 };
 
index aba88dddcbf61c83215d0469e35aaf7aee6ac540..09395daa490fb60863efb958aef62ca8f0cefa67 100644 (file)
@@ -108,75 +108,74 @@ bool FGNavList::init( SGPath path ) {
 }
 
 
-// query the database for the specified frequency, lon and lat are in
-// degrees, elev is in meters
-bool FGNavList::query( double lon, double lat, double elev, double freq,
-                      FGNav *nav )
+// Query the database for the specified frequency.  It is assumed that
+// there will be multiple stations with matching frequencies so a
+// position must be specified.  Lon and lat are in degrees, elev is in
+// meters.
+FGNav *FGNavList::findByFreq( double freq, double lon, double lat, double elev )
 {
     nav_list_type stations = navaids[(int)(freq*100.0 + 0.5)];
-
-    nav_list_iterator current = stations.begin();
-    nav_list_iterator last = stations.end();
-
     Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
-    return findNavFromList(aircraft, current, last, nav);
+
+    return findNavFromList( aircraft, stations );
 }
 
 
-bool FGNavList::findByIdent(const char* ident, double lon, double lat,
-                            FGNav *nav)
+FGNav *FGNavList::findByIdent( const char* ident,
+                               const double lon, const double lat )
 {
     nav_list_type stations = ident_navaids[ident];
-
-    nav_list_iterator current = stations.begin();
-    nav_list_iterator last = stations.end();
-       
     Point3D aircraft = sgGeodToCart( Point3D(lon, lat, 0.0) );
-    return findNavFromList(aircraft, current, last, nav);
+
+    return findNavFromList( aircraft, stations );
 }
 
 
-bool FGNavList::findByIdentAndFreq(const char* ident, const double& freq,
-                                   FGNav *nav)
+// Given an Ident and optional freqency, return the first matching
+// station.
+FGNav *FGNavList::findByIdentAndFreq( const char* ident, const double freq )
 {
-    cout << "ident = " << ident << endl;
     nav_list_type stations = ident_navaids[ident];
-    cout << " matches = " << stations.size() << endl;
-    nav_list_iterator current = stations.begin();
-    nav_list_iterator last = stations.end();
 
-    if ( stations.size() > 1 ) {
-        // more than one match on this ident, use freq to refine
+    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);
-        for ( ; current != last ; ++current ) {
-            if ( f == (*current)->get_freq() ) {
-                *nav = (**current);
-                return true;
+        for ( unsigned int i = 0; i < stations.size(); ++i ) {
+            if ( f == stations[i]->get_freq() ) {
+                return stations[i];
             }
         }
     } else {
-        *nav = (**current);
-        return true;
+        return stations[0];
     }
 
-    return false;
+    return NULL;
 }
 
 
-bool FGNavList::findNavFromList(const Point3D &aircraft, 
-                                nav_list_iterator current,
-                                nav_list_iterator end, FGNav *nav)
+// Given a point and a list of stations, return the closest one to the
+// specified point.
+FGNav *FGNavList::findNavFromList( const Point3D &aircraft, 
+                                   const nav_list_type &stations )
 {
-    // double az1, az2, s;
-    
+    FGNav *nav = NULL;
     Point3D station;
     double d2;
-    double min_dist = 99999999999999.9;
-    bool found_one = false;
-    for ( ; current != end ; ++current ) {
+    double min_dist;
+
+    // prime the pump with info from stations[0]
+    if ( stations.size() > 0 ) {
+        nav = stations[0];
+       station = Point3D( nav->get_x(), nav->get_y(), nav->get_z());
+       min_dist = aircraft.distance3Dsquared( station );
+    }
+
+    // check if any of the remaining stations are closer
+    for ( unsigned int i = 1; i < stations.size(); ++i ) {
        // cout << "testing " << current->get_ident() << endl;
-       station = Point3D((*current)->get_x(), (*current)->get_y(),
-                          (*current)->get_z());
+       station = Point3D( stations[i]->get_x(), stations[i]->get_y(),
+                           stations[i]->get_z());
 
        d2 = aircraft.distance3Dsquared( station );
 
@@ -184,22 +183,11 @@ bool FGNavList::findNavFromList(const Point3D &aircraft,
        //      << "  range = " << current->get_range() * SG_NM_TO_METER
         //      << endl;
 
-       // match d^2 < 2 * range^2 the published range so we can model
-       // reduced signal strength
-       double twiceRange = 2 * (*current)->get_range() * SG_NM_TO_METER;
-       if ( d2 < (twiceRange * twiceRange)) {
-            // cout << "d2 = " << d2 << " min_dist = " << min_dist << endl;
-            if ( d2 < min_dist ) {
-                min_dist = d2;
-                found_one = true;
-                *nav = (**current);
-                // cout << "matched = " << (*current)->get_ident() << endl;
-            } else {
-                // cout << "matched, but too far away = "
-                //      << (*current)->get_ident() << endl;
-            }
-       }
+        if ( d2 < min_dist ) {
+            min_dist = d2;
+            nav = stations[i];
+        }
     }
 
-    return found_one;
+    return nav;
 }
index c890e0ef8d2971621b03129dfe50764fff3e3863..31e99727687037ec4a94c1c933bfeca25262d44c 100644 (file)
@@ -54,12 +54,10 @@ class FGNavList {
     nav_map_type navaids;
     nav_ident_map_type ident_navaids;
        
-    // internal helper to pick a Nav item from a nav_list based on
-    // distance from the aircraft point
-    bool findNavFromList(const Point3D &aircraft, 
-                         nav_list_iterator current,
-                         nav_list_iterator last,
-                         FGNav *n);
+    // Given a point and a list of stations, return the closest one to
+    // the specified point.
+    FGNav *findNavFromList( const Point3D &aircraft, 
+                            const nav_list_type &stations );
        
 public:
 
@@ -69,15 +67,18 @@ public:
     // load the navaids and build the map
     bool init( SGPath path );
 
-    // query the database for the specified frequency, lon and lat are
-    // in degrees, elev is in meters
-    bool query( double lon, double lat, double elev, double freq, FGNav *nav );
+    // Query the database for the specified frequency.  It is assumed
+    // that there will be multiple stations with matching frequencies
+    // so a position must be specified.  Lon and lat are in degrees,
+    // elev is in meters.
+    FGNav *findByFreq( double freq, double lon, double lat, double elev );
 
     // locate closest item in the DB matching the requested ident
-    bool findByIdent(const char* ident, double lon, double lat, FGNav *nav);
+    FGNav *findByIdent( const char* ident, const double lon, const double lat );
 
-    // locate item in the DB matching the requested ident
-    bool findByIdentAndFreq(const char* ident, const double& freq, FGNav *nav);
+    // Given an Ident and optional freqency, return the first matching
+    // station.
+    FGNav *findByIdentAndFreq( const char* ident, const double freq = 0.0 );
 };
 
 
index 3e95bbcff9be88186df6f98887112c964a77b0b5..b18455bf115c3eb42a76e9e6d7185d4ae95138c6 100644 (file)
@@ -16,25 +16,27 @@ int main() {
 
     current_navlist->init( p_nav );
        
-    FGNav n;
-    if ( current_navlist->query( -93.2 * SG_DEGREES_TO_RADIANS,
-                                 45.14 * SG_DEGREES_TO_RADIANS,
-                                 3000, 117.30, &n) )
+    FGNav *n;
+    if ( (n = current_navlist->findByFreq( -93.2 * SG_DEGREES_TO_RADIANS,
+                                           45.14 * SG_DEGREES_TO_RADIANS,
+                                           3000, 117.30)) != NULL )
     {
        cout << "Found a vor station in range" << endl;
-       cout << " id = " << n.get_ident() << endl;
+       cout << " id = " << n->get_ident() << endl;
     } else {
        cout << "not picking up vor. :-(" << endl;
     }
 
-    FGNav dcs;
-    if (current_navlist->findByIdent("DCS", -3.3 * SG_DEGREES_TO_RADIANS,
-                                     55.9 * SG_DEGREES_TO_RADIANS, &dcs)) {
+    FGNav *dcs;
+    if ( (dcs = current_navlist->findByIdent( "DCS",
+                                              -3.3 * SG_DEGREES_TO_RADIANS,
+                                              55.9 * SG_DEGREES_TO_RADIANS))
+         != NULL ) {
                                                
         cout << "Found DCS by ident" << endl;
-        if (dcs.get_freq() != 11520)
+        if (dcs->get_freq() != 11520)
             cout << "Frequency for DCS VOR is wrong (should be 115.20), it's " 
-                 << dcs.get_freq() << endl;
+                 << dcs->get_freq() << endl;
     } else {
         cout << "couldn't locate DCS (Dean-Cross) VOR" << endl;
     }