Hi!

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.)

Please review, test (especially that std::multimap works on all our
supported platforms) and apply.

-- 
Thanks,
Csaba/Jester
Index: src/Navaids/fixlist.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Navaids/fixlist.cxx,v
retrieving revision 1.8
diff -u -r1.8 fixlist.cxx
--- src/Navaids/fixlist.cxx	21 Feb 2006 01:19:37 -0000	1.8
+++ src/Navaids/fixlist.cxx	25 Apr 2008 22:39:43 -0000
@@ -30,6 +30,7 @@
 #include <simgear/math/sg_geodesy.hxx>
 
 #include "fixlist.hxx"
+SG_USING_STD(pair);
 
 
 // Constructor
@@ -76,7 +77,7 @@
              << ", 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,8 +87,9 @@
 // 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() ) {
+    fix_map_const_iterator it = fixlist.find(ident);
+    if ( it != fixlist.end() ) {
+        *fix = it->second;
 	return true;
     } else {
         return false;
@@ -101,18 +103,27 @@
                                   double elev, FGFix *fix, double *heading,
                                   double *dist )
 {
-    *fix = fixlist[ident];
-    if ( fix->get_ident().empty() ) {
+    pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
+
+    if (range.first == range.second) {
 	return false;
     }
 
-    double az1, az2, s;
-    geo_inverse_wgs_84( elev, lat, lon, 
-			fix->get_lat(), fix->get_lon(),
+    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;
-    *heading = az2;
-    *dist = s;
+        // cout << "  dist = " << s << endl;
+        if (min_s < 0 || s < min_s) {
+            *heading = az2;
+            *dist = s;
+            min_s = s;
+            *fix = current->second;
+        }
+    }
+    
     return true;
 }
 
Index: src/Navaids/fixlist.hxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Navaids/fixlist.hxx,v
retrieving revision 1.6
diff -u -r1.6 fixlist.hxx
--- src/Navaids/fixlist.hxx	21 Feb 2006 01:19:37 -0000	1.6
+++ src/Navaids/fixlist.hxx	25 Apr 2008 22:39:43 -0000
@@ -34,12 +34,12 @@
 
 #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;
 
Index: src/Autopilot/route_mgr.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Autopilot/route_mgr.cxx,v
retrieving revision 1.16
diff -u -r1.16 route_mgr.cxx
--- src/Autopilot/route_mgr.cxx	14 May 2006 11:14:49 -0000	1.16
+++ src/Autopilot/route_mgr.cxx	25 Apr 2008 22:39:44 -0000
@@ -332,15 +332,6 @@
         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 @@
         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;
 
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to