]> git.mxchange.org Git - flightgear.git/commitdiff
Csaba "Jester" HALASZ:
authormfranz <mfranz>
Mon, 28 Apr 2008 11:26:02 +0000 (11:26 +0000)
committermfranz <mfranz>
Mon, 28 Apr 2008 11:26:02 +0000 (11:26 +0000)
Attached patch adds support for multiple FIXes with the same name.
Applies to both branches.
New functionality is in query_and_offset, which now returns the FIX
closest to the passed in location.
Updated route manager to take advantage of this.

Otherwise, query functions return an unspecified member from the set
of identically named FIXes. (This was previously the one occurring
last in the database file, but I don't think anybody counted on that.)

src/Autopilot/route_mgr.cxx
src/Navaids/fixlist.cxx
src/Navaids/fixlist.hxx

index f9175aa1e3e3fb89c3ca1b8e1a079d36bdfe523f..3cac4bd303e54ffc638294f07dedf7c2aad6bbb4 100644 (file)
@@ -332,15 +332,6 @@ int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) {
         return 2;
     }
 
-    // check for fix id
-    FGFix f;
-    if ( globals->get_fixlist()->query( target, &f ) ) {
-        SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
-        *wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
-        return 3;
-    }
-
-    // Try finding a nav matching the ID
     double lat, lon;
     // The base lon/lat are determined by the last WP,
     // or the current pos if the WP list is empty.
@@ -355,6 +346,18 @@ int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) {
         lon = fgGetNode("/position/longitude-deg")->getDoubleValue();
     }
 
+    // check for fix id
+    FGFix f;
+    double heading;
+    double dist;
+
+    if ( globals->get_fixlist()->query_and_offset( target, lon, lat, 0, &f, &heading, &dist ) ) {
+        SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
+        *wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
+        return 3;
+    }
+
+    // Try finding a nav matching the ID
     lat *= SGD_DEGREES_TO_RADIANS;
     lon *= SGD_DEGREES_TO_RADIANS;
 
index c51534b1dd8c57095d2cc37f2090e3687238de45..1b87d4ca8e46e76db4554590b4f3e53e2e1a1a76 100644 (file)
@@ -30,6 +30,7 @@
 #include <simgear/math/sg_geodesy.hxx>
 
 #include "fixlist.hxx"
+SG_USING_STD(pair);
 
 
 // Constructor
@@ -76,7 +77,7 @@ bool FGFixList::init( SGPath path ) {
              << ", lat=" << fix.get_lat()
              << ", lon=" << fix.get_lon() << endl; */
 
-        fixlist[fix.get_ident()] = fix;
+        fixlist.insert(pair<string, FGFix>(fix.get_ident(), fix));
         in >> skipcomment;
     }
     return true;
@@ -86,9 +87,10 @@ bool FGFixList::init( SGPath path ) {
 // query the database for the specified fix, lon and lat are in
 // degrees, elev is in meters
 bool FGFixList::query( const string& ident, FGFix *fix ) {
-    *fix = fixlist[ident];
-    if ( ! fix->get_ident().empty() ) {
-       return true;
+    fix_map_const_iterator it = fixlist.find(ident);
+    if ( it != fixlist.end() ) {
+        *fix = it->second;
+        return true;
     } else {
         return false;
     }
@@ -101,18 +103,27 @@ bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
                                   double elev, FGFix *fix, double *heading,
                                   double *dist )
 {
-    *fix = fixlist[ident];
-    if ( fix->get_ident().empty() ) {
-       return false;
+    pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
+
+    if (range.first == range.second) {
+        return false;
+    }
+
+    double min_s = -1.0;
+    for (fix_map_const_iterator current = range.first; current != range.second; ++current) {
+        double az1, az2, s;
+        geo_inverse_wgs_84( elev, lat, lon,
+                        current->second.get_lat(), current->second.get_lon(),
+                        &az1, &az2, &s );
+        // cout << "  dist = " << s << endl;
+        if (min_s < 0 || s < min_s) {
+            *heading = az2;
+            *dist = s;
+            min_s = s;
+            *fix = current->second;
+        }
     }
 
-    double az1, az2, s;
-    geo_inverse_wgs_84( elev, lat, lon, 
-                       fix->get_lat(), fix->get_lon(),
-                       &az1, &az2, &s );
-    // cout << "  dist = " << s << endl;
-    *heading = az2;
-    *dist = s;
     return true;
 }
 
index dbf0ef2c579f9b0e1ef6c60dedc0ef246d0792b8..8280c1df0f142471883210e60dd5acf104c329b6 100644 (file)
 
 #include "fix.hxx"
 
-SG_USING_STD(map);
+SG_USING_STD(multimap);
 SG_USING_STD(vector);
 SG_USING_STD(string);
 
-// TODO - fix names may be globally non-unique.  Allow for this.
-typedef map < string, FGFix > fix_map_type;
+// fix names may be globally non-unique.  Allow for this.
+typedef multimap < string, FGFix > fix_map_type;
 typedef fix_map_type::iterator fix_map_iterator;
 typedef fix_map_type::const_iterator fix_map_const_iterator;
 
@@ -57,8 +57,8 @@ public:
 
     // query the database for the specified fix
     bool query( const string& ident, FGFix *f );
-       
-    // Find fix of requested type with closest exact or following ident 
+
+    // Find fix of requested type with closest exact or following ident
     // (by ACSII values) to that supplied (ie. a lower-bound lookup).
     // Supplying true for exact forces only exact matches to be returned (similar to above function)
     // Returns NULL if no match found.
@@ -69,7 +69,7 @@ public:
     bool query_and_offset( const string& ident, double lon, double lat,
                            double elev, FGFix *f, double *heading,
                            double *dist );
-                                                  
+
     // Return a pointer to the master fixlist
     inline const fix_map_type* getFixList() { return(&fixlist); }
 };