Diff of /trunk/src/gpx.c

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

revision 7 by harbaum, Thu Jun 25 15:24:24 2009 UTC revision 152 by harbaum, Mon Nov 2 10:53:01 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 114  void gpx_free_all(gpx_t *gpx) { Line 119  void gpx_free_all(gpx_t *gpx) {
119  }  }
120    
121  static const char *cache_type_str[] = { "<Unknown>",  static const char *cache_type_str[] = { "<Unknown>",
122    "Traditional Cache|Traditional|Geocache", "Multi-cache|Multi",    "Traditional Cache|Traditional|Geocache", "Multi-cache|Multi|Multicache",
123    "Unknown Cache|Other",    "Unknown Cache|Other|Unknown",
124    "Virtual Cache|Virtual", "Webcam Cache|Webcam", "Event Cache|Event|Geocoins:",    "Virtual Cache|Virtual", "Webcam Cache|Webcam", "Event Cache|Event|Geocoins:",
125    "Letterbox Hybrid|Letterbox", "Earthcache", "Wherigo Cache",    "Letterbox Hybrid|Letterbox", "Earthcache", "Wherigo Cache",
126    "Mega-Event Cache", "Cache In Trash Out Event",    "Mega-Event Cache", "Cache In Trash Out Event",
# Line 155  gpx_dialog_t *gpx_busy_dialog_new(GtkWid Line 160  gpx_dialog_t *gpx_busy_dialog_new(GtkWid
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("    id:       #%u\n", log->id);
277    //  printf("    text:     %s\n", log->text);    //  printf("    text:     %s\n", log->text);
278  }  }
279    
# Line 279  void gpx_display_cache(cache_t *cache) { Line 285  void gpx_display_cache(cache_t *cache) {
285    printf("  name:       %s\n", cache->name);    printf("  name:       %s\n", cache->name);
286    printf("  latitude:   %f\n", cache->pos.lat);    printf("  latitude:   %f\n", cache->pos.lat);
287    printf("  longitude:  %f\n", cache->pos.lon);    printf("  longitude:  %f\n", cache->pos.lon);
288    printf("  owner:      %s\n", cache->owner);    printf("  owner:      %s\n", cache->owner->name);
289    printf("  type:       %s\n", cache_type_str[cache->type+1]);    printf("  type:       %s\n", cache_type_str[cache->type+1]);
290    printf("  container:  %s\n", cache_container_str[cache->container+1]);    printf("  container:  %s\n", cache_container_str[cache->container+1]);
291    printf("  difficulty: %.1f\n", cache->difficulty);    printf("  difficulty: %.1f\n", cache->difficulty);
# Line 326  static float xml_get_prop_float(xmlTextR Line 332  static float xml_get_prop_float(xmlTextR
332    return ret;    return ret;
333  }  }
334    
335    static unsigned int xml_get_prop_id(xmlTextReaderPtr reader) {
336      unsigned int ret = 0;
337      char *prop;
338      if((prop = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id"))) {
339        ret = atoi(prop);
340        xmlFree(prop);
341      }
342      return ret;
343    }
344    
345  static int xml_prop_is(xmlTextReaderPtr reader, char *name, char *value,  static int xml_prop_is(xmlTextReaderPtr reader, char *name, char *value,
346                         int def_value) {                         int def_value) {
347    int match = def_value;    int match = def_value;
# Line 360  static gboolean skip_element(xmlTextRead Line 376  static gboolean skip_element(xmlTextRead
376    
377  static char *process_text(xmlTextReaderPtr reader) {  static char *process_text(xmlTextReaderPtr reader) {
378    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))) {  
379    
380      /* found a text fragment */    if(!xmlTextReaderIsEmptyElement(reader)) {
381      if((xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ||  
382         (xmlTextReaderNodeType(reader) == XML_READER_TYPE_CDATA)) {      int depth = xmlTextReaderDepth(reader);
383        char *frag = (char*)xmlTextReaderConstValue(reader);      int ret = xmlTextReaderRead(reader);
384        while((ret == 1) &&
385        if(!text) text = strdup(frag);            ((xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) ||
386        else {             (xmlTextReaderDepth(reader) != depth))) {
387          char *old = text;  
388          text = malloc(strlen(old) + strlen(frag) + 1);        /* found a text fragment */
389          strcpy(text, old);        if((xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ||
390          strcat(text, frag);           (xmlTextReaderNodeType(reader) == XML_READER_TYPE_CDATA)) {
391          free(old);          char *frag = (char*)xmlTextReaderConstValue(reader);
392    
393            if(!text) text = strdup(frag);
394            else {
395              char *old = text;
396              text = malloc(strlen(old) + strlen(frag) + 1);
397              strcpy(text, old);
398              strcat(text, frag);
399              free(old);
400            }
401        }        }
402          ret = xmlTextReaderRead(reader);
403      }      }
     ret = xmlTextReaderRead(reader);  
404    }    }
405    
406    return text;    return text;
# Line 421  static log_t *process_gpx_wpt_gc_logs_lo Line 441  static log_t *process_gpx_wpt_gc_logs_lo
441      return NULL;      return NULL;
442    
443    /* create a new log entry */    /* create a new log entry */
444    log_t *log = malloc(sizeof(log_t));    log_t *log = g_new0(log_t, 1);
445    memset(log, 0, sizeof(log_t));  
446      char *prop = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
447      if(prop)
448        log->id = atoi(prop);
449    
450    /* process all sub-nodes */    /* process all sub-nodes */
451    int depth = xmlTextReaderDepth(reader);    int depth = xmlTextReaderDepth(reader);
# Line 442  static log_t *process_gpx_wpt_gc_logs_lo Line 465  static log_t *process_gpx_wpt_gc_logs_lo
465            log->type = xml_str_search(reader, log_type_str, "log", 0);            log->type = xml_str_search(reader, log_type_str, "log", 0);
466          } else if((strcasecmp(name, "finder") == 0) ||          } else if((strcasecmp(name, "finder") == 0) ||
467                    (strcasecmp(name, "geocacher") == 0)) {                    (strcasecmp(name, "geocacher") == 0)) {
468            if(!log->finder) log->finder = process_text(reader);            if(!log->finder) {
469                log->finder = g_new0(user_t, 1);
470                log->finder->name = process_text(reader);
471                log->finder->id = xml_get_prop_id(reader);
472              }
473          } else if(strcasecmp(name, "text") == 0) {          } else if(strcasecmp(name, "text") == 0) {
474            if(!log->text) log->text = process_text(reader);            if(!log->text) log->text = process_text(reader);
475          } else          } else
# Line 463  static log_t *process_gpx_wpt_gc_logs_lo Line 490  static log_t *process_gpx_wpt_gc_logs_lo
490      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
491    }    }
492    
493    g_assert(0);    gpx_free_log(log);
494    return log;    return NULL;
495  }  }
496    
497  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 540  static log_t *process_gpx_wpt_gc_logs(xm
540      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
541    }    }
542    
543    g_assert(0);    /* free the entire log chain */
544    return log_chain;    while(log_chain) {
545        log_t *next = log_chain->next;
546        gpx_free_log(log_chain);
547        log_chain = next;
548      }
549    
550      return NULL;
551  }  }
552    
553  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 565  static tb_t *process_gpx_wpt_gc_tbs_trav
565    else    else
566      tb->ref = strdup("<NONE>");      tb->ref = strdup("<NONE>");
567    
568      if((prop = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id")))
569        tb->id = atoi(prop);
570    
571    /* process all sub-nodes */    /* process all sub-nodes */
572    int depth = xmlTextReaderDepth(reader);    int depth = xmlTextReaderDepth(reader);
573    int ret = xmlTextReaderRead(reader);    int ret = xmlTextReaderRead(reader);
# Line 563  static tb_t *process_gpx_wpt_gc_tbs_trav Line 599  static tb_t *process_gpx_wpt_gc_tbs_trav
599      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
600    }    }
601    
602    g_assert(0);    gpx_free_tb(tb);
603    return tb;    return NULL;
604  }  }
605    
606  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 641  static tb_t *process_gpx_wpt_gc_tbs(xmlT
641      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
642    }    }
643    
644    g_assert(0);    while(tb) {
645    return tb;      tb_t *next = tb;
646        gpx_free_tb(tb);
647        tb = next;
648      }
649    
650      return NULL;
651  }  }
652    
653  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 671  static void process_gpx_wpt_gc(xmlTextRe
671          if(strcasecmp(name, "name") == 0) {          if(strcasecmp(name, "name") == 0) {
672            if(!cache->name) cache->name = process_text(reader);            if(!cache->name) cache->name = process_text(reader);
673          } else if(strcasecmp(name, "owner") == 0) {          } else if(strcasecmp(name, "owner") == 0) {
674            if(!cache->owner) cache->owner = process_text(reader);            if(!cache->owner) {
675                cache->owner = g_new0(user_t, 1);
676                cache->owner->name = process_text(reader);
677                cache->owner->id = xml_get_prop_id(reader);
678              }
679          } else if(strcasecmp(name, "type") == 0) {          } else if(strcasecmp(name, "type") == 0) {
680            cache->type = xml_str_search(reader, cache_type_str,            cache->type = xml_str_search(reader, cache_type_str,
681                                         "cache type", CACHE_TYPE_UNKNOWN);                                         "cache type", CACHE_TYPE_UNKNOWN);
# Line 653  static void process_gpx_wpt_gc(xmlTextRe Line 698  static void process_gpx_wpt_gc(xmlTextRe
698                    (strcasecmp(name, "hints") == 0))     {                    (strcasecmp(name, "hints") == 0))     {
699            if(!cache->hint) {            if(!cache->hint) {
700              cache->hint = process_text(reader);              cache->hint = process_text(reader);
701    
702              /* often hints aren't more than just a bunch of blanks ... */              /* often hints aren't more than just a bunch of blanks ... */
703              if(cache->hint && all_is_white(cache->hint)) {              if(cache->hint && all_is_white(cache->hint)) {
704                free(cache->hint);                free(cache->hint);
# Line 764  static cache_t *process_gpx_wpt(xmlTextR Line 810  static cache_t *process_gpx_wpt(xmlTextR
810        /* neither geocaching.com GC* nor opencaching.com OC* nor */        /* neither geocaching.com GC* nor opencaching.com OC* nor */
811        /* geocaching australia GA* waypoint */        /* geocaching australia GA* waypoint */
812        if(cache->id &&        if(cache->id &&
813             (strncasecmp(cache->id, "__", 2) != 0) &&
814           (strncasecmp(cache->id, "GC", 2) != 0) &&           (strncasecmp(cache->id, "GC", 2) != 0) &&
815           (strncasecmp(cache->id, "OC", 2) != 0) &&           (strncasecmp(cache->id, "OC", 2) != 0) &&
816           (strncasecmp(cache->id, "GA", 2) != 0)) {           (strncasecmp(cache->id, "GA", 2) != 0)) {
# Line 830  static cache_t *process_gpx_wpt(xmlTextR Line 877  static cache_t *process_gpx_wpt(xmlTextR
877      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
878    }    }
879    
880    g_assert(0);    gpx_free_cache(cache);
881    return cache;    return NULL;
882  }  }
883    
884  static void process_gpx(xmlTextReaderPtr reader, gpx_dialog_t *dialog,  static gboolean process_gpx(xmlTextReaderPtr reader, gpx_dialog_t *dialog,
885                          gpx_t *gpx) {                              gpx_t *gpx) {
886    
887    /* no attributes of interest */    /* no attributes of interest */
888    
# Line 846  static void process_gpx(xmlTextReaderPtr Line 893  static void process_gpx(xmlTextReaderPtr
893    while(*cache) cache = &(*cache)->next;    while(*cache) cache = &(*cache)->next;
894    
895    const xmlChar *name = xmlTextReaderConstName(reader);    const xmlChar *name = xmlTextReaderConstName(reader);
896    g_assert(name);    if(!name) return FALSE;
897    
898    /* read next node */    /* read next node */
899    int ret = xmlTextReaderRead(reader);    int ret = xmlTextReaderRead(reader);
# Line 876  static void process_gpx(xmlTextReaderPtr Line 923  static void process_gpx(xmlTextReaderPtr
923      case XML_READER_TYPE_END_ELEMENT:      case XML_READER_TYPE_END_ELEMENT:
924        /* end element must be for the current element */        /* end element must be for the current element */
925        g_assert(xmlTextReaderDepth(reader) == 0);        g_assert(xmlTextReaderDepth(reader) == 0);
926        return;        return TRUE;
927        break;        break;
928    
929      default:      default:
# Line 885  static void process_gpx(xmlTextReaderPtr Line 932  static void process_gpx(xmlTextReaderPtr
932      ret = xmlTextReaderRead(reader);      ret = xmlTextReaderRead(reader);
933    }    }
934    
935    g_assert(0);    return FALSE;
936  }  }
937    
938  /* parse loc waypoint entry */  /* parse loc waypoint entry */
# Line 1069  static gpx_t *gpx_parse_file(gpx_dialog_ Line 1116  static gpx_t *gpx_parse_file(gpx_dialog_
1116      *dot = 0;      *dot = 0;
1117      snprintf(wpts_name, sizeof(wpts_name), "%s-wpts.gpx", filename);      snprintf(wpts_name, sizeof(wpts_name), "%s-wpts.gpx", filename);
1118      *dot = '.';      *dot = '.';
   
1119      if(g_file_test(wpts_name,  G_FILE_TEST_EXISTS)) {      if(g_file_test(wpts_name,  G_FILE_TEST_EXISTS)) {
   
1120        xmlTextReaderPtr reader = xmlReaderForFile(wpts_name, NULL, 0);        xmlTextReaderPtr reader = xmlReaderForFile(wpts_name, NULL, 0);
1121        if (reader != NULL) {        if (reader != NULL) {
1122          gpx = process_root(reader, dialog, wpts_name, gpx);          gpx = process_root(reader, dialog, wpts_name, gpx);
# Line 1284  int gpx_total_caches(gpx_t *gpx) { Line 1329  int gpx_total_caches(gpx_t *gpx) {
1329    return num;    return num;
1330  }  }
1331    
1332    /* return number of caches in all gpx files */
1333    int gpx_total_caches_global(gpx_t *gpx) {
1334      int num = 0;
1335      while(gpx) {
1336        num += gpx_total_caches(gpx);
1337        gpx = gpx->next;
1338      }
1339    
1340      return num;
1341    }
1342    
1343  int gpx_number_of_waypoints(wpt_t *wpt) {  int gpx_number_of_waypoints(wpt_t *wpt) {
1344    int num = 0;    int num = 0;
1345    
# Line 1347  float gpx_pos_get_distance(pos_t p1, pos Line 1403  float gpx_pos_get_distance(pos_t p1, pos
1403    
1404  void gpx_pos_get_distance_str(char *str, int len,  void gpx_pos_get_distance_str(char *str, int len,
1405                                pos_t p1, pos_t p2, int mil) {                                pos_t p1, pos_t p2, int mil) {
1406    if(!p1.lat && !p1.lon) {    if(isnan(p1.lat) || isnan(p1.lon)) {
1407      snprintf(str, len, "---");      snprintf(str, len, "---");
1408      return;      return;
1409    }    }
# Line 1356  void gpx_pos_get_distance_str(char *str, Line 1412  void gpx_pos_get_distance_str(char *str,
1412    distance_str(str, len, dist, mil);    distance_str(str, len, dist, mil);
1413  }  }
1414    
 /* http://library.gnome.org/devel/gtk/unstable/GtkRadioButton.html */  
1415  void gpx_sort(gpx_t *gpx, int by, pos_t *refpos) {  void gpx_sort(gpx_t *gpx, int by, pos_t *refpos) {
1416    cache_t **new;    cache_t **new;
1417    cache_t *cur = gpx->cache;    cache_t *cur = gpx->cache;
# Line 1365  void gpx_sort(gpx_t *gpx, int by, pos_t Line 1420  void gpx_sort(gpx_t *gpx, int by, pos_t
1420    
1421    gpx->cache = NULL;  /* detach old chain */    gpx->cache = NULL;  /* detach old chain */
1422    while(cur) {    while(cur) {
1423      float cur_dist = gpx_pos_get_distance(*refpos, gpx_cache_pos(cur), 0);      float cur_dist = -1;
1424      int cur_cnt = 0;      int cur_cnt = 0;
1425    
1426        if(!isnan(cur->pos.lat) && !isnan(cur->pos.lon))
1427          cur_dist = gpx_pos_get_distance(*refpos, gpx_cache_pos(cur), 0);
1428    
1429      new = &(gpx->cache);      new = &(gpx->cache);
1430    
1431      /* search for currect insertion point */      /* search for currect insertion point */

Legend:
Removed from v.7  
changed lines
  Added in v.152