]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktrwlayer.c
help/Makefile.am: explicitly list figures.
[andy/viking.git] / src / viktrwlayer.c
index 3634fc67e710d5fea92b40e7c135ed47a57c4ec8..c8220d6c07739099518276247f2413f5da3bbb0b 100644 (file)
 #define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js"
 #endif
 
-#define VIK_TRW_LAYER_TRACK_GC 5
+#define VIK_TRW_LAYER_TRACK_GC 6
 #define VIK_TRW_LAYER_TRACK_GCS 10
 #define VIK_TRW_LAYER_TRACK_GC_BLACK 0
 #define VIK_TRW_LAYER_TRACK_GC_SLOW 1
 #define VIK_TRW_LAYER_TRACK_GC_AVER 2
 #define VIK_TRW_LAYER_TRACK_GC_FAST 3
 #define VIK_TRW_LAYER_TRACK_GC_STOP 4
+#define VIK_TRW_LAYER_TRACK_GC_SINGLE 5
 
 #define DRAWMODE_BY_TRACK 0
 #define DRAWMODE_BY_SPEED 1
-#define DRAWMODE_ALL_BLACK 2
+#define DRAWMODE_ALL_SAME_COLOR 2
 // Note using DRAWMODE_BY_SPEED may be slow especially for vast numbers of trackpoints
 //  as we are (re)calculating the colour for every point
 
@@ -148,6 +149,7 @@ struct _VikTrwLayer {
   gdouble track_draw_speed_factor;
   GArray *track_gc;
   GdkGC *track_1color_gc;
+  GdkColor track_color;
   GdkGC *current_track_gc;
   // Separate GC for a track's potential new point as drawn via separate method
   //  (compared to the actual track points drawn in the main trw_layer_draw_track function)
@@ -217,6 +219,7 @@ typedef struct {
 struct DrawingParams {
   VikViewport *vp;
   VikTrwLayer *vtl;
+  VikWindow *vw;
   gdouble xmpp, ympp;
   guint16 width, height;
   gdouble cc; // Cosine factor in track directions
@@ -232,15 +235,15 @@ static void trw_layer_delete_item ( gpointer pass_along[6] );
 static void trw_layer_copy_item_cb ( gpointer pass_along[6] );
 static void trw_layer_cut_item_cb ( gpointer pass_along[6] );
 
-static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] );
-static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] );
+static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] );
+static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] );
 static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2]);
 
 static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp );
 static void trw_layer_free_track_gcs ( VikTrwLayer *vtl );
 
-static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp );
-static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp );
+static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp );
+static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp );
 
 static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord );
 static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] );
@@ -293,6 +296,7 @@ static void trw_layer_acquire_google_cb ( gpointer lav[2] );
 #endif
 #ifdef VIK_CONFIG_OPENSTREETMAP
 static void trw_layer_acquire_osm_cb ( gpointer lav[2] );
+static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] );
 #endif
 #ifdef VIK_CONFIG_GEOCACHES
 static void trw_layer_acquire_geocache_cb ( gpointer lav[2] );
@@ -307,12 +311,14 @@ static void trw_layer_gps_upload ( gpointer lav[2] );
 //  Most track handling functions can handle operating on the route list
 //  However these ones are easier in separate functions
 static void trw_layer_auto_routes_view ( gpointer lav[2] );
+static void trw_layer_delete_all_routes ( gpointer lav[2] );
 static void trw_layer_delete_routes_from_selection ( gpointer lav[2] );
 
 /* pop-up items */
 static void trw_layer_properties_item ( gpointer pass_along[7] );
 static void trw_layer_goto_waypoint ( gpointer pass_along[6] );
 static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] );
+static void trw_layer_waypoint_webpage ( gpointer pass_along[6] );
 
 static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer pass_along[5] );
 static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pass_along[5] );
@@ -354,7 +360,7 @@ static VikTrackpoint *closest_tp_in_five_pixel_interval ( VikTrwLayer *vtl, VikV
 static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y );
 
 static void waypoint_convert ( const gpointer id, VikWaypoint *wp, VikCoordMode *dest_mode );
-static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode );
+static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode );
 
 static gchar *highest_wp_number_get(VikTrwLayer *vtl);
 static void highest_wp_number_reset(VikTrwLayer *vtl);
@@ -422,14 +428,26 @@ static VikToolInterface trw_layer_tools[] = {
     GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf },
 #endif
 };
-enum { TOOL_CREATE_WAYPOINT=0, TOOL_CREATE_TRACK, TOOL_CREATE_ROUTE, TOOL_EDIT_WAYPOINT, TOOL_EDIT_TRACKPOINT, TOOL_SHOW_PICTURE, NUM_TOOLS };
+
+enum {
+  TOOL_CREATE_WAYPOINT=0,
+  TOOL_CREATE_TRACK,
+  TOOL_CREATE_ROUTE,
+  TOOL_EDIT_WAYPOINT,
+  TOOL_EDIT_TRACKPOINT,
+  TOOL_SHOW_PICTURE,
+#ifdef VIK_CONFIG_GOOGLE
+  TOOL_ROUTE_FINDER,
+#endif
+  NUM_TOOLS
+};
 
 /****** PARAMETERS ******/
 
 static gchar *params_groups[] = { N_("Waypoints"), N_("Tracks"), N_("Waypoint Images") };
 enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES };
 
-static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Black"), 0 };
+static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Same Color"), NULL };
 static gchar *params_wpsymbols[] = { N_("Filled Square"), N_("Square"), N_("Circle"), N_("X"), 0 };
 
 #define MIN_POINT_SIZE 2
@@ -466,41 +484,45 @@ static gchar* params_font_sizes[] = {
   NULL };
 
 VikLayerParam trw_layer_params[] = {
-  { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
-  { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
-  { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
-
-  { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL },
-  { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 0 },
-  { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 11 },
-  { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 10 },
-  { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 9 },
-
-  { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 8 },
-
-  { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 6 },
-  { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, 0 },
-  { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 1 },
-
-  { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL },
-  { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, 0 },
-  { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, 0 },
-  { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, 0 },
-  { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, 0 },
-  { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL },
-  { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 7 },
-  { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON },
-
-  { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON },
-  { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 3 },
-  { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 4 },
-  { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 5 },
+  { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+  { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+  { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+
+  { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL },
+  { "trackcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("All Tracks Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL,
+    N_("The color used when 'All Tracks Same Color' drawing mode is selected") },
+  { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[0], NULL, NULL },
+  { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[11], NULL, NULL },
+  { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[10], NULL, NULL },
+  { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[9], NULL, NULL },
+
+  { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL,
+    N_("Whether to draw a marker when trackpoints are at the same position but over the minimum stop length apart in time") },
+  { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[8], NULL, NULL },
+
+  { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[6], NULL, NULL},
+  { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+  { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, &params_scales[1], NULL,
+    N_("The percentage factor away from the average speed determining the color used") },
+
+  { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL },
+  { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+  { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+  { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+  { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL },
+  { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[7], NULL, NULL },
+  { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+
+  { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+  { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, &params_scales[3], NULL, NULL },
+  { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[4], NULL, NULL },
+  { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[5], NULL, NULL },
 };
 
 // ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE
@@ -511,6 +533,7 @@ enum {
   PARAM_RV,
   // Tracks
   PARAM_DM,
+  PARAM_TC,
   PARAM_DL,
   PARAM_LT,
   PARAM_DD,
@@ -642,12 +665,6 @@ VikLayerInterface vik_trw_layer_interface = {
   (VikLayerFuncSelectedViewportMenu)    trw_layer_show_selected_viewport_menu,
 };
 
-// for copy & paste
-typedef struct {
-  guint len;
-  guint8 data[0];
-} FlatItem;
-
 GType vik_trw_layer_get_type ()
 {
   static GType vtl_type = 0;
@@ -761,7 +778,6 @@ static void trw_layer_paste_item_cb ( gpointer pass_along[6])
 
 static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len )
 {
-  FlatItem *fi;
   guint8 *id;
   guint il;
 
@@ -770,44 +786,36 @@ static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer subla
     return;
   }
 
-  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
-  {
+  GByteArray *ba = g_byte_array_new ();
+
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
     vik_waypoint_marshall ( g_hash_table_lookup ( vtl->waypoints, sublayer ), &id, &il );
-    // 'Simple' memory copy of byte array from the marshalling above
-    *len = sizeof(FlatItem) + 1 + il; // not sure what the 1 is for yet...
-    fi = g_malloc ( *len );
-    fi->len = *len;
-    memcpy(fi->data, id, il);
   } else if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
     vik_track_marshall ( g_hash_table_lookup ( vtl->tracks, sublayer ), &id, &il );
-    // less magic than before...
-    *len = sizeof(FlatItem) + 1 + il;
-    fi = g_malloc ( *len );
-    fi->len = *len;
-    memcpy(fi->data, id, il);
   } else {
     vik_track_marshall ( g_hash_table_lookup ( vtl->routes, sublayer ), &id, &il );
-    // less magic than before...
-    *len = sizeof(FlatItem) + 1 + il;
-    fi = g_malloc ( *len );
-    fi->len = *len;
-    memcpy(fi->data, id, il);
   }
 
+  g_byte_array_append ( ba, id, il );
+
   g_free(id);
-  *item = (guint8 *)fi;
+
+  *len = ba->len;
+  *item = ba->data;
 }
 
 static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *item, guint len )
 {
-  FlatItem *fi = (FlatItem *) item;
+  if ( !item )
+    return FALSE;
+
+  gchar *name;
 
-  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && fi )
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
   {
     VikWaypoint *w;
-    gchar *name;
 
-    w = vik_waypoint_unmarshall(fi->data, fi->len);
+    w = vik_waypoint_unmarshall ( item, len );
     // When copying - we'll create a new name based on the original
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name);
     vik_trw_layer_add_waypoint ( vtl, name, w );
@@ -815,15 +823,14 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->waypoints_visible && w->visible )
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
-  if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && fi )
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
     VikTrack *t;
-    gchar *name;
 
-    t = vik_track_unmarshall(fi->data, fi->len);
+    t = vik_track_unmarshall ( item, len );
     // When copying - we'll create a new name based on the original
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name);
     vik_trw_layer_add_track ( vtl, name, t );
@@ -831,15 +838,14 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->tracks_visible && t->visible )
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
-  if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && fi )
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE )
   {
     VikTrack *t;
-    gchar *name;
 
-    t = vik_track_unmarshall(fi->data, fi->len);
+    t = vik_track_unmarshall ( item, len );
     // When copying - we'll create a new name based on the original
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name);
     vik_trw_layer_add_route ( vtl, name, t );
@@ -847,7 +853,7 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->routes_visible && t->visible )
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
   return FALSE;
@@ -868,6 +874,10 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara
     case PARAM_WV: vtl->waypoints_visible = data.b; break;
     case PARAM_RV: vtl->routes_visible = data.b; break;
     case PARAM_DM: vtl->drawmode = data.u; break;
+    case PARAM_TC:
+      vtl->track_color = data.c;
+      trw_layer_new_track_gcs ( vtl, vp );
+      break;
     case PARAM_DP: vtl->drawpoints = data.b; break;
     case PARAM_DPS:
       if ( data.u >= MIN_POINT_SIZE && data.u <= MAX_POINT_SIZE )
@@ -893,7 +903,7 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara
                      trw_layer_new_track_gcs ( vtl, vp );
                    }
                    break;
-    case PARAM_BLT: if ( data.u >= 0 && data.u <= 8 && data.u != vtl->bg_line_thickness )
+    case PARAM_BLT: if ( data.u <= 8 && data.u != vtl->bg_line_thickness )
                    {
                      vtl->bg_line_thickness = data.u;
                      trw_layer_new_track_gcs ( vtl, vp );
@@ -937,6 +947,7 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo
     case PARAM_WV: rv.b = vtl->waypoints_visible; break;
     case PARAM_RV: rv.b = vtl->routes_visible; break;
     case PARAM_DM: rv.u = vtl->drawmode; break;
+    case PARAM_TC: rv.c = vtl->track_color; break;
     case PARAM_DP: rv.b = vtl->drawpoints; break;
     case PARAM_DPS: rv.u = vtl->drawpoints_size; break;
     case PARAM_DE: rv.b = vtl->drawelevation; break;
@@ -970,58 +981,126 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo
 static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len )
 {
   guint8 *pd;
-  gchar *dd;
-  gsize dl;
   gint pl;
-  gchar *tmpname;
-  FILE *f;
 
   *data = NULL;
 
-  if ((f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
-    a_gpx_write_file(vtl, f, NULL);
-    vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
-    fclose(f);
-    f = NULL;
-    g_file_get_contents(tmpname, &dd, &dl, NULL);
-    *len = sizeof(pl) + pl + dl;
-    *data = g_malloc(*len);
-    memcpy(*data, &pl, sizeof(pl));
-    memcpy(*data + sizeof(pl), pd, pl);
-    memcpy(*data + sizeof(pl) + pl, dd, dl);
-    
-    g_free(pd);
-    g_free(dd);
-    g_remove(tmpname);
-    g_free(tmpname);
+  // Use byte arrays to store sublayer data
+  // much like done elsewhere e.g. vik_layer_marshall_params()
+  GByteArray *ba = g_byte_array_new ( );
+
+  guint8 *sl_data;
+  guint sl_len;
+
+  guint object_length;
+  guint subtype;
+  // store:
+  // the length of the item
+  // the sublayer type of item
+  // the the actual item
+#define tlm_append(object_pointer, size, type) \
+  subtype = (type); \
+  object_length = (size); \
+  g_byte_array_append ( ba, (guint8 *)&object_length, sizeof(object_length) ); \
+  g_byte_array_append ( ba, (guint8 *)&subtype, sizeof(subtype) ); \
+  g_byte_array_append ( ba, (object_pointer), object_length );
+
+  // Layer parameters first
+  vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
+  g_byte_array_append ( ba, (guint8 *)&pl, sizeof(pl) ); \
+  g_byte_array_append ( ba, pd, pl );
+  g_free ( pd );
+
+  // Now sublayer data
+  GHashTableIter iter;
+  gpointer key, value;
+
+  // Waypoints
+  g_hash_table_iter_init ( &iter, vtl->waypoints );
+  while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+    vik_waypoint_marshall ( VIK_WAYPOINT(value), &sl_data, &sl_len );
+    tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_WAYPOINT );
+    g_free ( sl_data );
+  }
+
+  // Tracks
+  g_hash_table_iter_init ( &iter, vtl->tracks );
+  while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+    vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len );
+    tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_TRACK );
+    g_free ( sl_data );
+  }
+
+  // Routes
+  g_hash_table_iter_init ( &iter, vtl->routes );
+  while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+    vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len );
+    tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_ROUTE );
+    g_free ( sl_data );
   }
+
+#undef tlm_append
+
+  *data = ba->data;
+  *len = ba->len;
 }
 
 static VikTrwLayer *trw_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
 {
-  VikTrwLayer *rv = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
+  VikTrwLayer *vtl = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
   gint pl;
-  gchar *tmpname;
-  FILE *f;
-
+  gint consumed_length;
 
+  // First the overall layer parameters
   memcpy(&pl, data, sizeof(pl));
   data += sizeof(pl);
-  vik_layer_unmarshall_params ( VIK_LAYER(rv), data, pl, vvp );
+  vik_layer_unmarshall_params ( VIK_LAYER(vtl), data, pl, vvp );
   data += pl;
 
-  if (!(f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
-    g_critical("couldn't open temp file");
-    exit(1);
-  }
-  fwrite(data, len - pl - sizeof(pl), 1, f);
-  rewind(f);
-  a_gpx_read_file(rv, f);
-  fclose(f);
-  f = NULL;
-  g_remove(tmpname);
-  g_free(tmpname);
-  return rv;
+  consumed_length = pl;
+  const gint sizeof_len_and_subtype = sizeof(gint) + sizeof(gint);
+
+#define tlm_size (*(gint *)data)
+  // See marshalling above for order of how this is written
+#define tlm_next \
+  data += sizeof_len_and_subtype + tlm_size;
+
+  // Now the individual sublayers:
+
+  while ( *data && consumed_length < len ) {
+    // Normally four extra bytes at the end of the datastream
+    //  (since it's a GByteArray and that's where it's length is stored)
+    //  So only attempt read when there's an actual block of sublayer data
+    if ( consumed_length + tlm_size < len ) {
+
+      // Reuse pl to read the subtype from the data stream
+      memcpy(&pl, data+sizeof(gint), sizeof(pl));
+
+      if ( pl == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+        VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 );
+        gchar *name = g_strdup ( trk->name );
+        vik_trw_layer_add_track ( vtl, name, trk );
+        g_free ( name );
+      }
+      if ( pl == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+        VikWaypoint *wp = vik_waypoint_unmarshall ( data + sizeof_len_and_subtype, 0 );
+        gchar *name = g_strdup ( wp->name );
+        vik_trw_layer_add_waypoint ( vtl, name, wp );
+        g_free ( name );
+      }
+      if ( pl == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+        VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 );
+        gchar *name = g_strdup ( trk->name );
+        vik_trw_layer_add_route ( vtl, name, trk );
+        g_free ( name );
+      }
+    }
+    consumed_length += tlm_size + sizeof_len_and_subtype;
+    tlm_next;
+  }
+  //g_debug ("consumed_length %d vs len %d", consumed_length, len);
+
+  return vtl;
 }
 
 // Keep interesting hash function at least visible
@@ -1051,11 +1130,6 @@ static guint strcase_hash(gconstpointer v)
 
 static VikTrwLayer* trw_layer_new ( gint drawmode )
 {
-  if (trw_layer_params[PARAM_DM].widget_data == NULL)
-    trw_layer_params[PARAM_DM].widget_data = str_array_to_glist(params_drawmodes);
-  if (trw_layer_params[PARAM_WPSYM].widget_data == NULL)
-    trw_layer_params[PARAM_WPSYM].widget_data = str_array_to_glist(params_wpsymbols);
-
   VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
   vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW );
 
@@ -1142,12 +1216,13 @@ static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, Vi
 {
   dp->vtl = vtl;
   dp->vp = vp;
+  dp->vw = (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl);
   dp->xmpp = vik_viewport_get_xmpp ( vp );
   dp->ympp = vik_viewport_get_ympp ( vp );
   dp->width = vik_viewport_get_width ( vp );
   dp->height = vik_viewport_get_height ( vp );
-  dp->cc = vtl->drawdirections_size*cos(45 * DEG2RAD); // Calculate once per vtl update - even if not used
-  dp->ss = vtl->drawdirections_size*sin(45 * DEG2RAD); // Calculate once per vtl update - even if not used
+  dp->cc = vtl->drawdirections_size*cos(DEG2RAD(45)); // Calculate once per vtl update - even if not used
+  dp->ss = vtl->drawdirections_size*sin(DEG2RAD(45)); // Calculate once per vtl update - even if not used
 
   dp->center = vik_viewport_get_center ( vp );
   dp->one_zone = vik_viewport_is_one_zone ( vp ); /* false if some other projection besides UTM */
@@ -1209,7 +1284,7 @@ static void draw_utm_skip_insignia ( VikViewport *vvp, GdkGC *gc, gint x, gint y
   vik_viewport_draw_line ( vvp, gc, x+5, y-5, x-5, y+5 );
 }
 
-static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline )
+static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline )
 {
   /* TODO: this function is a mess, get rid of any redundancy */
   GList *list = track->trackpoints;
@@ -1237,7 +1312,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
 
   /* admittedly this is not an efficient way to do it because we go through the whole GC thing all over... */
   if ( dp->vtl->bg_line_thickness && !draw_track_outline )
-    trw_layer_draw_track ( name, track, dp, TRUE );
+    trw_layer_draw_track ( id, track, dp, TRUE );
 
   if ( draw_track_outline )
     drawpoints = drawstops = FALSE;
@@ -1256,10 +1331,10 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
       /* if track is member of selected layer or is the current selected track
         then draw in the highlight colour.
         NB this supercedes the drawmode */
-      if ( dp->vtl && ( ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
-                       ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) ||
-                       ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) ||
-                       track == vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) {
+      if ( ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ) ||
+           ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
+           ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
+           ( track == vik_window_get_selected_track ( dp->vw ) ) ) {
        main_gc = vik_viewport_get_gc_highlight (dp->vp);
        drawing_highlight = TRUE;
       }
@@ -1274,9 +1349,9 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
         main_gc = dp->vtl->track_1color_gc;
        break;
       default:
-        // Mostly for DRAWMODE_ALL_BLACK
+        // Mostly for DRAWMODE_ALL_SAME_COLOR
         // but includes DRAWMODE_BY_SPEED, main_gc is set later on as necessary
-        main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_BLACK);
+        main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_SINGLE);
         break;
       }
     }
@@ -1474,9 +1549,9 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
 }
 
 /* the only reason this exists is so that trw_layer_draw_track can first call itself to draw the white track background */
-static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp )
+static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp )
 {
-  trw_layer_draw_track ( name, track, dp, FALSE );
+  trw_layer_draw_track ( id, track, dp, FALSE );
 }
 
 static void cached_pixbuf_free ( CachedPixbuf *cp )
@@ -1490,7 +1565,7 @@ static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name )
   return strcmp ( cp->image, name );
 }
 
-static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp )
+static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp )
 {
   if ( wp->visible )
   if ( (!dp->one_zone && !dp->lat_lon) || ( ( dp->lat_lon || wp->coord.utm_zone == dp->center->utm_zone ) && 
@@ -1562,9 +1637,9 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct
         if ( x+(w/2) > 0 && y+(h/2) > 0 && x-(w/2) < dp->width && y-(h/2) < dp->height ) /* always draw within boundaries */
         {
          if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
-           if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
-                dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
-                wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) {
+            if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
+                 dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
+                 wp == vik_window_get_selected_waypoint ( dp->vw ) ) {
              // Highlighted - so draw a little border around the chosen one
              // single line seems a little weak so draw 2 of them
              vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
@@ -1644,9 +1719,9 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct
 
       /* if highlight mode on, then draw background text in highlight colour */
       if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
-       if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
-            dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
-            wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) )
+       if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
+             dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
+             wp == vik_window_get_selected_waypoint ( dp->vw ) )
          vik_viewport_draw_rectangle ( dp->vp, vik_viewport_get_gc_highlight (dp->vp), TRUE, label_x - 1, label_y-1,width+2,height+2);
        else
          vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2);
@@ -1744,6 +1819,8 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp )
   gc[VIK_TRW_LAYER_TRACK_GC_AVER] = vik_viewport_new_gc ( vp, "#D2CD26", width ); // yellow-ish
   gc[VIK_TRW_LAYER_TRACK_GC_FAST] = vik_viewport_new_gc ( vp, "#2B8700", width ); // green-ish
 
+  gc[VIK_TRW_LAYER_TRACK_GC_SINGLE] = vik_viewport_new_gc_from_color ( vp, &(vtl->track_color), width );
+
   g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC );
 }
 
@@ -1760,6 +1837,8 @@ static VikTrwLayer* trw_layer_create ( VikViewport *vp )
   rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
   pango_layout_set_font_description (rv->wplabellayout, GTK_WIDGET(vp)->style->font_desc);
 
+  gdk_color_parse ( "#000000", &(rv->track_color) ); // Black
+
   trw_layer_new_track_gcs ( rv, vp );
 
   rv->waypoint_gc = vik_viewport_new_gc ( vp, "#000000", 2 );
@@ -2418,7 +2497,7 @@ VikTrack *vik_trw_layer_get_route ( VikTrwLayer *vtl, const gchar *name )
   return g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find, (gpointer) name );
 }
 
-static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] )
+static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] )
 {
   static VikCoord fixme;
   vik_coord_copy_convert ( &(w->coord), VIK_COORD_LATLON, &fixme );
@@ -2432,7 +2511,7 @@ static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoi
     maxmin[1].lon = VIK_LATLON(&fixme)->lon;
 }
 
-static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] )
+static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] )
 {
   GList *tr = trk->trackpoints;
   static VikCoord fixme;
@@ -2798,35 +2877,16 @@ gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikC
 
 static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] )
 {
-  VikCoord one, two;
-  struct LatLon one_ll, two_ll;
   struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
-
   VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
   VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
-  vik_viewport_screen_to_coord ( vvp, 0, 0, &one);
-  vik_viewport_screen_to_coord ( vvp, vik_viewport_get_width(vvp), vik_viewport_get_height(vvp), &two);
-  vik_coord_to_latlon(&one, &one_ll);
-  vik_coord_to_latlon(&two, &two_ll);
-  if (one_ll.lat > two_ll.lat) {
-    maxmin[0].lat = one_ll.lat;
-    maxmin[1].lat = two_ll.lat;
-  }
-  else {
-    maxmin[0].lat = two_ll.lat;
-    maxmin[1].lat = one_ll.lat;
-  }
-  if (one_ll.lon > two_ll.lon) {
-    maxmin[0].lon = one_ll.lon;
-    maxmin[1].lon = two_ll.lon;
-  }
-  else {
-    maxmin[0].lon = two_ll.lon;
-    maxmin[1].lon = one_ll.lon;
-  }
-  a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin);
+
+  // Note the order is max part first then min part - thus reverse order of use in min_max function:
+  vik_viewport_get_min_max_lat_lon ( vvp, &maxmin[1].lat, &maxmin[0].lat, &maxmin[1].lon, &maxmin[0].lon );
+  a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+  vik_layers_panel_emit_update ( vlp );
 }
 
 static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] )
@@ -2836,7 +2896,8 @@ static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] )
   struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
   
   trw_layer_find_maxmin (vtl, maxmin);
-  a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin);
+  a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+  vik_layers_panel_emit_update ( vlp );
 }
 
 #ifdef VIK_CONFIG_GEOTAG
@@ -2929,6 +2990,19 @@ static void trw_layer_acquire_osm_cb ( gpointer lav[2] )
 
   a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface );
 }
+
+/**
+ * Acquire into this TRW Layer from OSM for 'My' Traces
+ */
+static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+  VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
+  VikViewport *vvp =  vik_window_viewport(vw);
+
+  a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface );
+}
 #endif
 
 #ifdef VIK_CONFIG_GEOCACHES
@@ -3097,15 +3171,26 @@ static void trw_layer_new_wp ( gpointer lav[2] )
     vik_layers_panel_emit_update ( vlp );
 }
 
+static void new_track_create_common ( VikTrwLayer *vtl, gchar *name )
+{
+  vtl->current_track = vik_track_new();
+  vtl->current_track->visible = TRUE;
+  if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR )
+    // Create track with the preferred colour from the layer properties
+    vtl->current_track->color = vtl->track_color;
+  else
+    gdk_color_parse ( "#000000", &(vtl->current_track->color) );
+  vtl->current_track->has_color = TRUE;
+  vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+}
+
 static void trw_layer_new_track ( gpointer lav[2] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
 
   if ( ! vtl->current_track ) {
     gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")) ;
-    vtl->current_track = vik_track_new();
-    vtl->current_track->visible = TRUE;
-    vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+    new_track_create_common ( vtl, name );
 
     vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
   }
@@ -3151,7 +3236,7 @@ static void trw_layer_finish_track ( gpointer lav[2] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
   vtl->current_track = NULL;
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 static void trw_layer_auto_tracks_view ( gpointer lav[2] )
@@ -3167,7 +3252,7 @@ static void trw_layer_auto_tracks_view ( gpointer lav[2] )
   }
 }
 
-static void trw_layer_single_waypoint_jump ( const gchar *name, const VikWaypoint *wp, gpointer vvp )
+static void trw_layer_single_waypoint_jump ( const gpointer id, const VikWaypoint *wp, gpointer vvp )
 {
   /* NB do not care if wp is visible or not */
   vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), &(wp->coord) );
@@ -3331,27 +3416,6 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   // Make it available only when a new track *not* already in progress
   gtk_widget_set_sensitive ( item, ! (gboolean)GPOINTER_TO_INT(vtl->current_track) );
 
-#ifdef VIK_CONFIG_GEONAMES
-  GtkWidget *wikipedia_submenu = gtk_menu_new();
-  item = gtk_image_menu_item_new_with_mnemonic ( _("_Add Wikipedia Waypoints") );
-  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) );
-  gtk_menu_shell_append(GTK_MENU_SHELL (menu), item);
-  gtk_widget_show(item);
-  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu);
-
-  item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") );
-  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
-  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along );
-  gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
-  gtk_widget_show ( item );
-
-  item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") );
-  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) );
-  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along );
-  gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
-  gtk_widget_show ( item );
-#endif
-
 #ifdef VIK_CONFIG_GEOTAG
   item = gtk_menu_item_new_with_mnemonic ( _("Geotag _Images...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_geotagging), pass_along );
@@ -3360,7 +3424,7 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
 #endif
 
   GtkWidget *acquire_submenu = gtk_menu_new ();
-  item = gtk_image_menu_item_new_with_mnemonic ( _("Ac_quire") );
+  item = gtk_image_menu_item_new_with_mnemonic ( _("_Acquire") );
   gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU) );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
@@ -3372,7 +3436,7 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   gtk_widget_show ( item );
 
 #ifdef VIK_CONFIG_GOOGLE
-  item = gtk_menu_item_new_with_mnemonic ( _("From G_oogle Directions...") );
+  item = gtk_menu_item_new_with_mnemonic ( _("From Google _Directions...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_google_cb), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
@@ -3383,6 +3447,32 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_cb), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
+
+  item = gtk_menu_item_new_with_mnemonic ( _("From _My OSM Traces...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_my_traces_cb), pass_along );
+  gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
+  gtk_widget_show ( item );
+#endif
+
+#ifdef VIK_CONFIG_GEONAMES
+  GtkWidget *wikipedia_submenu = gtk_menu_new();
+  item = gtk_image_menu_item_new_with_mnemonic ( _("From _Wikipedia Waypoints") );
+  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) );
+  gtk_menu_shell_append(GTK_MENU_SHELL (acquire_submenu), item);
+  gtk_widget_show(item);
+  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu);
+
+  item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") );
+  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along );
+  gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
+  gtk_widget_show ( item );
+
+  item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") );
+  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along );
+  gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
+  gtk_widget_show ( item );
 #endif
 
 #ifdef VIK_CONFIG_GEOCACHES
@@ -3443,6 +3533,18 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_tracks_from_selection), pass_along );
   gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
   gtk_widget_show ( item );
+
+  item = gtk_image_menu_item_new_with_mnemonic ( _("Delete _All Routes") );
+  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_routes), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
+
+  item = gtk_image_menu_item_new_with_mnemonic ( _("_Delete Routes From Selection...") );
+  gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_routes_from_selection), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
   
   item = gtk_image_menu_item_new_with_mnemonic ( _("Delete All _Waypoints") );
   gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) );
@@ -3656,7 +3758,7 @@ static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, g
 
     gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
 
-    VikTrack *trk2 = vik_track_copy ( trk );
+    VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_track ( vtl_dest, newname, trk2 );
     vik_trw_layer_delete_track ( vtl_src, trk );
   }
@@ -3666,7 +3768,7 @@ static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, g
 
     gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
 
-    VikTrack *trk2 = vik_track_copy ( trk );
+    VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_route ( vtl_dest, newname, trk2 );
     vik_trw_layer_delete_route ( vtl_src, trk );
   }
@@ -3960,7 +4062,7 @@ static gboolean trw_layer_delete_track_by_name ( VikTrwLayer *vtl, const gchar *
     return FALSE;
 }
 
-static void remove_item_from_treeview(const gchar *name, GtkTreeIter *it, VikTreeview * vt)
+static void remove_item_from_treeview ( const gpointer id, GtkTreeIter *it, VikTreeview * vt )
 {
     vik_treeview_item_delete (vt, it );
 }
@@ -3980,7 +4082,7 @@ void vik_trw_layer_delete_all_routes ( VikTrwLayer *vtl )
 
   vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter) );
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl )
@@ -3998,7 +4100,7 @@ void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl )
 
   vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter) );
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
@@ -4015,7 +4117,7 @@ void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
 
   vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter) );
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 static void trw_layer_delete_all_tracks ( gpointer lav[2] )
@@ -4093,7 +4195,7 @@ static void trw_layer_delete_item ( gpointer pass_along[6] )
     }
   }
   if ( was_visible )
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 
@@ -4109,11 +4211,11 @@ static void trw_layer_properties_item ( gpointer pass_along[7] )
       gboolean updated = FALSE;
       a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, wp, vtl->coord_mode, FALSE, &updated );
 
-      if ( updated && pass_along[6] )
+      if ( updated && wp->symbol && pass_along[6] )
         vik_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, pass_along[6], get_wp_sym_small (wp->symbol) );
 
       if ( updated && VIK_LAYER(vtl)->visible )
-       vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+       vik_layer_emit_update ( VIK_LAYER(vtl) );
     }
   }
   else
@@ -4188,7 +4290,7 @@ static void goto_coord ( gpointer *vlp, gpointer vl, gpointer vvp, const VikCoor
     /* since vlp not set, vl & vvp should be valid instead! */
     if ( vl && vvp ) {
       vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), coord );
-      vik_layer_emit_update ( VIK_LAYER(vl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vl) );
     }
   }
 }
@@ -4251,7 +4353,7 @@ static void trw_layer_convert_track_route ( gpointer pass_along[6] )
 }
 
   // Copy it
-  VikTrack *trk_copy = vik_track_copy ( trk );
+  VikTrack *trk_copy = vik_track_copy ( trk, TRUE );
 
   // Convert
   trk_copy->is_route = !trk_copy->is_route;
@@ -4275,7 +4377,7 @@ static void trw_layer_convert_track_route ( gpointer pass_along[6] )
   g_free ( name );
 
   // Update in case color of track / route changes when moving between sublayers
-  vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
 }
 
 
@@ -4305,10 +4407,12 @@ static void trw_layer_extend_track_end ( gpointer pass_along[6] )
 static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
-  VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+  VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
+  if ( !track )
+    return;
   VikCoord last_coord = (((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord);
 
-  vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, NUM_TOOLS );
+  vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER );
   vtl->route_finder_coord =  last_coord;
   vtl->route_finder_current_track = track;
   vtl->route_finder_started = TRUE;
@@ -4427,7 +4531,7 @@ static void trw_layer_auto_track_view ( gpointer pass_along[6] )
     if ( pass_along[1] )
       vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) );
     else
-      vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
   }
 }
 
@@ -4654,7 +4758,7 @@ static void trw_layer_merge_with_other ( gpointer pass_along[6] )
     for (l = merge_list; l != NULL; l = g_list_next(l))
       g_free(l->data);
     g_list_free(merge_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
 
@@ -4741,7 +4845,7 @@ static void trw_layer_append_track ( gpointer pass_along[6] )
     for (l = append_list; l != NULL; l = g_list_next(l))
       g_free(l->data);
     g_list_free(append_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
 
@@ -4837,7 +4941,7 @@ static void trw_layer_append_other ( gpointer pass_along[6] )
     for (l = append_list; l != NULL; l = g_list_next(l))
       g_free(l->data);
     g_list_free(append_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
 
@@ -4951,7 +5055,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
   }
 
   g_list_free(nearby_tracks);
-  vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update( VIK_LAYER(vtl) );
 }
 
 /**
@@ -4965,15 +5069,12 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
   if ( vtl->current_tpl->next && vtl->current_tpl->prev ) {
     gchar *name = trw_layer_new_unique_sublayer_name(vtl, subtype, vtl->current_tp_track->name);
     if ( name ) {
-      VikTrack *tr = vik_track_new ();
+      VikTrack *tr = vik_track_copy ( vtl->current_tp_track, FALSE );
       GList *newglist = g_list_alloc ();
       newglist->prev = NULL;
       newglist->next = vtl->current_tpl->next;
       newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data));
       tr->trackpoints = newglist;
-      tr->is_route = vtl->current_tp_track->is_route;
-      tr->color = vtl->current_tp_track->color;
-      tr->visible = TRUE;
 
       vtl->current_tpl->next->prev = newglist; /* end old track here */
       vtl->current_tpl->next = NULL;
@@ -5002,7 +5103,7 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
       else
         vtl->current_tp_id = NULL;
 
-      vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+      vik_layer_emit_update(VIK_LAYER(vtl));
     }
   }
 }
@@ -5063,8 +5164,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
       gchar *new_tr_name;
       VikTrack *tr;
 
-      tr = vik_track_new();
-      tr->visible = track->visible;
+      tr = vik_track_copy ( track, FALSE );
       tr->trackpoints = (GList *)(iter->data);
 
       new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name);
@@ -5076,7 +5176,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
     }
     // Remove original track and then update the display
     vik_trw_layer_delete_track (vtl, track);
-    vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE);
+    vik_layer_emit_update(VIK_LAYER(pass_along[0]));
   }
   g_list_free(newlists);
 }
@@ -5146,10 +5246,7 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
       gchar *new_tr_name;
       VikTrack *tr;
 
-      tr = vik_track_new();
-      tr->visible = track->visible;
-      tr->is_route = track->is_route;
-      tr->color = track->color;
+      tr = vik_track_copy ( track, FALSE );
       tr->trackpoints = (GList *)(iter->data);
 
       if ( track->is_route ) {
@@ -5167,7 +5264,7 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
       vik_trw_layer_delete_route (vtl, track);
     else
       vik_trw_layer_delete_track (vtl, track);
-    vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE);
+    vik_layer_emit_update(VIK_LAYER(pass_along[0]));
   }
   g_list_free(newlists);
 }
@@ -5209,7 +5306,7 @@ static void trw_layer_split_segments ( gpointer pass_along[6] )
     g_free ( tracks );
     // Remove original track
     vik_trw_layer_delete_track ( vtl, trk );
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
   }
   else {
     a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Can not split track as it has no segments"));
@@ -5244,7 +5341,7 @@ static void trw_layer_delete_points_same_position ( gpointer pass_along[6] )
   g_snprintf(str, 64, tmp_str, removed);
   a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 /**
@@ -5274,7 +5371,7 @@ static void trw_layer_delete_points_same_time ( gpointer pass_along[6] )
   g_snprintf(str, 64, tmp_str, removed);
   a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
 /**
@@ -5299,7 +5396,7 @@ static void trw_layer_reverse ( gpointer pass_along[6] )
 
   vik_track_reverse ( track );
  
-  vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
 }
 
 /**
@@ -5520,7 +5617,7 @@ static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] )
       trw_layer_delete_track_by_name (vtl, l->data, vtl->tracks);
     }
     g_list_free(delete_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
 
@@ -5567,7 +5664,7 @@ static void trw_layer_delete_routes_from_selection ( gpointer lav[2] )
       trw_layer_delete_track_by_name (vtl, l->data, vtl->routes);
     }
     g_list_free(delete_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
 
@@ -5747,7 +5844,7 @@ static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] )
       trw_layer_delete_waypoint_by_name (vtl, l->data);
     }
     g_list_free(delete_list);
-    vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 
 }
@@ -5761,11 +5858,26 @@ static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
 
 static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] )
 {
-  gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", (gchar *) pass_along[3] );
+  VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+  if ( !wp )
+    return;
+  gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", wp->name );
   open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
   g_free ( webpage );
 }
 
+static void trw_layer_waypoint_webpage ( gpointer pass_along[6] )
+{
+  VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+  if ( !wp )
+    return;
+  if ( !strncmp(wp->comment, "http", 4) ) {
+    open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->comment);
+  } else if ( !strncmp(wp->description, "http", 4) ) {
+    open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->description);
+  }
+}
+
 static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter )
 {
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
@@ -5889,13 +6001,13 @@ static void trw_layer_track_use_with_filter ( gpointer pass_along[6] )
 #ifdef VIK_CONFIG_GOOGLE
 static gboolean is_valid_google_route ( VikTrwLayer *vtl, const gpointer track_id )
 {
-  VikTrack *tr = g_hash_table_lookup ( vtl->tracks, track_id );
+  VikTrack *tr = g_hash_table_lookup ( vtl->routes, track_id );
   return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) );
 }
 
-static void trw_layer_track_google_route_webpage ( gpointer pass_along[6] )
+static void trw_layer_google_route_webpage ( gpointer pass_along[6] )
 {
-  VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+  VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
   if ( tr ) {
     gchar *escaped = uri_escape ( tr->comment );
     gchar *webpage = g_strdup_printf("http://maps.google.com/maps?f=q&hl=en&q=%s", escaped );
@@ -6034,6 +6146,18 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
 #endif
       }
 
+      if ( wp )
+      {
+        if ( ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
+             ( wp->description && !strncmp(wp->description, "http", 4) )) {
+          item = gtk_image_menu_item_new_with_mnemonic ( _("Visit _Webpage") );
+          gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
+          g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_webpage), pass_along );
+          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+          gtk_widget_show ( item );
+        }
+      }
+
     }
   }
 
@@ -6404,11 +6528,13 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     gtk_widget_show ( item );
 
 #ifdef VIK_CONFIG_GOOGLE
-    item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
-    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
-    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along );
-    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
-    gtk_widget_show ( item );
+    if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+      item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
+      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+      g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along );
+      gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+      gtk_widget_show ( item );
+    }
 #endif
 
     // ATM can't upload a single waypoint but can do waypoints to a GPS
@@ -6427,6 +6553,17 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     }
   }
 
+#ifdef VIK_CONFIG_GOOGLE
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && is_valid_google_route ( l, sublayer ) )
+  {
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_google_route_webpage), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+  }
+#endif
+
   // Some things aren't usable with routes
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
 #ifdef VIK_CONFIG_OPENSTREETMAP
@@ -6439,23 +6576,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     gtk_widget_show ( item );
 #endif
 
-    item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload to GPS...") );
-    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU) );
-    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_gps_upload_any), pass_along );
-    gtk_menu_shell_append ( GTK_MENU_SHELL(upload_submenu), item );
-    gtk_widget_show ( item );
-
-#ifdef VIK_CONFIG_GOOGLE
-    if ( is_valid_google_route ( l, sublayer ) )
-    {
-      item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") );
-      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
-      g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_google_route_webpage), pass_along );
-      gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
-      gtk_widget_show ( item );
-    }
-#endif
-
     item = gtk_image_menu_item_new_with_mnemonic ( _("Use with _Filter") );
     gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_use_with_filter), pass_along );
@@ -6576,7 +6696,7 @@ static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy )
     vtl->current_tpl = NULL;
     vtl->current_tp_track = NULL;
     vtl->current_tp_id = NULL;
-    vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+    vik_layer_emit_update(VIK_LAYER(vtl));
   }
 }
 
@@ -6621,7 +6741,7 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
       if ( vtl->current_tp_track )
         vik_trw_layer_tpwin_set_tp ( vtl->tpwin, new_tpl, vtl->current_tp_track->name );
 
-      vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+      vik_layer_emit_update(VIK_LAYER(vtl));
     }
     else
     {
@@ -6635,21 +6755,21 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
   {
     if ( vtl->current_tp_track )
       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->next, vtl->current_tp_track->name );
-    vik_layer_emit_update(VIK_LAYER(vtl), FALSE); /* TODO longone: either move or only update if tp is inside drawing window */
+    vik_layer_emit_update(VIK_LAYER(vtl)); /* TODO longone: either move or only update if tp is inside drawing window */
   }
   else if ( response == VIK_TRW_LAYER_TPWIN_BACK && vtl->current_tpl->prev )
   {
     if ( vtl->current_tp_track )
       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->prev, vtl->current_tp_track->name );
-    vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+    vik_layer_emit_update(VIK_LAYER(vtl));
   }
   else if ( response == VIK_TRW_LAYER_TPWIN_INSERT && vtl->current_tpl->next )
   {
     trw_layer_insert_tp_after_current_tp ( vtl );
-    vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+    vik_layer_emit_update(VIK_LAYER(vtl));
   }
   else if ( response == VIK_TRW_LAYER_TPWIN_DATA_CHANGED )
-    vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+    vik_layer_emit_update(VIK_LAYER(vtl));
 }
 
 static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
@@ -6865,7 +6985,7 @@ static gboolean trw_layer_select_release ( VikTrwLayer *vtl, GdkEventButton *eve
     vtl->current_wp_id = NULL;
     trw_layer_cancel_current_tp ( vtl, FALSE );
 
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
   return FALSE;
@@ -6919,7 +7039,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event
       vtl->current_wp =    wp_params.closest_wp;
       vtl->current_wp_id = wp_params.closest_wp_id;
 
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
 
       return TRUE;
     }
@@ -6962,7 +7082,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event
       if ( vtl->tpwin )
        vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
 
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
       return TRUE;
     }
   }
@@ -6997,7 +7117,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event
       if ( vtl->tpwin )
        vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
 
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
       return TRUE;
     }
   }
@@ -7222,14 +7342,14 @@ static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *eve
     vtl->current_wp_id = params.closest_wp_id;
 
     /* could make it so don't update if old WP is off screen and new is null but oh well */
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
 
   vtl->current_wp = NULL;
   vtl->current_wp_id = NULL;
   vtl->waypoint_rightclick = FALSE;
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
   return FALSE;
 }
 
@@ -7304,7 +7424,7 @@ static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *e
     marker_end_move ( t );
 
     vtl->current_wp->coord = new_coord;
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
   /* PUT IN RIGHT PLACE!!! */
@@ -7390,11 +7510,14 @@ static gchar* distance_string (gdouble distance)
 /*
  * Actually set the message in statusbar
  */
-static void statusbar_write (const gchar *distance_string, gdouble elev_gain, gdouble elev_loss, VikTrwLayer *vtl )
+static void statusbar_write (gdouble distance, gdouble elev_gain, gdouble elev_loss, gdouble last_step, gdouble angle, VikTrwLayer *vtl )
 {
   // Only show elevation data when track has some elevation properties
   gchar str_gain_loss[64];
   str_gain_loss[0] = '\0';
+  gchar str_last_step[64];
+  str_last_step[0] = '\0';
+  gchar *str_total = distance_string (distance);
   
   if ( (elev_gain > 0.1) || (elev_loss > 0.1) ) {
     if ( a_vik_get_units_height () == VIK_UNITS_HEIGHT_METRES )
@@ -7402,11 +7525,20 @@ static void statusbar_write (const gchar *distance_string, gdouble elev_gain, gd
     else
       g_sprintf(str_gain_loss, _(" - Gain %dft:Loss %dft"), (int)VIK_METERS_TO_FEET(elev_gain), (int)VIK_METERS_TO_FEET(elev_loss));
   }
+  
+  if ( last_step > 0 ) {
+      gchar *tmp = distance_string (last_step);
+      g_sprintf(str_last_step, _(" - Bearing %3.1f° - Step %s"), RAD2DEG(angle), tmp);
+      g_free ( tmp );
+  }
+  
+  VikWindow *vw = VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl));
 
   // Write with full gain/loss information
-  gchar *msg = g_strdup_printf ( "%s%s", distance_string, str_gain_loss);
-  vik_statusbar_set_message ( vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl))), VIK_STATUSBAR_INFO, msg );
+  gchar *msg = g_strdup_printf ( "Total %s%s%s", str_total, str_last_step, str_gain_loss);
+  vik_statusbar_set_message ( vik_window_get_statusbar (vw), VIK_STATUSBAR_INFO, msg );
   g_free ( msg );
+  g_free ( str_total );
 }
 
 /*
@@ -7420,11 +7552,8 @@ static void update_statusbar ( VikTrwLayer *vtl )
 
   /* Find out actual distance of current track */
   gdouble distance = vik_track_get_length (vtl->current_track);
-  gchar *str = distance_string (distance);
-
-  statusbar_write (str, elev_gain, elev_loss, vtl);
 
-  g_free (str);
+  statusbar_write (distance, elev_gain, elev_loss, 0, 0, vtl);
 }
 
 
@@ -7476,7 +7605,8 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     struct LatLon ll;
     vik_viewport_screen_to_coord ( vvp, (gint) event->x, (gint) event->y, &coord );
     vik_coord_to_latlon ( &coord, &ll );
-    distance = distance + vik_coord_diff( &coord, &(last_tpt->coord));
+    gdouble last_step = vik_coord_diff( &coord, &(last_tpt->coord));
+    distance = distance + last_step;
 
     // Get elevation data
     gdouble elev_gain, elev_loss;
@@ -7496,7 +7626,7 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
          elev_loss += last_tpt->altitude - elev_new;
       }
     }
-      
+    
     gchar *str = distance_string (distance);
 
     PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
@@ -7525,8 +7655,12 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     passalong->drawable = GTK_WIDGET(vvp)->window;
     passalong->gc = vtl->current_track_newpoint_gc;
 
+    gdouble angle;
+    gdouble baseangle;
+    vik_viewport_compute_bearing ( vvp, x1, y1, event->x, event->y, &angle, &baseangle );
+
     // Update statusbar with full gain/loss information
-    statusbar_write (str, elev_gain, elev_loss, vtl);
+    statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl);
 
     g_free (str);
 
@@ -7542,7 +7676,7 @@ static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event,
 {
   if ( vtl->current_track && event->keyval == GDK_Escape ) {
     vtl->current_track = NULL;
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   } else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
     /* undo */
@@ -7555,7 +7689,7 @@ static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event,
 
     update_statusbar ( vtl );
 
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
   return FALSE;
@@ -7594,7 +7728,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
     }
     update_statusbar ( vtl );
 
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
 
@@ -7609,7 +7743,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
       /* undo last, then end */
       vtl->current_track = NULL;
     }
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
 
@@ -7639,7 +7773,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
   vtl->ct_x2 = event->x;
   vtl->ct_y2 = event->y;
 
-  vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
   return TRUE;
 }
 
@@ -7651,9 +7785,7 @@ static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event,
     gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track"));
     if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks, name, FALSE ) ) )
     {
-      vtl->current_track = vik_track_new();
-      vtl->current_track->visible = TRUE;
-      vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+      new_track_create_common ( vtl, name );
     }
     else
       return TRUE;
@@ -7705,7 +7837,7 @@ static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *even
     return FALSE;
   vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord );
   if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible)
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
   return TRUE;
 }
 
@@ -7778,7 +7910,7 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e
     vtl->current_tp_track = g_hash_table_lookup ( vtl->tracks, params.closest_track_id );
     trw_layer_tpwin_init ( vtl );
     set_statusbar_msg_info_trkpt ( vtl, params.closest_tp );
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
 
@@ -7793,7 +7925,7 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e
     vtl->current_tp_track = g_hash_table_lookup ( vtl->routes, params.closest_track_id );
     trw_layer_tpwin_init ( vtl );
     set_statusbar_msg_info_trkpt ( vtl, params.closest_tp );
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
 
@@ -7863,7 +7995,7 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton
     if ( vtl->tpwin )
       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
 
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
   return FALSE;
@@ -7888,7 +8020,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
     if ( new_end ) {
       vtl->route_finder_coord = *new_end;
       g_free ( new_end );
-      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+      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' );
@@ -7923,7 +8055,8 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
                           g_ascii_dtostr (startlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lon),
                           g_ascii_dtostr (endlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lat),
                           g_ascii_dtostr (endlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lon));
-    a_babel_convert_from_url ( vtl, url, "google", NULL, NULL );
+    // NB normally this returns a GPX Route - so subsequent usage of it must lookup via the routes hash
+    a_babel_convert_from_url ( vtl, url, "google", NULL, NULL, NULL );
     g_free ( url );
 
     /* see if anything was done -- a track was added or appended to */
@@ -7938,7 +8071,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
     vtl->route_finder_check_added_track = FALSE;
     vtl->route_finder_append = FALSE;
 
-    vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
   } else {
     vtl->route_finder_started = TRUE;
     vtl->route_finder_coord = tmp;
@@ -7956,7 +8089,7 @@ static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp)
 }
 
 /* Params are: vvp, event, last match found or NULL */
-static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[3] )
+static void tool_show_picture_wp ( const gpointer id, VikWaypoint *wp, gpointer params[3] )
 {
   if ( wp->image && wp->visible )
   {
@@ -8018,10 +8151,7 @@ static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *even
  ***************************************************************************/
 
 
-
-
-
-static void image_wp_make_list ( char *name, VikWaypoint *wp, GSList **pics )
+static void image_wp_make_list ( const gpointer id, VikWaypoint *wp, GSList **pics )
 {
   if ( wp->image && ( ! a_thumbnails_exists ( wp->image ) ) )
     *pics = g_slist_append ( *pics, (gpointer) g_strdup ( wp->image ) );
@@ -8048,7 +8178,7 @@ static int create_thumbnails_thread ( thumbnail_create_thread_data *tctd, gpoint
 
   // Redraw to show the thumbnails as they are now created
   if ( IS_VIK_LAYER(tctd->vtl) )
-    vik_layer_emit_update ( VIK_LAYER(tctd->vtl), TRUE ); // Yes update from background thread
+    vik_layer_emit_update ( VIK_LAYER(tctd->vtl) ); // NB update from background thread
 
   return 0;
 }
@@ -8092,14 +8222,14 @@ static const gchar* my_track_colors ( gint ii )
 {
   static const gchar* colors[VIK_TRW_LAYER_TRACK_GCS] = {
     "#2d870a",
-    "#0a8742",
+    "#135D34",
     "#0a8783",
     "#0e4d87",
     "#05469f",
-    "#1b059f",
+    "#695CBB",
     "#2d059f",
     "#4a059f",
-    "#84059f",
+    "#5A171A",
     "#96059f"
   };
   // Fast and reliable way of returning a colour
@@ -8119,7 +8249,11 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl )
 
     // Tracks get a random spread of colours if not already assigned
     if ( ! VIK_TRACK(value)->has_color ) {
-      gdk_color_parse ( my_track_colors (ii) , &(VIK_TRACK(value)->color) );
+      if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR )
+        VIK_TRACK(value)->color = vtl->track_color;
+      else {
+        gdk_color_parse ( my_track_colors (ii), &(VIK_TRACK(value)->color) );
+      }
       VIK_TRACK(value)->has_color = TRUE;
     }
 
@@ -8183,7 +8317,7 @@ static void waypoint_convert ( const gpointer id, VikWaypoint *wp, VikCoordMode
   vik_coord_convert ( &(wp->coord), *dest_mode );
 }
 
-static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode )
+static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode )
 {
   vik_track_convert ( tr, *dest_mode );
 }
@@ -8195,6 +8329,7 @@ static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mo
     vtl->coord_mode = dest_mode;
     g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_convert, &dest_mode );
     g_hash_table_foreach ( vtl->tracks, (GHFunc) track_convert, &dest_mode );
+    g_hash_table_foreach ( vtl->routes, (GHFunc) track_convert, &dest_mode );
   }
 }