]> git.street.me.uk Git - andy/viking.git/commitdiff
Support GPX 'type' field on Waypoints, Tracks and Routes.
authorRob Norris <rw_norris@hotmail.com>
Tue, 9 Feb 2016 20:51:34 +0000 (20:51 +0000)
committerRob Norris <rw_norris@hotmail.com>
Thu, 11 Feb 2016 23:52:28 +0000 (23:52 +0000)
src/gpspoint.c
src/gpx.c
src/viktrack.c
src/viktrack.h
src/viktrwlayer_propwin.c
src/viktrwlayer_wpwin.c
src/vikwaypoint.c
src/vikwaypoint.h

index 8e48315786861fee8659ea8aca46cae48839688f..3e57e53e82b3957cb274a5955f79d3ee2c6b5e38 100644 (file)
@@ -77,6 +77,7 @@ static gchar *line_name;
 static gchar *line_comment;
 static gchar *line_description;
 static gchar *line_source;
+static gchar *line_xtype;
 static gchar *line_color;
 static gint line_name_label = 0;
 static gint line_dist_label = 0;
@@ -249,6 +250,9 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f, const gchar *dirpath )
       if ( line_source )
         vik_waypoint_set_source ( wp, line_source );
 
+      if ( line_xtype )
+        vik_waypoint_set_type ( wp, line_xtype );
+
       if ( line_image ) {
         // Ensure the filename is absolute
         if ( g_path_is_absolute ( line_image ) )
@@ -288,6 +292,9 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f, const gchar *dirpath )
       if ( line_source )
         vik_track_set_source ( pl, line_source );
 
+      if ( line_xtype )
+        vik_track_set_type ( pl, line_xtype );
+
       if ( line_color )
       {
         if ( gdk_color_parse ( line_color, &(pl->color) ) )
@@ -335,6 +342,8 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f, const gchar *dirpath )
       g_free ( line_description );
     if (line_source)
       g_free ( line_source );
+    if (line_xtype)
+      g_free ( line_xtype );
     if (line_color)
       g_free ( line_color );
     if (line_image)
@@ -344,6 +353,7 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f, const gchar *dirpath )
     line_comment = NULL;
     line_description = NULL;
     line_source = NULL;
+    line_xtype = NULL;
     line_color = NULL;
     line_image = NULL;
     line_symbol = NULL;
@@ -467,6 +477,12 @@ static void gpspoint_process_key_and_value ( const gchar *key, guint key_len, co
     if (line_source == NULL)
       line_source = deslashndup ( value, value_len );
   }
+  // NB using 'xtype' to differentiate from our own 'type' key
+  else if (key_len == 5 && strncasecmp( key, "xtype", key_len ) == 0 && value != NULL)
+  {
+    if (line_xtype == NULL)
+      line_xtype = deslashndup ( value, value_len );
+  }
   else if (key_len == 5 && strncasecmp( key, "color", key_len ) == 0 && value != NULL)
   {
     if (line_color == NULL)
@@ -593,6 +609,12 @@ static void a_gpspoint_write_waypoint ( const gpointer id, const VikWaypoint *wp
     fprintf ( f, " source=\"%s\"", tmp_source );
     g_free ( tmp_source );
   }
+  if ( wp->type )
+  {
+    gchar *tmp_type = slashdup(wp->type);
+    fprintf ( f, " xtype=\"%s\"", tmp_type );
+    g_free ( tmp_type );
+  }
   if ( wp->image )
   {
     gchar *tmp_image = NULL;
@@ -727,6 +749,12 @@ static void a_gpspoint_write_track ( const gpointer id, const VikTrack *trk, FIL
     g_free ( tmp );
   }
 
+  if ( trk->type ) {
+    gchar *tmp = slashdup(trk->type);
+    fprintf ( f, " xtype=\"%s\"", tmp );
+    g_free ( tmp );
+  }
+
   if ( trk->has_color ) {
     fprintf ( f, " color=#%.2x%.2x%.2x", (int)(trk->color.red/256),(int)(trk->color.green/256),(int)(trk->color.blue/256));
   }
index f251e432a19a6e5763be5aac14672482e5896f0d..4306191a8d3142f346bd42dc1acefe0f64179f48 100644 (file)
--- a/src/gpx.c
+++ b/src/gpx.c
@@ -60,6 +60,7 @@ typedef enum {
         tt_wpt_cmt,
         tt_wpt_desc,
         tt_wpt_src,
+        tt_wpt_type,
         tt_wpt_name,
         tt_wpt_ele,
         tt_wpt_sym,
@@ -71,6 +72,7 @@ typedef enum {
         tt_trk_cmt,
         tt_trk_desc,
         tt_trk_src,
+        tt_trk_type,
         tt_trk_name,
 
         tt_rte,
@@ -139,6 +141,7 @@ tag_mapping tag_path_map[] = {
         { tt_wpt_cmt, "/gpx/wpt/cmt" },
         { tt_wpt_desc, "/gpx/wpt/desc" },
         { tt_wpt_src, "/gpx/wpt/src" },
+        { tt_wpt_type, "/gpx/wpt/type" },
         { tt_wpt_sym, "/gpx/wpt/sym" },
         { tt_wpt_sym, "/loc/waypoint/type" },
         { tt_wpt_url, "/gpx/wpt/url" },
@@ -149,6 +152,7 @@ tag_mapping tag_path_map[] = {
         { tt_trk_cmt, "/gpx/trk/cmt" },
         { tt_trk_desc, "/gpx/trk/desc" },
         { tt_trk_src, "/gpx/trk/src" },
+        { tt_trk_type, "/gpx/trk/type" },
         { tt_trk_trkseg, "/gpx/trk/trkseg" },
         { tt_trk_trkseg_trkpt, "/gpx/trk/trkseg/trkpt" },
         { tt_trk_trkseg_trkpt_ele, "/gpx/trk/trkseg/trkpt/ele" },
@@ -293,6 +297,7 @@ static void gpx_start(VikTrwLayer *vtl, const char *el, const char **attr)
      case tt_wpt_cmt:
      case tt_wpt_desc:
      case tt_wpt_src:
+     case tt_wpt_type:
      case tt_wpt_name:
      case tt_wpt_ele:
      case tt_wpt_time:
@@ -301,6 +306,7 @@ static void gpx_start(VikTrwLayer *vtl, const char *el, const char **attr)
      case tt_trk_cmt:
      case tt_trk_desc:
      case tt_trk_src:
+     case tt_trk_type:
      case tt_trk_name:
        g_string_erase ( c_cdata, 0, -1 ); /* clear the cdata buffer */
        break;
@@ -438,6 +444,11 @@ static void gpx_end(VikTrwLayer *vtl, const char *el)
        g_string_erase ( c_cdata, 0, -1 );
        break;
 
+     case tt_wpt_type:
+       vik_waypoint_set_type ( c_wp, c_cdata->str );
+       g_string_erase ( c_cdata, 0, -1 );
+       break;
+
      case tt_wpt_url:
        vik_waypoint_set_url ( c_wp, c_cdata->str );
        g_string_erase ( c_cdata, 0, -1 );
@@ -464,6 +475,11 @@ static void gpx_end(VikTrwLayer *vtl, const char *el)
        g_string_erase ( c_cdata, 0, -1 );
        break;
 
+     case tt_trk_type:
+       vik_track_set_type ( c_tr, c_cdata->str );
+       g_string_erase ( c_cdata, 0, -1 );
+       break;
+
      case tt_trk_cmt:
        vik_track_set_comment ( c_tr, c_cdata->str );
        g_string_erase ( c_cdata, 0, -1 );
@@ -555,12 +571,14 @@ static void gpx_cdata(void *dta, const XML_Char *s, int len)
     case tt_wpt_cmt:
     case tt_wpt_desc:
     case tt_wpt_src:
+    case tt_wpt_type:
     case tt_wpt_sym:
     case tt_wpt_url:
     case tt_wpt_link:
     case tt_trk_cmt:
     case tt_trk_desc:
     case tt_trk_src:
+    case tt_trk_type:
     case tt_trk_trkseg_trkpt_time:
     case tt_wpt_time:
     case tt_trk_trkseg_trkpt_name:
@@ -849,6 +867,12 @@ static void gpx_write_waypoint ( VikWaypoint *wp, GpxWritingContext *context )
     fprintf ( f, "  <src>%s</src>\n", tmp );
     g_free ( tmp );
   }
+  if ( wp->type )
+  {
+    tmp = entitize(wp->type);
+    fprintf ( f, "  <type>%s</type>\n", tmp );
+    g_free ( tmp );
+  }
   if ( wp->url )
   {
     tmp = entitize(wp->url);
@@ -1030,6 +1054,13 @@ static void gpx_write_track ( VikTrack *t, GpxWritingContext *context )
     g_free ( tmp );
   }
 
+  if ( t->type )
+  {
+    tmp = entitize ( t->type );
+    fprintf ( f, "  <type>%s</type>\n", tmp );
+    g_free ( tmp );
+  }
+
   /* No such thing as a rteseg! */
   if ( !t->is_route )
     fprintf ( f, "  <trkseg>\n" );
index fac2594c6c46f54a72be660caf8359973fd6c7a2..0a5dd73bc9931a23f82ad72ad7ef90bfb87e51cd 100644 (file)
@@ -116,6 +116,17 @@ void vik_track_set_source(VikTrack *tr, const gchar *source)
     tr->source = NULL;
 }
 
+void vik_track_set_type(VikTrack *tr, const gchar *type)
+{
+  if ( tr->type )
+    g_free ( tr->type );
+
+  if ( type && type[0] != '\0' )
+    tr->type = g_strdup(type);
+  else
+    tr->type = NULL;
+}
+
 void vik_track_ref(VikTrack *tr)
 {
   tr->ref_count++;
@@ -145,6 +156,8 @@ void vik_track_free(VikTrack *tr)
     g_free ( tr->description );
   if ( tr->source )
     g_free ( tr->source );
+  if ( tr->type )
+    g_free ( tr->type );
   g_list_foreach ( tr->trackpoints, (GFunc) vik_trackpoint_free, NULL );
   g_list_free( tr->trackpoints );
   if (tr->property_dialog)
index 8d78fb637bd9adc2774bda141a24e033a9c56d92..9397466658030820501967a764606c404b58cf4e 100644 (file)
@@ -85,6 +85,7 @@ struct _VikTrack {
   gchar *comment;
   gchar *description;
   gchar *source;
+  gchar *type;
   guint8 ref_count;
   gchar *name;
   GtkWidget *property_dialog;
@@ -99,6 +100,7 @@ void vik_track_set_name(VikTrack *tr, const gchar *name);
 void vik_track_set_comment(VikTrack *tr, const gchar *comment);
 void vik_track_set_description(VikTrack *tr, const gchar *description);
 void vik_track_set_source(VikTrack *tr, const gchar *source);
+void vik_track_set_type(VikTrack *tr, const gchar *type);
 void vik_track_ref(VikTrack *tr);
 void vik_track_free(VikTrack *tr);
 VikTrack *vik_track_copy ( const VikTrack *tr, gboolean copy_points );
index c49216e457d4ab94549cf20e6834352df126cdd9..be0e3d6fb1931e35b16fa7316874e7897c3f1be1 100644 (file)
@@ -132,6 +132,7 @@ typedef struct _propwidgets {
   GtkWidget *w_comment;
   GtkWidget *w_description;
   GtkWidget *w_source;
+  GtkWidget *w_type;
   GtkWidget *w_track_length;
   GtkWidget *w_tp_count;
   GtkWidget *w_segment_count;
@@ -2883,6 +2884,7 @@ static void propwin_response_cb( GtkDialog *dialog, gint resp, PropWidgets *widg
       vik_track_set_comment(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_comment)));
       vik_track_set_description(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_description)));
       vik_track_set_source(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_source)));
+      vik_track_set_type(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_type)));
       gtk_color_button_get_color ( GTK_COLOR_BUTTON(widgets->w_color), &(tr->color) );
       tr->draw_name_mode = gtk_combo_box_get_active ( GTK_COMBO_BOX(widgets->w_namelabel) );
       tr->max_number_dist_labels = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widgets->w_number_distlabels) );
@@ -3134,6 +3136,7 @@ void vik_trw_layer_propwin_run ( GtkWindow *parent,
     N_("<b>Comment:</b>"),
     N_("<b>Description:</b>"),
     N_("<b>Source:</b>"),
+    N_("<b>Type:</b>"),
     N_("<b>Color:</b>"),
     N_("<b>Draw Name:</b>"),
     N_("<b>Distance Labels:</b>"),
@@ -3172,6 +3175,11 @@ void vik_trw_layer_propwin_run ( GtkWindow *parent,
     gtk_entry_set_text ( GTK_ENTRY(widgets->w_source), tr->source );
   content_prop[cnt_prop++] = widgets->w_source;
 
+  widgets->w_type = gtk_entry_new ();
+  if ( tr->type )
+    gtk_entry_set_text ( GTK_ENTRY(widgets->w_type), tr->type );
+  content_prop[cnt_prop++] = widgets->w_type;
+
   widgets->w_color = content_prop[cnt_prop++] = gtk_color_button_new_with_color ( &(tr->color) );
 
   static gchar *draw_name_labels[] = {
index 2d71fa3a8ab2177194e05c1f873a0c8c6df91530..4f01238f05e2eee1a09e3ca63955524eedb89266 100644 (file)
@@ -113,6 +113,7 @@ gchar *a_dialog_waypoint ( GtkWindow *parent, gchar *default_name, VikTrwLayer *
   GtkWidget *latlabel, *lonlabel, *namelabel, *latentry, *lonentry, *altentry, *altlabel, *nameentry=NULL;
   GtkWidget *commentlabel, *commententry, *descriptionlabel, *descriptionentry, *imagelabel, *imageentry, *symbollabel, *symbolentry;
   GtkWidget *sourcelabel = NULL, *sourceentry = NULL;
+  GtkWidget *typelabel = NULL, *typeentry = NULL;
   GtkWidget *timelabel = NULL;
   GtkWidget *timevaluebutton = NULL;
   GtkWidget *hasGeotagCB = NULL;
@@ -187,6 +188,12 @@ gchar *a_dialog_waypoint ( GtkWindow *parent, gchar *default_name, VikTrwLayer *
     gtk_entry_set_text(GTK_ENTRY(sourceentry), wp->source);
   }
 
+  typelabel = gtk_label_new (_("Type:"));
+  if ( wp->type ) {
+    typeentry = gtk_entry_new ();
+    gtk_entry_set_text(GTK_ENTRY(typeentry), wp->type);
+  }
+
   imagelabel = gtk_label_new (_("Image:"));
   imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN, VF_FILTER_IMAGE, NULL, NULL);
 
@@ -300,6 +307,10 @@ gchar *a_dialog_waypoint ( GtkWindow *parent, gchar *default_name, VikTrwLayer *
     gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), sourcelabel, FALSE, FALSE, 0);
     gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), sourceentry, FALSE, FALSE, 0);
   }
+  if ( wp->type ) {
+    gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), typelabel, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), typeentry, FALSE, FALSE, 0);
+  }
   gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), imagelabel, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), imageentry, FALSE, FALSE, 0);
   if ( hasGeotagCB ) {
@@ -352,6 +363,8 @@ gchar *a_dialog_waypoint ( GtkWindow *parent, gchar *default_name, VikTrwLayer *
         vik_waypoint_set_image ( wp, vik_file_entry_get_filename ( VIK_FILE_ENTRY(imageentry) ) );
       if ( g_strcmp0 ( wp->source, gtk_entry_get_text ( GTK_ENTRY(sourceentry) ) ) )
         vik_waypoint_set_source ( wp, gtk_entry_get_text ( GTK_ENTRY(sourceentry) ) );
+      if ( g_strcmp0 ( wp->type, gtk_entry_get_text ( GTK_ENTRY(typeentry) ) ) )
+        vik_waypoint_set_type ( wp, gtk_entry_get_text ( GTK_ENTRY(typeentry) ) );
       if ( wp->image && *(wp->image) && (!a_thumbnails_exists(wp->image)) )
         a_thumbnails_create ( wp->image );
       if ( edit_wp->timestamp ) {
index 136aead5234b4dd5db8b4b533931eaaab519798d..fad5589f3d9f6d3c83764bdd5d08839f7dd69985 100644 (file)
@@ -86,6 +86,17 @@ void vik_waypoint_set_source(VikWaypoint *wp, const gchar *source)
     wp->source = NULL;
 }
 
+void vik_waypoint_set_type(VikWaypoint *wp, const gchar *type)
+{
+  if ( wp->type )
+    g_free ( wp->type );
+
+  if ( type && type[0] != '\0' )
+    wp->type = g_strdup(type);
+  else
+    wp->type = NULL;
+}
+
 void vik_waypoint_set_url(VikWaypoint *wp, const gchar *url)
 {
   if ( wp->url )
@@ -139,6 +150,8 @@ void vik_waypoint_free(VikWaypoint *wp)
     g_free ( wp->description );
   if ( wp->source )
     g_free ( wp->source );
+  if ( wp->type )
+    g_free ( wp->type );
   if ( wp->url )
     g_free ( wp->url );
   if ( wp->image )
@@ -160,6 +173,7 @@ VikWaypoint *vik_waypoint_copy(const VikWaypoint *wp)
   vik_waypoint_set_comment(new_wp,wp->comment);
   vik_waypoint_set_description(new_wp,wp->description);
   vik_waypoint_set_source(new_wp,wp->source);
+  vik_waypoint_set_type(new_wp,wp->type);
   vik_waypoint_set_url(new_wp,wp->url);
   vik_waypoint_set_image(new_wp,wp->image);
   vik_waypoint_set_symbol(new_wp,wp->symbol);
@@ -211,6 +225,7 @@ void vik_waypoint_marshall ( VikWaypoint *wp, guint8 **data, guint *datalen)
   vwm_append(wp->comment);
   vwm_append(wp->description);
   vwm_append(wp->source);
+  vwm_append(wp->type);
   vwm_append(wp->url);
   vwm_append(wp->image);
   vwm_append(wp->symbol);
@@ -247,6 +262,7 @@ VikWaypoint *vik_waypoint_unmarshall (guint8 *data, guint datalen)
   vwu_get(new_wp->comment);
   vwu_get(new_wp->description);
   vwu_get(new_wp->source);
+  vwu_get(new_wp->type);
   vwu_get(new_wp->url);
   vwu_get(new_wp->image); 
   vwu_get(new_wp->symbol);
index a1680058b9b994946e14d9955946850f84a033e6..555a46591bbf4cfe66d84c5166fb4b0d6b6e0b32 100644 (file)
@@ -43,6 +43,7 @@ struct _VikWaypoint {
   gchar *comment;
   gchar *description;
   gchar *source;
+  gchar *type;
   gchar *url;
   gchar *image;
   /* a rather misleading, ugly hack needed for trwlayer's click image.
@@ -60,6 +61,7 @@ void vik_waypoint_set_name(VikWaypoint *wp, const gchar *name);
 void vik_waypoint_set_comment(VikWaypoint *wp, const gchar *comment);
 void vik_waypoint_set_description(VikWaypoint *wp, const gchar *description);
 void vik_waypoint_set_source(VikWaypoint *wp, const gchar *source);
+void vik_waypoint_set_type(VikWaypoint *wp, const gchar *type);
 void vik_waypoint_set_url(VikWaypoint *wp, const gchar *url);
 void vik_waypoint_set_image(VikWaypoint *wp, const gchar *image);
 void vik_waypoint_set_symbol(VikWaypoint *wp, const gchar *symname);