#include "thumbnails.h"
#include "background.h"
#include "gpx.h"
+#include "geojson.h"
#include "babel.h"
#include "dem.h"
#include "dems.h"
/* route finder tool */
gboolean route_finder_started;
- VikCoord route_finder_coord;
gboolean route_finder_check_added_track;
VikTrack *route_finder_added_track;
- VikTrack *route_finder_current_track;
gboolean route_finder_append;
gboolean drawlabels;
static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp );
static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp);
static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp);
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp );
static void cached_pixbuf_free ( CachedPixbuf *cp );
static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf, NULL },
+ { { "ExtendedRouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
+ (VikToolConstructorFunc) tool_extended_route_finder_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_extended_route_finder_click,
+ (VikToolMouseMoveFunc) tool_new_track_move, // -\#
+ (VikToolMouseFunc) tool_new_track_release, // -> Reuse these track methods on a route
+ (VikToolKeyFunc) tool_extended_route_finder_key_press,
+ TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
+ GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf, NULL },
+
{ { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
(VikToolConstructorFunc) tool_edit_waypoint_create,
(VikToolDestructorFunc) tool_edit_waypoint_destroy,
FALSE,
GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf, NULL },
- { { "RouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
- (VikToolConstructorFunc) tool_route_finder_create, NULL, NULL, NULL,
- (VikToolMouseFunc) tool_route_finder_click, NULL, NULL, (VikToolKeyFunc) NULL,
- FALSE,
- GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf, NULL },
};
enum {
TOOL_CREATE_WAYPOINT=0,
TOOL_CREATE_TRACK,
TOOL_CREATE_ROUTE,
+ TOOL_ROUTE_FINDER,
TOOL_EDIT_WAYPOINT,
TOOL_EDIT_TRACKPOINT,
TOOL_SHOW_PICTURE,
- TOOL_ROUTE_FINDER,
NUM_TOOLS
};
};
static gboolean have_diary_program = FALSE;
+static gboolean have_geojson_export = FALSE;
+
// NB Only performed once per program run
static void vik_trwlayer_class_init ( VikTrwLayerClass *klass )
g_free ( stdout );
g_free ( stderr );
}
+
+ if ( g_find_program_in_path ( a_geojson_program_export() ) ) {
+ have_geojson_export = TRUE;
+ }
}
GType vik_trw_layer_get_type ()
case WP_SYMBOL_CIRCLE: vik_viewport_draw_arc ( dp->vp, dp->vtl->waypoint_gc, TRUE, x - dp->vtl->wp_size, y - dp->vtl->wp_size, dp->vtl->wp_size, dp->vtl->wp_size, 0, 360*64 ); break;
case WP_SYMBOL_X: vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x - dp->vtl->wp_size*2, y - dp->vtl->wp_size*2, x + dp->vtl->wp_size*2, y + dp->vtl->wp_size*2 );
vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x - dp->vtl->wp_size*2, y + dp->vtl->wp_size*2, x + dp->vtl->wp_size*2, y - dp->vtl->wp_size*2 );
+ default: break;
}
}
else {
case WP_SYMBOL_CIRCLE: vik_viewport_draw_arc ( dp->vp, dp->vtl->waypoint_gc, TRUE, x-dp->vtl->wp_size/2, y-dp->vtl->wp_size/2, dp->vtl->wp_size, dp->vtl->wp_size, 0, 360*64 ); break;
case WP_SYMBOL_X: vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x-dp->vtl->wp_size, y-dp->vtl->wp_size, x+dp->vtl->wp_size, y+dp->vtl->wp_size );
vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x-dp->vtl->wp_size, y+dp->vtl->wp_size, x+dp->vtl->wp_size, y-dp->vtl->wp_size ); break;
+ default: break;
}
}
else
return TRUE;
}
+ default: break;
}
return TRUE;
}
tt->length = tt->length + vik_track_get_length (tr);
// Ensure times are available
- if ( tr->trackpoints &&
- vik_track_get_tp_first(tr)->has_timestamp &&
- vik_track_get_tp_last(tr)->has_timestamp ) {
-
- time_t t1, t2;
- t1 = vik_track_get_tp_first(tr)->timestamp;
- t2 = vik_track_get_tp_last(tr)->timestamp;
+ if ( tr->trackpoints && vik_track_get_tp_first(tr)->has_timestamp ) {
+ // Get trkpt only once - as using vik_track_get_tp_last() iterates whole track each time
+ VikTrackpoint *trkpt_last = vik_track_get_tp_last(tr);
+ if ( trkpt_last->has_timestamp ) {
+ time_t t1, t2;
+ t1 = vik_track_get_tp_first(tr)->timestamp;
+ t2 = trkpt_last->timestamp;
- // Assume never actually have a track with a time of 0 (1st Jan 1970)
- // Hence initialize to the first 'proper' value
- if ( tt->start_time == 0 )
- tt->start_time = t1;
- if ( tt->end_time == 0 )
- tt->end_time = t2;
+ // Assume never actually have a track with a time of 0 (1st Jan 1970)
+ // Hence initialize to the first 'proper' value
+ if ( tt->start_time == 0 )
+ tt->start_time = t1;
+ if ( tt->end_time == 0 )
+ tt->end_time = t2;
- // Update find the earliest / last times
- if ( t1 < tt->start_time )
- tt->start_time = t1;
- if ( t2 > tt->end_time )
- tt->end_time = t2;
+ // Update find the earliest / last times
+ if ( t1 < tt->start_time )
+ tt->start_time = t1;
+ if ( t2 > tt->end_time )
+ tt->end_time = t2;
- // Keep track of total time
- // there maybe gaps within a track (eg segments)
- // but this should be generally good enough for a simple indicator
- tt->duration = tt->duration + (int)(t2-t1);
+ // Keep track of total time
+ // there maybe gaps within a track (eg segments)
+ // but this should be generally good enough for a simple indicator
+ tt->duration = tt->duration + (int)(t2-t1);
+ }
}
}
if ( tr->trackpoints && vik_track_get_tp_first(tr)->has_timestamp ) {
// %x The preferred date representation for the current locale without the time.
strftime (time_buf1, sizeof(time_buf1), "%x: ", gmtime(&(vik_track_get_tp_first(tr)->timestamp)));
- if ( vik_track_get_tp_last(tr)->has_timestamp ) {
- gint dur = ( (vik_track_get_tp_last(tr)->timestamp) - (vik_track_get_tp_first(tr)->timestamp) );
- if ( dur > 0 )
- g_snprintf ( time_buf2, sizeof(time_buf2), _("- %d:%02d hrs:mins"), (int)round(dur/3600), (int)round((dur/60)%60) );
- }
+ time_t dur = vik_track_get_duration ( tr );
+ if ( dur > 0 )
+ g_snprintf ( time_buf2, sizeof(time_buf2), _("- %d:%02d hrs:mins"), (int)round(dur/3600), (int)round((dur/60)%60) );
}
// Get length and consider the appropriate distance units
gdouble tr_len = vik_track_get_length(tr);
g_free ( auto_save_name );
}
+static void trw_layer_export_geojson ( menu_array_layer values )
+{
+ gchar *auto_save_name = append_file_ext ( vik_layer_get_name(VIK_LAYER(values[MA_VTL])), FILE_TYPE_GEOJSON );
+
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), _("Export Layer"), auto_save_name, NULL, FILE_TYPE_GEOJSON );
+
+ g_free ( auto_save_name );
+}
+
static void trw_layer_export_babel ( gpointer layer_and_vlp[2] )
{
const gchar *auto_save_name = vik_layer_get_name(VIK_LAYER(layer_and_vlp[0]));
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
- a_acquire ( vw, vlp, vvp, datasource, NULL, NULL );
+ vik_datasource_mode_t mode = datasource->mode;
+ if ( mode == VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT )
+ mode = VIK_DATASOURCE_ADDTOLAYER;
+ a_acquire ( vw, vlp, vvp, mode, datasource, NULL, NULL );
}
/*
*/
static void trw_layer_acquire_gps_cb ( menu_array_layer values )
{
- vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
trw_layer_acquire ( values, &vik_datasource_gps_interface );
}
*/
static void trw_layer_acquire_url_cb ( menu_array_layer values )
{
- vik_datasource_url_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
trw_layer_acquire ( values, &vik_datasource_url_interface );
}
{
VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
- vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
trw_layer_acquire ( values, &vik_datasource_geotag_interface );
// Reverify thumbnails as they may have changed
}
#endif
+/*
+ * Acquire into this TRW Layer from any GPS Babel supported file
+ */
+static void trw_layer_acquire_file_cb ( menu_array_layer values )
+{
+ trw_layer_acquire ( values, &vik_datasource_file_interface );
+}
+
static void trw_layer_gps_upload ( menu_array_layer values )
{
menu_array_sublayer data;
turn_off );
}
-/*
- * Acquire into this TRW Layer from any GPS Babel supported file
- */
-static void trw_layer_acquire_file_cb ( menu_array_layer values )
-{
- VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
- VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
- VikViewport *vvp = vik_window_viewport(vw);
-
- a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface, NULL, NULL );
-}
-
static void trw_layer_new_wp ( menu_array_layer values )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
{
VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
vtl->current_track = NULL;
+ vtl->route_finder_started = FALSE;
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
gtk_widget_show ( item );
+ if ( have_geojson_export ) {
+ item = gtk_menu_item_new_with_mnemonic ( _("Export as GEO_JSON...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_geojson), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
+ gtk_widget_show ( item );
+ }
+
item = gtk_menu_item_new_with_mnemonic ( _("Export via GPSbabel...") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_babel), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr )
{
- if ( vtl->route_finder_append && vtl->route_finder_current_track ) {
+ if ( vtl->route_finder_append && vtl->current_track ) {
vik_track_remove_dup_points ( tr ); /* make "double point" track work to undo */
- vik_track_steal_and_append_trackpoints ( vtl->route_finder_current_track, tr );
+
+ // enforce end of current track equal to start of tr
+ VikTrackpoint *cur_end = vik_track_get_tp_last ( vtl->current_track );
+ VikTrackpoint *new_start = vik_track_get_tp_first ( tr );
+ if ( ! vik_coord_equals ( &cur_end->coord, &new_start->coord ) ) {
+ vik_track_add_trackpoint ( vtl->current_track,
+ vik_trackpoint_copy ( cur_end ),
+ FALSE );
+ }
+
+ vik_track_steal_and_append_trackpoints ( vtl->current_track, tr );
vik_track_free ( tr );
vtl->route_finder_append = FALSE; /* this means we have added it */
} else {
vtl->current_tp_track = NULL;
vtl->current_tp_id = NULL;
vtl->moving_tp = FALSE;
+ vtl->route_finder_started = FALSE;
}
was_visible = trk->visible;
- if ( trk == vtl->route_finder_current_track )
- vtl->route_finder_current_track = NULL;
-
if ( trk == vtl->route_finder_added_track )
vtl->route_finder_added_track = NULL;
was_visible = trk->visible;
- if ( trk == vtl->route_finder_current_track )
- vtl->route_finder_current_track = NULL;
-
if ( trk == vtl->route_finder_added_track )
vtl->route_finder_added_track = NULL;
{
vtl->current_track = NULL;
- vtl->route_finder_current_track = NULL;
vtl->route_finder_added_track = NULL;
if (vtl->current_tp_track)
trw_layer_cancel_current_tp(vtl, FALSE);
{
vtl->current_track = NULL;
- vtl->route_finder_current_track = NULL;
vtl->route_finder_added_track = NULL;
if (vtl->current_tp_track)
trw_layer_cancel_current_tp(vtl, FALSE);
VikTrack *track = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
if ( !track )
return;
- if ( !track->trackpoints )
- return;
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER );
- vtl->route_finder_coord = vik_track_get_tp_last(track)->coord;
- vtl->route_finder_current_track = track;
+ vtl->current_track = track;
vtl->route_finder_started = TRUE;
- goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &vtl->route_finder_coord );
+ if ( track->trackpoints )
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &vik_track_get_tp_last(track)->coord );
}
/**
*(user_data->result) = g_list_prepend(*(user_data->result), key);
}
-/* called for each key in track hash table. if original track user_data[1] is close enough
- * to the passed one, add it to list in user_data[0]
+/**
+ * find_nearby_tracks_by_time:
+ *
+ * Called for each track in track hash table.
+ * If the original track (in user_data[1]) is close enough (threshold period in user_data[2])
+ * to the current track, then the current track is added to the list in user_data[0]
*/
static void find_nearby_tracks_by_time (gpointer key, gpointer value, gpointer user_data)
{
- time_t t1, t2;
- VikTrackpoint *p1, *p2;
VikTrack *trk = VIK_TRACK(value);
GList **nearby_tracks = ((gpointer *)user_data)[0];
+ VikTrack *orig_trk = VIK_TRACK(((gpointer *)user_data)[1]);
+
+ if ( !orig_trk || !orig_trk->trackpoints )
+ return;
/* outline:
* detect reasons for not merging, and return
return;
}
- t1 = vik_track_get_tp_first(trk)->timestamp;
- t2 = vik_track_get_tp_last(trk)->timestamp;
+ time_t t1 = vik_track_get_tp_first(orig_trk)->timestamp;
+ time_t t2 = vik_track_get_tp_last(orig_trk)->timestamp;
if (trk->trackpoints) {
- p1 = vik_track_get_tp_first(trk);
- p2 = vik_track_get_tp_last(trk);
+
+ VikTrackpoint *p1 = vik_track_get_tp_first(trk);
+ VikTrackpoint *p2 = vik_track_get_tp_last(trk);
if (!p1->has_timestamp || !p2->has_timestamp) {
//g_print("no timestamp\n");
}
params[0] = &nearby_tracks;
- params[1] = (gpointer)trps;
+ params[1] = orig_trk;
params[2] = GUINT_TO_POINTER (threshold_in_minutes*60); // In seconds
/* get a list of adjacent-in-time tracks */
VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( !wp )
return;
- if ( !strncmp(wp->comment, "http", 4) ) {
+ if ( wp->url ) {
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->url);
+ } else if ( !strncmp(wp->comment, "http", 4) ) {
open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->comment);
} else if ( !strncmp(wp->description, "http", 4) ) {
open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->description);
if ( wp )
{
- if ( ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
+ if ( wp->url ||
+ ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
( wp->description && !strncmp(wp->description, "http", 4) )) {
item = gtk_image_menu_item_new_with_mnemonic ( _("Visit _Webpage") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
if ( response == VIK_TRW_LAYER_TPWIN_SPLIT && vtl->current_tpl->next && vtl->current_tpl->prev )
{
trw_layer_split_at_selected_trackpoint ( vtl, vtl->current_tp_track->is_route ? VIK_TRW_LAYER_SUBLAYER_ROUTE : VIK_TRW_LAYER_SUBLAYER_TRACK );
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
}
else if ( response == VIK_TRW_LAYER_TPWIN_DELETE )
{
if ( vtl->current_tpl )
// Reset dialog with the available adjacent trackpoint
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_FORWARD && vtl->current_tpl->next )
{
if ( vtl->current_tp_track )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->next, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->next, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update(VIK_LAYER(vtl)); /* TODO longone: either move or only update if tp is inside drawing window */
}
else if ( response == VIK_TRW_LAYER_TPWIN_BACK && vtl->current_tpl->prev )
{
if ( vtl->current_tp_track )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->prev, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->prev, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_INSERT && vtl->current_tpl->next )
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 );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
/* set layer name and TP data */
}
if ( vtl->tpwin )
if ( vtl->current_tp_track )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
// NB don't reset the selected trackpoint, thus ensuring it's still in the tpwin
}
}
set_statusbar_msg_info_trkpt ( vtl, tp_params.closest_tp );
if ( vtl->tpwin )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
set_statusbar_msg_info_trkpt ( vtl, tp_params.closest_tp );
if ( vtl->tpwin )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
+ // if we were running the route finder, cancel it
+ vtl->route_finder_started = FALSE;
+
// ----------------------------------------------------- if current is a route - switch to new track
if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && vtl->current_track->is_route ) ))
{
static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
- // -------------------------- if current is a track - switch to new route
- if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && !vtl->current_track->is_route ) ) )
+ // if we were running the route finder, cancel it
+ vtl->route_finder_started = FALSE;
+
+ // -------------------------- if current is a track - switch to new route,
+ if ( event->button == 1 && ( ! vtl->current_track ||
+ (vtl->current_track && !vtl->current_track->is_route ) ) )
{
gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route"));
if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), name, TRUE ) ) ) {
/* diff dist is diff from orig */
if ( vtl->tpwin )
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name, vtl->current_tp_track->is_route );
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
-/*** Route Finder ***/
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
+/*** Extended Route Finder ***/
+
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp)
{
return vvp;
}
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static void tool_extended_route_finder_undo ( VikTrwLayer *vtl )
+{
+ VikCoord *new_end;
+ new_end = vik_track_cut_back_to_double_point ( vtl->current_track );
+ if ( new_end ) {
+ g_free ( new_end );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+
+ /* remove last ' to:...' */
+ if ( vtl->current_track->comment ) {
+ gchar *last_to = strrchr ( vtl->current_track->comment, 't' );
+ if ( last_to && (last_to - vtl->current_track->comment > 1) ) {
+ gchar *new_comment = g_strndup ( vtl->current_track->comment,
+ last_to - vtl->current_track->comment - 1);
+ vik_track_set_comment_no_copy ( vtl->current_track, new_comment );
+ }
+ }
+ }
+}
+
+
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
VikCoord tmp;
if ( !vtl ) return FALSE;
vik_viewport_screen_to_coord ( vvp, event->x, event->y, &tmp );
- if ( event->button == 3 && vtl->route_finder_current_track ) {
- VikCoord *new_end;
- new_end = vik_track_cut_back_to_double_point ( vtl->route_finder_current_track );
- if ( new_end ) {
- vtl->route_finder_coord = *new_end;
- g_free ( new_end );
- vik_layer_emit_update ( VIK_LAYER(vtl) );
- /* remove last ' to:...' */
- if ( vtl->route_finder_current_track->comment ) {
- gchar *last_to = strrchr ( vtl->route_finder_current_track->comment, 't' );
- if ( last_to && (last_to - vtl->route_finder_current_track->comment > 1) ) {
- gchar *new_comment = g_strndup ( vtl->route_finder_current_track->comment,
- last_to - vtl->route_finder_current_track->comment - 1);
- vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
- }
- }
- }
+ if ( event->button == 3 && vtl->current_track ) {
+ tool_extended_route_finder_undo ( vtl );
}
- else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
+ else if ( event->button == 2 ) {
+ vtl->draw_sync_do = FALSE;
+ return FALSE;
+ }
+ // if we started the track but via undo deleted all the track points, begin again
+ else if ( vtl->current_track && vtl->current_track->is_route && ! vik_track_get_tp_first ( vtl->current_track ) ) {
+ return tool_new_track_or_route_click ( vtl, event, vvp );
+ }
+ else if ( ( vtl->current_track && vtl->current_track->is_route ) ||
+ ( event->state & GDK_CONTROL_MASK && vtl->current_track ) ) {
struct LatLon start, end;
- vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
+ VikTrackpoint *tp_start = vik_track_get_tp_last ( vtl->current_track );
+ vik_coord_to_latlon ( &(tp_start->coord), &start );
vik_coord_to_latlon ( &(tmp), &end );
- vtl->route_finder_coord = tmp; /* for continuations */
- /* these are checked when adding a track from a file (vik_trw_layer_filein_add_track) */
- if ( event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track ) {
- vtl->route_finder_append = TRUE; // merge tracks. keep started true.
- } else {
- vtl->route_finder_check_added_track = TRUE;
- vtl->route_finder_started = FALSE;
+ vtl->route_finder_started = TRUE;
+ vtl->route_finder_append = TRUE; // merge tracks. keep started true.
+
+ // update UI to let user know what's going on
+ VikStatusbar *sb = vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)));
+ VikRoutingEngine *engine = vik_routing_default_engine ( );
+ if ( ! engine ) {
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, "Cannot plan route without a default routing engine." );
+ return TRUE;
}
+ gchar *msg = g_strdup_printf ( _("Querying %s for route between (%.3f, %.3f) and (%.3f, %.3f)."),
+ vik_routing_engine_get_label ( engine ),
+ start.lat, start.lon, end.lat, end.lon );
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+ g_free ( msg );
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
- vik_routing_default_find ( vtl, start, end);
- /* see if anything was done -- a track was added or appended to */
- if ( vtl->route_finder_check_added_track && vtl->route_finder_added_track ) {
- vik_track_set_comment_no_copy ( vtl->route_finder_added_track, g_strdup_printf("from: %f,%f to: %f,%f", start.lat, start.lon, end.lat, end.lon ) );
- } else if ( vtl->route_finder_append == FALSE && vtl->route_finder_current_track ) {
- /* route_finder_append was originally TRUE but set to FALSE by filein_add_track */
- gchar *new_comment = g_strdup_printf("%s to: %f,%f", vtl->route_finder_current_track->comment, end.lat, end.lon );
- vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
- }
+ /* Give GTK a change to display the new status bar before querying the web */
+ while ( gtk_events_pending ( ) )
+ gtk_main_iteration ( );
- if ( vtl->route_finder_added_track )
- vik_track_calculate_bounds ( vtl->route_finder_added_track );
+ gboolean find_status = vik_routing_default_find ( vtl, start, end );
- vtl->route_finder_added_track = NULL;
- vtl->route_finder_check_added_track = FALSE;
- vtl->route_finder_append = FALSE;
+ /* Update UI to say we're done */
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+ msg = ( find_status ) ? g_strdup_printf ( _("%s returned route between (%.3f, %.3f) and (%.3f, %.3f)."),
+ vik_routing_engine_get_label ( engine ),
+ start.lat, start.lon, end.lat, end.lon )
+ : g_strdup_printf ( _("Error getting route from %s."),
+ vik_routing_engine_get_label ( engine ) );
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+ g_free ( msg );
vik_layer_emit_update ( VIK_LAYER(vtl) );
} else {
+ vtl->current_track = NULL;
+
+ // create a new route where we will add the planned route to
+ gboolean ret = tool_new_route_click( vtl, event, vvp );
+
vtl->route_finder_started = TRUE;
- vtl->route_finder_coord = tmp;
- vtl->route_finder_current_track = NULL;
+
+ return ret;
}
return TRUE;
}
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp )
+{
+ if ( vtl->current_track && event->keyval == GDK_Escape ) {
+ vtl->route_finder_started = FALSE;
+ vtl->current_track = NULL;
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+ } else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
+ tool_extended_route_finder_undo ( vtl );
+ }
+ return FALSE;
+}
+
+
+
/*** Show picture ****/
static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp)
g_message("%s: this feature works only in Mercator mode", __FUNCTION__);
if (fillins) {
- GList *iter = fillins;
- while (iter) {
- cur_coord = (VikCoord *)(iter->data);
+ GList *fiter = fillins;
+ while (fiter) {
+ cur_coord = (VikCoord *)(fiter->data);
vik_coord_set_area(cur_coord, &wh, &tl, &br);
rect = g_malloc(sizeof(Rect));
rect->tl = tl;
rect->br = br;
rect->center = *cur_coord;
rects_to_download = g_list_prepend(rects_to_download, rect);
- iter = iter->next;
+ fiter = fiter->next;
}
}