Diff of /trunk/src/gpx.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1 by harbaum, Sat Jun 20 11:08:47 2009 UTC revision 137 by harbaum, Mon Oct 19 18:21:20 2009 UTC
# Line 42  void gpx_free_wpt(wpt_t *wpt) { Line 42  void gpx_free_wpt(wpt_t *wpt) {
42    free(wpt);    free(wpt);
43  }  }
44    
45    void gpx_free_user(user_t *user) {
46      if(user->name) xmlFree(user->name);
47      free(user);
48    }
49    
50  void gpx_free_log(log_t *log) {  void gpx_free_log(log_t *log) {
51    if(log->finder)  xmlFree(log->finder);    if(log->finder)  gpx_free_user(log->finder);
52    if(log->text)    xmlFree(log->text);    if(log->text)    xmlFree(log->text);
53    free(log);    free(log);
54  }  }
# Line 61  void gpx_free_cache(cache_t *cache) { Line 66  void gpx_free_cache(cache_t *cache) {
66    
67    if(cache->id)                xmlFree(cache->id);    if(cache->id)                xmlFree(cache->id);
68    if(cache->name)              xmlFree(cache->name);    if(cache->name)              xmlFree(cache->name);
69    if(cache->owner)             xmlFree(cache->owner);    if(cache->owner)             gpx_free_user(cache->owner);
70    if(cache->short_description) xmlFree(cache->short_description);    if(cache->short_description) xmlFree(cache->short_description);
71    if(cache->long_description)  xmlFree(cache->long_description);    if(cache->long_description)  xmlFree(cache->long_description);
72    if(cache->hint)              xmlFree(cache->hint);    if(cache->hint)              xmlFree(cache->hint);
# Line 152  gpx_dialog_t *gpx_busy_dialog_new(GtkWid Line 157  gpx_dialog_t *gpx_busy_dialog_new(GtkWid
157    dialog->dialog = gtk_dialog_new();    dialog->dialog = gtk_dialog_new();
158    
159    gtk_dialog_set_has_separator(GTK_DIALOG(dialog->dialog), FALSE);    gtk_dialog_set_has_separator(GTK_DIALOG(dialog->dialog), FALSE);
160    gtk_window_set_title(GTK_WINDOW(dialog->dialog), _("Loading..."));    gtk_window_set_title(GTK_WINDOW(dialog->dialog), _("Loading"));
161    gtk_window_set_default_size(GTK_WINDOW(dialog->dialog), 300, 10);    gtk_window_set_default_size(GTK_WINDOW(dialog->dialog), 300, 10);
162    
163    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);    gtk_window_set_modal(GTK_WINDOW(dialog->dialog), TRUE);
164    gtk_window_set_transient_for(GTK_WINDOW(dialog->dialog), GTK_WINDOW(parent));    gtk_window_set_transient_for(GTK_WINDOW(dialog->dialog), GTK_WINDOW(parent));
165    
166    dialog->label = gtk_label_new("---");    dialog->label = gtk_label_new("---");
# Line 267  void gpx_display_log(log_t *log) { Line 272  void gpx_display_log(log_t *log) {
272    printf("  Log:\n");    printf("  Log:\n");
273    printf("    date:     %d.%d.%d\n", log->day, log->month, log->year);    printf("    date:     %d.%d.%d\n", log->day, log->month, log->year);
274    printf("    type:     %s\n", log_type_str[log->type+1]);    printf("    type:     %s\n", log_type_str[log->type+1]);
275    printf("    finder:   %s\n", log->finder);    printf("    finder:   %s\n", log->finder->name);
276    //  printf("    text:     %s\n", log->text);    //  printf("    text:     %s\n", log->text);
277  }  }
278    
# Line 279  void gpx_display_cache(cache_t *cache) { Line 284  void gpx_display_cache(cache_t *cache) {
284    printf("  name:       %s\n", cache->name);    printf("  name:       %s\n", cache->name);
285    printf("  latitude:   %f\n", cache->pos.lat);    printf("  latitude:   %f\n", cache->pos.lat);
286    printf("  longitude:  %f\n", cache->pos.lon);    printf("  longitude:  %f\n", cache->pos.lon);
287    printf("  owner:      %s\n", cache->owner);    printf("  owner:      %s\n", cache->owner->name);
288    printf("  type:       %s\n", cache_type_str[cache->type+1]);    printf("  type:       %s\n", cache_type_str[cache->type+1]);
289    printf("  container:  %s\n", cache_container_str[cache->container+1]);    printf("  container:  %s\n", cache_container_str[cache->container+1]);
290    printf("  difficulty: %.1f\n", cache->difficulty);    printf("  difficulty: %.1f\n", cache->difficulty);
# Line 326  static float xml_get_prop_float(xmlTextR Line 331  static float xml_get_prop_float(xmlTextR
331    return ret;    return ret;
332  }  }
333    
334    static unsigned int xml_get_prop_id(xmlTextReaderPtr reader) {
335      unsigned int ret = 0;
336      char *prop;
337      if((prop = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id"))) {
338        ret = atoi(prop);
339        xmlFree(prop);
340      }
341      return ret;
342    }
343    
344  static int xml_prop_is(xmlTextReaderPtr reader, char *name, char *value,  static int xml_prop_is(xmlTextReaderPtr reader, char *name, char *value,
345                         int def_value) {                         int def_value) {
346    int match = def_value;    int match = def_value;
# Line 360  static gboolean skip_element(xmlTextRead Line 375  static gboolean skip_element(xmlTextRead
375    
376  static char *process_text(xmlTextReaderPtr reader) {  static char *process_text(xmlTextReaderPtr reader) {
377    char *text = NULL;    char *text = NULL;
   int depth = xmlTextReaderDepth(reader);  
   int ret = xmlTextReaderRead(reader);  
   while((ret == 1) &&  
         ((xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) ||  
          (xmlTextReaderDepth(reader) != depth))) {  
378    
379      /* found a text fragment */    if(!xmlTextReaderIsEmptyElement(reader)) {
380      if((xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ||  
381         (xmlTextReaderNodeType(reader) == XML_READER_TYPE_CDATA)) {      int depth = xmlTextReaderDepth(reader);
382        char *frag = (char*)xmlTextReaderConstValue(reader);      int ret = xmlTextReaderRead(reader);
383        while((ret == 1) &&
384        if(!text) text = strdup(frag);            ((xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) ||
385        else {             (xmlTextReaderDepth(reader) != depth))) {
386          char *old = text;  
387          text = malloc(strlen(old) + strlen(frag) + 1);        /* found a text fragment */
388          strcpy(text, old);        if((xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ||
389          strcat(text, frag);           (xmlTextReaderNodeType(reader) == XML_READER_TYPE_CDATA)) {
390          free(old);          char *frag = (char*)xmlTextReaderConstValue(reader);
391    
392            if(!text) text = strdup(frag);
393            else {
394              char *old = text;
395              text = malloc(strlen(old) + strlen(frag) + 1);
396              strcpy(text, old);
397              strcat(text, frag);
398              free(old);
399            }
400        }        }
401          ret = xmlTextReaderRead(reader);
402      }      }
     ret = xmlTextReaderRead(reader);  
403    }    }
404    
405    return text;    return text;
# Line 442  static log_t *process_gpx_wpt_gc_logs_lo Line 461  static log_t *process_gpx_wpt_gc_logs_lo
461            log->type = xml_str_search(reader, log_type_str, "log", 0);            log->type = xml_str_search(reader, log_type_str, "log", 0);
462          } else if((strcasecmp(name, "finder") == 0) ||          } else if((strcasecmp(name, "finder") == 0) ||
463                    (strcasecmp(name, "geocacher") == 0)) {                    (strcasecmp(name, "geocacher") == 0)) {
464            if(!log->finder) log->finder = process_text(reader);            if(!log->finder) {
465                log->finder = g_new0(user_t, 1);
466                log->finder->name = process_text(reader);
467                log->finder->id = xml_get_prop_id(reader);
468              }
469          } else if(strcasecmp(name, "text") == 0) {          } else if(strcasecmp(name, "text") == 0) {
470            if(!log->text) log->text = process_text(reader);            if(!log->text) log->text = process_text(reader);
471          } else          } else
# Line 463  static log_t *process_gpx_wpt_gc_logs_lo Line 486  static log_t *process_gpx_wpt_gc_logs_lo
486      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
487    }    }
488    
489    g_assert(0);    gpx_free_log(log);
490    return log;    return NULL;
491  }  }
492    
493  static log_t *process_gpx_wpt_gc_logs(xmlTextReaderPtr reader) {  static log_t *process_gpx_wpt_gc_logs(xmlTextReaderPtr reader) {
# Line 513  static log_t *process_gpx_wpt_gc_logs(xm Line 536  static log_t *process_gpx_wpt_gc_logs(xm
536      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
537    }    }
538    
539    g_assert(0);    /* free the entire log chain */
540    return log_chain;    while(log_chain) {
541        log_t *next = log_chain->next;
542        gpx_free_log(log_chain);
543        log_chain = next;
544      }
545    
546      return NULL;
547  }  }
548    
549  static tb_t *process_gpx_wpt_gc_tbs_travelbug(xmlTextReaderPtr reader) {  static tb_t *process_gpx_wpt_gc_tbs_travelbug(xmlTextReaderPtr reader) {
# Line 532  static tb_t *process_gpx_wpt_gc_tbs_trav Line 561  static tb_t *process_gpx_wpt_gc_tbs_trav
561    else    else
562      tb->ref = strdup("<NONE>");      tb->ref = strdup("<NONE>");
563    
564      if((prop = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id")))
565        tb->id = atoi(prop);
566    
567    /* process all sub-nodes */    /* process all sub-nodes */
568    int depth = xmlTextReaderDepth(reader);    int depth = xmlTextReaderDepth(reader);
569    int ret = xmlTextReaderRead(reader);    int ret = xmlTextReaderRead(reader);
# Line 563  static tb_t *process_gpx_wpt_gc_tbs_trav Line 595  static tb_t *process_gpx_wpt_gc_tbs_trav
595      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
596    }    }
597    
598    g_assert(0);    gpx_free_tb(tb);
599    return tb;    return NULL;
600  }  }
601    
602  static tb_t *process_gpx_wpt_gc_tbs(xmlTextReaderPtr reader) {  static tb_t *process_gpx_wpt_gc_tbs(xmlTextReaderPtr reader) {
# Line 605  static tb_t *process_gpx_wpt_gc_tbs(xmlT Line 637  static tb_t *process_gpx_wpt_gc_tbs(xmlT
637      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
638    }    }
639    
640    g_assert(0);    while(tb) {
641    return tb;      tb_t *next = tb;
642        gpx_free_tb(tb);
643        tb = next;
644      }
645    
646      return NULL;
647  }  }
648    
649  static void process_gpx_wpt_gc(xmlTextReaderPtr reader, cache_t *cache) {  static void process_gpx_wpt_gc(xmlTextReaderPtr reader, cache_t *cache) {
# Line 630  static void process_gpx_wpt_gc(xmlTextRe Line 667  static void process_gpx_wpt_gc(xmlTextRe
667          if(strcasecmp(name, "name") == 0) {          if(strcasecmp(name, "name") == 0) {
668            if(!cache->name) cache->name = process_text(reader);            if(!cache->name) cache->name = process_text(reader);
669          } else if(strcasecmp(name, "owner") == 0) {          } else if(strcasecmp(name, "owner") == 0) {
670            if(!cache->owner) cache->owner = process_text(reader);            if(!cache->owner) {
671                cache->owner = g_new0(user_t, 1);
672                cache->owner->name = process_text(reader);
673                cache->owner->id = xml_get_prop_id(reader);
674              }
675          } else if(strcasecmp(name, "type") == 0) {          } else if(strcasecmp(name, "type") == 0) {
676            cache->type = xml_str_search(reader, cache_type_str,            cache->type = xml_str_search(reader, cache_type_str,
677                                         "cache type", CACHE_TYPE_UNKNOWN);                                         "cache type", CACHE_TYPE_UNKNOWN);
# Line 653  static void process_gpx_wpt_gc(xmlTextRe Line 694  static void process_gpx_wpt_gc(xmlTextRe
694                    (strcasecmp(name, "hints") == 0))     {                    (strcasecmp(name, "hints") == 0))     {
695            if(!cache->hint) {            if(!cache->hint) {
696              cache->hint = process_text(reader);              cache->hint = process_text(reader);
697    
698              /* often hints aren't more than just a bunch of blanks ... */              /* often hints aren't more than just a bunch of blanks ... */
699              if(cache->hint && all_is_white(cache->hint)) {              if(cache->hint && all_is_white(cache->hint)) {
700                free(cache->hint);                free(cache->hint);
# Line 764  static cache_t *process_gpx_wpt(xmlTextR Line 806  static cache_t *process_gpx_wpt(xmlTextR
806        /* neither geocaching.com GC* nor opencaching.com OC* nor */        /* neither geocaching.com GC* nor opencaching.com OC* nor */
807        /* geocaching australia GA* waypoint */        /* geocaching australia GA* waypoint */
808        if(cache->id &&        if(cache->id &&
809             (strncasecmp(cache->id, "__", 2) != 0) &&
810           (strncasecmp(cache->id, "GC", 2) != 0) &&           (strncasecmp(cache->id, "GC", 2) != 0) &&
811           (strncasecmp(cache->id, "OC", 2) != 0) &&           (strncasecmp(cache->id, "OC", 2) != 0) &&
812           (strncasecmp(cache->id, "GA", 2) != 0)) {           (strncasecmp(cache->id, "GA", 2) != 0)) {
# Line 830  static cache_t *process_gpx_wpt(xmlTextR Line 873  static cache_t *process_gpx_wpt(xmlTextR
873      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
874    }    }
875    
876    g_assert(0);    gpx_free_cache(cache);
877    return cache;    return NULL;
878  }  }
879    
880  static void process_gpx(xmlTextReaderPtr reader, gpx_dialog_t *dialog,  static gboolean process_gpx(xmlTextReaderPtr reader, gpx_dialog_t *dialog,
881                          gpx_t *gpx) {                              gpx_t *gpx) {
882    
883    /* no attributes of interest */    /* no attributes of interest */
884    
# Line 846  static void process_gpx(xmlTextReaderPtr Line 889  static void process_gpx(xmlTextReaderPtr
889    while(*cache) cache = &(*cache)->next;    while(*cache) cache = &(*cache)->next;
890    
891    const xmlChar *name = xmlTextReaderConstName(reader);    const xmlChar *name = xmlTextReaderConstName(reader);
892    g_assert(name);    if(!name) return FALSE;
893    
894    /* read next node */    /* read next node */
895    int ret = xmlTextReaderRead(reader);    int ret = xmlTextReaderRead(reader);
# Line 876  static void process_gpx(xmlTextReaderPtr Line 919  static void process_gpx(xmlTextReaderPtr
919      case XML_READER_TYPE_END_ELEMENT:      case XML_READER_TYPE_END_ELEMENT:
920        /* end element must be for the current element */        /* end element must be for the current element */
921        g_assert(xmlTextReaderDepth(reader) == 0);        g_assert(xmlTextReaderDepth(reader) == 0);
922        return;        return TRUE;
923        break;        break;
924    
925      default:      default:
# Line 885  static void process_gpx(xmlTextReaderPtr Line 928  static void process_gpx(xmlTextReaderPtr
928      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
929    }    }
930    
931    g_assert(0);    return FALSE;
932  }  }
933    
934  /* parse loc waypoint entry */  /* parse loc waypoint entry */
# Line 1069  static gpx_t *gpx_parse_file(gpx_dialog_ Line 1112  static gpx_t *gpx_parse_file(gpx_dialog_
1112      *dot = 0;      *dot = 0;
1113      snprintf(wpts_name, sizeof(wpts_name), "%s-wpts.gpx", filename);      snprintf(wpts_name, sizeof(wpts_name), "%s-wpts.gpx", filename);
1114      *dot = '.';      *dot = '.';
   
1115      if(g_file_test(wpts_name,  G_FILE_TEST_EXISTS)) {      if(g_file_test(wpts_name,  G_FILE_TEST_EXISTS)) {
   
1116        xmlTextReaderPtr reader = xmlReaderForFile(wpts_name, NULL, 0);        xmlTextReaderPtr reader = xmlReaderForFile(wpts_name, NULL, 0);
1117        if (reader != NULL) {        if (reader != NULL) {
1118          gpx = process_root(reader, dialog, wpts_name, gpx);          gpx = process_root(reader, dialog, wpts_name, gpx);
# Line 1347  float gpx_pos_get_distance(pos_t p1, pos Line 1388  float gpx_pos_get_distance(pos_t p1, pos
1388    
1389  void gpx_pos_get_distance_str(char *str, int len,  void gpx_pos_get_distance_str(char *str, int len,
1390                                pos_t p1, pos_t p2, int mil) {                                pos_t p1, pos_t p2, int mil) {
1391    if(!p1.lat && !p1.lon) {    if(isnan(p1.lat) || isnan(p1.lon)) {
1392      snprintf(str, len, "---");      snprintf(str, len, "---");
1393      return;      return;
1394    }    }
# Line 1356  void gpx_pos_get_distance_str(char *str, Line 1397  void gpx_pos_get_distance_str(char *str,
1397    distance_str(str, len, dist, mil);    distance_str(str, len, dist, mil);
1398  }  }
1399    
 /* http://library.gnome.org/devel/gtk/unstable/GtkRadioButton.html */  
1400  void gpx_sort(gpx_t *gpx, int by, pos_t *refpos) {  void gpx_sort(gpx_t *gpx, int by, pos_t *refpos) {
1401    cache_t **new;    cache_t **new;
1402    cache_t *cur = gpx->cache;    cache_t *cur = gpx->cache;
# Line 1365  void gpx_sort(gpx_t *gpx, int by, pos_t Line 1405  void gpx_sort(gpx_t *gpx, int by, pos_t
1405    
1406    gpx->cache = NULL;  /* detach old chain */    gpx->cache = NULL;  /* detach old chain */
1407    while(cur) {    while(cur) {
1408      float cur_dist = gpx_pos_get_distance(*refpos, gpx_cache_pos(cur), 0);      float cur_dist = -1;
1409      int cur_cnt = 0;      int cur_cnt = 0;
1410    
1411        if(!isnan(cur->pos.lat) && !isnan(cur->pos.lon))
1412          cur_dist = gpx_pos_get_distance(*refpos, gpx_cache_pos(cur), 0);
1413    
1414      new = &(gpx->cache);      new = &(gpx->cache);
1415    
1416      /* search for currect insertion point */      /* search for currect insertion point */

Legend:
Removed from v.1  
changed lines
  Added in v.137