]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktrwlayer.c
Start to make compression code more reuseable.
[andy/viking.git] / src / viktrwlayer.c
index 9080b4c1f11d201a59bd981ee4723f9686f8acf0..f6bc0838302c8c27db1fcbceac2018f0709e04f1 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2007, Quy Tonthat <qtonthat@gmail.com>
  * Copyright (C) 2009, Hein Ragas <viking@ragas.nl>
  * Copyright (c) 2012, Rob Norris <rw_norris@hotmail.com>
  * Copyright (C) 2007, Quy Tonthat <qtonthat@gmail.com>
  * Copyright (C) 2009, Hein Ragas <viking@ragas.nl>
  * Copyright (c) 2012, Rob Norris <rw_norris@hotmail.com>
+ * Copyright (c) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,6 +35,7 @@
 #include "vikgpslayer.h"
 #include "viktrwlayer_tpwin.h"
 #include "viktrwlayer_propwin.h"
 #include "vikgpslayer.h"
 #include "viktrwlayer_tpwin.h"
 #include "viktrwlayer_propwin.h"
+#include "viktrwlayer_analysis.h"
 #ifdef VIK_CONFIG_GEOTAG
 #include "viktrwlayer_geotag.h"
 #include "geotag_exif.h"
 #ifdef VIK_CONFIG_GEOTAG
 #include "viktrwlayer_geotag.h"
 #include "geotag_exif.h"
 #include "acquire.h"
 #include "datasources.h"
 #include "datasource_gps.h"
 #include "acquire.h"
 #include "datasources.h"
 #include "datasource_gps.h"
+#include "vikexttool_datasources.h"
 #include "util.h"
 
 #include "util.h"
 
+#include "vikrouting.h"
+
 #include "icons/icons.h"
 
 #ifdef HAVE_MATH_H
 #include "icons/icons.h"
 
 #ifdef HAVE_MATH_H
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 
-#ifdef VIK_CONFIG_GOOGLE
-#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_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_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
 
 // Note using DRAWMODE_BY_SPEED may be slow especially for vast numbers of trackpoints
 //  as we are (re)calculating the colour for every point
 
@@ -127,6 +129,8 @@ struct _VikTrwLayer {
   GHashTable *waypoints;
   GtkTreeIter tracks_iter, routes_iter, waypoints_iter;
   gboolean tracks_visible, routes_visible, waypoints_visible;
   GHashTable *waypoints;
   GtkTreeIter tracks_iter, routes_iter, waypoints_iter;
   gboolean tracks_visible, routes_visible, waypoints_visible;
+  LatLonBBox waypoints_bbox;
+
   guint8 drawmode;
   guint8 drawpoints;
   guint8 drawpoints_size;
   guint8 drawmode;
   guint8 drawpoints;
   guint8 drawpoints_size;
@@ -139,23 +143,28 @@ struct _VikTrwLayer {
   guint8 drawdirections_size;
   guint8 line_thickness;
   guint8 bg_line_thickness;
   guint8 drawdirections_size;
   guint8 line_thickness;
   guint8 bg_line_thickness;
+  vik_layer_sort_order_t track_sort_order;
 
   guint8 wp_symbol;
   guint8 wp_size;
   gboolean wp_draw_symbols;
   font_size_t wp_font_size;
 
   guint8 wp_symbol;
   guint8 wp_size;
   gboolean wp_draw_symbols;
   font_size_t wp_font_size;
+  gchar *wp_fsize_str;
+  vik_layer_sort_order_t wp_sort_order;
 
   gdouble track_draw_speed_factor;
   GArray *track_gc;
   GdkGC *track_1color_gc;
 
   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)
   GdkGC *current_track_newpoint_gc;
   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)
   GdkGC *current_track_newpoint_gc;
-  GdkGC *track_bg_gc;
-  GdkGC *waypoint_gc;
-  GdkGC *waypoint_text_gc;
-  GdkGC *waypoint_bg_gc;
+  GdkGC *track_bg_gc; GdkColor track_bg_color;
+  GdkGC *waypoint_gc; GdkColor waypoint_color;
+  GdkGC *waypoint_text_gc; GdkColor waypoint_text_color;
+  GdkGC *waypoint_bg_gc; GdkColor waypoint_bg_color;
+  gboolean wpbgand;
   GdkFont *waypoint_font;
   VikTrack *current_track; // ATM shared between new tracks and new routes
   guint16 ct_x1, ct_y1, ct_x2, ct_y2;
   GdkFont *waypoint_font;
   VikTrack *current_track; // ATM shared between new tracks and new routes
   guint16 ct_x1, ct_y1, ct_x2, ct_y2;
@@ -206,6 +215,9 @@ struct _VikTrwLayer {
   VikStdLayerMenuItem menu_selection;
 
   gint highest_wp_number;
   VikStdLayerMenuItem menu_selection;
 
   gint highest_wp_number;
+
+  // One per layer
+  GtkWidget *tracks_analysis_dialog;
 };
 
 /* A caached waypoint image. */
 };
 
 /* A caached waypoint image. */
@@ -225,6 +237,7 @@ struct DrawingParams {
   const VikCoord *center;
   gboolean one_zone, lat_lon;
   gdouble ce1, ce2, cn1, cn2;
   const VikCoord *center;
   gboolean one_zone, lat_lon;
   gdouble ce1, ce2, cn1, cn2;
+  LatLonBBox bbox;
 };
 
 static gboolean trw_layer_delete_waypoint ( VikTrwLayer *vtl, VikWaypoint *wp );
 };
 
 static gboolean trw_layer_delete_waypoint ( VikTrwLayer *vtl, VikWaypoint *wp );
@@ -233,7 +246,6 @@ 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_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 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_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]);
 
@@ -243,6 +255,8 @@ static void trw_layer_free_track_gcs ( VikTrwLayer *vtl );
 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 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 trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl );
+
 static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord );
 static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] );
 static void trw_layer_goto_track_endpoint ( gpointer pass_along[6] );
 static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord );
 static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] );
 static void trw_layer_goto_track_endpoint ( gpointer pass_along[6] );
@@ -289,9 +303,7 @@ static void trw_layer_geotagging_track ( gpointer pass_along[6] );
 static void trw_layer_geotagging ( gpointer lav[2] );
 #endif
 static void trw_layer_acquire_gps_cb ( gpointer lav[2] );
 static void trw_layer_geotagging ( gpointer lav[2] );
 #endif
 static void trw_layer_acquire_gps_cb ( gpointer lav[2] );
-#ifdef VIK_CONFIG_GOOGLE
-static void trw_layer_acquire_google_cb ( gpointer lav[2] );
-#endif
+static void trw_layer_acquire_routing_cb ( gpointer lav[2] );
 #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] );
 #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] );
@@ -328,12 +340,14 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response );
 static void trw_layer_tpwin_init ( VikTrwLayer *vtl );
 
 static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp);
 static void trw_layer_tpwin_init ( VikTrwLayer *vtl );
 
 static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp);
+static void tool_edit_trackpoint_destroy ( tool_ed_t *t );
 static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gboolean tool_edit_trackpoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
 static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp ); 
 static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gboolean tool_edit_trackpoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
 static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp ); 
 static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp);
+static void tool_edit_waypoint_destroy ( tool_ed_t *t );
 static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
 static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
 static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
 static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
@@ -346,10 +360,8 @@ 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 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 );
-#ifdef VIK_CONFIG_GOOGLE
 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_route_finder_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-#endif
 
 static void cached_pixbuf_free ( CachedPixbuf *cp );
 static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
 
 static void cached_pixbuf_free ( CachedPixbuf *cp );
 static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
@@ -397,7 +409,9 @@ static VikToolInterface trw_layer_tools[] = {
     GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf },
 
   { { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
     GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf },
 
   { { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
-    (VikToolConstructorFunc) tool_edit_waypoint_create,   NULL, NULL, NULL,
+    (VikToolConstructorFunc) tool_edit_waypoint_create,
+    (VikToolDestructorFunc) tool_edit_waypoint_destroy,
+    NULL, NULL,
     (VikToolMouseFunc) tool_edit_waypoint_click,   
     (VikToolMouseMoveFunc) tool_edit_waypoint_move,
     (VikToolMouseFunc) tool_edit_waypoint_release, (VikToolKeyFunc) NULL,
     (VikToolMouseFunc) tool_edit_waypoint_click,   
     (VikToolMouseMoveFunc) tool_edit_waypoint_move,
     (VikToolMouseFunc) tool_edit_waypoint_release, (VikToolKeyFunc) NULL,
@@ -405,7 +419,9 @@ static VikToolInterface trw_layer_tools[] = {
     GDK_CURSOR_IS_PIXMAP, &cursor_edwp_pixbuf },
 
   { { "EditTrackpoint", "vik-icon-Edit Trackpoint", N_("Edit Trac_kpoint"), "<control><shift>K", N_("Edit Trackpoint"), 0 },
     GDK_CURSOR_IS_PIXMAP, &cursor_edwp_pixbuf },
 
   { { "EditTrackpoint", "vik-icon-Edit Trackpoint", N_("Edit Trac_kpoint"), "<control><shift>K", N_("Edit Trackpoint"), 0 },
-    (VikToolConstructorFunc) tool_edit_trackpoint_create, NULL, NULL, NULL,
+    (VikToolConstructorFunc) tool_edit_trackpoint_create,
+    (VikToolDestructorFunc) tool_edit_trackpoint_destroy,
+    NULL, NULL,
     (VikToolMouseFunc) tool_edit_trackpoint_click,
     (VikToolMouseMoveFunc) tool_edit_trackpoint_move,
     (VikToolMouseFunc) tool_edit_trackpoint_release, (VikToolKeyFunc) NULL,
     (VikToolMouseFunc) tool_edit_trackpoint_click,
     (VikToolMouseMoveFunc) tool_edit_trackpoint_move,
     (VikToolMouseFunc) tool_edit_trackpoint_release, (VikToolKeyFunc) NULL,
@@ -418,13 +434,11 @@ static VikToolInterface trw_layer_tools[] = {
     FALSE,
     GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
 
     FALSE,
     GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
 
-#ifdef VIK_CONFIG_GOOGLE
   { { "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 },
   { { "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 },
-#endif
 };
 
 enum {
 };
 
 enum {
@@ -434,9 +448,7 @@ enum {
   TOOL_EDIT_WAYPOINT,
   TOOL_EDIT_TRACKPOINT,
   TOOL_SHOW_PICTURE,
   TOOL_EDIT_WAYPOINT,
   TOOL_EDIT_TRACKPOINT,
   TOOL_SHOW_PICTURE,
-#ifdef VIK_CONFIG_GOOGLE
   TOOL_ROUTE_FINDER,
   TOOL_ROUTE_FINDER,
-#endif
   NUM_TOOLS
 };
 
   NUM_TOOLS
 };
 
@@ -445,7 +457,7 @@ enum {
 static gchar *params_groups[] = { N_("Waypoints"), N_("Tracks"), N_("Waypoint Images") };
 enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES };
 
 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
 static gchar *params_wpsymbols[] = { N_("Filled Square"), N_("Square"), N_("Circle"), N_("X"), 0 };
 
 #define MIN_POINT_SIZE 2
@@ -481,44 +493,88 @@ static gchar* params_font_sizes[] = {
   N_("Extra Extra Large"),
   NULL };
 
   N_("Extra Extra Large"),
   NULL };
 
+// Needs to align with vik_layer_sort_order_t
+static gchar* params_sort_order[] = {
+  N_("None"),
+  N_("Name Ascending"),
+  N_("Name Descending"),
+  NULL
+};
+
+static VikLayerParamData black_color_default ( void ) {
+  VikLayerParamData data; gdk_color_parse ( "#000000", &data.c ); return data; // Black
+}
+static VikLayerParamData drawmode_default ( void ) { return VIK_LPD_UINT ( DRAWMODE_BY_TRACK ); }
+static VikLayerParamData line_thickness_default ( void ) { return VIK_LPD_UINT ( 1 ); }
+static VikLayerParamData trkpointsize_default ( void ) { return VIK_LPD_UINT ( MIN_POINT_SIZE ); }
+static VikLayerParamData trkdirectionsize_default ( void ) { return VIK_LPD_UINT ( 5 ); }
+static VikLayerParamData bg_line_thickness_default ( void ) { return VIK_LPD_UINT ( 0 ); }
+static VikLayerParamData trackbgcolor_default ( void ) {
+  VikLayerParamData data; gdk_color_parse ( "#FFFFFF", &data.c ); return data; // White
+}
+static VikLayerParamData elevation_factor_default ( void ) { return VIK_LPD_UINT ( 30 ); }
+static VikLayerParamData stop_length_default ( void ) { return VIK_LPD_UINT ( 60 ); }
+static VikLayerParamData speed_factor_default ( void ) { return VIK_LPD_DOUBLE ( 30.0 ); }
+
+static VikLayerParamData wpfontsize_default ( void ) { return VIK_LPD_UINT ( FS_MEDIUM ); }
+static VikLayerParamData wptextcolor_default ( void ) {
+  VikLayerParamData data; gdk_color_parse ( "#FFFFFF", &data.c ); return data; // White
+}
+static VikLayerParamData wpbgcolor_default ( void ) {
+  VikLayerParamData data; gdk_color_parse ( "#8383C4", &data.c ); return data; // Kind of Blue
+}
+static VikLayerParamData wpsize_default ( void ) { return VIK_LPD_UINT ( 4 ); }
+static VikLayerParamData wpsymbol_default ( void ) { return VIK_LPD_UINT ( WP_SYMBOL_FILLED_SQUARE ); }
+
+static VikLayerParamData image_size_default ( void ) { return VIK_LPD_UINT ( 64 ); }
+static VikLayerParamData image_alpha_default ( void ) { return VIK_LPD_UINT ( 255 ); }
+static VikLayerParamData image_cache_size_default ( void ) { return VIK_LPD_UINT ( 300 ); }
+
+static VikLayerParamData sort_order_default ( void ) { return VIK_LPD_UINT ( 0 ); }
+
 VikLayerParam trw_layer_params[] = {
 VikLayerParam trw_layer_params[] = {
-  { "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 },
-  { "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 },
+  { VIK_LAYER_TRW, "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL, drawmode_default, NULL, NULL },
+  { VIK_LAYER_TRW, "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"), black_color_default, NULL, NULL },
+  { VIK_LAYER_TRW, "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[0], NULL, NULL, line_thickness_default, NULL, NULL },
+  { VIK_LAYER_TRW, "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+  { VIK_LAYER_TRW, "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[11], NULL, NULL, trkdirectionsize_default, NULL, NULL },
+  { VIK_LAYER_TRW, "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[10], NULL, NULL, trkpointsize_default, NULL, NULL },
+  { VIK_LAYER_TRW, "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+  { VIK_LAYER_TRW, "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[9], NULL, NULL, elevation_factor_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "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"), vik_lpd_false_default, NULL, NULL },
+  { VIK_LAYER_TRW, "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[8], NULL, NULL, stop_length_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[6], NULL, NULL, bg_line_thickness_default, NULL, NULL },
+  { VIK_LAYER_TRW, "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, trackbgcolor_default, NULL, NULL },
+  { VIK_LAYER_TRW, "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"), speed_factor_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "tracksortorder", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Sort Order:"), VIK_LAYER_WIDGET_COMBOBOX, params_sort_order, NULL, NULL, sort_order_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL, wpfontsize_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, black_color_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wptextcolor_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wpbgcolor_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL, wpsymbol_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, &params_scales[7], NULL, NULL, wpsize_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "wpsortorder", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Sort Order:"), VIK_LAYER_WIDGET_COMBOBOX, params_sort_order, NULL, NULL, sort_order_default, NULL, NULL },
+
+  { VIK_LAYER_TRW, "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+  { VIK_LAYER_TRW, "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, &params_scales[3], NULL, NULL, image_size_default, NULL, NULL },
+  { VIK_LAYER_TRW, "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[4], NULL, NULL, image_alpha_default, NULL, NULL },
+  { VIK_LAYER_TRW, "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, &params_scales[5], NULL, NULL, image_cache_size_default, NULL, NULL },
 };
 
 // ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE
 };
 
 // ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE
@@ -529,6 +585,7 @@ enum {
   PARAM_RV,
   // Tracks
   PARAM_DM,
   PARAM_RV,
   // Tracks
   PARAM_DM,
+  PARAM_TC,
   PARAM_DL,
   PARAM_LT,
   PARAM_DD,
   PARAM_DL,
   PARAM_LT,
   PARAM_DD,
@@ -542,6 +599,7 @@ enum {
   PARAM_BLT,
   PARAM_TBGC,
   PARAM_TDSF,
   PARAM_BLT,
   PARAM_TBGC,
   PARAM_TDSF,
+  PARAM_TSO,
   // Waypoints
   PARAM_DLA,
   PARAM_WPFONTSIZE,
   // Waypoints
   PARAM_DLA,
   PARAM_WPFONTSIZE,
@@ -552,6 +610,7 @@ enum {
   PARAM_WPSYM,
   PARAM_WPSIZE,
   PARAM_WPSYMS,
   PARAM_WPSYM,
   PARAM_WPSIZE,
   PARAM_WPSYMS,
+  PARAM_WPSO,
   // WP images
   PARAM_DI,
   PARAM_IS,
   // WP images
   PARAM_DI,
   PARAM_IS,
@@ -567,11 +626,10 @@ enum {
 
 /****** END PARAMETERS ******/
 
 
 /****** END PARAMETERS ******/
 
-static VikTrwLayer* trw_layer_new ( gint drawmode );
 /* Layer Interface function definitions */
 static VikTrwLayer* trw_layer_create ( VikViewport *vp );
 static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter );
 /* Layer Interface function definitions */
 static VikTrwLayer* trw_layer_create ( VikViewport *vp );
 static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter );
-static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp );
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp, gboolean from_file );
 static void trw_layer_free ( VikTrwLayer *trwlayer );
 static void trw_layer_draw ( VikTrwLayer *l, gpointer data );
 static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode );
 static void trw_layer_free ( VikTrwLayer *trwlayer );
 static void trw_layer_draw ( VikTrwLayer *l, gpointer data );
 static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode );
@@ -815,6 +873,9 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name);
     vik_trw_layer_add_waypoint ( vtl, name, w );
     waypoint_convert (NULL, w, &vtl->coord_mode);
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name);
     vik_trw_layer_add_waypoint ( vtl, name, w );
     waypoint_convert (NULL, w, &vtl->coord_mode);
+    g_free ( name );
+
+    trw_layer_calculate_bounds_waypoints ( vtl );
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->waypoints_visible && w->visible )
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->waypoints_visible && w->visible )
@@ -830,6 +891,7 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name);
     vik_trw_layer_add_track ( vtl, name, t );
     vik_track_convert (t, vtl->coord_mode);
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name);
     vik_trw_layer_add_track ( vtl, name, t );
     vik_track_convert (t, vtl->coord_mode);
+    g_free ( name );
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->tracks_visible && t->visible )
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->tracks_visible && t->visible )
@@ -845,6 +907,7 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name);
     vik_trw_layer_add_route ( vtl, name, t );
     vik_track_convert (t, vtl->coord_mode);
     name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name);
     vik_trw_layer_add_route ( vtl, name, t );
     vik_track_convert (t, vtl->coord_mode);
+    g_free ( name );
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->routes_visible && t->visible )
 
     // Consider if redraw necessary for the new item
     if ( vtl->vl.visible && vtl->routes_visible && t->visible )
@@ -869,6 +932,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_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;
+      if ( vp ) 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 )
     case PARAM_DP: vtl->drawpoints = data.b; break;
     case PARAM_DPS:
       if ( data.u >= MIN_POINT_SIZE && data.u <= MAX_POINT_SIZE )
@@ -891,17 +958,22 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara
     case PARAM_LT: if ( data.u > 0 && data.u < 15 && data.u != vtl->line_thickness )
                    {
                      vtl->line_thickness = data.u;
     case PARAM_LT: if ( data.u > 0 && data.u < 15 && data.u != vtl->line_thickness )
                    {
                      vtl->line_thickness = data.u;
-                     trw_layer_new_track_gcs ( vtl, vp );
+                     if ( vp ) trw_layer_new_track_gcs ( vtl, vp );
                    }
                    break;
                    }
                    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;
                    {
                      vtl->bg_line_thickness = data.u;
-                     trw_layer_new_track_gcs ( vtl, vp );
+                     if ( vp ) trw_layer_new_track_gcs ( vtl, vp );
                    }
                    break;
                    }
                    break;
-    case PARAM_TBGC: gdk_gc_set_rgb_fg_color(vtl->track_bg_gc, &(data.c)); break;
+    case PARAM_TBGC:
+      vtl->track_bg_color = data.c;
+      if ( vtl->track_bg_gc )
+        gdk_gc_set_rgb_fg_color(vtl->track_bg_gc, &(vtl->track_bg_color));
+      break;
     case PARAM_TDSF: vtl->track_draw_speed_factor = data.d; break;
     case PARAM_TDSF: vtl->track_draw_speed_factor = data.d; break;
+    case PARAM_TSO: if ( data.u < VL_SO_LAST ) vtl->track_sort_order = data.u; break;
     case PARAM_DLA: vtl->drawlabels = data.b; break;
     case PARAM_DI: vtl->drawimages = data.b; break;
     case PARAM_IS: if ( data.u != vtl->image_size )
     case PARAM_DLA: vtl->drawlabels = data.b; break;
     case PARAM_DI: vtl->drawimages = data.b; break;
     case PARAM_IS: if ( data.u != vtl->image_size )
@@ -917,14 +989,45 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara
       while ( vtl->image_cache->length > vtl->image_cache_size ) /* if shrinking cache_size, free pixbuf ASAP */
           cached_pixbuf_free ( g_queue_pop_tail ( vtl->image_cache ) );
       break;
       while ( vtl->image_cache->length > vtl->image_cache_size ) /* if shrinking cache_size, free pixbuf ASAP */
           cached_pixbuf_free ( g_queue_pop_tail ( vtl->image_cache ) );
       break;
-    case PARAM_WPC: gdk_gc_set_rgb_fg_color(vtl->waypoint_gc, &(data.c)); break;
-    case PARAM_WPTC: gdk_gc_set_rgb_fg_color(vtl->waypoint_text_gc, &(data.c)); break;
-    case PARAM_WPBC: gdk_gc_set_rgb_fg_color(vtl->waypoint_bg_gc, &(data.c)); break;
-    case PARAM_WPBA: gdk_gc_set_function(vtl->waypoint_bg_gc, data.b ? GDK_AND : GDK_COPY ); break;
+    case PARAM_WPC:
+      vtl->waypoint_color = data.c;
+      if ( vtl->waypoint_gc )
+        gdk_gc_set_rgb_fg_color(vtl->waypoint_gc, &(vtl->waypoint_color));
+      break;
+    case PARAM_WPTC:
+      vtl->waypoint_text_color = data.c;
+      if ( vtl->waypoint_text_gc )
+        gdk_gc_set_rgb_fg_color(vtl->waypoint_text_gc, &(vtl->waypoint_text_color));
+      break;
+    case PARAM_WPBC:
+      vtl->waypoint_bg_color = data.c;
+      if ( vtl->waypoint_bg_gc )
+        gdk_gc_set_rgb_fg_color(vtl->waypoint_bg_gc, &(vtl->waypoint_bg_color));
+      break;
+    case PARAM_WPBA:
+      vtl->wpbgand = data.b;
+      if ( vtl->waypoint_bg_gc )
+        gdk_gc_set_function(vtl->waypoint_bg_gc, data.b ? GDK_AND : GDK_COPY );
+      break;
     case PARAM_WPSYM: if ( data.u < WP_NUM_SYMBOLS ) vtl->wp_symbol = data.u; break;
     case PARAM_WPSIZE: if ( data.u > 0 && data.u <= 64 ) vtl->wp_size = data.u; break;
     case PARAM_WPSYMS: vtl->wp_draw_symbols = data.b; break;
     case PARAM_WPSYM: if ( data.u < WP_NUM_SYMBOLS ) vtl->wp_symbol = data.u; break;
     case PARAM_WPSIZE: if ( data.u > 0 && data.u <= 64 ) vtl->wp_size = data.u; break;
     case PARAM_WPSYMS: vtl->wp_draw_symbols = data.b; break;
-    case PARAM_WPFONTSIZE: if ( data.u < FS_NUM_SIZES ) vtl->wp_font_size = data.u; break;
+    case PARAM_WPFONTSIZE:
+      if ( data.u < FS_NUM_SIZES ) {
+        vtl->wp_font_size = data.u;
+        g_free ( vtl->wp_fsize_str );
+        switch ( vtl->wp_font_size ) {
+          case FS_XX_SMALL: vtl->wp_fsize_str = g_strdup ( "xx-small" ); break;
+          case FS_X_SMALL: vtl->wp_fsize_str = g_strdup ( "x-small" ); break;
+          case FS_SMALL: vtl->wp_fsize_str = g_strdup ( "small" ); break;
+          case FS_LARGE: vtl->wp_fsize_str = g_strdup ( "large" ); break;
+          case FS_X_LARGE: vtl->wp_fsize_str = g_strdup ( "x-large" ); break;
+          case FS_XX_LARGE: vtl->wp_fsize_str = g_strdup ( "xx-large" ); break;
+          default: vtl->wp_fsize_str = g_strdup ( "medium" ); break;
+        }
+      }
+      break;
+    case PARAM_WPSO: if ( data.u < VL_SO_LAST ) vtl->wp_sort_order = data.u; break;
   }
   return TRUE;
 }
   }
   return TRUE;
 }
@@ -938,6 +1041,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_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;
     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;
@@ -951,19 +1055,21 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo
     case PARAM_BLT: rv.u = vtl->bg_line_thickness; break;
     case PARAM_DLA: rv.b = vtl->drawlabels; break;
     case PARAM_DI: rv.b = vtl->drawimages; break;
     case PARAM_BLT: rv.u = vtl->bg_line_thickness; break;
     case PARAM_DLA: rv.b = vtl->drawlabels; break;
     case PARAM_DI: rv.b = vtl->drawimages; break;
-    case PARAM_TBGC: vik_gc_get_fg_color(vtl->track_bg_gc, &(rv.c)); break;
+    case PARAM_TBGC: rv.c = vtl->track_bg_color; break;
     case PARAM_TDSF: rv.d = vtl->track_draw_speed_factor; break;
     case PARAM_TDSF: rv.d = vtl->track_draw_speed_factor; break;
+    case PARAM_TSO: rv.u = vtl->track_sort_order; break;
     case PARAM_IS: rv.u = vtl->image_size; break;
     case PARAM_IA: rv.u = vtl->image_alpha; break;
     case PARAM_ICS: rv.u = vtl->image_cache_size; break;
     case PARAM_IS: rv.u = vtl->image_size; break;
     case PARAM_IA: rv.u = vtl->image_alpha; break;
     case PARAM_ICS: rv.u = vtl->image_cache_size; break;
-    case PARAM_WPC: vik_gc_get_fg_color(vtl->waypoint_gc, &(rv.c)); break;
-    case PARAM_WPTC: vik_gc_get_fg_color(vtl->waypoint_text_gc, &(rv.c)); break;
-    case PARAM_WPBC: vik_gc_get_fg_color(vtl->waypoint_bg_gc, &(rv.c)); break;
-    case PARAM_WPBA: rv.b = (vik_gc_get_function(vtl->waypoint_bg_gc)==GDK_AND); break;
+    case PARAM_WPC: rv.c = vtl->waypoint_color; break;
+    case PARAM_WPTC: rv.c = vtl->waypoint_text_color; break;
+    case PARAM_WPBC: rv.c = vtl->waypoint_bg_color; break;
+    case PARAM_WPBA: rv.b = vtl->wpbgand; break;
     case PARAM_WPSYM: rv.u = vtl->wp_symbol; break;
     case PARAM_WPSIZE: rv.u = vtl->wp_size; break;
     case PARAM_WPSYMS: rv.b = vtl->wp_draw_symbols; break;
     case PARAM_WPFONTSIZE: rv.u = vtl->wp_font_size; break;
     case PARAM_WPSYM: rv.u = vtl->wp_symbol; break;
     case PARAM_WPSIZE: rv.u = vtl->wp_size; break;
     case PARAM_WPSYMS: rv.b = vtl->wp_draw_symbols; break;
     case PARAM_WPFONTSIZE: rv.u = vtl->wp_font_size; break;
+    case PARAM_WPSO: rv.u = vtl->wp_sort_order; break;
   }
   return rv;
 }
   }
   return rv;
 }
@@ -1090,6 +1196,9 @@ static VikTrwLayer *trw_layer_unmarshall( guint8 *data, gint len, VikViewport *v
   }
   //g_debug ("consumed_length %d vs len %d", consumed_length, len);
 
   }
   //g_debug ("consumed_length %d vs len %d", consumed_length, len);
 
+  // Not stored anywhere else so need to regenerate
+  trw_layer_calculate_bounds_waypoints ( vtl );
+
   return vtl;
 }
 
   return vtl;
 }
 
@@ -1118,7 +1227,9 @@ static guint strcase_hash(gconstpointer v)
 }
 */
 
 }
 */
 
-static VikTrwLayer* trw_layer_new ( gint drawmode )
+// Stick a 1 at the end of the function name to make it more unique
+//  thus more easily searchable in a simple text editor
+static VikTrwLayer* trw_layer_new1 ( VikViewport *vvp )
 {
   VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
   vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW );
 {
   VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
   vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW );
@@ -1142,27 +1253,16 @@ static VikTrwLayer* trw_layer_new ( gint drawmode )
   rv->routes = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) vik_track_free );
   rv->routes_iters = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, g_free );
 
   rv->routes = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) vik_track_free );
   rv->routes_iters = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, g_free );
 
-  // Default values
+  rv->image_cache = g_queue_new(); // Must be performed before set_params via set_defaults
+
+  vik_layer_set_defaults ( VIK_LAYER(rv), vvp );
+
+  // Param settings that are not available via the GUI
+  // Force to on after processing params (which defaults them to off with a zero value)
   rv->waypoints_visible = rv->tracks_visible = rv->routes_visible = TRUE;
   rv->waypoints_visible = rv->tracks_visible = rv->routes_visible = TRUE;
-  rv->drawmode = drawmode;
-  rv->drawpoints = TRUE;
-  rv->drawpoints_size = MIN_POINT_SIZE;
-  rv->drawdirections_size = 5;
-  rv->elevation_factor = 30;
-  rv->stop_length = 60;
-  rv->drawlines = TRUE;
-  rv->track_draw_speed_factor = 30.0;
-  rv->line_thickness = 1;
 
   rv->draw_sync_done = TRUE;
   rv->draw_sync_do = TRUE;
 
   rv->draw_sync_done = TRUE;
   rv->draw_sync_do = TRUE;
-
-  rv->image_cache = g_queue_new();
-  rv->image_size = 64;
-  rv->image_alpha = 255;
-  rv->image_cache_size = 300;
-  rv->drawimages = TRUE;
-  rv->drawlabels = TRUE;
   // Everything else is 0, FALSE or NULL
 
   return rv;
   // Everything else is 0, FALSE or NULL
 
   return rv;
@@ -1172,7 +1272,11 @@ static VikTrwLayer* trw_layer_new ( gint drawmode )
 static void trw_layer_free ( VikTrwLayer *trwlayer )
 {
   g_hash_table_destroy(trwlayer->waypoints);
 static void trw_layer_free ( VikTrwLayer *trwlayer )
 {
   g_hash_table_destroy(trwlayer->waypoints);
+  g_hash_table_destroy(trwlayer->waypoints_iters);
   g_hash_table_destroy(trwlayer->tracks);
   g_hash_table_destroy(trwlayer->tracks);
+  g_hash_table_destroy(trwlayer->tracks_iters);
+  g_hash_table_destroy(trwlayer->routes);
+  g_hash_table_destroy(trwlayer->routes_iters);
 
   /* ODC: replace with GArray */
   trw_layer_free_track_gcs ( trwlayer );
 
   /* ODC: replace with GArray */
   trw_layer_free_track_gcs ( trwlayer );
@@ -1181,7 +1285,7 @@ static void trw_layer_free ( VikTrwLayer *trwlayer )
     g_object_ref_sink ( G_OBJECT(trwlayer->wp_right_click_menu) );
 
   if ( trwlayer->track_right_click_menu )
     g_object_ref_sink ( G_OBJECT(trwlayer->wp_right_click_menu) );
 
   if ( trwlayer->track_right_click_menu )
-    gtk_object_sink ( GTK_OBJECT(trwlayer->track_right_click_menu) );
+    g_object_ref_sink ( G_OBJECT(trwlayer->track_right_click_menu) );
 
   if ( trwlayer->wplabellayout != NULL)
     g_object_unref ( G_OBJECT ( trwlayer->wplabellayout ) );
 
   if ( trwlayer->wplabellayout != NULL)
     g_object_unref ( G_OBJECT ( trwlayer->wplabellayout ) );
@@ -1195,9 +1299,14 @@ static void trw_layer_free ( VikTrwLayer *trwlayer )
   if ( trwlayer->waypoint_bg_gc != NULL )
     g_object_unref ( G_OBJECT ( trwlayer->waypoint_bg_gc ) );
 
   if ( trwlayer->waypoint_bg_gc != NULL )
     g_object_unref ( G_OBJECT ( trwlayer->waypoint_bg_gc ) );
 
+  g_free ( trwlayer->wp_fsize_str );
+
   if ( trwlayer->tpwin != NULL )
     gtk_widget_destroy ( GTK_WIDGET(trwlayer->tpwin) );
 
   if ( trwlayer->tpwin != NULL )
     gtk_widget_destroy ( GTK_WIDGET(trwlayer->tpwin) );
 
+  if ( trwlayer->tracks_analysis_dialog != NULL )
+    gtk_widget_destroy ( GTK_WIDGET(trwlayer->tracks_analysis_dialog) );
+
   g_list_foreach ( trwlayer->image_cache->head, (GFunc) cached_pixbuf_free, NULL );
   g_queue_free ( trwlayer->image_cache );
 }
   g_list_foreach ( trwlayer->image_cache->head, (GFunc) cached_pixbuf_free, NULL );
   g_queue_free ( trwlayer->image_cache );
 }
@@ -1240,6 +1349,8 @@ static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, Vi
     dp->cn1 = bottomright.north_south;
     dp->cn2 = upperleft.north_south;
   }
     dp->cn1 = bottomright.north_south;
     dp->cn2 = upperleft.north_south;
   }
+
+  vik_viewport_get_min_max_lat_lon ( vp, &(dp->bbox.south), &(dp->bbox.north), &(dp->bbox.west), &(dp->bbox.east) );
 }
 
 /*
 }
 
 /*
@@ -1276,6 +1387,9 @@ static void draw_utm_skip_insignia ( VikViewport *vvp, GdkGC *gc, gint x, gint y
 
 static void trw_layer_draw_track ( const gpointer id, 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 )
 {
+  if ( ! track->visible )
+    return;
+
   /* TODO: this function is a mess, get rid of any redundancy */
   GList *list = track->trackpoints;
   GdkGC *main_gc;
   /* TODO: this function is a mess, get rid of any redundancy */
   GList *list = track->trackpoints;
   GdkGC *main_gc;
@@ -1297,9 +1411,6 @@ static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct Dr
       alt_diff = max_alt - min_alt;
   }
 
       alt_diff = max_alt - min_alt;
   }
 
-  if ( ! track->visible )
-    return;
-
   /* 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 ( id, track, dp, TRUE );
   /* 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 ( id, track, dp, TRUE );
@@ -1339,9 +1450,9 @@ static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct Dr
         main_gc = dp->vtl->track_1color_gc;
        break;
       default:
         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
         // 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;
       }
     }
         break;
       }
     }
@@ -1466,9 +1577,9 @@ static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct Dr
 
              GdkGC *tmp_gc;
              if ( ((oldx - x) > 0 && (oldy - y) > 0) || ((oldx - x) < 0 && (oldy - y) < 0))
 
              GdkGC *tmp_gc;
              if ( ((oldx - x) > 0 && (oldy - y) > 0) || ((oldx - x) < 0 && (oldy - y) < 0))
-               tmp_gc = GTK_WIDGET(dp->vp)->style->light_gc[3];
+               tmp_gc = gtk_widget_get_style(GTK_WIDGET(dp->vp))->light_gc[3];
              else
              else
-               tmp_gc = GTK_WIDGET(dp->vp)->style->dark_gc[0];
+               tmp_gc = gtk_widget_get_style(GTK_WIDGET(dp->vp))->dark_gc[0];
              vik_viewport_draw_polygon ( dp->vp, tmp_gc, TRUE, tmp, 4);
 
               vik_viewport_draw_line ( dp->vp, main_gc, oldx, oldy-FIXALTITUDE(list->data), x, y-FIXALTITUDE(list->next->data));
              vik_viewport_draw_polygon ( dp->vp, tmp_gc, TRUE, tmp, 4);
 
               vik_viewport_draw_line ( dp->vp, main_gc, oldx, oldy-FIXALTITUDE(list->data), x, y-FIXALTITUDE(list->next->data));
@@ -1538,10 +1649,11 @@ static void trw_layer_draw_track ( const gpointer id, 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 gpointer id, VikTrack *track, struct DrawingParams *dp )
 {
 static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp )
 {
-  trw_layer_draw_track ( id, track, dp, FALSE );
+  if ( BBOX_INTERSECT ( track->bbox, dp->bbox ) ) {
+    trw_layer_draw_track ( id, track, dp, FALSE );
+  }
 }
 
 static void cached_pixbuf_free ( CachedPixbuf *cp )
 }
 
 static void cached_pixbuf_free ( CachedPixbuf *cp )
@@ -1563,7 +1675,6 @@ static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct
              wp->coord.north_south > dp->cn1 && wp->coord.north_south < dp->cn2 ) )
   {
     gint x, y;
              wp->coord.north_south > dp->cn1 && wp->coord.north_south < dp->cn2 ) )
   {
     gint x, y;
-    GdkPixbuf *sym = NULL;
     vik_viewport_coord_to_screen ( dp->vp, &(wp->coord), &x, &y );
 
     /* if in shrunken_cache, get that. If not, get and add to shrunken_cache */
     vik_viewport_coord_to_screen ( dp->vp, &(wp->coord), &x, &y );
 
     /* if in shrunken_cache, get that. If not, get and add to shrunken_cache */
@@ -1647,9 +1758,9 @@ static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct
       }
     }
 
       }
     }
 
-    /* DRAW ACTUAL DOT */
-    if ( dp->vtl->wp_draw_symbols && wp->symbol && (sym = a_get_wp_sym(wp->symbol)) ) {
-      vik_viewport_draw_pixbuf ( dp->vp, sym, 0, 0, x - gdk_pixbuf_get_width(sym)/2, y - gdk_pixbuf_get_height(sym)/2, -1, -1 );
+    // Draw appropriate symbol - either symbol image or simple types
+    if ( dp->vtl->wp_draw_symbols && wp->symbol && wp->symbol_pixbuf ) {
+      vik_viewport_draw_pixbuf ( dp->vp, wp->symbol_pixbuf, 0, 0, x - gdk_pixbuf_get_width(wp->symbol_pixbuf)/2, y - gdk_pixbuf_get_height(wp->symbol_pixbuf)/2, -1, -1 );
     } 
     else if ( wp == dp->vtl->current_wp ) {
       switch ( dp->vtl->wp_symbol ) {
     } 
     else if ( wp == dp->vtl->current_wp ) {
       switch ( dp->vtl->wp_symbol ) {
@@ -1678,18 +1789,7 @@ static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct
       // Hopefully name won't break the markup (may need to sanitize - g_markup_escape_text())
 
       // Could this stored in the waypoint rather than recreating each pass?
       // Hopefully name won't break the markup (may need to sanitize - g_markup_escape_text())
 
       // Could this stored in the waypoint rather than recreating each pass?
-      gchar *fsize = NULL;
-      switch (dp->vtl->wp_font_size) {
-        case FS_XX_SMALL: fsize = g_strdup ( "xx-small" ); break;
-        case FS_X_SMALL: fsize = g_strdup ( "x-small" ); break;
-        case FS_SMALL: fsize = g_strdup ( "small" ); break;
-        case FS_LARGE: fsize = g_strdup ( "large" ); break;
-        case FS_X_LARGE: fsize = g_strdup ( "x-large" ); break;
-        case FS_XX_LARGE: fsize = g_strdup ( "xx-large" ); break;
-        default: fsize = g_strdup ( "medium" ); break;
-      }
-
-      gchar *wp_label_markup = g_strdup_printf ( "<span size=\"%s\">%s</span>", fsize, wp->name );
+      gchar *wp_label_markup = g_strdup_printf ( "<span size=\"%s\">%s</span>", dp->vtl->wp_fsize_str, wp->name );
 
       if ( pango_parse_markup ( wp_label_markup, -1, 0, NULL, NULL, NULL, NULL ) )
         pango_layout_set_markup ( dp->vtl->wplabellayout, wp_label_markup, -1 );
 
       if ( pango_parse_markup ( wp_label_markup, -1, 0, NULL, NULL, NULL, NULL ) )
         pango_layout_set_markup ( dp->vtl->wplabellayout, wp_label_markup, -1 );
@@ -1698,12 +1798,11 @@ static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct
         pango_layout_set_text ( dp->vtl->wplabellayout, wp->name, -1 );
 
       g_free ( wp_label_markup );
         pango_layout_set_text ( dp->vtl->wplabellayout, wp->name, -1 );
 
       g_free ( wp_label_markup );
-      g_free ( fsize );
 
       pango_layout_get_pixel_size ( dp->vtl->wplabellayout, &width, &height );
       label_x = x - width/2;
 
       pango_layout_get_pixel_size ( dp->vtl->wplabellayout, &width, &height );
       label_x = x - width/2;
-      if (sym)
-        label_y = y - height - 2 - gdk_pixbuf_get_height(sym)/2;
+      if ( wp->symbol_pixbuf )
+        label_y = y - height - 2 - gdk_pixbuf_get_height(wp->symbol_pixbuf)/2;
       else
         label_y = y - dp->vtl->wp_size - height - 2;
 
       else
         label_y = y - dp->vtl->wp_size - height - 2;
 
@@ -1724,6 +1823,13 @@ static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct
   }
 }
 
   }
 }
 
+static void trw_layer_draw_waypoint_cb ( gpointer id, VikWaypoint *wp, struct DrawingParams *dp )
+{
+  if ( BBOX_INTERSECT ( dp->vtl->waypoints_bbox, dp->bbox ) ) {
+    trw_layer_draw_waypoint ( id, wp, dp );
+  }
+}
+
 static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
 {
   static struct DrawingParams dp;
 static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
 {
   static struct DrawingParams dp;
@@ -1738,7 +1844,7 @@ static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
     g_hash_table_foreach ( l->routes, (GHFunc) trw_layer_draw_track_cb, &dp );
 
   if (l->waypoints_visible)
     g_hash_table_foreach ( l->routes, (GHFunc) trw_layer_draw_track_cb, &dp );
 
   if (l->waypoints_visible)
-    g_hash_table_foreach ( l->waypoints, (GHFunc) trw_layer_draw_waypoint, &dp );
+    g_hash_table_foreach ( l->waypoints, (GHFunc) trw_layer_draw_waypoint_cb, &dp );
 }
 
 static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
 }
 
 static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
@@ -1783,7 +1889,7 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp )
 
   if ( vtl->track_bg_gc )
     g_object_unref ( vtl->track_bg_gc );
 
   if ( vtl->track_bg_gc )
     g_object_unref ( vtl->track_bg_gc );
-  vtl->track_bg_gc = vik_viewport_new_gc ( vp, "#FFFFFF", width + vtl->bg_line_thickness );
+  vtl->track_bg_gc = vik_viewport_new_gc_from_color ( vp, &(vtl->track_bg_color), width + vtl->bg_line_thickness );
 
   // Ensure new track drawing heeds line thickness setting
   //  however always have a minium of 2, as 1 pixel is really narrow
 
   // Ensure new track drawing heeds line thickness setting
   //  however always have a minium of 2, as 1 pixel is really narrow
@@ -1809,34 +1915,30 @@ 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_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 );
 }
 
 static VikTrwLayer* trw_layer_create ( VikViewport *vp )
 {
   g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC );
 }
 
 static VikTrwLayer* trw_layer_create ( VikViewport *vp )
 {
-  VikTrwLayer *rv = trw_layer_new ( DRAWMODE_BY_TRACK );
+  VikTrwLayer *rv = trw_layer_new1 ( vp );
   vik_layer_rename ( VIK_LAYER(rv), vik_trw_layer_interface.name );
 
   vik_layer_rename ( VIK_LAYER(rv), vik_trw_layer_interface.name );
 
-  if ( vp == NULL || GTK_WIDGET(vp)->window == NULL ) {
+  if ( vp == NULL || gtk_widget_get_window(GTK_WIDGET(vp)) == NULL ) {
     /* early exit, as the rest is GUI related */
     return rv;
   }
 
   rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
     /* early exit, as the rest is GUI related */
     return rv;
   }
 
   rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
-  pango_layout_set_font_description (rv->wplabellayout, GTK_WIDGET(vp)->style->font_desc);
+  pango_layout_set_font_description (rv->wplabellayout, gtk_widget_get_style(GTK_WIDGET(vp))->font_desc);
 
   trw_layer_new_track_gcs ( rv, vp );
 
 
   trw_layer_new_track_gcs ( rv, vp );
 
-  rv->waypoint_gc = vik_viewport_new_gc ( vp, "#000000", 2 );
-  rv->waypoint_text_gc = vik_viewport_new_gc ( vp, "#FFFFFF", 1 );
-  rv->waypoint_bg_gc = vik_viewport_new_gc ( vp, "#8383C4", 1 );
-  gdk_gc_set_function ( rv->waypoint_bg_gc, GDK_AND );
-
-  rv->has_verified_thumbnails = FALSE;
-  rv->wp_symbol = WP_SYMBOL_FILLED_SQUARE;
-  rv->wp_size = 4;
-  rv->wp_draw_symbols = TRUE;
-  rv->wp_font_size = FS_MEDIUM;
+  rv->waypoint_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_color), 2 );
+  rv->waypoint_text_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_text_color), 1 );
+  rv->waypoint_bg_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_bg_color), 1 );
+  gdk_gc_set_function ( rv->waypoint_bg_gc, rv->wpbgand );
 
   rv->coord_mode = vik_viewport_get_coord_mode ( vp );
 
 
   rv->coord_mode = vik_viewport_get_coord_mode ( vp );
 
@@ -1877,11 +1979,7 @@ static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pas
     gdk_pixbuf_fill ( pixbuf, pixel );
   }
 
     gdk_pixbuf_fill ( pixbuf, pixel );
   }
 
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-  vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
-#else
   vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
   vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
-#endif
 
   if ( pixbuf )
     g_object_unref (pixbuf);
 
   if ( pixbuf )
     g_object_unref (pixbuf);
@@ -1900,11 +1998,7 @@ static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-  vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#else
   vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_UINT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
   vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_UINT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#endif
 
   *new_iter = *((GtkTreeIter *) pass_along[1]);
   g_hash_table_insert ( VIK_TRW_LAYER(pass_along[2])->waypoints_iters, id, new_iter );
 
   *new_iter = *((GtkTreeIter *) pass_along[1]);
   g_hash_table_insert ( VIK_TRW_LAYER(pass_along[2])->waypoints_iters, id, new_iter );
@@ -1915,29 +2009,17 @@ static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer
 
 static void trw_layer_add_sublayer_tracks ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
 
 static void trw_layer_add_sublayer_tracks ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-  vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->tracks_iter), _("Tracks"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_TRACKS, NULL, TRUE, FALSE );
-#else
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->tracks_iter), _("Tracks"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_TRACKS, NULL, TRUE, FALSE );
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->tracks_iter), _("Tracks"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_TRACKS, NULL, TRUE, FALSE );
-#endif
 }
 
 static void trw_layer_add_sublayer_waypoints ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
 }
 
 static void trw_layer_add_sublayer_waypoints ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-  vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->waypoints_iter), _("Waypoints"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, NULL, TRUE, FALSE );
-#else
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->waypoints_iter), _("Waypoints"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, NULL, TRUE, FALSE );
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->waypoints_iter), _("Waypoints"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, NULL, TRUE, FALSE );
-#endif
 }
 
 static void trw_layer_add_sublayer_routes ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
 }
 
 static void trw_layer_add_sublayer_routes ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 {
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-  vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->routes_iter), _("Routes"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_ROUTES, NULL, TRUE, FALSE );
-#else
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->routes_iter), _("Routes"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_ROUTES, NULL, TRUE, FALSE );
   vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->routes_iter), _("Routes"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_ROUTES, NULL, TRUE, FALSE );
-#endif
 }
 
 static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
 }
 
 static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
@@ -1947,13 +2029,13 @@ static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *
 
   if ( g_hash_table_size (vtl->tracks) > 0 ) {
     trw_layer_add_sublayer_tracks ( vtl, vt , layer_iter );
 
   if ( g_hash_table_size (vtl->tracks) > 0 ) {
     trw_layer_add_sublayer_tracks ( vtl, vt , layer_iter );
+
     g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_realize_track, pass_along );
 
     g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_realize_track, pass_along );
 
-    vik_treeview_item_set_visible ( (VikTreeview *) vt, &(vtl->tracks_iter), vtl->tracks_visible );
+    vik_treeview_item_set_visible ( vt, &(vtl->tracks_iter), vtl->tracks_visible );
   }
 
   if ( g_hash_table_size (vtl->routes) > 0 ) {
   }
 
   if ( g_hash_table_size (vtl->routes) > 0 ) {
-
     trw_layer_add_sublayer_routes ( vtl, vt, layer_iter );
 
     pass_along[0] = &(vtl->routes_iter);
     trw_layer_add_sublayer_routes ( vtl, vt, layer_iter );
 
     pass_along[0] = &(vtl->routes_iter);
@@ -2232,8 +2314,12 @@ static const gchar* trw_layer_sublayer_tooltip ( VikTrwLayer *l, gint subtype, g
     {
       VikWaypoint *w = g_hash_table_lookup ( l->waypoints, sublayer );
       // NB It's OK to return NULL
     {
       VikWaypoint *w = g_hash_table_lookup ( l->waypoints, sublayer );
       // NB It's OK to return NULL
-      if ( w )
-        return w->comment;
+      if ( w ) {
+        if ( w->comment )
+          return w->comment;
+        else
+          return w->description;
+      }
     }
     break;
     default: break;
     }
     break;
     default: break;
@@ -2432,6 +2518,28 @@ GHashTable *vik_trw_layer_get_waypoints ( VikTrwLayer *l )
   return l->waypoints;
 }
 
   return l->waypoints;
 }
 
+gboolean vik_trw_layer_is_empty ( VikTrwLayer *vtl )
+{
+  return ! ( g_hash_table_size ( vtl->tracks ) ||
+             g_hash_table_size ( vtl->routes ) ||
+             g_hash_table_size ( vtl->waypoints ) );
+}
+
+gboolean vik_trw_layer_get_tracks_visibility ( VikTrwLayer *vtl )
+{
+  return vtl->tracks_visible;
+}
+
+gboolean vik_trw_layer_get_routes_visibility ( VikTrwLayer *vtl )
+{
+  return vtl->routes_visible;
+}
+
+gboolean vik_trw_layer_get_waypoints_visibility ( VikTrwLayer *vtl )
+{
+  return vtl->waypoints_visible;
+}
+
 /*
  * ATM use a case sensitive find
  * Finds the first one
 /*
  * ATM use a case sensitive find
  * Finds the first one
@@ -2483,44 +2591,26 @@ 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 );
 }
 
   return g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find, (gpointer) name );
 }
 
-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 );
-  if ( VIK_LATLON(&fixme)->lat > maxmin[0].lat || maxmin[0].lat == 0.0 )
-    maxmin[0].lat = VIK_LATLON(&fixme)->lat;
-  if ( VIK_LATLON(&fixme)->lat < maxmin[1].lat || maxmin[1].lat == 0.0 )
-    maxmin[1].lat = VIK_LATLON(&fixme)->lat;
-  if ( VIK_LATLON(&fixme)->lon > maxmin[0].lon || maxmin[0].lon == 0.0 )
-    maxmin[0].lon = VIK_LATLON(&fixme)->lon;
-  if ( VIK_LATLON(&fixme)->lon < maxmin[1].lon || maxmin[1].lon == 0.0 )
-    maxmin[1].lon = VIK_LATLON(&fixme)->lon;
-}
-
 static void trw_layer_find_maxmin_tracks ( const gpointer id, 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;
-
-  while ( tr )
-  {
-    vik_coord_copy_convert ( &(VIK_TRACKPOINT(tr->data)->coord), VIK_COORD_LATLON, &fixme );
-    if ( VIK_LATLON(&fixme)->lat > maxmin[0].lat || maxmin[0].lat == 0.0 )
-      maxmin[0].lat = VIK_LATLON(&fixme)->lat;
-    if ( VIK_LATLON(&fixme)->lat < maxmin[1].lat || maxmin[1].lat == 0.0 )
-      maxmin[1].lat = VIK_LATLON(&fixme)->lat;
-    if ( VIK_LATLON(&fixme)->lon > maxmin[0].lon || maxmin[0].lon == 0.0 )
-      maxmin[0].lon = VIK_LATLON(&fixme)->lon;
-    if ( VIK_LATLON(&fixme)->lon < maxmin[1].lon || maxmin[1].lon == 0.0 )
-      maxmin[1].lon = VIK_LATLON(&fixme)->lon;
-    tr = tr->next;
-  }
+  if ( trk->bbox.north > maxmin[0].lat || maxmin[0].lat == 0.0 )
+    maxmin[0].lat = trk->bbox.north;
+  if ( trk->bbox.south < maxmin[1].lat || maxmin[1].lat == 0.0 )
+    maxmin[1].lat = trk->bbox.south;
+  if ( trk->bbox.east > maxmin[0].lon || maxmin[0].lon == 0.0 )
+    maxmin[0].lon = trk->bbox.east;
+  if ( trk->bbox.west < maxmin[1].lon || maxmin[1].lon == 0.0 )
+    maxmin[1].lon = trk->bbox.west;
 }
 
 static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2])
 {
   // Continually reuse maxmin to find the latest maximum and minimum values
 }
 
 static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2])
 {
   // Continually reuse maxmin to find the latest maximum and minimum values
-  g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_find_maxmin_waypoints, maxmin );
+  // First set to waypoints bounds
+  maxmin[0].lat = vtl->waypoints_bbox.north;
+  maxmin[1].lat = vtl->waypoints_bbox.south;
+  maxmin[0].lon = vtl->waypoints_bbox.east;
+  maxmin[1].lon = vtl->waypoints_bbox.west;
   g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
   g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
 }
   g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
   g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
 }
@@ -2631,6 +2721,12 @@ static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, co
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                               NULL);
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                               NULL);
+  gchar *cwd = g_get_current_dir();
+  if ( cwd ) {
+    gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(file_selector), cwd );
+    g_free ( cwd );
+  }
+
   gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(file_selector), default_name);
 
   while ( gtk_dialog_run ( GTK_DIALOG(file_selector) ) == GTK_RESPONSE_ACCEPT )
   gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(file_selector), default_name);
 
   while ( gtk_dialog_run ( GTK_DIALOG(file_selector) ) == GTK_RESPONSE_ACCEPT )
@@ -2639,7 +2735,9 @@ static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, co
     if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE )
     {
       gtk_widget_hide ( file_selector );
     if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE )
     {
       gtk_widget_hide ( file_selector );
+      vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
       failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
       failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
+      vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
       break;
     }
     else
       break;
     }
     else
@@ -2647,7 +2745,9 @@ static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, co
       if ( a_dialog_yes_or_no ( GTK_WINDOW(file_selector), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
       {
         gtk_widget_hide ( file_selector );
       if ( a_dialog_yes_or_no ( GTK_WINDOW(file_selector), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
       {
         gtk_widget_hide ( file_selector );
+        vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
        failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
        failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
+        vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
         break;
       }
     }
         break;
       }
     }
@@ -2701,7 +2801,9 @@ static void trw_layer_export_external_gpx ( gpointer layer_and_vlp[2], const gch
   int fd;
 
   if ((fd = g_file_open_tmp("tmp-viking.XXXXXX.gpx", &name_used, NULL)) >= 0) {
   int fd;
 
   if ((fd = g_file_open_tmp("tmp-viking.XXXXXX.gpx", &name_used, NULL)) >= 0) {
+    vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
     gboolean failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), name_used, FILE_TYPE_GPX, NULL, TRUE);
     gboolean failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), name_used, FILE_TYPE_GPX, NULL, TRUE);
+    vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
     if (failed) {
       a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("Could not create temporary file for export.") );
     }
     if (failed) {
       a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("Could not create temporary file for export.") );
     }
@@ -2791,8 +2893,8 @@ static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] )
   label = gtk_label_new(_("Waypoint Name:"));
   entry = gtk_entry_new();
 
   label = gtk_label_new(_("Waypoint Name:"));
   entry = gtk_entry_new();
 
-  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dia)->vbox), label, FALSE, FALSE, 0);
-  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dia)->vbox), entry, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dia))), label, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dia))), entry, FALSE, FALSE, 0);
   gtk_widget_show_all ( label );
   gtk_widget_show_all ( entry );
 
   gtk_widget_show_all ( label );
   gtk_widget_show_all ( entry );
 
@@ -2846,7 +2948,7 @@ gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikC
   if ( elev != VIK_DEM_INVALID_ELEVATION )
     wp->altitude = (gdouble)elev;
 
   if ( elev != VIK_DEM_INVALID_ELEVATION )
     wp->altitude = (gdouble)elev;
 
-  returned_name = a_dialog_waypoint ( w, default_name, wp, vtl->coord_mode, TRUE, &updated );
+  returned_name = a_dialog_waypoint ( w, default_name, vtl, wp, vtl->coord_mode, TRUE, &updated );
 
   if ( returned_name )
   {
 
   if ( returned_name )
   {
@@ -2872,6 +2974,7 @@ static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] )
   // 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);
   // 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);
+  trw_layer_calculate_bounds_waypoints ( vtl );
   vik_layers_panel_emit_update ( vlp );
 }
 
   vik_layers_panel_emit_update ( vlp );
 }
 
@@ -2883,6 +2986,7 @@ static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] )
   
   trw_layer_find_maxmin (vtl, maxmin);
   a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
   
   trw_layer_find_maxmin (vtl, maxmin);
   a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+  trw_layer_calculate_bounds_waypoints ( vtl );
   vik_layers_panel_emit_update ( vlp );
 }
 
   vik_layers_panel_emit_update ( vlp );
 }
 
@@ -2945,23 +3049,21 @@ static void trw_layer_acquire_gps_cb ( gpointer lav[2] )
   VikViewport *vvp =  vik_window_viewport(vw);
 
   vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
   VikViewport *vvp =  vik_window_viewport(vw);
 
   vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
-  a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface, NULL, NULL );
 }
 
 }
 
-#ifdef VIK_CONFIG_GOOGLE
 /*
 /*
- * Acquire into this TRW Layer from Google Directions
+ * Acquire into this TRW Layer from Directions
  */
  */
-static void trw_layer_acquire_google_cb ( gpointer lav[2] )
+static void trw_layer_acquire_routing_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);
 
 {
   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_google_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_routing_interface, NULL, NULL );
 }
 }
-#endif
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
 /*
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
 /*
@@ -2974,7 +3076,7 @@ static void trw_layer_acquire_osm_cb ( gpointer lav[2] )
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
-  a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface, NULL, NULL );
 }
 
 /**
 }
 
 /**
@@ -2987,7 +3089,7 @@ static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] )
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
   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 );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface, NULL, NULL );
 }
 #endif
 
 }
 #endif
 
@@ -3002,7 +3104,7 @@ static void trw_layer_acquire_geocache_cb ( gpointer lav[2] )
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
-  a_acquire ( vw, vlp, vvp, &vik_datasource_gc_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_gc_interface, NULL, NULL );
 }
 #endif
 
 }
 #endif
 
@@ -3018,7 +3120,7 @@ static void trw_layer_acquire_geotagged_cb ( gpointer lav[2] )
   VikViewport *vvp =  vik_window_viewport(vw);
 
   vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
   VikViewport *vvp =  vik_window_viewport(vw);
 
   vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
-  a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface, NULL, NULL );
 
   // Reverify thumbnails as they may have changed
   vtl->has_verified_thumbnails = FALSE;
 
   // Reverify thumbnails as they may have changed
   vtl->has_verified_thumbnails = FALSE;
@@ -3144,7 +3246,7 @@ static void trw_layer_acquire_file_cb ( gpointer lav[2] )
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
   VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
   VikViewport *vvp =  vik_window_viewport(vw);
 
-  a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface );
+  a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface, NULL, NULL );
 }
 
 static void trw_layer_new_wp ( gpointer lav[2] )
 }
 
 static void trw_layer_new_wp ( gpointer lav[2] )
@@ -3153,8 +3255,23 @@ static void trw_layer_new_wp ( gpointer lav[2] )
   VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
   /* TODO longone: okay, if layer above (aggregate) is invisible but vtl->visible is true, this redraws for no reason.
      instead return true if you want to update. */
   VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
   /* TODO longone: okay, if layer above (aggregate) is invisible but vtl->visible is true, this redraws for no reason.
      instead return true if you want to update. */
-  if ( vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), vik_viewport_get_center(vik_layers_panel_get_viewport(vlp))) && VIK_LAYER(vtl)->visible )
+  if ( vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), vik_viewport_get_center(vik_layers_panel_get_viewport(vlp))) && VIK_LAYER(vtl)->visible ) {
+    trw_layer_calculate_bounds_waypoints ( vtl );
     vik_layers_panel_emit_update ( vlp );
     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] )
 }
 
 static void trw_layer_new_track ( gpointer lav[2] )
@@ -3163,9 +3280,8 @@ static void trw_layer_new_track ( gpointer lav[2] )
 
   if ( ! vtl->current_track ) {
     gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")) ;
 
   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 );
+    g_free ( name );
 
     vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
   }
 
     vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
   }
@@ -3189,6 +3305,7 @@ static void trw_layer_new_route ( gpointer lav[2] )
   if ( ! vtl->current_track ) {
     gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route")) ;
     new_route_create_common ( vtl, name );
   if ( ! vtl->current_track ) {
     gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route")) ;
     new_route_create_common ( vtl, name );
+    g_free ( name );
     vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_ROUTE );
   }
 }
     vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_ROUTE );
   }
 }
@@ -3247,7 +3364,10 @@ static void trw_layer_auto_waypoints_view ( gpointer lav[2] )
   else if ( g_hash_table_size (vtl->waypoints) > 1 )
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
   else if ( g_hash_table_size (vtl->waypoints) > 1 )
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
-    g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_find_maxmin_waypoints, maxmin );
+    maxmin[0].lat = vtl->waypoints_bbox.north;
+    maxmin[1].lat = vtl->waypoints_bbox.south;
+    maxmin[0].lon = vtl->waypoints_bbox.east;
+    maxmin[1].lon = vtl->waypoints_bbox.west;
     trw_layer_zoom_to_show_latlons ( vtl, vik_layers_panel_get_viewport (vlp), maxmin );
   }
 
     trw_layer_zoom_to_show_latlons ( vtl, vik_layers_panel_get_viewport (vlp), maxmin );
   }
 
@@ -3410,12 +3530,11 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
 
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
 
-#ifdef VIK_CONFIG_GOOGLE
-  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 );
+  /* FIXME: only add menu when at least a routing engine has support for Directions */
+  item = gtk_menu_item_new_with_mnemonic ( _("From _Directions...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_routing_cb), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
-#endif
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
   item = gtk_menu_item_new_with_mnemonic ( _("From _OSM Traces...") );
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
   item = gtk_menu_item_new_with_mnemonic ( _("From _OSM Traces...") );
@@ -3469,6 +3588,8 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
 
   gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
   gtk_widget_show ( item );
 
+  vik_ext_tool_datasources_add_menu_items_to_menu ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), GTK_MENU (acquire_submenu) );
+
   GtkWidget *upload_submenu = gtk_menu_new ();
   item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload") );
   gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
   GtkWidget *upload_submenu = gtk_menu_new ();
   item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload") );
   gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
@@ -3567,15 +3688,15 @@ void vik_trw_layer_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
 
     // Visibility column always needed for waypoints
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
 
     // Visibility column always needed for waypoints
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#else
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#endif
+
     // Actual setting of visibility dependent on the waypoint
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
 
     g_hash_table_insert ( vtl->waypoints_iters, GUINT_TO_POINTER(wp_uuid), iter );
     // Actual setting of visibility dependent on the waypoint
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
 
     g_hash_table_insert ( vtl->waypoints_iters, GUINT_TO_POINTER(wp_uuid), iter );
+
+    // Sort now as post_read is not called on a realized waypoint
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
   }
 
   highest_wp_number_add_wp(vtl, name);
   }
 
   highest_wp_number_add_wp(vtl, name);
@@ -3601,15 +3722,15 @@ void vik_trw_layer_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t )
 
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
     // Visibility column always needed for tracks
 
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
     // Visibility column always needed for tracks
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), iter, name, vtl, GUINT_TO_POINTER(tr_uuid), VIK_TRW_LAYER_SUBLAYER_TRACK, NULL, TRUE, TRUE );
-#else
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), iter, name, vtl, GUINT_TO_POINTER(tr_uuid), VIK_TRW_LAYER_SUBLAYER_TRACK, NULL, TRUE, TRUE );
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), iter, name, vtl, GUINT_TO_POINTER(tr_uuid), VIK_TRW_LAYER_SUBLAYER_TRACK, NULL, TRUE, TRUE );
-#endif
+
     // Actual setting of visibility dependent on the track
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
 
     g_hash_table_insert ( vtl->tracks_iters, GUINT_TO_POINTER(tr_uuid), iter );
     // Actual setting of visibility dependent on the track
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
 
     g_hash_table_insert ( vtl->tracks_iters, GUINT_TO_POINTER(tr_uuid), iter );
+
+    // Sort now as post_read is not called on a realized track
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->track_sort_order );
   }
 
   g_hash_table_insert ( vtl->tracks, GUINT_TO_POINTER(tr_uuid), t );
   }
 
   g_hash_table_insert ( vtl->tracks, GUINT_TO_POINTER(tr_uuid), t );
@@ -3634,16 +3755,15 @@ void vik_trw_layer_add_route ( VikTrwLayer *vtl, gchar *name, VikTrack *t )
     }
 
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
     }
 
     GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
-    // Visibility column always needed for tracks
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), iter, name, vtl, GUINT_TO_POINTER(rt_uuid), VIK_TRW_LAYER_SUBLAYER_ROUTE, NULL, TRUE, TRUE );
-#else
+    // Visibility column always needed for routes
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), iter, name, vtl, GUINT_TO_POINTER(rt_uuid), VIK_TRW_LAYER_SUBLAYER_ROUTE, NULL, TRUE, TRUE );
     vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), iter, name, vtl, GUINT_TO_POINTER(rt_uuid), VIK_TRW_LAYER_SUBLAYER_ROUTE, NULL, TRUE, TRUE );
-#endif
-    // Actual setting of visibility dependent on the track
+    // Actual setting of visibility dependent on the route
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
 
     g_hash_table_insert ( vtl->routes_iters, GUINT_TO_POINTER(rt_uuid), iter );
     vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
 
     g_hash_table_insert ( vtl->routes_iters, GUINT_TO_POINTER(rt_uuid), iter );
+
+    // Sort now as post_read is not called on a realized route
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->track_sort_order );
   }
 
   g_hash_table_insert ( vtl->routes, GUINT_TO_POINTER(rt_uuid), t );
   }
 
   g_hash_table_insert ( vtl->routes, GUINT_TO_POINTER(rt_uuid), t );
@@ -3658,6 +3778,32 @@ void trw_layer_cancel_tps_of_track ( VikTrwLayer *vtl, VikTrack *trk )
     trw_layer_cancel_current_tp ( vtl, FALSE );
 }
 
     trw_layer_cancel_current_tp ( vtl, FALSE );
 }
 
+/**
+ * Normally this is done to due the waypoint size preference having changed
+ */
+void vik_trw_layer_reset_waypoints ( VikTrwLayer *vtl )
+{
+  GHashTableIter iter;
+  gpointer key, value;
+
+  // Foreach waypoint
+  g_hash_table_iter_init ( &iter, vtl->waypoints );
+  while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
+    VikWaypoint *wp = VIK_WAYPOINT(value);
+    if ( wp->symbol ) {
+      // Reapply symbol setting to update the pixbuf
+      gchar *tmp_symbol = g_strdup ( wp->symbol );
+      vik_waypoint_set_symbol ( wp, tmp_symbol );
+      g_free ( tmp_symbol );
+    }
+  }
+}
+
+/**
+ * trw_layer_new_unique_sublayer_name:
+ *
+ * Allocates a unique new name
+ */
 gchar *trw_layer_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name)
 {
   gint i = 2;
 gchar *trw_layer_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name)
 {
   gint i = 2;
@@ -3728,34 +3874,58 @@ static void trw_layer_enum_item ( gpointer id, GList **tr, GList **l )
  */
 static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, gpointer id, gint type )
 {
  */
 static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, gpointer id, gint type )
 {
+  // TODO reconsider strategy when moving within layer (if anything...)
+  gboolean rename = ( vtl_src != vtl_dest );
+  if ( ! rename )
+    return;
+
   if (type == VIK_TRW_LAYER_SUBLAYER_TRACK) {
     VikTrack *trk = g_hash_table_lookup ( vtl_src->tracks, id );
 
   if (type == VIK_TRW_LAYER_SUBLAYER_TRACK) {
     VikTrack *trk = g_hash_table_lookup ( vtl_src->tracks, id );
 
-    gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
+    gchar *newname;
+    if ( rename )
+      newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, trk->name );
+    else
+      newname = g_strdup ( trk->name );
 
     VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_track ( vtl_dest, newname, trk2 );
 
     VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_track ( vtl_dest, newname, trk2 );
+    g_free ( newname );
     vik_trw_layer_delete_track ( vtl_src, trk );
   }
 
   if (type == VIK_TRW_LAYER_SUBLAYER_ROUTE) {
     VikTrack *trk = g_hash_table_lookup ( vtl_src->routes, id );
 
     vik_trw_layer_delete_track ( vtl_src, trk );
   }
 
   if (type == VIK_TRW_LAYER_SUBLAYER_ROUTE) {
     VikTrack *trk = g_hash_table_lookup ( vtl_src->routes, id );
 
-    gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
+    gchar *newname;
+    if ( rename )
+      newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, trk->name );
+    else
+      newname = g_strdup ( trk->name );
 
     VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_route ( vtl_dest, newname, trk2 );
 
     VikTrack *trk2 = vik_track_copy ( trk, TRUE );
     vik_trw_layer_add_route ( vtl_dest, newname, trk2 );
+    g_free ( newname );
     vik_trw_layer_delete_route ( vtl_src, trk );
   }
 
   if (type == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) {
     VikWaypoint *wp = g_hash_table_lookup ( vtl_src->waypoints, id );
 
     vik_trw_layer_delete_route ( vtl_src, trk );
   }
 
   if (type == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) {
     VikWaypoint *wp = g_hash_table_lookup ( vtl_src->waypoints, id );
 
-    gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, wp->name);
+    gchar *newname;
+    if ( rename )
+      newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, wp->name );
+    else
+      newname = g_strdup ( wp->name );
 
     VikWaypoint *wp2 = vik_waypoint_copy ( wp );
     vik_trw_layer_add_waypoint ( vtl_dest, newname, wp2 );
 
     VikWaypoint *wp2 = vik_waypoint_copy ( wp );
     vik_trw_layer_add_waypoint ( vtl_dest, newname, wp2 );
+    g_free ( newname );
     trw_layer_delete_waypoint ( vtl_src, wp );
     trw_layer_delete_waypoint ( vtl_src, wp );
+
+    // Recalculate bounds even if not renamed as maybe dragged between layers
+    trw_layer_calculate_bounds_waypoints ( vtl_dest );
+    trw_layer_calculate_bounds_waypoints ( vtl_src );
   }
 }
 
   }
 }
 
@@ -3782,8 +3952,7 @@ static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl
     while (iter) {
       if (type==VIK_TRW_LAYER_SUBLAYER_TRACKS) {
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_TRACK);
     while (iter) {
       if (type==VIK_TRW_LAYER_SUBLAYER_TRACKS) {
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_TRACK);
-      }
-      else if (type==VIK_TRW_LAYER_SUBLAYER_ROUTES) {
+      } else if (type==VIK_TRW_LAYER_SUBLAYER_ROUTES) {
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_ROUTE);
       } else {
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_WAYPOINT);
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_ROUTE);
       } else {
         trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_WAYPOINT);
@@ -4173,6 +4342,30 @@ static void trw_layer_delete_item ( gpointer pass_along[6] )
     vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
     vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
+/**
+ *  Rename waypoint and maintain corresponding name of waypoint in the treeview
+ */
+static void trw_layer_waypoint_rename ( VikTrwLayer *vtl, VikWaypoint *wp, const gchar *new_name )
+{
+  vik_waypoint_set_name ( wp, new_name );
+
+  // Now update the treeview as well
+  wpu_udata udataU;
+  udataU.wp   = wp;
+  udataU.uuid = NULL;
+
+  // Need key of it for treeview update
+  gpointer *wpf = g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, &udataU );
+
+  if ( wpf && udataU.uuid ) {
+    GtkTreeIter *it = g_hash_table_lookup ( vtl->waypoints_iters, udataU.uuid );
+
+    if ( it ) {
+      vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, new_name );
+      vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
+    }
+  }
+}
 
 static void trw_layer_properties_item ( gpointer pass_along[7] )
 {
 
 static void trw_layer_properties_item ( gpointer pass_along[7] )
 {
@@ -4184,9 +4377,11 @@ static void trw_layer_properties_item ( gpointer pass_along[7] )
     if ( wp && wp->name )
     {
       gboolean updated = FALSE;
     if ( wp && wp->name )
     {
       gboolean updated = FALSE;
-      a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, wp, vtl->coord_mode, FALSE, &updated );
+      gchar *new_name = a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, vtl, wp, vtl->coord_mode, FALSE, &updated );
+      if ( new_name )
+        trw_layer_waypoint_rename ( vtl, wp, new_name );
 
 
-      if ( updated && wp->symbol && pass_along[6] )
+      if ( updated && 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_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, pass_along[6], get_wp_sym_small (wp->symbol) );
 
       if ( updated && VIK_LAYER(vtl)->visible )
@@ -4375,7 +4570,6 @@ static void trw_layer_extend_track_end ( gpointer pass_along[6] )
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
 }
 
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
 }
 
-#ifdef VIK_CONFIG_GOOGLE
 /**
  * extend a track using route finder
  */
 /**
  * extend a track using route finder
  */
@@ -4396,7 +4590,6 @@ static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] )
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
 
 }
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
 
 }
-#endif
 
 static void trw_layer_apply_dem_data ( gpointer pass_along[6] )
 {
 
 static void trw_layer_apply_dem_data ( gpointer pass_along[6] )
 {
@@ -4491,7 +4684,7 @@ static void trw_layer_goto_track_min_alt ( gpointer pass_along[6] )
  */
 static void trw_layer_auto_track_view ( gpointer pass_along[6] )
 {
  */
 static void trw_layer_auto_track_view ( gpointer pass_along[6] )
 {
-  VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+  VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   VikTrack *trk;
   if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
     trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
   VikTrack *trk;
   if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
     trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
@@ -4502,11 +4695,11 @@ static void trw_layer_auto_track_view ( gpointer pass_along[6] )
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
     trw_layer_find_maxmin_tracks ( NULL, trk, maxmin );
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
     trw_layer_find_maxmin_tracks ( NULL, trk, maxmin );
-    trw_layer_zoom_to_show_latlons ( VIK_TRW_LAYER(pass_along[0]), pass_along[5], maxmin );
+    trw_layer_zoom_to_show_latlons ( vtl, pass_along[5], maxmin );
     if ( pass_along[1] )
       vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) );
     else
     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]) );
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
   }
 }
 
   }
 }
 
@@ -4720,8 +4913,7 @@ static void trw_layer_merge_with_other ( gpointer pass_along[6] )
         merge_track = vik_trw_layer_get_track ( vtl, l->data );
 
       if (merge_track) {
         merge_track = vik_trw_layer_get_track ( vtl, l->data );
 
       if (merge_track) {
-        track->trackpoints = g_list_concat(track->trackpoints, merge_track->trackpoints);
-        merge_track->trackpoints = NULL;
+        vik_track_steal_and_append_trackpoints ( track, merge_track );
         if ( track->is_route )
           vik_trw_layer_delete_route (vtl, merge_track);
         else
         if ( track->is_route )
           vik_trw_layer_delete_route (vtl, merge_track);
         else
@@ -4729,10 +4921,10 @@ static void trw_layer_merge_with_other ( gpointer pass_along[6] )
         track->trackpoints = g_list_sort(track->trackpoints, trackpoint_compare);
       }
     }
         track->trackpoints = g_list_sort(track->trackpoints, trackpoint_compare);
       }
     }
-    /* TODO: free data before free merge_list */
     for (l = merge_list; l != NULL; l = g_list_next(l))
       g_free(l->data);
     g_list_free(merge_list);
     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) );
   }
 }
     vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
@@ -4809,8 +5001,7 @@ static void trw_layer_append_track ( gpointer pass_along[6] )
         append_track = vik_trw_layer_get_track ( vtl, l->data );
 
       if ( append_track ) {
         append_track = vik_trw_layer_get_track ( vtl, l->data );
 
       if ( append_track ) {
-        trk->trackpoints = g_list_concat(trk->trackpoints, append_track->trackpoints);
-        append_track->trackpoints = NULL;
+        vik_track_steal_and_append_trackpoints ( trk, append_track );
         if ( trk->is_route )
           vik_trw_layer_delete_route (vtl, append_track);
         else
         if ( trk->is_route )
           vik_trw_layer_delete_route (vtl, append_track);
         else
@@ -4820,6 +5011,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);
     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) );
   }
 }
     vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 }
@@ -4903,8 +5095,7 @@ static void trw_layer_append_other ( gpointer pass_along[6] )
           }
         }
 
           }
         }
 
-        trk->trackpoints = g_list_concat(trk->trackpoints, append_track->trackpoints);
-        append_track->trackpoints = NULL;
+        vik_track_steal_and_append_trackpoints ( trk, append_track );
 
        // Delete copied which is FROM THE OTHER TYPE list
         if ( trk->is_route )
 
        // Delete copied which is FROM THE OTHER TYPE list
         if ( trk->is_route )
@@ -5016,8 +5207,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
        */
 
       /* remove trackpoints from merged track, delete track */
        */
 
       /* remove trackpoints from merged track, delete track */
-      orig_trk->trackpoints = g_list_concat(orig_trk->trackpoints, VIK_TRACK(l->data)->trackpoints);
-      VIK_TRACK(l->data)->trackpoints = NULL;
+      vik_track_steal_and_append_trackpoints ( orig_trk, VIK_TRACK(l->data) );
       vik_trw_layer_delete_track (vtl, VIK_TRACK(l->data));
 
       // Tracks have changed, therefore retry again against all the remaining tracks
       vik_trw_layer_delete_track (vtl, VIK_TRACK(l->data));
 
       // Tracks have changed, therefore retry again against all the remaining tracks
@@ -5030,6 +5220,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
   }
 
   g_list_free(nearby_tracks);
   }
 
   g_list_free(nearby_tracks);
+
   vik_layer_emit_update( VIK_LAYER(vtl) );
 }
 
   vik_layer_emit_update( VIK_LAYER(vtl) );
 }
 
@@ -5054,6 +5245,9 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
       vtl->current_tpl->next->prev = newglist; /* end old track here */
       vtl->current_tpl->next = NULL;
 
       vtl->current_tpl->next->prev = newglist; /* end old track here */
       vtl->current_tpl->next = NULL;
 
+      // Bounds of the selected track changed due to the split
+      vik_track_calculate_bounds ( vtl->current_tp_track );
+
       vtl->current_tpl = newglist; /* change tp to first of new track. */
       vtl->current_tp_track = tr;
 
       vtl->current_tpl = newglist; /* change tp to first of new track. */
       vtl->current_tp_track = tr;
 
@@ -5062,6 +5256,9 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
       else
         vik_trw_layer_add_track ( vtl, name, tr );
 
       else
         vik_trw_layer_add_track ( vtl, name, tr );
 
+      // Bounds of the new track created by the split
+      vik_track_calculate_bounds ( tr );
+
       trku_udata udata;
       udata.trk  = tr;
       udata.uuid = NULL;
       trku_udata udata;
       udata.trk  = tr;
       udata.uuid = NULL;
@@ -5080,6 +5277,7 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
 
       vik_layer_emit_update(VIK_LAYER(vtl));
     }
 
       vik_layer_emit_update(VIK_LAYER(vtl));
     }
+    g_free ( name );
   }
 }
 
   }
 }
 
@@ -5112,10 +5310,19 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
 
   while (iter) {
     ts = VIK_TRACKPOINT(iter->data)->timestamp;
 
   while (iter) {
     ts = VIK_TRACKPOINT(iter->data)->timestamp;
+
+    // Check for unordered time points - this is quite a rare occurence - unless one has reversed a track.
     if (ts < prev_ts) {
     if (ts < prev_ts) {
-      g_print("panic: ts < prev_ts: this should never happen!\n");
+      gchar tmp_str[64];
+      strftime ( tmp_str, sizeof(tmp_str), "%c", localtime(&ts) );
+      if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                _("Can not split track due to trackpoints not ordered in time - such as at %s.\n\nGoto this trackpoint?"),
+                                tmp_str ) ) {
+       goto_coord ( pass_along[1], vtl, pass_along[5], &(VIK_TRACKPOINT(iter->data)->coord) );
+      }
       return;
     }
       return;
     }
+
     if (ts - prev_ts > thr*60) {
       /* flush accumulated trackpoints into new list */
       newlists = g_list_append(newlists, g_list_reverse(newtps));
     if (ts - prev_ts > thr*60) {
       /* flush accumulated trackpoints into new list */
       newlists = g_list_append(newlists, g_list_reverse(newtps));
@@ -5146,7 +5353,8 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
       vik_trw_layer_add_track(vtl, new_tr_name, tr);
       /*    g_print("adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp,
          VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp);*/
       vik_trw_layer_add_track(vtl, new_tr_name, tr);
       /*    g_print("adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp,
          VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp);*/
-
+      g_free ( new_tr_name );
+      vik_track_calculate_bounds ( tr );
       iter = g_list_next(iter);
     }
     // Remove original track and then update the display
       iter = g_list_next(iter);
     }
     // Remove original track and then update the display
@@ -5232,6 +5440,9 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
         new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name);
         vik_trw_layer_add_track(vtl, new_tr_name, tr);
       }
         new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name);
         vik_trw_layer_add_track(vtl, new_tr_name, tr);
       }
+      g_free ( new_tr_name );
+      vik_track_calculate_bounds ( tr );
+
       iter = g_list_next(iter);
     }
     // Remove original track and then update the display
       iter = g_list_next(iter);
     }
     // Remove original track and then update the display
@@ -5275,6 +5486,7 @@ static void trw_layer_split_segments ( gpointer pass_along[6] )
     if ( tracks[i] ) {
       new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, trk->name);
       vik_trw_layer_add_track ( vtl, new_tr_name, tracks[i] );
     if ( tracks[i] ) {
       new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, trk->name);
       vik_trw_layer_add_track ( vtl, new_tr_name, tracks[i] );
+      g_free ( new_tr_name );
     }
   }
   if ( tracks ) {
     }
   }
   if ( tracks ) {
@@ -5364,11 +5576,6 @@ static void trw_layer_reverse ( gpointer pass_along[6] )
   if ( ! track )
     return;
 
   if ( ! track )
     return;
 
-  // Check valid track
-  GList *trps = track->trackpoints;
-  if ( !trps )
-    return;
-
   vik_track_reverse ( track );
  
   vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
   vik_track_reverse ( track );
  
   vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
@@ -5528,9 +5735,10 @@ static void vik_trw_layer_uniquify_tracks ( VikTrwLayer *vtl, VikLayersPanel *vl
 
       if ( it ) {
         vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, newname );
 
       if ( it ) {
         vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, newname );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-        vik_treeview_sublayer_realphabetize ( VIK_LAYER(vtl)->vt, it, newname );
-#endif
+        if ( ontrack )
+          vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->wp_sort_order );
+       else
+          vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->wp_sort_order );
       }
     }
 
       }
     }
 
@@ -5549,6 +5757,52 @@ static void vik_trw_layer_uniquify_tracks ( VikTrwLayer *vtl, VikLayersPanel *vl
   vik_layers_panel_emit_update ( vlp );
 }
 
   vik_layers_panel_emit_update ( vlp );
 }
 
+static void trw_layer_sort_order_a2z ( gpointer pass_along[6] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+  GtkTreeIter *iter;
+
+  switch (GPOINTER_TO_INT (pass_along[2])) {
+  case VIK_TRW_LAYER_SUBLAYER_TRACKS:
+    iter = &(vtl->tracks_iter);
+    vtl->track_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+    break;
+  case VIK_TRW_LAYER_SUBLAYER_ROUTES:
+    iter = &(vtl->routes_iter);
+    vtl->track_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+    break;
+  default: // VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
+    iter = &(vtl->waypoints_iter);
+    vtl->wp_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+    break;
+  }
+
+  vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, iter, VL_SO_ALPHABETICAL_ASCENDING );
+}
+
+static void trw_layer_sort_order_z2a ( gpointer pass_along[6] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+  GtkTreeIter *iter;
+
+  switch (GPOINTER_TO_INT (pass_along[2])) {
+  case VIK_TRW_LAYER_SUBLAYER_TRACKS:
+    iter = &(vtl->tracks_iter);
+    vtl->track_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+    break;
+  case VIK_TRW_LAYER_SUBLAYER_ROUTES:
+    iter = &(vtl->routes_iter);
+    vtl->track_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+    break;
+  default: // VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
+    iter = &(vtl->waypoints_iter);
+    vtl->wp_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+    break;
+  }
+
+  vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, iter, VL_SO_ALPHABETICAL_DESCENDING );
+}
+
 /**
  *
  */
 /**
  *
  */
@@ -5739,26 +5993,8 @@ static void vik_trw_layer_uniquify_waypoints ( VikTrwLayer *vtl, VikLayersPanel
 
     // Rename it
     gchar *newname = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, udata.same_waypoint_name );
 
     // Rename it
     gchar *newname = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, udata.same_waypoint_name );
-    vik_waypoint_set_name ( waypoint, newname );
-
-    wpu_udata udataU;
-    udataU.wp   = waypoint;
-    udataU.uuid = NULL;
-
-    // Need want key of it for treeview update
-    gpointer *wpf = g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, &udataU );
-
-    if ( wpf && udataU.uuid ) {
 
 
-      GtkTreeIter *it = g_hash_table_lookup ( vtl->waypoints_iters, udataU.uuid );
-
-      if ( it ) {
-        vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, newname );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-        vik_treeview_sublayer_realphabetize ( VIK_LAYER(vtl)->vt, it, newname );
-#endif
-      }
-    }
+    trw_layer_waypoint_rename ( vtl, waypoint, newname );
 
     // Start trying to find same names again...
     waypoint_names = NULL;
 
     // Start trying to find same names again...
     waypoint_names = NULL;
@@ -5819,11 +6055,249 @@ 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);
       trw_layer_delete_waypoint_by_name (vtl, l->data);
     }
     g_list_free(delete_list);
+
+    trw_layer_calculate_bounds_waypoints ( vtl );
     vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 
 }
 
     vik_layer_emit_update( VIK_LAYER(vtl) );
   }
 
 }
 
+/**
+ *
+ */
+static void trw_layer_iter_visibility_toggle ( gpointer id, GtkTreeIter *it, VikTreeview *vt )
+{
+  vik_treeview_item_toggle_visible ( vt, it );
+}
+
+/**
+ *
+ */
+static void trw_layer_iter_visibility ( gpointer id, GtkTreeIter *it, gpointer vis_data[2] )
+{
+  vik_treeview_item_set_visible ( (VikTreeview*)vis_data[0], it, GPOINTER_TO_INT (vis_data[1]) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility ( gpointer id, VikWaypoint *wp, gpointer on_off )
+{
+  wp->visible = GPOINTER_TO_INT (on_off);
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_toggle_visibility ( gpointer id, VikWaypoint *wp )
+{
+  wp->visible = !wp->visible;
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_off ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+  g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_on ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+  g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_toggle ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+  g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_toggle_visibility, NULL );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility ( gpointer id, VikTrack *trk, gpointer on_off )
+{
+  trk->visible = GPOINTER_TO_INT (on_off);
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_toggle_visibility ( gpointer id, VikTrack *trk )
+{
+  trk->visible = !trk->visible;
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_off ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+  g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_on ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+  g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_toggle ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+  g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_toggle_visibility, NULL );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_off ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+  g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_on ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+  g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+  g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_toggle ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+  g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_toggle_visibility, NULL );
+  // Redraw
+  vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ * trw_layer_analyse_close:
+ *
+ * Stuff to do on dialog closure
+ */
+static void trw_layer_analyse_close ( GtkWidget *dialog, gint resp, VikLayer* vl )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+  gtk_widget_destroy ( dialog );
+  vtl->tracks_analysis_dialog = NULL;
+}
+
+/**
+ * trw_layer_analyse_create_list:
+ *
+ * Create the latest list of tracks with the associated layer(s)
+ *  Although this will always be from a single layer here
+ */
+static GList* trw_layer_analyse_create_list ( VikLayer *vl, gpointer user_data )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+  GList *tracks = NULL;
+  if ( GPOINTER_TO_INT(user_data) == VIK_TRW_LAYER_SUBLAYER_TRACKS )
+    tracks = g_hash_table_get_values ( vik_trw_layer_get_tracks(vtl) );
+  else
+    tracks = g_hash_table_get_values ( vik_trw_layer_get_routes(vtl) );
+
+  GList *tracks_and_layers = NULL;
+  // build tracks_and_layers list
+  tracks = g_list_first ( tracks );
+  while ( tracks ) {
+    vik_trw_track_list_t *vtdl = g_malloc (sizeof(vik_trw_track_list_t));
+    vtdl->trk = VIK_TRACK(tracks->data);
+    vtdl->vtl = vtl;
+    tracks_and_layers = g_list_prepend ( tracks_and_layers, vtdl );
+    tracks = g_list_next ( tracks );
+  }
+
+  return tracks_and_layers;
+}
+
+static void trw_layer_tracks_stats ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  // There can only be one!
+  if ( vtl->tracks_analysis_dialog )
+    return;
+
+  vtl->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                                             VIK_LAYER(vtl)->name,
+                                                             VIK_LAYER(vtl),
+                                                             GINT_TO_POINTER(VIK_TRW_LAYER_SUBLAYER_TRACKS),
+                                                             trw_layer_analyse_create_list,
+                                                             trw_layer_analyse_close );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_stats ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  // There can only be one!
+  if ( vtl->tracks_analysis_dialog )
+    return;
+
+  vtl->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                                             VIK_LAYER(vtl)->name,
+                                                             VIK_LAYER(vtl),
+                                                             GINT_TO_POINTER(VIK_TRW_LAYER_SUBLAYER_ROUTES),
+                                                             trw_layer_analyse_create_list,
+                                                             trw_layer_analyse_close );
+}
+
 static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
 {
   VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
 static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
 {
   VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
@@ -5860,8 +6334,9 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     VikWaypoint *wp = g_hash_table_lookup ( l->waypoints, sublayer );
 
     // No actual change to the name supplied
     VikWaypoint *wp = g_hash_table_lookup ( l->waypoints, sublayer );
 
     // No actual change to the name supplied
-    if (strcmp(newname, wp->name) == 0 )
-      return NULL;
+    if ( wp->name )
+      if (strcmp(newname, wp->name) == 0 )
+       return NULL;
 
     VikWaypoint *wpf = vik_trw_layer_get_waypoint ( l, newname );
 
 
     VikWaypoint *wpf = vik_trw_layer_get_waypoint ( l, newname );
 
@@ -5876,9 +6351,8 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     // Update WP name and refresh the treeview
     vik_waypoint_set_name (wp, newname);
 
     // Update WP name and refresh the treeview
     vik_waypoint_set_name (wp, newname);
 
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+    vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+    vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->waypoints_iter), l->wp_sort_order );
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
@@ -5890,8 +6364,9 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     VikTrack *trk = g_hash_table_lookup ( l->tracks, sublayer );
 
     // No actual change to the name supplied
     VikTrack *trk = g_hash_table_lookup ( l->tracks, sublayer );
 
     // No actual change to the name supplied
-    if (strcmp(newname, trk->name) == 0)
-      return NULL;
+    if ( trk->name )
+      if (strcmp(newname, trk->name) == 0)
+       return NULL;
 
     VikTrack *trkf = vik_trw_layer_get_track ( l, (gpointer) newname );
 
 
     VikTrack *trkf = vik_trw_layer_get_track ( l, (gpointer) newname );
 
@@ -5913,9 +6388,8 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     // Property Dialog of the track
     vik_trw_layer_propwin_update ( trk );
 
     // Property Dialog of the track
     vik_trw_layer_propwin_update ( trk );
 
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+    vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+    vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->tracks_iter), l->track_sort_order );
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
@@ -5927,8 +6401,9 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     VikTrack *trk = g_hash_table_lookup ( l->routes, sublayer );
 
     // No actual change to the name supplied
     VikTrack *trk = g_hash_table_lookup ( l->routes, sublayer );
 
     // No actual change to the name supplied
-    if (strcmp(newname, trk->name) == 0)
-      return NULL;
+    if ( trk->name )
+      if (strcmp(newname, trk->name) == 0)
+        return NULL;
 
     VikTrack *trkf = vik_trw_layer_get_route ( l, (gpointer) newname );
 
 
     VikTrack *trkf = vik_trw_layer_get_route ( l, (gpointer) newname );
 
@@ -5950,9 +6425,8 @@ static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gc
     // Property Dialog of the track
     vik_trw_layer_propwin_update ( trk );
 
     // Property Dialog of the track
     vik_trw_layer_propwin_update ( trk );
 
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
-    vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+    vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+    vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->tracks_iter), l->track_sort_order );
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
 
     vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
 
@@ -6096,7 +6570,7 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
        pass_along[5] = wp->image;
 
         item = gtk_image_menu_item_new_with_mnemonic ( _("_Show Picture...") );
        pass_along[5] = wp->image;
 
         item = gtk_image_menu_item_new_with_mnemonic ( _("_Show Picture...") );
-       gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Show Picture", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+       gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-Show Picture", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
         g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_show_picture), pass_along );
         gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
         gtk_widget_show ( item );
         g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_show_picture), pass_along );
         gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
         gtk_widget_show ( item );
@@ -6188,6 +6662,30 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_waypoints_from_selection), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_waypoints_from_selection), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
+
+    GtkWidget *vis_submenu = gtk_menu_new ();
+    item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Waypoints") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_on), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Waypoints") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_off), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_toggle), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
   }
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS )
   }
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS )
@@ -6230,6 +6728,35 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     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(menu), item );
     gtk_widget_show ( item );
     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(menu), item );
     gtk_widget_show ( item );
+
+    GtkWidget *vis_submenu = gtk_menu_new ();
+    item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Tracks") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_on), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Tracks") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_off), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_toggle), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("_Statistics") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_stats), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
   }
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTES )
   }
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTES )
@@ -6273,6 +6800,57 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     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(menu), item );
     gtk_widget_show ( item );
     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(menu), item );
     gtk_widget_show ( item );
+
+    GtkWidget *vis_submenu = gtk_menu_new ();
+    item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Routes") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_on), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Routes") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_off), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_toggle), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("_Statistics") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_stats), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+  }
+
+
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS || subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS || subtype == VIK_TRW_LAYER_SUBLAYER_ROUTES ) {
+    GtkWidget *submenu_sort = gtk_menu_new ();
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Sort") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, 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), submenu_sort );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("Name _Ascending") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_SORT_ASCENDING, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_sort_order_a2z), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(submenu_sort), item );
+    gtk_widget_show ( item );
+
+    item = gtk_image_menu_item_new_with_mnemonic ( _("Name _Descending") );
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_SORT_DESCENDING, GTK_ICON_SIZE_MENU) );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_sort_order_z2a), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(submenu_sort), item );
+    gtk_widget_show ( item );
   }
 
   GtkWidget *upload_submenu = gtk_menu_new ();
   }
 
   GtkWidget *upload_submenu = gtk_menu_new ();
@@ -6463,14 +7041,14 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
         item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Track...") );
       else
         item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Route...") );
         item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Track...") );
       else
         item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Route...") );
-      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Maps Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-Maps Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
       g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_download_map_along_track_cb), pass_along );
       gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
       gtk_widget_show ( item );
     }
 
     item = gtk_image_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
       g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_download_map_along_track_cb), pass_along );
       gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
       gtk_widget_show ( item );
     }
 
     item = gtk_image_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
-    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("DEM Download/Import", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+    gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-DEM Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
@@ -6502,15 +7080,13 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
-#ifdef VIK_CONFIG_GOOGLE
     if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
       item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
     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
+      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-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 );
     }
       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
     if ( subtype != VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
 
     // ATM can't upload a single waypoint but can do waypoints to a GPS
     if ( subtype != VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
@@ -6635,7 +7211,7 @@ static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl )
        if courses in degrees are 350 + 020, the mid course more likely to be 005 (not 185)
        [similar applies if value is in radians] */
     if (tp_current->course != NAN && tp_next->course != NAN)
        if courses in degrees are 350 + 020, the mid course more likely to be 005 (not 185)
        [similar applies if value is in radians] */
     if (tp_current->course != NAN && tp_next->course != NAN)
-      tp_new->speed = (tp_current->course + tp_next->course)/2;
+      tp_new->course = (tp_current->course + tp_next->course)/2;
 
     /* DOP / sat values remain at defaults as not they do not seem applicable to a dreamt up point */
 
 
     /* DOP / sat values remain at defaults as not they do not seem applicable to a dreamt up point */
 
@@ -6649,6 +7225,7 @@ static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl )
 
     gint index =  g_list_index ( trk->trackpoints, tp_current );
     if ( index > -1 ) {
 
     gint index =  g_list_index ( trk->trackpoints, tp_current );
     if ( index > -1 ) {
+      // NB no recalculation of bounds since it is inserted between points
       trk->trackpoints = g_list_insert ( trk->trackpoints, tp_new, index+1 );
     }
   }
       trk->trackpoints = g_list_insert ( trk->trackpoints, tp_new, index+1 );
     }
   }
@@ -6713,8 +7290,10 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
       vtl->current_tpl = new_tpl;
 
       // Reset dialog with the available adjacent trackpoint
       vtl->current_tpl = new_tpl;
 
       // Reset dialog with the available adjacent trackpoint
-      if ( vtl->current_tp_track )
+      if ( vtl->current_tp_track ) {
+        vik_track_calculate_bounds ( vtl->current_tp_track );
         vik_trw_layer_tpwin_set_tp ( vtl->tpwin, new_tpl, vtl->current_tp_track->name );
         vik_trw_layer_tpwin_set_tp ( vtl->tpwin, new_tpl, vtl->current_tp_track->name );
+      }
 
       vik_layer_emit_update(VIK_LAYER(vtl));
     }
 
       vik_layer_emit_update(VIK_LAYER(vtl));
     }
@@ -6747,6 +7326,99 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
     vik_layer_emit_update(VIK_LAYER(vtl));
 }
 
     vik_layer_emit_update(VIK_LAYER(vtl));
 }
 
+/**
+ * trw_layer_dialog_shift:
+ * @vertical: The reposition strategy. If Vertical moves dialog vertically, otherwise moves it horizontally
+ *
+ * Try to reposition a dialog if it's over the specified coord
+ *  so to not obscure the item of interest
+ */
+void trw_layer_dialog_shift ( VikTrwLayer *vtl, GtkWindow *dialog, VikCoord *coord, gboolean vertical )
+{
+  GtkWindow *parent = VIK_GTK_WINDOW_FROM_LAYER(vtl); //i.e. the main window
+
+  // Attempt force dialog to be shown so we can find out where it is more reliably...
+  while ( gtk_events_pending() )
+    gtk_main_iteration ();
+
+  // get parent window position & size
+  gint win_pos_x, win_pos_y;
+  gtk_window_get_position ( parent, &win_pos_x, &win_pos_y );
+
+  gint win_size_x, win_size_y;
+  gtk_window_get_size ( parent, &win_size_x, &win_size_y );
+
+  // get own dialog size
+  gint dia_size_x, dia_size_y;
+  gtk_window_get_size ( dialog, &dia_size_x, &dia_size_y );
+
+  // get own dialog position
+  gint dia_pos_x, dia_pos_y;
+  gtk_window_get_position ( dialog, &dia_pos_x, &dia_pos_y );
+
+  // Dialog not 'realized'/positioned - so can't really do any repositioning logic
+  if ( dia_pos_x > 2 && dia_pos_y > 2 ) {
+
+    VikViewport *vvp = vik_window_viewport ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+
+    gint vp_xx, vp_yy; // In viewport pixels
+    vik_viewport_coord_to_screen ( vvp, coord, &vp_xx, &vp_yy );
+
+    // Work out the 'bounding box' in pixel terms of the dialog and only move it when over the position
+
+    gint dest_x = 0;
+    gint dest_y = 0;
+    if ( gtk_widget_translate_coordinates ( GTK_WIDGET(vvp), GTK_WIDGET(parent), 0, 0, &dest_x, &dest_y ) ) {
+
+      // Transform Viewport pixels into absolute pixels
+      gint tmp_xx = vp_xx + dest_x + win_pos_x - 10;
+      gint tmp_yy = vp_yy + dest_y + win_pos_y - 10;
+
+      // Is dialog over the point (to within an  ^^ edge value)
+      if ( (tmp_xx > dia_pos_x) && (tmp_xx < (dia_pos_x + dia_size_x)) &&
+           (tmp_yy > dia_pos_y) && (tmp_yy < (dia_pos_y + dia_size_y)) ) {
+
+        if ( vertical ) {
+         // Shift up<->down
+          gint hh = vik_viewport_get_height ( vvp );
+
+          // Consider the difference in viewport to the full window
+          gint offset_y = dest_y;
+          // Add difference between dialog and window sizes
+          offset_y += win_pos_y + (hh/2 - dia_size_y)/2;
+
+          if ( vp_yy > hh/2 ) {
+            // Point in bottom half, move window to top half
+            gtk_window_move ( dialog, dia_pos_x, offset_y );
+          }
+          else {
+            // Point in top half, move dialog down
+            gtk_window_move ( dialog, dia_pos_x, hh/2 + offset_y );
+          }
+       }
+       else {
+         // Shift left<->right
+          gint ww = vik_viewport_get_width ( vvp );
+
+          // Consider the difference in viewport to the full window
+          gint offset_x = dest_x;
+          // Add difference between dialog and window sizes
+          offset_x += win_pos_x + (ww/2 - dia_size_x)/2;
+
+          if ( vp_xx > ww/2 ) {
+            // Point on right, move window to left
+            gtk_window_move ( dialog, offset_x, dia_pos_y );
+          }
+          else {
+            // Point on left, move right
+            gtk_window_move ( dialog, ww/2 + offset_x, dia_pos_y );
+          }
+       }
+      }
+    }
+  }
+}
+
 static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
 {
   if ( ! vtl->tpwin )
 static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
 {
   if ( ! vtl->tpwin )
@@ -6755,8 +7427,18 @@ static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
     g_signal_connect_swapped ( GTK_DIALOG(vtl->tpwin), "response", G_CALLBACK(trw_layer_tpwin_response), vtl );
     /* connect signals -- DELETE SIGNAL VERY IMPORTANT TO SET TO NULL */
     g_signal_connect_swapped ( vtl->tpwin, "delete-event", G_CALLBACK(trw_layer_cancel_current_tp), vtl );
     g_signal_connect_swapped ( GTK_DIALOG(vtl->tpwin), "response", G_CALLBACK(trw_layer_tpwin_response), vtl );
     /* connect signals -- DELETE SIGNAL VERY IMPORTANT TO SET TO NULL */
     g_signal_connect_swapped ( vtl->tpwin, "delete-event", G_CALLBACK(trw_layer_cancel_current_tp), vtl );
+
     gtk_widget_show_all ( GTK_WIDGET(vtl->tpwin) );
     gtk_widget_show_all ( GTK_WIDGET(vtl->tpwin) );
+
+    if ( vtl->current_tpl ) {
+      // get tp pixel position
+      VikTrackpoint *tp = VIK_TRACKPOINT(vtl->current_tpl->data);
+
+      // Shift up<->down to try not to obscure the trackpoint.
+      trw_layer_dialog_shift ( vtl, GTK_WINDOW(vtl->tpwin), &(tp->coord), TRUE );
+    }
   }
   }
+
   if ( vtl->current_tpl )
     if ( vtl->current_tp_track )
       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
   if ( vtl->current_tpl )
     if ( vtl->current_tp_track )
       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
@@ -6772,6 +7454,7 @@ static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
 typedef struct {
   gint x, y;
   gint closest_x, closest_y;
 typedef struct {
   gint x, y;
   gint closest_x, closest_y;
+  gboolean draw_images;
   gpointer *closest_wp_id;
   VikWaypoint *closest_wp;
   VikViewport *vvp;
   gpointer *closest_wp_id;
   VikWaypoint *closest_wp;
   VikViewport *vvp;
@@ -6784,6 +7467,7 @@ typedef struct {
   VikTrackpoint *closest_tp;
   VikViewport *vvp;
   GList *closest_tpl;
   VikTrackpoint *closest_tp;
   VikViewport *vvp;
   GList *closest_tpl;
+  LatLonBBox bbox;
 } TPSearchParams;
 
 static void waypoint_search_closest_tp ( gpointer id, VikWaypoint *wp, WPSearchParams *params )
 } TPSearchParams;
 
 static void waypoint_search_closest_tp ( gpointer id, VikWaypoint *wp, WPSearchParams *params )
@@ -6795,7 +7479,7 @@ static void waypoint_search_closest_tp ( gpointer id, VikWaypoint *wp, WPSearchP
   vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
 
   // If waypoint has an image then use the image size to select
   vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
 
   // If waypoint has an image then use the image size to select
-  if ( wp->image ) {
+  if ( params->draw_images && wp->image ) {
     gint slackx, slacky;
     slackx = wp->image_width / 2;
     slacky = wp->image_height / 2;
     gint slackx, slacky;
     slackx = wp->image_width / 2;
     slacky = wp->image_height / 2;
@@ -6827,6 +7511,9 @@ static void track_search_closest_tp ( gpointer id, VikTrack *t, TPSearchParams *
   if ( !t->visible )
     return;
 
   if ( !t->visible )
     return;
 
+  if ( ! BBOX_INTERSECT ( t->bbox, params->bbox ) )
+    return;
+
   while (tpl)
   {
     gint x, y;
   while (tpl)
   {
     gint x, y;
@@ -6858,6 +7545,7 @@ static VikTrackpoint *closest_tp_in_five_pixel_interval ( VikTrwLayer *vtl, VikV
   params.vvp = vvp;
   params.closest_track_id = NULL;
   params.closest_tp = NULL;
   params.vvp = vvp;
   params.closest_track_id = NULL;
   params.closest_tp = NULL;
+  vik_viewport_get_min_max_lat_lon ( params.vvp, &(params.bbox.south), &(params.bbox.north), &(params.bbox.west), &(params.bbox.east) );
   g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &params);
   return params.closest_tp;
 }
   g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &params);
   return params.closest_tp;
 }
@@ -6868,6 +7556,7 @@ static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikVie
   params.x = x;
   params.y = y;
   params.vvp = vvp;
   params.x = x;
   params.y = y;
   params.vvp = vvp;
+  params.draw_images = vtl->drawimages;
   params.closest_wp = NULL;
   params.closest_wp_id = NULL;
   g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, &params);
   params.closest_wp = NULL;
   params.closest_wp_id = NULL;
   g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, &params);
@@ -6943,12 +7632,17 @@ static gboolean trw_layer_select_release ( VikTrwLayer *vtl, GdkEventButton *eve
     marker_end_move ( t );
 
     // Determine if working on a waypoint or a trackpoint
     marker_end_move ( t );
 
     // Determine if working on a waypoint or a trackpoint
-    if ( t->is_waypoint )
+    if ( t->is_waypoint ) {
       vtl->current_wp->coord = new_coord;
       vtl->current_wp->coord = new_coord;
+      trw_layer_calculate_bounds_waypoints ( vtl );
+    }
     else {
       if ( vtl->current_tpl ) {
         VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
     else {
       if ( vtl->current_tpl ) {
         VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
-      
+
+        if ( vtl->current_tp_track )
+          vik_track_calculate_bounds ( vtl->current_tp_track );
+
        if ( vtl->tpwin )
           if ( vtl->current_tp_track )
             vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
        if ( vtl->tpwin )
           if ( vtl->current_tp_track )
             vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
@@ -6982,13 +7676,17 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event
   if ( !vtl->tracks_visible && !vtl->waypoints_visible && !vtl->routes_visible )
     return FALSE;
 
   if ( !vtl->tracks_visible && !vtl->waypoints_visible && !vtl->routes_visible )
     return FALSE;
 
+  LatLonBBox bbox;
+  vik_viewport_get_min_max_lat_lon ( vvp, &(bbox.south), &(bbox.north), &(bbox.west), &(bbox.east) );
+
   // Go for waypoints first as these often will be near a track, but it's likely the wp is wanted rather then the track
 
   // Go for waypoints first as these often will be near a track, but it's likely the wp is wanted rather then the track
 
-  if (vtl->waypoints_visible) {
+  if ( vtl->waypoints_visible && BBOX_INTERSECT (vtl->waypoints_bbox, bbox ) ) {
     WPSearchParams wp_params;
     wp_params.vvp = vvp;
     wp_params.x = event->x;
     wp_params.y = event->y;
     WPSearchParams wp_params;
     wp_params.vvp = vvp;
     wp_params.x = event->x;
     wp_params.y = event->y;
+    wp_params.draw_images = vtl->drawimages;
     wp_params.closest_wp_id = NULL;
     wp_params.closest_wp = NULL;
 
     wp_params.closest_wp_id = NULL;
     wp_params.closest_wp = NULL;
 
@@ -7027,6 +7725,8 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event
   tp_params.y = event->y;
   tp_params.closest_track_id = NULL;
   tp_params.closest_tp = NULL;
   tp_params.y = event->y;
   tp_params.closest_track_id = NULL;
   tp_params.closest_tp = NULL;
+  tp_params.closest_tpl = NULL;
+  tp_params.bbox = bbox;
 
   if (vtl->tracks_visible) {
     g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &tp_params);
 
   if (vtl->tracks_visible) {
     g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &tp_params);
@@ -7128,7 +7828,7 @@ static gboolean trw_layer_show_selected_viewport_menu ( VikTrwLayer *vtl, GdkEve
     if ( track->name ) {
 
       if ( vtl->track_right_click_menu )
     if ( track->name ) {
 
       if ( vtl->track_right_click_menu )
-        gtk_object_sink ( GTK_OBJECT(vtl->track_right_click_menu) );
+        g_object_ref_sink ( G_OBJECT(vtl->track_right_click_menu) );
 
       vtl->track_right_click_menu = GTK_MENU ( gtk_menu_new () );
       
 
       vtl->track_right_click_menu = GTK_MENU ( gtk_menu_new () );
       
@@ -7171,7 +7871,7 @@ static gboolean trw_layer_show_selected_viewport_menu ( VikTrwLayer *vtl, GdkEve
     if ( waypoint->name ) {
 
       if ( vtl->wp_right_click_menu )
     if ( waypoint->name ) {
 
       if ( vtl->wp_right_click_menu )
-        gtk_object_sink ( GTK_OBJECT(vtl->wp_right_click_menu) );
+        g_object_ref_sink ( G_OBJECT(vtl->wp_right_click_menu) );
 
       vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
 
 
       vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
 
@@ -7256,6 +7956,11 @@ static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp)
   return t;
 }
 
   return t;
 }
 
+static void tool_edit_waypoint_destroy ( tool_ed_t *t )
+{
+  g_free ( t );
+}
+
 static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
 {
   WPSearchParams params;
 static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
 {
   WPSearchParams params;
@@ -7293,6 +7998,7 @@ static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *eve
   params.vvp = vvp;
   params.x = event->x;
   params.y = event->y;
   params.vvp = vvp;
   params.x = event->x;
   params.y = event->y;
+  params.draw_images = vtl->drawimages;
   params.closest_wp_id = NULL;
   /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
   params.closest_wp = NULL;
   params.closest_wp_id = NULL;
   /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
   params.closest_wp = NULL;
@@ -7399,6 +8105,8 @@ static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *e
     marker_end_move ( t );
 
     vtl->current_wp->coord = new_coord;
     marker_end_move ( t );
 
     vtl->current_wp->coord = new_coord;
+
+    trw_layer_calculate_bounds_waypoints ( vtl );
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
   }
@@ -7449,6 +8157,7 @@ static gboolean draw_sync ( gpointer data )
     ds->vtl->draw_sync_done = TRUE;
     gdk_threads_leave();
   }
     ds->vtl->draw_sync_done = TRUE;
     gdk_threads_leave();
   }
+  g_free ( ds );
   return FALSE;
 }
 
   return FALSE;
 }
 
@@ -7545,12 +8254,12 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     w1 = vik_viewport_get_width(vvp);
     h1 = vik_viewport_get_height(vvp);
     if (!pixmap) {
     w1 = vik_viewport_get_width(vvp);
     h1 = vik_viewport_get_height(vvp);
     if (!pixmap) {
-      pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+      pixmap = gdk_pixmap_new ( gtk_widget_get_window(GTK_WIDGET(vvp)), w1, h1, -1 );
     }
     gdk_drawable_get_size (pixmap, &w2, &h2);
     if (w1 != w2 || h1 != h2) {
       g_object_unref ( G_OBJECT ( pixmap ) );
     }
     gdk_drawable_get_size (pixmap, &w2, &h2);
     if (w1 != w2 || h1 != h2) {
       g_object_unref ( G_OBJECT ( pixmap ) );
-      pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+      pixmap = gdk_pixmap_new ( gtk_widget_get_window(GTK_WIDGET(vvp)), w1, h1, -1 );
     }
 
     // Reset to background
     }
 
     // Reset to background
@@ -7601,33 +8310,39 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
          elev_loss += last_tpt->altitude - elev_new;
       }
     }
          elev_loss += last_tpt->altitude - elev_new;
       }
     }
-    
-    gchar *str = distance_string (distance);
 
 
-    PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
-    pango_layout_set_font_description (pl, GTK_WIDGET(vvp)->style->font_desc);
+    //
+    // Display of the distance 'tooltip' during track creation is controlled by a preference
+    //
+    if ( a_vik_get_create_track_tooltip() ) {
 
 
-    pango_layout_set_text (pl, str, -1);
-    gint wd, hd;
-    pango_layout_get_pixel_size ( pl, &wd, &hd );
+      gchar *str = distance_string (distance);
 
 
-    gint xd,yd;
-    // offset from cursor a bit depending on font size
-    xd = event->x + 10;
-    yd = event->y - hd;
+      PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
+      pango_layout_set_font_description (pl, gtk_widget_get_style(GTK_WIDGET(vvp))->font_desc);
+      pango_layout_set_text (pl, str, -1);
+      gint wd, hd;
+      pango_layout_get_pixel_size ( pl, &wd, &hd );
 
 
-    // Create a background block to make the text easier to read over the background map
-    GdkGC *background_block_gc = vik_viewport_new_gc ( vvp, "#cccccc", 1);
-    gdk_draw_rectangle (pixmap, background_block_gc, TRUE, xd-2, yd-2, wd+4, hd+2);
-    gdk_draw_layout (pixmap, vtl->current_track_newpoint_gc, xd, yd, pl);
+      gint xd,yd;
+      // offset from cursor a bit depending on font size
+      xd = event->x + 10;
+      yd = event->y - hd;
 
 
-    g_object_unref ( G_OBJECT ( pl ) );
-    g_object_unref ( G_OBJECT ( background_block_gc ) );
+      // Create a background block to make the text easier to read over the background map
+      GdkGC *background_block_gc = vik_viewport_new_gc ( vvp, "#cccccc", 1);
+      gdk_draw_rectangle (pixmap, background_block_gc, TRUE, xd-2, yd-2, wd+4, hd+2);
+      gdk_draw_layout (pixmap, vtl->current_track_newpoint_gc, xd, yd, pl);
+
+      g_object_unref ( G_OBJECT ( pl ) );
+      g_object_unref ( G_OBJECT ( background_block_gc ) );
+      g_free (str);
+    }
 
     passalong = g_new(draw_sync_t,1); // freed by draw_sync()
     passalong->vtl = vtl;
     passalong->pixmap = pixmap;
 
     passalong = g_new(draw_sync_t,1); // freed by draw_sync()
     passalong->vtl = vtl;
     passalong->pixmap = pixmap;
-    passalong->drawable = GTK_WIDGET(vvp)->window;
+    passalong->drawable = gtk_widget_get_window(GTK_WIDGET(vvp));
     passalong->gc = vtl->current_track_newpoint_gc;
 
     gdouble angle;
     passalong->gc = vtl->current_track_newpoint_gc;
 
     gdouble angle;
@@ -7637,8 +8352,6 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     // Update statusbar with full gain/loss information
     statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl);
 
     // Update statusbar with full gain/loss information
     statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl);
 
-    g_free (str);
-
     // draw pixmap when we have time to
     g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, draw_sync, passalong, NULL);
     vtl->draw_sync_done = FALSE;
     // draw pixmap when we have time to
     g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, draw_sync, passalong, NULL);
     vtl->draw_sync_done = FALSE;
@@ -7701,6 +8414,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
       g_free ( last->data );
       vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
     }
       g_free ( last->data );
       vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
     }
+    vik_track_calculate_bounds ( vtl->current_track );
     update_statusbar ( vtl );
 
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     update_statusbar ( vtl );
 
     vik_layer_emit_update ( VIK_LAYER(vtl) );
@@ -7738,7 +8452,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton
   tp->timestamp = 0;
 
   if ( vtl->current_track ) {
   tp->timestamp = 0;
 
   if ( vtl->current_track ) {
-    vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
+    vik_track_add_trackpoint ( vtl->current_track, tp, TRUE ); // Ensure bounds is updated
     /* Auto attempt to get elevation from DEM data (if it's available) */
     vik_track_apply_dem_data_last_trackpoint ( vtl->current_track );
   }
     /* Auto attempt to get elevation from DEM data (if it's available) */
     vik_track_apply_dem_data_last_trackpoint ( vtl->current_track );
   }
@@ -7760,9 +8474,8 @@ 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 ) ) )
     {
     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 );
+      g_free ( name );
     }
     else
       return TRUE;
     }
     else
       return TRUE;
@@ -7792,8 +8505,10 @@ static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event,
   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 ( 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), vtl->routes, name, TRUE ) ) )
+    if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->routes, name, TRUE ) ) ) {
       new_route_create_common ( vtl, name );
       new_route_create_common ( vtl, name );
+      g_free ( name );
+    }
     else
       return TRUE;
   }
     else
       return TRUE;
   }
@@ -7813,8 +8528,10 @@ static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *even
   if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
     return FALSE;
   vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord );
   if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
     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)
+  if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible) {
+    trw_layer_calculate_bounds_waypoints ( vtl );
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     vik_layer_emit_update ( VIK_LAYER(vtl) );
+  }
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -7829,6 +8546,11 @@ static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp)
   return t;
 }
 
   return t;
 }
 
+static void tool_edit_trackpoint_destroy ( tool_ed_t *t )
+{
+  g_free ( t );
+}
+
 static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
 {
   tool_ed_t *t = data;
 static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
 {
   tool_ed_t *t = data;
@@ -7846,6 +8568,8 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e
   params.closest_track_id = NULL;
   /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
   params.closest_tp = NULL;
   params.closest_track_id = NULL;
   /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
   params.closest_tp = NULL;
+  params.closest_tpl = NULL;
+  vik_viewport_get_min_max_lat_lon ( vvp, &(params.bbox.south), &(params.bbox.north), &(params.bbox.west), &(params.bbox.east) );
 
   if ( event->button != 1 ) 
     return FALSE;
 
   if ( event->button != 1 ) 
     return FALSE;
@@ -7965,6 +8689,8 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton
     }
 
     VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
     }
 
     VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
+    if ( vtl->current_tp_track )
+      vik_track_calculate_bounds ( vtl->current_tp_track );
 
     marker_end_move ( t );
 
 
     marker_end_move ( t );
 
@@ -7979,7 +8705,6 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton
 }
 
 
 }
 
 
-#ifdef VIK_CONFIG_GOOGLE
 /*** Route Finder ***/
 static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
 {
 /*** Route Finder ***/
 static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
 {
@@ -8011,9 +8736,6 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
   }
   else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
     struct LatLon start, end;
   }
   else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
     struct LatLon start, end;
-    gchar startlat[G_ASCII_DTOSTR_BUF_SIZE], startlon[G_ASCII_DTOSTR_BUF_SIZE];
-    gchar endlat[G_ASCII_DTOSTR_BUF_SIZE], endlon[G_ASCII_DTOSTR_BUF_SIZE];
-    gchar *url;
 
     vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
     vik_coord_to_latlon ( &(tmp), &end );
 
     vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
     vik_coord_to_latlon ( &(tmp), &end );
@@ -8027,14 +8749,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
       vtl->route_finder_started = FALSE;
     }
 
       vtl->route_finder_started = FALSE;
     }
 
-    url = g_strdup_printf(GOOGLE_DIRECTIONS_STRING,
-                          g_ascii_dtostr (startlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lat),
-                          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));
-    // 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 );
+    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 ) {
 
     /* see if anything was done -- a track was added or appended to */
     if ( vtl->route_finder_check_added_track && vtl->route_finder_added_track ) {
@@ -8044,6 +8759,10 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
       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 );
     }
       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 );
     }
+
+    if ( vtl->route_finder_added_track )
+      vik_track_calculate_bounds ( vtl->route_finder_added_track );
+
     vtl->route_finder_added_track = NULL;
     vtl->route_finder_check_added_track = FALSE;
     vtl->route_finder_append = FALSE;
     vtl->route_finder_added_track = NULL;
     vtl->route_finder_check_added_track = FALSE;
     vtl->route_finder_append = FALSE;
@@ -8056,7 +8775,6 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
   }
   return TRUE;
 }
   }
   return TRUE;
 }
-#endif
 
 /*** Show picture ****/
 
 
 /*** Show picture ****/
 
@@ -8226,7 +8944,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 ) {
 
     // 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;
     }
 
       VIK_TRACK(value)->has_color = TRUE;
     }
 
@@ -8258,10 +8980,89 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl )
   }
 }
 
   }
 }
 
-static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vp )
+/*
+ * (Re)Calculate the bounds of the waypoints in this layer,
+ * This should be called whenever waypoints are changed
+ */
+static void trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl )
 {
 {
-  trw_layer_verify_thumbnails ( vtl, vp );
+  struct LatLon topleft = { 0.0, 0.0 };
+  struct LatLon bottomright = { 0.0, 0.0 };
+  struct LatLon ll;
+
+  GHashTableIter iter;
+  gpointer key, value;
+
+  g_hash_table_iter_init ( &iter, vtl->waypoints );
+
+  // Set bounds to first point
+  if ( g_hash_table_iter_next (&iter, &key, &value) ) {
+    vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &topleft );
+    vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &bottomright );
+  }
+
+  // Ensure there is another point...
+  if ( g_hash_table_size ( vtl->waypoints ) > 1 ) {
+
+    while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+
+      // See if this point increases the bounds.
+      vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &ll );
+
+      if ( ll.lat > topleft.lat) topleft.lat = ll.lat;
+      if ( ll.lon < topleft.lon) topleft.lon = ll.lon;
+      if ( ll.lat < bottomright.lat) bottomright.lat = ll.lat;
+      if ( ll.lon > bottomright.lon) bottomright.lon = ll.lon;
+    }
+  }
+
+  vtl->waypoints_bbox.north = topleft.lat;
+  vtl->waypoints_bbox.east = bottomright.lon;
+  vtl->waypoints_bbox.south = bottomright.lat;
+  vtl->waypoints_bbox.west = topleft.lon;
+}
+
+static void trw_layer_calculate_bounds_track ( gpointer id, VikTrack *trk )
+{
+  vik_track_calculate_bounds ( trk );
+}
+
+static void trw_layer_calculate_bounds_tracks ( VikTrwLayer *vtl )
+{
+  g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_calculate_bounds_track, NULL );
+  g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_calculate_bounds_track, NULL );
+}
+
+static void trw_layer_sort_all ( VikTrwLayer *vtl )
+{
+  if ( ! VIK_LAYER(vtl)->vt )
+    return;
+
+  // Obviously need 2 to tango - sorting with only 1 (or less) is a lonely activity!
+  if ( g_hash_table_size (vtl->tracks) > 1 )
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->track_sort_order );
+
+  if ( g_hash_table_size (vtl->routes) > 1 )
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->track_sort_order );
+
+  if ( g_hash_table_size (vtl->waypoints) > 1 )
+    vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
+}
+
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp, gboolean from_file )
+{
+  trw_layer_verify_thumbnails ( vtl, vvp );
   trw_layer_track_alloc_colors ( vtl );
   trw_layer_track_alloc_colors ( vtl );
+
+  trw_layer_calculate_bounds_waypoints ( vtl );
+  trw_layer_calculate_bounds_tracks ( vtl );
+
+  // Apply treeview sort after loading all the tracks for this layer
+  //  (rather than sorted insert on each individual track additional)
+  //  and after subsequent changes to the properties as the specified order may have changed.
+  //  since the sorting of a treeview section is now very quick
+  // NB sorting is also performed after every name change as well to maintain the list order
+  trw_layer_sort_all ( vtl );
 }
 
 VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl )
 }
 
 VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl )
@@ -8453,7 +9254,7 @@ void vik_track_download_map(VikTrack *tr, VikMapsLayer *vml, VikViewport *vvp, g
   }
 
   for (rect_iter = rects_to_download; rect_iter; rect_iter = rect_iter->next) {
   }
 
   for (rect_iter = rects_to_download; rect_iter; rect_iter = rect_iter->next) {
-    maps_layer_download_section (vml, vvp, &(((Rect *)(rect_iter->data))->tl), &(((Rect *)(rect_iter->data))->br), zoom_level);
+    vik_maps_layer_download_section (vml, vvp, &(((Rect *)(rect_iter->data))->tl), &(((Rect *)(rect_iter->data))->br), zoom_level);
   }
 
   if (fillins) {
   }
 
   if (fillins) {