Hello list,

the last patch was based on 1.5.1 so it's probably hard to apply it to trunk, 
esp. since work on timestamps already had been done in the repo.  Please find 
attached patch that has been rebased on current trunk, stripped of the custom 
date time picker in favor of what's been commited to trunk..

The patch adds menu entries and functions to

- interpolate timestamps of a track between first and last trackpoint
- have some more external program calls for a selected trackpoint
  -> remote control josm, either loading and zooming or just zooming
  -> browse geohack or osm.org

It also fixes a bug concerning
  static menu_array_sublayer pass_along

The MA_MISC field of this static was modified more than once, but 
g_signal_connect_swapped() will not make a copy of this struct.  Essentially 
this means, all menu item callbacks would be called with the same MA_MISC value 
- i.e. the one assigned last.  This bug was fixed by copying the struct to a 
dedicated one for each g_signal_connect_swapped taking a modified-from-default 
pass_along value.


Cheers,
Christian
 src/dialog.c      |   3 ++
 src/viktrack.c    |  44 ++++++++++++++++
 src/viktrack.h    |   1 +
 src/viktrwlayer.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 192 insertions(+), 6 deletions(-)

diff --git a/src/dialog.c b/src/dialog.c
index 9bc2848..666e5c6 100644
--- a/src/dialog.c
+++ b/src/dialog.c
@@ -371,6 +371,9 @@ GtkWidget *a_dialog_create_label_vbox ( gchar **texts, int label_count, gint spa
   {
     label = gtk_label_new(NULL);
     gtk_label_set_markup ( GTK_LABEL(label), _(texts[i]) );
+    if ( strchr(texts[i], ':') ) {
+      gtk_misc_set_alignment ( GTK_MISC(label), 1.0, 0.5 );
+    }
     gtk_box_pack_start ( GTK_BOX(vbox), label, FALSE, TRUE, padding );
   }
   return vbox;
diff --git a/src/viktrack.c b/src/viktrack.c
index 7c8b071..0d335ad 100644
--- a/src/viktrack.c
+++ b/src/viktrack.c
@@ -1616,6 +1616,50 @@ void vik_track_anonymize_times ( VikTrack *tr )
 
 
 /**
+ * vik_track_interpolate_times:
+ *
+ * Interpolate the timestamps between first and last trackpoint,
+ * so that the track is driven at equal speed, regardless of the
+ * distance between individual trackpoints.
+ */
+void vik_track_interpolate_times ( VikTrack *tr )
+{
+  gdouble tr_dist, cur_dist;
+  time_t tsdiff, tsfirst;
+
+  GList *iter;
+  iter = tr->trackpoints;
+
+  VikTrackpoint *tp = VIK_TRACKPOINT(iter->data);
+  if ( tp->has_timestamp ) {
+    tsfirst = tp->timestamp;
+
+    while ( iter->next ) {
+      iter = iter->next;
+    }
+    tp = VIK_TRACKPOINT(iter->data);
+    if ( tp->has_timestamp ) {
+      tsdiff = tp->timestamp - tsfirst;
+
+      tr_dist = vik_track_get_length_including_gaps ( tr );
+      cur_dist = 0.0;
+
+      if ( tr_dist > 0 ) {
+        iter = tr->trackpoints;
+        while ( iter->next && iter->next->next ) {
+          iter = iter->next;
+          tp = VIK_TRACKPOINT(iter->data);
+          cur_dist += vik_coord_diff ( &(tp->coord), &(VIK_TRACKPOINT(iter->prev->data)->coord) );
+
+          tp->timestamp = (cur_dist / tr_dist) * tsdiff + tsfirst;
+        }
+      }
+    }
+  }
+}
+
+
+/**
  * vik_track_apply_dem_data:
  * @skip_existing: When TRUE, don't change the elevation if the trackpoint already has a value
  *
diff --git a/src/viktrack.h b/src/viktrack.h
index d2de2a9..5a2ac4c 100644
--- a/src/viktrack.h
+++ b/src/viktrack.h
@@ -150,6 +150,7 @@ VikTrack *vik_track_unmarshall (guint8 *data, guint datalen);
 void vik_track_calculate_bounds ( VikTrack *trk );
 
 void vik_track_anonymize_times ( VikTrack *tr );
+void vik_track_interpolate_times ( VikTrack *tr );
 gulong vik_track_apply_dem_data ( VikTrack *tr, gboolean skip_existing );
 void vik_track_apply_dem_data_last_trackpoint ( VikTrack *tr );
 gulong vik_track_smooth_missing_elevation_data ( VikTrack *tr, gboolean flat );
diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c
index 72c8964..d998499 100644
--- a/src/viktrwlayer.c
+++ b/src/viktrwlayer.c
@@ -111,6 +111,11 @@
 #define DRAW_ELEVATION_FACTOR 30 /* height of elevation plotting, sort of relative to zoom level ("mpp" that isn't mpp necessarily) */
                                  /* this is multiplied by user-inputted value from 1-100. */
 
+#define BROWSE_TP_GEOHACK 1
+#define BROWSE_TP_OSM 2
+#define BROWSE_TP_LOADZOOM_JOSM 3
+#define BROWSE_TP_ZOOM_JOSM 4
+
 enum { WP_SYMBOL_FILLED_SQUARE, WP_SYMBOL_SQUARE, WP_SYMBOL_CIRCLE, WP_SYMBOL_X, WP_NUM_SYMBOLS };
 
 // See http://developer.gnome.org/pango/stable/PangoMarkupFormat.html
@@ -5318,6 +5323,19 @@ static void trw_layer_anonymize_times ( menu_array_sublayer values )
     vik_track_anonymize_times ( track );
 }
 
+static void trw_layer_interpolate_times ( menu_array_sublayer values )
+{
+  VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+  VikTrack *track;
+  if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+    track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+  else
+    track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+  if ( track )
+    vik_track_interpolate_times ( track );
+}
+
 static void trw_layer_extend_track_end ( menu_array_sublayer values )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
@@ -6851,6 +6869,79 @@ static void trw_layer_astro ( menu_array_sublayer values )
 }
 
 /**
+ * Open a browser with a webservice centered at position of trackpoint
+ */
+static void trw_layer_browse_tp ( menu_array_sublayer values )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+
+  if ( GPOINTER_TO_INT(values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+    VikTrack *trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+    if ( ! trk )
+      return;
+
+    VikTrackpoint *tp = NULL;
+    if ( vtl->current_tpl )
+      // Current Trackpoint
+      tp = VIK_TRACKPOINT(vtl->current_tpl->data);
+    else if ( trk->trackpoints )
+      // Otherwise first trackpoint
+      tp = VIK_TRACKPOINT(trk->trackpoints->data);
+    else
+      // Give up
+      return;
+
+    struct LatLon ll;
+    vik_coord_to_latlon ( &tp->coord, &ll );
+
+    gchar url[0xFF], lat[0x1F], lon[0x1f], *cmd = NULL;
+    g_snprintf ( lat, sizeof(lat), "%d.%d", (int)ll.lat, (int)(1e6*(ll.lat-(int)ll.lat)));
+    g_snprintf ( lon, sizeof(lon), "%d.%d", (int)ll.lon, (int)(1e6*(ll.lon-(int)ll.lon)));
+
+    switch ( GPOINTER_TO_INT( values[MA_MISC] ) ) {
+      case BROWSE_TP_GEOHACK: {
+        g_snprintf ( url, sizeof(url),
+          "http://tools.wmflabs.org/geohack/geohack.php?params=%s;%s";,
+          lat, lon );
+        open_url ( VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), url );
+        break;
+      }
+      case BROWSE_TP_OSM: {
+        g_snprintf ( url, sizeof(url),
+          "http://www.openstreetmap.org/?mlat=%s&mlon=%s#map=14/%s/%s";,
+          lat, lon, lat, lon );
+        open_url ( VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), url );
+        break;
+      }
+      case BROWSE_TP_LOADZOOM_JOSM: {
+        cmd = "load_and_zoom";
+        /* fall through */;;
+      }
+      case BROWSE_TP_ZOOM_JOSM: {
+        if ( !cmd ) cmd = "zoom";
+
+        ll.lat += 0.001;
+        ll.lon -= 0.002;
+        g_snprintf ( lat, sizeof(lat), "%d.%d", (int)ll.lat, (int)(1e6*(ll.lat-(int)ll.lat)));
+        g_snprintf ( lon, sizeof(lon), "%d.%d", (int)ll.lon, (int)(1e6*(ll.lon-(int)ll.lon)));
+
+        gchar bottom[0x1F], right[0x1f];
+        ll.lat -= 0.002;
+        ll.lon += 0.004;
+        g_snprintf ( bottom, sizeof(bottom), "%d.%d", (int)ll.lat, (int)(1e6*(ll.lat-(int)ll.lat)));
+        g_snprintf ( right, sizeof(right), "%d.%d", (int)ll.lon, (int)(1e6*(ll.lon-(int)ll.lon)));
+
+        g_snprintf ( url, sizeof(url),
+          "http://127.0.0.1:8111/%s?top=%s%%26left=%s%%26bottom=%s%%26right=%s%%26new_layer=true";,
+          cmd, lat, lon, bottom, right );
+        open_url ( VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), url );
+        break;
+      }
+    }
+  }
+}
+
+/**
  * Similar to trw_layer_enum_item, but this uses a sorted method
  */
 /* Currently unused
@@ -7876,11 +7967,13 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
       if ( wp && wp->image )
       {
         // Set up image paramater
-        pass_along[MA_MISC] = wp->image;
+        static menu_array_sublayer pass_along_1;
+        memcpy(pass_along_1, pass_along, sizeof(pass_along_1));
+        pass_along_1[MA_MISC] = 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 ("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 );
+        g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_show_picture), pass_along_1 );
         gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
         gtk_widget_show ( item );
 
@@ -8459,6 +8552,12 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
       gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
       gtk_widget_set_tooltip_text (item, _("Shift timestamps to a relative offset from 1901-01-01"));
       gtk_widget_show ( item );
+
+      item = gtk_image_menu_item_new_with_mnemonic ( _("_Interpolate Times") );
+      g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_interpolate_times), pass_along );
+      gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+      gtk_widget_set_tooltip_text (item, _("Interpolate TP-Times between first and last TP such that track is traveled at equal speed"));
+      gtk_widget_show ( item );
     }
 
     if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
@@ -8533,7 +8632,7 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
   }
 
   // Only made available if a suitable program is installed
-  if ( (have_astro_program || have_diary_program) &&
+  if ( /*(have_astro_program || have_diary_program) &&*/
        (subtype == VIK_TRW_LAYER_SUBLAYER_TRACK || subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) ) {
     GtkWidget *external_submenu;
     external_submenu = gtk_menu_new ();
@@ -8557,6 +8656,44 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
       gtk_menu_shell_append ( GTK_MENU_SHELL(external_submenu), item );
       gtk_widget_show ( item );
     }
+
+    static menu_array_sublayer pass_along_2;
+    memcpy(pass_along_2, pass_along, sizeof(pass_along_2));
+    pass_along_2[MA_MISC] = GINT_TO_POINTER ( BROWSE_TP_GEOHACK );
+    item = gtk_image_menu_item_new_with_mnemonic ( _("Browse with _Geohack") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_browse_tp), pass_along_2 );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(external_submenu), item );
+    gtk_widget_set_tooltip_text ( item, _("Browse selected trackpoint with Geohack") );
+    gtk_widget_show ( item );
+
+#ifdef VIK_CONFIG_OPENSTREETMAP
+    static menu_array_sublayer pass_along_3;
+    memcpy(pass_along_3, pass_along, sizeof(pass_along_3));
+    pass_along_3[MA_MISC] = GINT_TO_POINTER ( BROWSE_TP_OSM );
+    item = gtk_image_menu_item_new_with_mnemonic ( _("Browse with _OpenStreetMap") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_browse_tp), pass_along_3 );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(external_submenu), item );
+    gtk_widget_set_tooltip_text ( item, _("Browse location of trackpoint using OpenStreetMap") );
+    gtk_widget_show ( item );
+
+    static menu_array_sublayer pass_along_4;
+    memcpy(pass_along_4, pass_along, sizeof(pass_along_4));
+    pass_along_4[MA_MISC] = GINT_TO_POINTER ( BROWSE_TP_LOADZOOM_JOSM );
+    item = gtk_image_menu_item_new_with_mnemonic ( _("Zomm to and load in _JOSM") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_browse_tp), pass_along_4 );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(external_submenu), item );
+    gtk_widget_set_tooltip_text ( item, _("Zoom to and Load a small area around this point in JOSM") );
+    gtk_widget_show ( item );
+
+    static menu_array_sublayer pass_along_5;
+    memcpy(pass_along_5, pass_along, sizeof(pass_along_5));
+    pass_along_5[MA_MISC] = GINT_TO_POINTER ( BROWSE_TP_ZOOM_JOSM );
+    item = gtk_image_menu_item_new_with_mnemonic ( _("_Load in JOSM") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_browse_tp), pass_along_5 );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(external_submenu), item );
+    gtk_widget_set_tooltip_text ( item, _("Zoom to an area around this point in JOSM") );
+    gtk_widget_show ( item );
+#endif
   }
 
 #ifdef VIK_CONFIG_GOOGLE
@@ -8573,11 +8710,12 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
   // Some things aren't usable with routes
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
 #ifdef VIK_CONFIG_OPENSTREETMAP
+    static menu_array_sublayer pass_along_6;
+    memcpy(pass_along_6, pass_along, sizeof(pass_along_6));
+    pass_along_6[MA_MISC] = g_hash_table_lookup ( l->tracks, sublayer); // Convert internal pointer into track
     item = gtk_image_menu_item_new_with_mnemonic ( _("Upload to _OSM...") );
-    // Convert internal pointer into track
-    pass_along[MA_MISC] = g_hash_table_lookup ( l->tracks, sublayer);
     gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
-    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_osm_traces_upload_track_cb), pass_along );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_osm_traces_upload_track_cb), pass_along_6 );
     gtk_menu_shell_append ( GTK_MENU_SHELL(upload_submenu), item );
     gtk_widget_show ( item );
 #endif
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Viking-devel mailing list
Viking-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/viking-devel
Viking home page: http://viking.sf.net/

Reply via email to