static void gpx_end(VikTrwLayer *vtl, const char *el) { static GTimeVal tp_time; static GTimeVal wp_time; g_string_truncate ( xpath, xpath->len - strlen(el) - 1 ); switch ( current_tag ) { case tt_gpx: vik_trw_layer_set_metadata ( vtl, c_md ); c_md = NULL; break; case tt_gpx_name: vik_layer_rename ( VIK_LAYER(vtl), c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_gpx_author: if ( c_md->author ) g_free ( c_md->description ); c_md->author = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_gpx_desc: if ( c_md->description ) g_free ( c_md->description ); c_md->description = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_gpx_keywords: if ( c_md->keywords ) g_free ( c_md->keywords ); c_md->keywords = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_gpx_time: if ( c_md->timestamp ) g_free ( c_md->timestamp ); c_md->timestamp = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_waypoint: case tt_wpt: if ( ! c_wp_name ) c_wp_name = g_strdup_printf("VIKING_WP%04d", unnamed_waypoints++); vik_trw_layer_filein_add_waypoint ( vtl, c_wp_name, c_wp ); g_free ( c_wp_name ); c_wp = NULL; c_wp_name = NULL; break; case tt_trk: if ( ! c_tr_name ) c_tr_name = g_strdup_printf("VIKING_TR%03d", unnamed_tracks++); // Delibrate fall through case tt_rte: if ( ! c_tr_name ) c_tr_name = g_strdup_printf("VIKING_RT%03d", unnamed_routes++); vik_trw_layer_filein_add_track ( vtl, c_tr_name, c_tr ); g_free ( c_tr_name ); c_tr = NULL; c_tr_name = NULL; break; case tt_wpt_name: if ( c_wp_name ) g_free ( c_wp_name ); c_wp_name = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_name: if ( c_tr_name ) g_free ( c_tr_name ); c_tr_name = g_strdup ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_wpt_ele: c_wp->altitude = g_ascii_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_ele: c_tp->altitude = g_ascii_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_waypoint_name: /* .loc name is really description. */ case tt_wpt_desc: vik_waypoint_set_description ( c_wp, c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_wpt_cmt: vik_waypoint_set_comment ( 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 ); break; case tt_wpt_link: vik_waypoint_set_image ( c_wp, c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_wpt_sym: { vik_waypoint_set_symbol ( c_wp, c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; } case tt_trk_desc: vik_track_set_description ( 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 ); break; case tt_wpt_time: if ( g_time_val_from_iso8601(c_cdata->str, &wp_time) ) { c_wp->timestamp = wp_time.tv_sec; c_wp->has_timestamp = TRUE; } g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_name: vik_trackpoint_set_name ( c_tp, c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_time: if ( g_time_val_from_iso8601(c_cdata->str, &tp_time) ) { c_tp->timestamp = tp_time.tv_sec; c_tp->has_timestamp = TRUE; } g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_course: c_tp->course = g_ascii_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_speed: c_tp->speed = g_ascii_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_fix: if (!strcmp("2d", c_cdata->str)) c_tp->fix_mode = VIK_GPS_MODE_2D; else if (!strcmp("3d", c_cdata->str)) c_tp->fix_mode = VIK_GPS_MODE_3D; else /* TODO: more fix modes here */ c_tp->fix_mode = VIK_GPS_MODE_NOT_SEEN; g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_sat: c_tp->nsats = atoi ( c_cdata->str ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_hdop: c_tp->hdop = g_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_vdop: c_tp->vdop = g_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; case tt_trk_trkseg_trkpt_pdop: c_tp->pdop = g_strtod ( c_cdata->str, NULL ); g_string_erase ( c_cdata, 0, -1 ); break; default: break; } current_tag = get_tag ( xpath->str ); }
/* * Returns whether file read was a success * No obvious way to test for a 'gpspoint' file, * thus set a flag if any actual tag found during processing of the file */ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f, const gchar *dirpath ) { VikCoordMode coord_mode = vik_trw_layer_get_coord_mode ( trw ); gchar *tag_start, *tag_end; g_assert ( f != NULL && trw != NULL ); line_type = 0; line_timestamp = 0; line_newsegment = FALSE; line_image = NULL; line_symbol = NULL; current_track = NULL; gboolean have_read_something = FALSE; while (fgets(line_buffer, VIKING_LINE_SIZE, f)) { gboolean inside_quote = 0; gboolean backslash = 0; line_buffer[strlen(line_buffer)-1] = '\0'; /* chop off newline */ /* for gpspoint files wrapped inside */ if ( strlen(line_buffer) >= 13 && strncmp ( line_buffer, "~EndLayerData", 13 ) == 0 ) { // Even just a blank TRW is ok when in a .vik file have_read_something = TRUE; break; } /* each line: nullify stuff, make thing if nes, free name if ness */ tag_start = line_buffer; for (;;) { /* my addition: find first non-whitespace character. if the null, skip line. */ while (*tag_start != '\0' && isspace(*tag_start)) tag_start++; if (*tag_start == '\0') break; if (*tag_start == '#') break; tag_end = tag_start; if (*tag_end == '"') inside_quote = !inside_quote; while (*tag_end != '\0' && (!isspace(*tag_end) || inside_quote)) { tag_end++; if (*tag_end == '\\' && !backslash) backslash = TRUE; else if (backslash) backslash = FALSE; else if (*tag_end == '"') inside_quote = !inside_quote; } // Won't have super massively long strings, so potential truncation in cast is acceptable. guint len = (guint)(tag_end - tag_start); gpspoint_process_tag ( tag_start, len ); if (*tag_end == '\0' ) break; else tag_start = tag_end+1; } if (line_type == GPSPOINT_TYPE_WAYPOINT && line_name) { have_read_something = TRUE; VikWaypoint *wp = vik_waypoint_new(); wp->visible = line_visible; wp->altitude = line_altitude; wp->has_timestamp = line_has_timestamp; wp->timestamp = line_timestamp; vik_coord_load_from_latlon ( &(wp->coord), coord_mode, &line_latlon ); vik_trw_layer_filein_add_waypoint ( trw, line_name, wp ); g_free ( line_name ); line_name = NULL; if ( line_comment ) vik_waypoint_set_comment ( wp, line_comment ); if ( line_description ) vik_waypoint_set_description ( wp, line_description ); 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 ) ) vik_waypoint_set_image ( wp, line_image ); else { // Otherwise create the absolute filename from the directory of the .vik file & and the relative filename gchar *full = g_strconcat(dirpath, G_DIR_SEPARATOR_S, line_image, NULL); gchar *absolute = file_realpath_dup ( full ); // resolved into the canonical name vik_waypoint_set_image ( wp, absolute ); g_free ( absolute ); g_free ( full ); } } if ( line_symbol ) vik_waypoint_set_symbol ( wp, line_symbol ); } else if ((line_type == GPSPOINT_TYPE_TRACK || line_type == GPSPOINT_TYPE_ROUTE) && line_name) { have_read_something = TRUE; VikTrack *pl = vik_track_new(); // NB don't set defaults here as all properties are stored in the GPS_POINT format //vik_track_set_defaults ( pl ); /* Thanks to Peter Jones for this Fix */ if (!line_name) line_name = g_strdup("UNK"); pl->visible = line_visible; pl->is_route = (line_type == GPSPOINT_TYPE_ROUTE); if ( line_comment ) vik_track_set_comment ( pl, line_comment ); if ( line_description ) vik_track_set_description ( pl, line_description ); 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) ) ) pl->has_color = TRUE; } pl->draw_name_mode = line_name_label; pl->max_number_dist_labels = line_dist_label; pl->trackpoints = NULL; vik_trw_layer_filein_add_track ( trw, line_name, pl ); g_free ( line_name ); line_name = NULL; current_track = pl; } else if ((line_type == GPSPOINT_TYPE_TRACKPOINT || line_type == GPSPOINT_TYPE_ROUTEPOINT) && current_track) { have_read_something = TRUE; VikTrackpoint *tp = vik_trackpoint_new(); vik_coord_load_from_latlon ( &(tp->coord), coord_mode, &line_latlon ); tp->newsegment = line_newsegment; tp->has_timestamp = line_has_timestamp; tp->timestamp = line_timestamp; tp->altitude = line_altitude; vik_trackpoint_set_name ( tp, line_name ); if (line_extended) { tp->speed = line_speed; tp->course = line_course; tp->nsats = line_sat; tp->fix_mode = line_fix; tp->hdop = line_hdop; tp->vdop = line_vdop; tp->pdop = line_pdop; } current_track->trackpoints = g_list_append ( current_track->trackpoints, tp ); } if (line_name) g_free ( line_name ); line_name = NULL; if (line_comment) g_free ( line_comment ); if (line_description) 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) g_free ( line_image ); if (line_symbol) g_free ( line_symbol ); line_comment = NULL; line_description = NULL; line_source = NULL; line_xtype = NULL; line_color = NULL; line_image = NULL; line_symbol = NULL; line_type = GPSPOINT_TYPE_NONE; line_newsegment = FALSE; line_has_timestamp = FALSE; line_timestamp = 0; line_altitude = VIK_DEFAULT_ALTITUDE; line_visible = TRUE; line_symbol = NULL; line_extended = FALSE; line_speed = NAN; line_course = NAN; line_sat = 0; line_fix = 0; line_hdop = VIK_DEFAULT_DOP; line_vdop = VIK_DEFAULT_DOP; line_pdop = VIK_DEFAULT_DOP; line_name_label = 0; line_dist_label = 0; } return have_read_something; }