X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/37dd047d3bdd3ff58320c691545d5e6cf160738c..3ceb0792a9dca925baca43dab19d87f7bf27ae9e:/src/file.c diff --git a/src/file.c b/src/file.c index 5b2a66cd..06406b89 100644 --- a/src/file.c +++ b/src/file.c @@ -2,6 +2,7 @@ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager * * Copyright (C) 2003-2005, Evan Battaglia + * Copyright (C) 2012, Guilhem Bonnefille * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +26,7 @@ #include "viking.h" #include "gpx.h" +#include "babel.h" #include #include @@ -152,7 +154,7 @@ static void write_layer_params_and_data ( VikLayer *l, FILE *f ) guint16 i, params_count = vik_layer_get_interface(l->type)->params_count; for ( i = 0; i < params_count; i++ ) { - data = get_param(l,i); + data = get_param(l, i, TRUE); file_write_layer_param(f, params[i].name, params[i].type, data); } } @@ -174,7 +176,7 @@ static void file_write ( VikAggregateLayer *top, FILE *f, gpointer vp ) VikLayer *current_layer; struct LatLon ll; VikViewportDrawMode mode; - gchar *modestring; + gchar *modestring = NULL; push(&stack); stack->data = (gpointer) vik_aggregate_layer_get_children(VIK_AGGREGATE_LAYER(top)); @@ -188,15 +190,18 @@ static void file_write ( VikAggregateLayer *top, FILE *f, gpointer vp ) case VIK_VIEWPORT_DRAWMODE_UTM: modestring = "utm"; break; case VIK_VIEWPORT_DRAWMODE_EXPEDIA: modestring = "expedia"; break; case VIK_VIEWPORT_DRAWMODE_MERCATOR: modestring = "mercator"; break; + case VIK_VIEWPORT_DRAWMODE_LATLON: modestring = "latlon"; break; default: g_critical("Houston, we've had a problem. mode=%d", mode); } - fprintf ( f, "#VIKING GPS Data file " VIKING_URL "\n\nxmpp=%f\nympp=%f\nlat=%f\nlon=%f\nmode=%s\ncolor=%s\ndrawscale=%s\ndrawcentermark=%s", + fprintf ( f, "#VIKING GPS Data file " VIKING_URL "\n\nxmpp=%f\nympp=%f\nlat=%f\nlon=%f\nmode=%s\ncolor=%s\nhighlightcolor=%s\ndrawscale=%s\ndrawcentermark=%s\ndrawhighlight=%s\n", vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ), ll.lat, ll.lon, modestring, vik_viewport_get_background_color(VIK_VIEWPORT(vp)), + vik_viewport_get_highlight_color(VIK_VIEWPORT(vp)), vik_viewport_get_draw_scale(VIK_VIEWPORT(vp)) ? "t" : "f", - vik_viewport_get_draw_centermark(VIK_VIEWPORT(vp)) ? "t" : "f" ); + vik_viewport_get_draw_centermark(VIK_VIEWPORT(vp)) ? "t" : "f", + vik_viewport_get_draw_highlight(VIK_VIEWPORT(vp)) ? "t" : "f" ); if ( ! VIK_LAYER(top)->visible ) fprintf ( f, "visible=f\n" ); @@ -259,7 +264,7 @@ static void string_list_set_param (gint i, GList *list, gpointer *layer_and_vp) { VikLayerParamData x; x.sl = list; - vik_layer_set_param ( VIK_LAYER(layer_and_vp[0]), i, x, layer_and_vp[1] ); + vik_layer_set_param ( VIK_LAYER(layer_and_vp[0]), i, x, layer_and_vp[1], TRUE ); } static void file_read ( VikAggregateLayer *top, FILE *f, VikViewport *vp ) @@ -431,12 +436,18 @@ static void file_read ( VikAggregateLayer *top, FILE *f, VikViewport *vp ) } else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "mercator" ) == 0) vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_MERCATOR ); + else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "latlon" ) == 0) + vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_LATLON ); else if ( stack->under == NULL && eq_pos == 5 && strncasecmp ( line, "color", eq_pos ) == 0 ) vik_viewport_set_background_color ( VIK_VIEWPORT(vp), line+6 ); + else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "highlightcolor", eq_pos ) == 0 ) + vik_viewport_set_highlight_color ( VIK_VIEWPORT(vp), line+15 ); else if ( stack->under == NULL && eq_pos == 9 && strncasecmp ( line, "drawscale", eq_pos ) == 0 ) vik_viewport_set_draw_scale ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+10) ); else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "drawcentermark", eq_pos ) == 0 ) vik_viewport_set_draw_centermark ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+15) ); + else if ( stack->under == NULL && eq_pos == 13 && strncasecmp ( line, "drawhighlight", eq_pos ) == 0 ) + vik_viewport_set_draw_highlight ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+14) ); else if ( stack->under && eq_pos == 4 && strncasecmp ( line, "name", eq_pos ) == 0 ) vik_layer_rename ( VIK_LAYER(stack->data), line+5 ); else if ( eq_pos == 7 && strncasecmp ( line, "visible", eq_pos ) == 0 ) @@ -477,7 +488,7 @@ static void file_read ( VikAggregateLayer *top, FILE *f, VikViewport *vp ) /* STRING or STRING_LIST -- if STRING_LIST, just set param to add a STRING */ default: x.s = line; } - vik_layer_set_param ( VIK_LAYER(stack->data), i, x, vp ); + vik_layer_set_param ( VIK_LAYER(stack->data), i, x, vp, TRUE ); } found_match = TRUE; break; @@ -550,10 +561,23 @@ static void xfclose ( FILE *f ) } } -/* 0 on failure, 1 on success (vik file) 2 on success (other file) */ -gshort a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar *filename_or_uri ) +/* + * Function to determine if a filename is a 'viking' type file + */ +gboolean check_file_magic_vik ( const gchar *filename ) +{ + gboolean result = FALSE; + FILE *ff = xfopen ( filename, "r" ); + if ( ff ) { + result = check_magic ( ff, VIK_MAGIC ); + xfclose ( ff ); + } + return result; +} + +VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar *filename_or_uri ) { - char *filename = filename_or_uri; + char *filename = (char *)filename_or_uri; if (strncmp(filename, "file://", 7) == 0) filename = filename + 7; @@ -563,34 +587,56 @@ gshort a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar *filen g_assert ( vp ); if ( ! f ) - return 0; + return LOAD_TYPE_READ_FAILURE; if ( !is_gpx_file && check_magic ( f, VIK_MAGIC ) ) { file_read ( top, f, vp ); if ( f != stdin ) xfclose(f); - return 1; + return LOAD_TYPE_VIK_SUCCESS; } else { - VikCoord new_center; + gboolean success = TRUE; VikLayer *vtl = vik_layer_create ( VIK_LAYER_TRW, vp, NULL, FALSE ); - vik_layer_rename ( vtl, a_file_basename ( filename ) ); - if ( is_gpx_file || check_magic ( f, GPX_MAGIC ) ) - a_gpx_read_file ( VIK_TRW_LAYER(vtl), f ); + // In fact both kml & gpx files start the same as they are in xml + if ( check_file_ext ( filename, ".kml" ) && check_magic ( f, GPX_MAGIC ) ) { + // Implicit Conversion + if ( ! a_babel_convert_from ( VIK_TRW_LAYER(vtl), "-i kml", filename, NULL, NULL ) ) { + // Probably want to remove the vtl, but I'm not sure how yet... + xfclose(f); + return LOAD_TYPE_GPSBABEL_FAILURE; + } + } + else if ( is_gpx_file || check_magic ( f, GPX_MAGIC ) ) { + success = a_gpx_read_file ( VIK_TRW_LAYER(vtl), f ); + if ( ! success ) { + // free up layer + g_object_unref ( vtl ); + xfclose(f); + return LOAD_TYPE_GPX_FAILURE; + } + } else - a_gpspoint_read_file ( VIK_TRW_LAYER(vtl), f ); + success = a_gpspoint_read_file ( VIK_TRW_LAYER(vtl), f ); - vik_layer_post_read ( vtl, vp, TRUE ); + // Refuse to load file types not supported + if ( ! success ) { + // free up layer + g_object_unref ( vtl ); + xfclose(f); + return LOAD_TYPE_UNSUPPORTED_FAILURE; + } + vik_layer_rename ( vtl, a_file_basename ( filename ) ); + vik_layer_post_read ( vtl, vp, TRUE ); vik_aggregate_layer_add_layer ( top, vtl ); + vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(vtl), vp ); - if ( vik_trw_layer_find_center ( VIK_TRW_LAYER(vtl), &new_center ) ) - vik_viewport_set_center_coord ( VIK_VIEWPORT(vp), &new_center ); xfclose(f); - return 2; + return LOAD_TYPE_OTHER_SUCCESS; } } @@ -644,17 +690,50 @@ gboolean check_file_ext ( const gchar *filename, const gchar *fileext ) return FALSE; } -gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, gshort file_type ) +gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, VikFileType_t file_type, VikTrack *trk ) { FILE *f = g_fopen ( filename, "w" ); if ( f ) { - if ( file_type == FILE_TYPE_GPSMAPPER ) - a_gpsmapper_write_file ( vtl, f ); - else if ( file_type == FILE_TYPE_GPX ) - a_gpx_write_file ( vtl, f ); - else - a_gpspoint_write_file ( vtl, f ); + if ( trk ) { + switch ( file_type ) { + case FILE_TYPE_GPX: + a_gpx_write_track_file ( trk, f ); + break; + default: + g_critical("Houston, we've had a problem. file_type=%d", file_type); + } + } else { + switch ( file_type ) { + case FILE_TYPE_GPSMAPPER: + a_gpsmapper_write_file ( vtl, f ); + break; + case FILE_TYPE_GPX: + a_gpx_write_file ( vtl, f ); + break; + case FILE_TYPE_GPSPOINT: + a_gpspoint_write_file ( vtl, f ); + break; + case FILE_TYPE_KML: + fclose ( f ); + f = NULL; + switch ( a_vik_get_kml_export_units () ) { + case VIK_KML_EXPORT_UNITS_STATUTE: + return a_babel_convert_to ( vtl, "-o kml", filename, NULL, NULL ); + break; + case VIK_KML_EXPORT_UNITS_NAUTICAL: + return a_babel_convert_to ( vtl, "-o kml,units=n", filename, NULL, NULL ); + break; + default: + // VIK_KML_EXPORT_UNITS_METRIC: + return a_babel_convert_to ( vtl, "-o kml,units=m", filename, NULL, NULL ); + break; + } + break; + default: + g_critical("Houston, we've had a problem. file_type=%d", file_type); + } + } fclose ( f ); f = NULL; return TRUE; @@ -662,32 +741,3 @@ gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, gshort file_ty return FALSE; } -const gchar *a_get_viking_dir() -{ - static gchar *viking_dir = NULL; - - // TODO: use g_get_user_config_dir ? - - if (!viking_dir) { - const gchar *home = g_getenv("HOME"); - if (!home || g_access(home, W_OK)) - home = g_get_home_dir (); -#ifdef HAVE_MKDTEMP - if (!home || g_access(home, W_OK)) - { - static gchar temp[] = {"/tmp/vikXXXXXX"}; - home = mkdtemp(temp); - } -#endif - if (!home || g_access(home, W_OK)) - /* Fatal error */ - g_critical("Unable to find a base directory"); - - /* Build the name of the directory */ - viking_dir = g_build_filename(home, ".viking", NULL); - if (g_file_test(viking_dir, G_FILE_TEST_EXISTS) == FALSE) - g_mkdir(viking_dir, 0755); - } - - return viking_dir; -}