]> git.street.me.uk Git - andy/viking.git/blobdiff - src/gpspoint.c
SF#3601584: Fix minimum vertical size for the track properties dialog.
[andy/viking.git] / src / gpspoint.c
index 5018d8cf10ff88ee38664270e30809ee71e1e5da..868168b9f5398f8d6a14fc48399989149481debd 100644 (file)
 #include <stdlib.h>
 /* strtod */
 
+typedef struct {
+  FILE *f;
+  gboolean is_route;
+} TP_write_info_type;
 
 static void a_gpspoint_write_track ( const gpointer id, const VikTrack *t, FILE *f );
-static void a_gpspoint_write_trackpoint ( VikTrackpoint *tp, FILE *f );
+static void a_gpspoint_write_trackpoint ( VikTrackpoint *tp, TP_write_info_type *write_info );
 static void a_gpspoint_write_waypoint ( const gpointer id, const VikWaypoint *wp, FILE *f );
 
 
@@ -62,10 +66,9 @@ static char line_buffer[2048];
 #define GPSPOINT_TYPE_NONE 0
 #define GPSPOINT_TYPE_WAYPOINT 1
 #define GPSPOINT_TYPE_TRACKPOINT 2
-/* #define GPSPOINT_TYPE_ROUTEPOINT 3 */
+#define GPSPOINT_TYPE_ROUTEPOINT 3
 #define GPSPOINT_TYPE_TRACK 4
-
-/* #define GPSPOINT_TYPE_ROUTE 5 */
+#define GPSPOINT_TYPE_ROUTE 5
 
 static VikTrack *current_track; /* pointer to pointer to first GList */
 
@@ -74,6 +77,7 @@ static struct LatLon line_latlon;
 static gchar *line_name;
 static gchar *line_comment;
 static gchar *line_description;
+static gchar *line_color;
 static gchar *line_image;
 static gchar *line_symbol;
 static gboolean line_newsegment = FALSE;
@@ -247,7 +251,7 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
        line_symbol = NULL;
       }
     }
-    else if (line_type == GPSPOINT_TYPE_TRACK && line_name)
+    else if ((line_type == GPSPOINT_TYPE_TRACK || line_type == GPSPOINT_TYPE_ROUTE) && line_name)
     {
       have_read_something = TRUE;
       VikTrack *pl = vik_track_new();
@@ -256,6 +260,7 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
       if (!line_name) line_name = g_strdup("UNK");
 
       pl->visible = line_visible;
+      pl->is_route = (line_type == GPSPOINT_TYPE_ROUTE);
 
       if ( line_comment )
       {
@@ -269,6 +274,12 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
         line_description = NULL;
       }
 
+      if ( line_color )
+      {
+        if ( gdk_color_parse ( line_color, &(pl->color) ) )
+        pl->has_color = TRUE;
+      }
+
       pl->trackpoints = NULL;
       vik_trw_layer_filein_add_track ( trw, line_name, pl );
       g_free ( line_name );
@@ -276,7 +287,7 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
 
       current_track = pl;
     }
-    else if (line_type == GPSPOINT_TYPE_TRACKPOINT && current_track)
+    else if ((line_type == GPSPOINT_TYPE_TRACKPOINT || line_type == GPSPOINT_TYPE_ROUTEPOINT) && current_track)
     {
       have_read_something = TRUE;
       VikTrackpoint *tp = vik_trackpoint_new();
@@ -301,12 +312,15 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
       g_free ( line_comment );
     if (line_description)
       g_free ( line_description );
+    if (line_color)
+      g_free ( line_color );
     if (line_image)
       g_free ( line_image );
     if (line_symbol)
       g_free ( line_symbol );
     line_comment = NULL;
     line_description = NULL;
+    line_color = NULL;
     line_image = NULL;
     line_symbol = NULL;
     line_type = GPSPOINT_TYPE_NONE;
@@ -390,6 +404,10 @@ static void gpspoint_process_key_and_value ( const gchar *key, gint key_len, con
       line_type = GPSPOINT_TYPE_TRACKPOINT;
     else if (value_len == 8 && strncasecmp( value, "waypoint", value_len ) == 0 )
       line_type = GPSPOINT_TYPE_WAYPOINT;
+    else if (value_len == 5 && strncasecmp( value, "route", value_len ) == 0 )
+      line_type = GPSPOINT_TYPE_ROUTE;
+    else if (value_len == 10 && strncasecmp( value, "routepoint", value_len ) == 0 )
+      line_type = GPSPOINT_TYPE_ROUTEPOINT;
     else
       /* all others are ignored */
       line_type = GPSPOINT_TYPE_NONE;
@@ -398,7 +416,7 @@ static void gpspoint_process_key_and_value ( const gchar *key, gint key_len, con
   {
     if (line_name == NULL)
     {
-      line_name = g_strndup ( value, value_len );
+      line_name = deslashndup ( value, value_len );
     }
   }
   else if (key_len == 7 && strncasecmp( key, "comment", key_len ) == 0 && value != NULL)
@@ -411,6 +429,11 @@ static void gpspoint_process_key_and_value ( const gchar *key, gint key_len, con
     if (line_description == NULL)
       line_description = deslashndup ( value, value_len );
   }
+  else if (key_len == 5 && strncasecmp( key, "color", key_len ) == 0 && value != NULL)
+  {
+    if (line_color == NULL)
+      line_color = deslashndup ( value, value_len );
+  }
   else if (key_len == 5 && strncasecmp( key, "image", key_len ) == 0 && value != NULL)
   {
     if (line_image == NULL)
@@ -479,7 +502,9 @@ static void a_gpspoint_write_waypoint ( const gpointer id, const VikWaypoint *wp
   vik_coord_to_latlon ( &(wp->coord), &ll );
   s_lat = a_coords_dtostr(ll.lat);
   s_lon = a_coords_dtostr(ll.lon);
-  fprintf ( f, "type=\"waypoint\" latitude=\"%s\" longitude=\"%s\" name=\"%s\"", s_lat, s_lon, wp->name );
+  gchar *tmp_name = slashdup(wp->name);
+  fprintf ( f, "type=\"waypoint\" latitude=\"%s\" longitude=\"%s\" name=\"%s\"", s_lat, s_lon, tmp_name );
+  g_free ( tmp_name );
   g_free ( s_lat ); 
   g_free ( s_lon );
 
@@ -502,30 +527,52 @@ static void a_gpspoint_write_waypoint ( const gpointer id, const VikWaypoint *wp
   }
   if ( wp->image )
   {
-    gchar *tmp_image = slashdup(wp->image);
-    fprintf ( f, " image=\"%s\"", tmp_image );
+    gchar *tmp_image = NULL;
+    gchar *cwd = NULL;
+    if ( a_vik_get_file_ref_format() == VIK_FILE_REF_FORMAT_RELATIVE ) {
+      cwd = g_get_current_dir();
+      if ( cwd )
+        tmp_image = g_strdup ( file_GetRelativeFilename ( cwd, wp->image ) );
+    }
+
+    // if cwd not available - use image filename as is
+    // this should be an absolute path as set in thumbnails
+    if ( !cwd )
+      tmp_image = slashdup(wp->image);
+
+    if ( tmp_image )
+      fprintf ( f, " image=\"%s\"", tmp_image );
+
+    g_free ( cwd );
     g_free ( tmp_image );
   }
   if ( wp->symbol )
   {
-    fprintf ( f, " symbol=\"%s\"", wp->symbol );
+    // Due to changes in garminsymbols - the symbol name is now in Title Case
+    // However to keep newly generated .vik files better compatible with older Viking versions
+    //   The symbol names will always be lowercase
+    gchar *tmp_symbol = g_utf8_strdown(wp->symbol, -1);
+    fprintf ( f, " symbol=\"%s\"", tmp_symbol );
+    g_free ( tmp_symbol );
   }
   if ( ! wp->visible )
     fprintf ( f, " visible=\"n\"" );
   fprintf ( f, "\n" );
 }
 
-static void a_gpspoint_write_trackpoint ( VikTrackpoint *tp, FILE *f )
+static void a_gpspoint_write_trackpoint ( VikTrackpoint *tp, TP_write_info_type *write_info )
 {
   static struct LatLon ll;
   gchar *s_lat, *s_lon;
   vik_coord_to_latlon ( &(tp->coord), &ll );
 
+  FILE *f = write_info->f;
+
   /* TODO: modify a_coords_dtostr() to accept (optional) buffer
    * instead of doing malloc/free everytime */
   s_lat = a_coords_dtostr(ll.lat);
   s_lon = a_coords_dtostr(ll.lon);
-  fprintf ( f, "type=\"trackpoint\" latitude=\"%s\" longitude=\"%s\"", s_lat, s_lon );
+  fprintf ( f, "type=\"%spoint\" latitude=\"%s\" longitude=\"%s\"", write_info->is_route ? "route" : "track", s_lat, s_lon );
   g_free ( s_lat ); 
   g_free ( s_lon );
 
@@ -568,7 +615,9 @@ static void a_gpspoint_write_track ( const gpointer id, const VikTrack *trk, FIL
   if ( !(trk->name) )
     return;
 
-  fprintf ( f, "type=\"track\" name=\"%s\"", trk->name);
+  gchar *tmp_name = slashdup(trk->name);
+  fprintf ( f, "type=\"%s\" name=\"%s\"", trk->is_route ? "route" : "track", tmp_name );
+  g_free ( tmp_name );
 
   if ( trk->comment ) {
     gchar *tmp = slashdup(trk->comment);
@@ -582,22 +631,29 @@ static void a_gpspoint_write_track ( const gpointer id, const VikTrack *trk, FIL
     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));
+  }
+
   if ( ! trk->visible ) {
     fprintf ( f, " visible=\"n\"" );
   }
   fprintf ( f, "\n" );
 
-  g_list_foreach ( trk->trackpoints, (GFunc) a_gpspoint_write_trackpoint, f );
-  fprintf ( f, "type=\"trackend\"\n" );
+  TP_write_info_type tp_write_info = { f, trk->is_route };
+  g_list_foreach ( trk->trackpoints, (GFunc) a_gpspoint_write_trackpoint, &tp_write_info );
+  fprintf ( f, "type=\"%send\"\n", trk->is_route ? "route" : "track" );
 }
 
 void a_gpspoint_write_file ( VikTrwLayer *trw, FILE *f )
 {
   GHashTable *tracks = vik_trw_layer_get_tracks ( trw );
+  GHashTable *routes = vik_trw_layer_get_routes ( trw );
   GHashTable *waypoints = vik_trw_layer_get_waypoints ( trw );
 
   fprintf ( f, "type=\"waypointlist\"\n" );
   g_hash_table_foreach ( waypoints, (GHFunc) a_gpspoint_write_waypoint, f );
   fprintf ( f, "type=\"waypointlistend\"\n" );
   g_hash_table_foreach ( tracks, (GHFunc) a_gpspoint_write_track, f );
+  g_hash_table_foreach ( routes, (GHFunc) a_gpspoint_write_track, f );
 }