]> git.street.me.uk Git - andy/viking.git/commitdiff
Improve the Route Finder Tool
authorMatthew Hague <matthewhague@zoho.com>
Tue, 4 Feb 2014 23:44:09 +0000 (23:44 +0000)
committerRob Norris <rw_norris@hotmail.com>
Wed, 5 Feb 2014 00:35:27 +0000 (00:35 +0000)
Changed route finder User Interface workings, it is now similar to the new route tool such that it shows the 'as the crow flys' direct line route,
but on creation of each new trackpoint the route from the last trackpoint is calculated using online services.

The user can switch between adding points with the new route tool or with the route finder tool, removed a lot of the vtk->route_finder fields and merged them with the new route fields instead, added code to ensure that double trackpoints get added at the joins between planned route segments.

Changed so that enforcing duplicates in viktrwlayer.c appending a track duplicates the end of the old track not the start of the new

Changed a bit of logic in route finder click to deal with a current empty route not created by the route finder

Like the current Create Track and Route tools, the Route Finder handles clicks when in pan mode and avoids extra dispay sync refreshing to avoid display flicker.

Update the UI during routing to show a busy cursor and info about the requests being made are shown in the statusbar (particularly in case the online requests are slow).

New icons haven been produced for route finder.

Signed-off-by: Rob Norris <rw_norris@hotmail.com>
src/icons/cursor_route_finder.png
src/icons/route_finder_18.png
src/viktrwlayer.c

index a808be29cefdba3de28d00d37e90c4e1ffaa2e48..4b19f13697f4d51a7f510b84d30deb25dea0bb57 100644 (file)
Binary files a/src/icons/cursor_route_finder.png and b/src/icons/cursor_route_finder.png differ
index 291447935c48d4cd325a813da08e2d6ee2972e3e..15def871ca1ee86850f7d269fd7f02cedac9d3b3 100644 (file)
Binary files a/src/icons/route_finder_18.png and b/src/icons/route_finder_18.png differ
index 6af595efd62b4198cc47e1424cea2e3fb677997f..84d963a1ddcc73024ccb70b48ea99826a47c20ef 100644 (file)
@@ -202,10 +202,8 @@ struct _VikTrwLayer {
 
   /* route finder tool */
   gboolean route_finder_started;
-  VikCoord route_finder_coord;
   gboolean route_finder_check_added_track;
   VikTrack *route_finder_added_track;
-  VikTrack *route_finder_current_track;
   gboolean route_finder_append;
 
   gboolean drawlabels;
@@ -390,8 +388,9 @@ static void tool_new_track_release ( VikTrwLayer *vtl, GdkEventButton *event, Vi
 static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp ); 
 static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp);
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp );
 
 static void cached_pixbuf_free ( CachedPixbuf *cp );
 static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
@@ -438,6 +437,15 @@ static VikToolInterface trw_layer_tools[] = {
     TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
     GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf, NULL },
 
+  { { "ExtendedRouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
+    (VikToolConstructorFunc) tool_extended_route_finder_create,  NULL, NULL, NULL,
+    (VikToolMouseFunc) tool_extended_route_finder_click,
+    (VikToolMouseMoveFunc) tool_new_track_move, // -\#
+    (VikToolMouseFunc) tool_new_track_release,  //   -> Reuse these track methods on a route
+    (VikToolKeyFunc) tool_extended_route_finder_key_press,
+    TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
+    GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf, NULL },
+
   { { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
     (VikToolConstructorFunc) tool_edit_waypoint_create,
     (VikToolDestructorFunc) tool_edit_waypoint_destroy,
@@ -464,21 +472,16 @@ static VikToolInterface trw_layer_tools[] = {
     FALSE,
     GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf, NULL },
 
-  { { "RouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
-    (VikToolConstructorFunc) tool_route_finder_create,  NULL, NULL, NULL,
-    (VikToolMouseFunc) tool_route_finder_click, NULL, NULL, (VikToolKeyFunc) NULL,
-    FALSE,
-    GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf, NULL },
 };
 
 enum {
   TOOL_CREATE_WAYPOINT=0,
   TOOL_CREATE_TRACK,
   TOOL_CREATE_ROUTE,
+  TOOL_ROUTE_FINDER,
   TOOL_EDIT_WAYPOINT,
   TOOL_EDIT_TRACKPOINT,
   TOOL_SHOW_PICTURE,
-  TOOL_ROUTE_FINDER,
   NUM_TOOLS
 };
 
@@ -3880,6 +3883,7 @@ static void trw_layer_finish_track ( menu_array_layer values )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
   vtl->current_track = NULL;
+  vtl->route_finder_started = FALSE;
   vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
@@ -4434,9 +4438,19 @@ void vik_trw_layer_filein_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypo
 
 void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr )
 {
-  if ( vtl->route_finder_append && vtl->route_finder_current_track ) {
+  if ( vtl->route_finder_append && vtl->current_track ) {
     vik_track_remove_dup_points ( tr ); /* make "double point" track work to undo */
-    vik_track_steal_and_append_trackpoints ( vtl->route_finder_current_track, tr );
+
+    // enforce end of current track equal to start of tr
+    VikTrackpoint *cur_end = vik_track_get_tp_last ( vtl->current_track );
+    VikTrackpoint *new_start = vik_track_get_tp_first ( tr );
+    if ( ! vik_coord_equals ( &cur_end->coord, &new_start->coord ) ) {
+        vik_track_add_trackpoint ( vtl->current_track,
+                                   vik_trackpoint_copy ( cur_end ),
+                                   FALSE );
+    }
+
+    vik_track_steal_and_append_trackpoints ( vtl->current_track, tr );
     vik_track_free ( tr );
     vtl->route_finder_append = FALSE; /* this means we have added it */
   } else {
@@ -4577,13 +4591,11 @@ gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, VikTrack *trk )
       vtl->current_tp_track = NULL;
       vtl->current_tp_id = NULL;
       vtl->moving_tp = FALSE;
+      vtl->route_finder_started = FALSE;
     }
 
     was_visible = trk->visible;
 
-    if ( trk == vtl->route_finder_current_track )
-      vtl->route_finder_current_track = NULL;
-
     if ( trk == vtl->route_finder_added_track )
       vtl->route_finder_added_track = NULL;
 
@@ -4632,9 +4644,6 @@ gboolean vik_trw_layer_delete_route ( VikTrwLayer *vtl, VikTrack *trk )
 
     was_visible = trk->visible;
 
-    if ( trk == vtl->route_finder_current_track )
-      vtl->route_finder_current_track = NULL;
-
     if ( trk == vtl->route_finder_added_track )
       vtl->route_finder_added_track = NULL;
 
@@ -4805,7 +4814,6 @@ void vik_trw_layer_delete_all_routes ( VikTrwLayer *vtl )
 {
 
   vtl->current_track = NULL;
-  vtl->route_finder_current_track = NULL;
   vtl->route_finder_added_track = NULL;
   if (vtl->current_tp_track)
     trw_layer_cancel_current_tp(vtl, FALSE);
@@ -4823,7 +4831,6 @@ void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl )
 {
 
   vtl->current_track = NULL;
-  vtl->route_finder_current_track = NULL;
   vtl->route_finder_added_track = NULL;
   if (vtl->current_tp_track)
     trw_layer_cancel_current_tp(vtl, FALSE);
@@ -5229,15 +5236,13 @@ static void trw_layer_extend_track_end_route_finder ( menu_array_sublayer values
   VikTrack *track = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
   if ( !track )
     return;
-  if ( !track->trackpoints )
-    return;
 
   vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER );
-  vtl->route_finder_coord = vik_track_get_tp_last(track)->coord;
-  vtl->route_finder_current_track = track;
+  vtl->current_track = track;
   vtl->route_finder_started = TRUE;
 
-  goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &vtl->route_finder_coord );
+  if ( track->trackpoints )
+      goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &vik_track_get_tp_last(track)->coord );
 }
 
 /**
@@ -9661,6 +9666,9 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
 
 static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
 {
+  // if we were running the route finder, cancel it
+  vtl->route_finder_started = FALSE;
+
   // ----------------------------------------------------- if current is a route - switch to new track
   if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && vtl->current_track->is_route ) ))
   {
@@ -9694,8 +9702,12 @@ static gpointer tool_new_route_create ( VikWindow *vw, VikViewport *vvp)
 
 static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
 {
-  // -------------------------- if current is a track - switch to new route
-  if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && !vtl->current_track->is_route ) ) )
+  // if we were running the route finder, cancel it
+  vtl->route_finder_started = FALSE;
+
+  // -------------------------- if current is a track - switch to new route,
+  if ( event->button == 1 && ( ! vtl->current_track ||
+                               (vtl->current_track && !vtl->current_track->is_route ) ) )
   {
     gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route"));
     if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), name, TRUE ) ) ) {
@@ -9898,77 +9910,121 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton
 }
 
 
-/*** Route Finder ***/
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
+/*** Extended Route Finder ***/
+
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp)
 {
   return vvp;
 }
 
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static void tool_extended_route_finder_undo ( VikTrwLayer *vtl )
+{
+  VikCoord *new_end;
+  new_end = vik_track_cut_back_to_double_point ( vtl->current_track );
+  if ( new_end ) {
+    g_free ( new_end );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
+
+    /* remove last ' to:...' */
+    if ( vtl->current_track->comment ) {
+      gchar *last_to = strrchr ( vtl->current_track->comment, 't' );
+      if ( last_to && (last_to - vtl->current_track->comment > 1) ) {
+        gchar *new_comment = g_strndup ( vtl->current_track->comment,
+                                         last_to - vtl->current_track->comment - 1);
+        vik_track_set_comment_no_copy ( vtl->current_track, new_comment );
+      }
+    }
+  }
+}
+
+
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
 {
   VikCoord tmp;
   if ( !vtl ) return FALSE;
   vik_viewport_screen_to_coord ( vvp, event->x, event->y, &tmp );
-  if ( event->button == 3 && vtl->route_finder_current_track ) {
-    VikCoord *new_end;
-    new_end = vik_track_cut_back_to_double_point ( vtl->route_finder_current_track );
-    if ( new_end ) {
-      vtl->route_finder_coord = *new_end;
-      g_free ( new_end );
-      vik_layer_emit_update ( VIK_LAYER(vtl) );
-      /* remove last ' to:...' */
-      if ( vtl->route_finder_current_track->comment ) {
-        gchar *last_to = strrchr ( vtl->route_finder_current_track->comment, 't' );
-        if ( last_to && (last_to - vtl->route_finder_current_track->comment > 1) ) {
-          gchar *new_comment = g_strndup ( vtl->route_finder_current_track->comment,
-                                           last_to - vtl->route_finder_current_track->comment - 1);
-          vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
-        }
-      }
-    }
+  if ( event->button == 3 && vtl->current_track ) {
+    tool_extended_route_finder_undo ( vtl );
+  }
+  else if ( event->button == 2 ) {
+     vtl->draw_sync_do = FALSE;
+     return FALSE;
   }
-  else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
+  // if we started the track but via undo deleted all the track points, begin again
+  else if ( vtl->current_track && vtl->current_track->is_route && ! vik_track_get_tp_first ( vtl->current_track ) ) {
+    return tool_new_track_or_route_click ( vtl, event, vvp );
+  }
+  else if ( ( vtl->current_track && vtl->current_track->is_route ) ||
+            ( event->state & GDK_CONTROL_MASK && vtl->current_track ) ) {
     struct LatLon start, end;
 
-    vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
+    VikTrackpoint *tp_start = vik_track_get_tp_last ( vtl->current_track );
+    vik_coord_to_latlon ( &(tp_start->coord), &start );
     vik_coord_to_latlon ( &(tmp), &end );
-    vtl->route_finder_coord = tmp; /* for continuations */
 
-    /* these are checked when adding a track from a file (vik_trw_layer_filein_add_track) */
-    if ( event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track ) {
-      vtl->route_finder_append = TRUE;  // merge tracks. keep started true.
-    } else {
-      vtl->route_finder_check_added_track = TRUE;
-      vtl->route_finder_started = FALSE;
+    vtl->route_finder_started = TRUE;
+    vtl->route_finder_append = TRUE;  // merge tracks. keep started true.
+
+    // update UI to let user know what's going on
+    VikStatusbar *sb = vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)));
+    VikRoutingEngine *engine = vik_routing_default_engine ( );
+    if ( ! engine ) {
+        vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, "Cannot plan route without a default routing engine." );
+        return TRUE;
     }
+    gchar *msg = g_strdup_printf ( _("Querying %s for route between (%.3f, %.3f) and (%.3f, %.3f)."),
+                                   vik_routing_engine_get_label ( engine ),
+                                   start.lat, start.lon, end.lat, end.lon );
+    vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+    g_free ( msg );
+    vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
 
-    vik_routing_default_find ( vtl, start, end);
 
-    /* see if anything was done -- a track was added or appended to */
-    if ( vtl->route_finder_check_added_track && vtl->route_finder_added_track ) {
-      vik_track_set_comment_no_copy ( vtl->route_finder_added_track, g_strdup_printf("from: %f,%f to: %f,%f", start.lat, start.lon, end.lat, end.lon ) );
-    } else if ( vtl->route_finder_append == FALSE && vtl->route_finder_current_track ) {
-      /* route_finder_append was originally TRUE but set to FALSE by filein_add_track */
-      gchar *new_comment = g_strdup_printf("%s to: %f,%f", vtl->route_finder_current_track->comment, end.lat, end.lon );
-      vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
-    }
+    /* Give GTK a change to display the new status bar before querying the web */
+    while ( gtk_events_pending ( ) )
+        gtk_main_iteration ( );
 
-    if ( vtl->route_finder_added_track )
-      vik_track_calculate_bounds ( vtl->route_finder_added_track );
+    gboolean find_status = vik_routing_default_find ( vtl, start, end );
 
-    vtl->route_finder_added_track = NULL;
-    vtl->route_finder_check_added_track = FALSE;
-    vtl->route_finder_append = FALSE;
+    /* Update UI to say we're done */
+    vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+    msg = ( find_status ) ? g_strdup_printf ( _("%s returned route between (%.3f, %.3f) and (%.3f, %.3f)."),
+                            vik_routing_engine_get_label ( engine ),
+                            start.lat, start.lon, end.lat, end.lon )
+                          : g_strdup_printf ( _("Error getting route from %s."),
+                                              vik_routing_engine_get_label ( engine ) );
+    vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+    g_free ( msg );
 
     vik_layer_emit_update ( VIK_LAYER(vtl) );
   } else {
+    vtl->current_track = NULL;
+
+    // create a new route where we will add the planned route to
+    gboolean ret = tool_new_route_click( vtl, event, vvp );
+
     vtl->route_finder_started = TRUE;
-    vtl->route_finder_coord = tmp;
-    vtl->route_finder_current_track = NULL;
+
+    return ret;
   }
   return TRUE;
 }
 
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp )
+{
+  if ( vtl->current_track && event->keyval == GDK_Escape ) {
+    vtl->route_finder_started = FALSE;
+    vtl->current_track = NULL;
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
+    return TRUE;
+  } else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
+    tool_extended_route_finder_undo ( vtl );
+  }
+  return FALSE;
+}
+
+
+
 /*** Show picture ****/
 
 static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp)