]> git.street.me.uk Git - andy/viking.git/commitdiff
Automatically remove suspicious first points of GPX Tracks.
authorRob Norris <rw_norris@hotmail.com>
Sat, 29 Apr 2017 16:40:08 +0000 (17:40 +0100)
committerRob Norris <rw_norris@hotmail.com>
Sat, 29 Apr 2017 16:43:58 +0000 (17:43 +0100)
ATM Primarily to remove dodgy first point inserted back at previous
 location by some Garmin GPS Etrex units after being significantly moved.

Advanced configuration options allow fine tuning the removal settings.

help/C/viking.xml
src/gpx.c
src/viktrack.c
src/viktrack.h
src/viktrwlayer.c
src/viktrwlayer.h

index 57b1f7f53eadba9d15e55ee952cd7159bf52dc2c..705b4fc071c5389588f3fac62ce928b11cffafa2 100644 (file)
@@ -3458,6 +3458,15 @@ Accept: */*
         <para>Some values in this file are <emphasis>read only</emphasis>, in the sense that there is no way to set it other than by manually entering in the keys and values (the key will not exist in the file otherwise). This allows some fine tuning of &app; behaviours, without resorting to recompiling the code. However is it not expected that these values should need to be changed for a normal user, hence no GUI options for these have been provided.</para>
         <para>Here is the list of the <emphasis>read only</emphasis> keys and their default values.</para>
        <orderedlist>
+         <listitem>
+           <para>gpx_tidy_points=true</para>
+           <para>ATM Only attempts to remove a suspicious first point of a GPX track
+                       (as opposed to any points within a track).</para>
+         </listitem>
+         <listitem>
+           <para>gpx_tidy_points_max_speed=340</para>
+           <para>Over this speed (in metres per second) for the first pair of points - the first point is removed.</para>
+         </listitem>
          <listitem>
            <para>layers_create_trw_auto_default=false</para>
            <para>Create new TrackWaypoint layers without showing the layer properties dialog first.</para>
index f11d781397256151aad6522c393ec55e7cfc8e1d..dc9c42f739752b06f9a3cf5dc74893abec3c8502 100644 (file)
--- a/src/gpx.c
+++ b/src/gpx.c
@@ -334,6 +334,35 @@ static void gpx_start(VikTrwLayer *vtl, const char *el, const char **attr)
   }
 }
 
+// Allow user override / refinement of GPX tidying
+#define VIK_SETTINGS_GPX_TIDY "gpx_tidy_points"
+#define VIK_SETTINGS_GPX_TIDY_SPEED "gpx_tidy_points_max_speed"
+
+/**
+ *
+ */
+static void track_tidy_processing ( VikTrwLayer *vtl )
+{
+  // Default to automatically attempt tiding
+  gboolean do_tidy = TRUE;
+  gboolean btmp = TRUE;
+  if ( a_settings_get_boolean ( VIK_SETTINGS_GPX_TIDY, &btmp ) )
+     do_tidy = btmp;
+
+  if ( do_tidy ) {
+    // highly unlikely to be going faster than this, especially for the first point
+    guint speed = 340; // Speed of Sound
+
+    gint itmp = 0;
+    if ( a_settings_get_integer ( VIK_SETTINGS_GPX_TIDY_SPEED, &itmp ) )
+      speed = (guint)itmp;
+
+    // NB bounds calculated in subsequent layer post read,
+    //  so no need to do it now
+    vik_trw_layer_tidy_tracks ( vtl, speed, FALSE );
+  }
+}
+
 static void gpx_end(VikTrwLayer *vtl, const char *el)
 {
   static GTimeVal tp_time;
@@ -346,6 +375,11 @@ static void gpx_end(VikTrwLayer *vtl, const char *el)
      case tt_gpx:
        vik_trw_layer_set_metadata ( vtl, c_md );
        c_md = NULL;
+
+       // Essentially the end for a TrackWaypoint layer,
+       //  so any specific GPX post processing can occur here
+       track_tidy_processing ( vtl );
+
        break;
 
      case tt_gpx_name:
index 0a5dd73bc9931a23f82ad72ad7ef90bfb87e51cd..0b76dc1246717c51f7627a8289fd572a1976fc5a 100644 (file)
@@ -461,6 +461,54 @@ gulong vik_track_remove_same_time_points ( VikTrack *tr )
   return num;
 }
 
+/**
+ * vik_track_remove_dodgy_first_point:
+ * @vt:            The track
+ * @speed:         Maximum speed in m/s between points allowed
+ * @recalc_bounds: Whether track bounds should be recalculated
+ *           (i.e. can be skipped if bounds will get calculated later on)
+ *
+ * Returns: Whether the first point was removed
+ *
+ * ATM Primarily to remove dodgy first point inserted back at previous
+ *  location by some Garmin GPS Etrex units after being significantly moved
+ * e.g. you've driven somewhere else and start recording a new cycle/walk etc...
+ *
+ * NB This function is limited to just handling first point issues,
+ *  rather than a more comprehensive attempt to remove any suspicious points
+ *  through-out the track.
+ */
+gboolean vik_track_remove_dodgy_first_point ( VikTrack *vt, guint speed, gboolean recalc_bounds )
+{
+  gboolean deleted = FALSE;
+
+  if ( vt->trackpoints ) {
+    GList *iter = g_list_first ( vt->trackpoints );
+    VikTrackpoint *tp1 = VIK_TRACKPOINT(iter->data);
+
+    if ( tp1->has_timestamp ) {
+      if ( iter->next ) {
+        VikTrackpoint *tp2 = VIK_TRACKPOINT(iter->next->data);
+        if ( tp2->has_timestamp ) {
+          gdouble dist_diff = vik_coord_diff ( &tp1->coord, &tp2->coord );
+          time_t time_diff = tp2->timestamp - tp1->timestamp;
+
+         gdouble spd = fabs(dist_diff / (gint)time_diff);
+          if ( spd > speed ) {
+            deleted = TRUE;
+            vik_trackpoint_free ( tp1 );
+            vt->trackpoints = g_list_delete_link ( vt->trackpoints, iter );
+            if ( recalc_bounds )
+              vik_track_calculate_bounds ( vt );
+         }
+       }
+      }
+    }
+  }
+
+  return deleted;
+}
+
 /*
  * Deletes all 'extra' trackpoint information
  *  such as time stamps, speed, course etc...
index 9397466658030820501967a764606c404b58cf4e..b2179447aad3e45621788e4f408aeef68de17fd4 100644 (file)
@@ -126,6 +126,8 @@ gulong vik_track_remove_dup_points ( VikTrack *vt );
 gulong vik_track_get_same_time_point_count ( const VikTrack *vt );
 gulong vik_track_remove_same_time_points ( VikTrack *vt );
 
+gboolean vik_track_remove_dodgy_first_point ( VikTrack *vt, guint speed, gboolean recalc_bounds );
+
 void vik_track_to_routepoints ( VikTrack *tr );
 
 gdouble vik_track_get_max_speed(const VikTrack *tr);
index 915713b7d85c0969673d1de42f96bea8dca038a2..18d4f040a78c025854937646811f1db15a56fa5d 100644 (file)
@@ -4666,6 +4666,22 @@ void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t
   }
 }
 
+/**
+ * ATM Only for removing bad first points
+ */
+void vik_trw_layer_tidy_tracks ( VikTrwLayer *vtl, guint speed, gboolean recalc_bounds )
+{
+  GHashTableIter iter;
+  gpointer key, value;
+
+  g_hash_table_iter_init ( &iter, vtl->tracks );
+  while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+    VikTrack *trk = VIK_TRACK(value);
+    if ( vik_track_remove_dodgy_first_point ( trk, speed, FALSE ) )
+      g_printf ( "%s: Removed dodgy first point from track: %s\n", __FUNCTION__, trk->name );
+  }
+}
+
 static void trw_layer_enum_item ( gpointer id, GList **tr, GList **l )
 {
   *l = g_list_append(*l, id);
index 0acc9e46a4a6a8ff9f9901d725ce85fd1166aca6..480e57e024379737f2a2a61cb07328b9065e1ba4 100644 (file)
@@ -77,6 +77,8 @@ gboolean vik_trw_layer_find_date ( VikTrwLayer *vtl, const gchar *date_str, VikC
 void vik_trw_layer_filein_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp );
 void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr );
 
+void vik_trw_layer_tidy_tracks ( VikTrwLayer *vtl, guint speed, gboolean recalc_bounds );
+
 gint vik_trw_layer_get_property_tracks_line_thickness ( VikTrwLayer *vtl );
 
 void vik_trw_layer_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp );