Reported by AnMaster on IRC ;)
Inserting and deleting waypoints not at the end of the route messes up
leg distances.

Beefed up the test prog a little, see patch #1.
Result (have cut out the irrelevant part):
Route dump: Init
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 2 (0, 2) @0 dist: 1
       #3 3 (2, 2) @0 dist: 2
       #4 4 (2, 4) @0 dist: 2
Route dump: removed WP2
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 3 (2, 2) @0 dist: 2 <- not updated
       #3 4 (2, 4) @0 dist: 2
Route dump: added back WP2 after WP3
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 3 (2, 2) @0 dist: 2
       #3 2 (0, 2) @0 dist: 1 <- not updated
       #4 4 (2, 4) @0 dist: 0 <- messed up

After fix by patch #2:
Route dump: Init
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 2 (0, 2) @0 dist: 1
       #3 3 (2, 2) @0 dist: 2
       #4 4 (2, 4) @0 dist: 2
Route dump: removed WP2
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 3 (2, 2) @0 dist: 2.23607 <- is updated
       #3 4 (2, 4) @0 dist: 2
Route dump: added back WP2 after WP3
       #0 Start (0, 0) @0 dist: 0
       #1 1 (0, 1) @0 dist: 1
       #2 3 (2, 2) @0 dist: 2.23607
       #3 2 (0, 2) @0 dist: 2 <- is updated
       #4 4 (2, 4) @0 dist: 2.82843 <- is correct

I have moved the add/delete functions into the cxx file, don't see any
need for them to be in the header.
Somebody please check this too, it is 5AM here.

Greets,
Csaba
Index: source/simgear/route/routetest.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/route/routetest.cxx,v
retrieving revision 1.2
diff -u -r1.2 routetest.cxx
--- source/simgear/route/routetest.cxx  31 Dec 2002 14:47:37 -0000      1.2
+++ source/simgear/route/routetest.cxx  6 Apr 2007 02:51:41 -0000
@@ -8,6 +8,17 @@
 
 SG_USING_STD(cout);
 SG_USING_STD(endl);
+
+void dump_route(const SGRoute& route, const char* message)
+{
+    cout << "Route dump: " << message << endl;
+    for(int i = 0; i < route.size(); i++) {
+       const SGWayPoint wp = route.get_waypoint(i);
+       cout << "\t#" << i << " " << wp.get_id() << " (" << wp.get_target_lat()
+               << ", " << wp.get_target_lon() << ") @" << wp.get_target_alt() 
+               << " dist: " << wp.get_distance() << endl;
+    }
+}
  
 int main() {
     SGRoute route;
@@ -17,7 +28,8 @@
     route.add_waypoint( SGWayPoint(2, 0, 0, SGWayPoint::CARTESIAN, "2") );
     route.add_waypoint( SGWayPoint(2, 2, 0, SGWayPoint::CARTESIAN, "3") );
     route.add_waypoint( SGWayPoint(4, 2, 0, SGWayPoint::CARTESIAN, "4") );
-   
+
+    dump_route(route, "Init");
     route.set_current( 1 );
 
     cout << "( 0.5, 0 ) = " << route.distance_off_route( 0.5, 0 ) << endl;
@@ -29,5 +41,12 @@
     cout << "( 2, 4 ) = " << route.distance_off_route( 2, 4 ) << endl;
     cout << "( 2.5, 4 ) = " << route.distance_off_route( 2.5, 4 ) << endl;
 
+    SGWayPoint wp2 = route.get_waypoint(2);
+    route.delete_waypoint(2);
+    dump_route(route, "removed WP2");
+
+    route.add_waypoint(wp2, 3);
+    dump_route(route, "added back WP2 after WP3");
+
     return 0;
 }
Index: source/simgear/route/route.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/route/route.cxx,v
retrieving revision 1.2
diff -u -r1.2 route.cxx
--- source/simgear/route/route.cxx      8 Mar 2006 18:16:09 -0000       1.2
+++ source/simgear/route/route.cxx      6 Apr 2007 02:53:34 -0000
@@ -68,3 +68,49 @@
        return 0;
     }
 }
+
+/** Update the length of the leg ending at waypoint index */
+void SGRoute::update_distance(int index)
+{
+    SGWayPoint& curr = route[ index ];
+    double tmpd, tmpc;
+
+    if ( index == 0 ) {
+       tmpd = 0;
+    } else {    
+       const SGWayPoint& prev = route[ index - 1 ];
+       curr.CourseAndDistance( prev, &tmpc, &tmpd );
+    }
+    
+    curr.set_distance( tmpd );
+}
+
+/**
+ * Add waypoint (default), or insert waypoint at position n.
+ * @param wp a waypoint
+ */
+void SGRoute::add_waypoint( const SGWayPoint &wp, int n ) {
+    int size = route.size();
+    if ( n < 0 || n >= size ) {
+       n = size;
+        route.push_back( wp );
+    } else {
+        route.insert( route.begin() + n, 1, wp );
+       // update distance of next leg if not at end of route
+       update_distance(n + 1);
+    }
+    update_distance(n);    
+}
+
+/** Delete waypoint with index n  (last one if n < 0) */
+void SGRoute::delete_waypoint( int n ) {
+    int size = route.size();
+    if ( size == 0 )
+        return;
+    if ( n < 0 || n >= size )
+        n = size - 1;
+
+    route.erase( route.begin() + n );
+    // update distance of next leg if not at end of route
+    if ( n < size - 1 ) update_distance(n);
+}
Index: source/simgear/route/route.hxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/route/route.hxx,v
retrieving revision 1.4
diff -u -r1.4 route.hxx
--- source/simgear/route/route.hxx      8 May 2006 11:31:16 -0000       1.4
+++ source/simgear/route/route.hxx      6 Apr 2007 02:53:34 -0000
@@ -55,6 +55,8 @@
     route_list route;
     int current_wp;
 
+    void update_distance(int index);
+
 public:
 
     /** Constructor */
@@ -73,21 +75,7 @@
      * Add waypoint (default), or insert waypoint at position n.
      * @param wp a waypoint
      */
-    void add_waypoint( const SGWayPoint &wp, int n = -1 ) {
-        if ( n < 0 || n >= (int)route.size() )
-            route.push_back( wp );
-        else
-            route.insert( route.begin() + n, 1, wp );
-
-       int size = route.size();
-       if ( size > 1 ) {
-           SGWayPoint next_to_last = route[ size - 2 ];
-           double tmpd, tmpc;
-           wp.CourseAndDistance( next_to_last, &tmpc, &tmpd );
-           route[size - 1].set_distance( tmpd );
-       }
-    }
-
+    void add_waypoint( const SGWayPoint &wp, int n = -1 );
     /**
      * Get the number of waypoints (i.e. route length )
      * @return route length
@@ -152,14 +140,7 @@
     inline void delete_first() { delete_waypoint(0); }
 
     /** Delete waypoint waypoint with index n  (last one if n < 0) */
-    void delete_waypoint( int n = 0 ) {
-        if ( !route.size() )
-            return;
-        if ( n < 0 || n >= (int)route.size() )
-            n = route.size() - 1;
-
-        route.erase( route.begin() + n );
-    }
+    void delete_waypoint( int n = 0 );
 
     /**
      * Calculate perpendicular distance from the current route segment
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to