From 1fcdf28b9b5deeea8beb4f7a38377cc8ee19639e Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:46:07 -0600 Subject: [PATCH] convert garmin_fs functions from char* -> QString (#1202) * convert garmin_fs functions from char* -> QString. * update comment * make tag_type a class enum * update garmin_fs includes --- garmin_fs.cc | 138 +++-------------- garmin_fs.h | 20 +-- garmin_txt.cc | 2 +- gpx.cc | 274 ++++++++++++++++++++------------- gpx.h | 415 +++++++++++++++++++++++++------------------------- 5 files changed, 407 insertions(+), 442 deletions(-) diff --git a/garmin_fs.cc b/garmin_fs.cc index d00f4a0c3..148db9169 100644 --- a/garmin_fs.cc +++ b/garmin_fs.cc @@ -20,17 +20,13 @@ */ -#include // for snprintf, sscanf -#include // for strtod +#include "garmin_fs.h" -#include // for QString, QStringLiteral -#include // for CaseInsensitive +#include // for QString +#include // for CaseInsensitive #include "defs.h" -#include "garmin_fs.h" -#include "garmin_tables.h" // for gt_switch_display_mode_value, gt_display_mode_symbol, gt_display_mode_symbol_and_comment, gt_display_mode_symbol_and_name -#include "inifile.h" // for inifile_readstr -#include "src/core/xmlstreamwriter.h" // for XmlStreamWriter +#include "inifile.h" // for inifile_readstr #define MYNAME "garmin_fs" @@ -76,130 +72,40 @@ garmin_fs_t::~garmin_fs_t() } } -/* GPX - out */ - -void -garmin_fs_xml_convert(const int base_tag, int tag, const QString& qstr, Waypoint* waypt) +bool +garmin_fs_convert_category(const QString& category_name, uint16_t* category) { - // FIXME: eliminate C string copy/use here: - const char* cdatastr = xstrdup(qstr); - garmin_fs_t* gmsd = garmin_fs_t::find(waypt); - if (gmsd == nullptr) { - gmsd = garmin_fs_alloc(-1); - waypt->fs.FsChainAdd(gmsd); - } - - tag -= base_tag; - /* - tt_garmin_waypt_extension, -> 0 - tt_garmin_proximity, -> 1 - tt_garmin_temperature,-> 2 - tt_garmin_depth, -> 3 - tt_garmin_display_mode, -> 4 - tt_garmin_categories, -> 5 - tt_garmin_category, -> 6 - tt_garmin_addr, -> 7 - tt_garmin_city, -> 8 - tt_garmin_state, -> 9 - tt_garmin_country, -> 10 - tt_garmin_postal_code, -> 11 - tt_garmin_phone_nr, -> 12 - */ - switch (tag) { - case 1: - if (*cdatastr) { - waypt->set_proximity(strtod(cdatastr, nullptr)); - } - break; - case 2: - if (*cdatastr) { - waypt->set_temperature(strtod(cdatastr, nullptr)); - } - break; - case 3: - if (*cdatastr) { - waypt->set_depth(strtod(cdatastr, nullptr)); - } - break; - case 4: - if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { - garmin_fs_t::set_display(gmsd, gt_display_mode_symbol); - } else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { - garmin_fs_t::set_display(gmsd, gt_display_mode_symbol_and_comment); - } else { - garmin_fs_t::set_display(gmsd, gt_display_mode_symbol_and_name); - } - break; - case 6: - if (! garmin_fs_merge_category(cdatastr, waypt)) { - // There's nothing a user can really do about this (well, they could - // create a gpsbabel.ini that mapped them to garmin category numbers - // but that feature is so obscure and used in so few outputs that - // there's no reason to alarm the user. Just silently disregard - // category names that don't map cleanly. - // warning(MYNAME ": Unable to convert category \"%s\"!\n", cdatastr); + // Is the name "Category" followed by a number? Use that number. + if (category_name.startsWith(u"Category ", Qt::CaseInsensitive)) { + bool ok; + int i = category_name.mid(9).toInt(&ok); + if (ok && (i >= 1) && (i <= 16)) { + *category = (1 << --i); + return true; } - break; - case 7: - garmin_fs_t::set_addr(gmsd, cdatastr); - break; - case 8: - garmin_fs_t::set_city(gmsd, cdatastr); - break; - case 9: - garmin_fs_t::set_state(gmsd, cdatastr); - break; - case 10: - garmin_fs_t::set_country(gmsd, cdatastr); - break; - case 11: - garmin_fs_t::set_postal_code(gmsd, cdatastr); - break; - case 12: - garmin_fs_t::set_phone_nr(gmsd, cdatastr); - break; } - xfree(cdatastr); -} - -unsigned char -garmin_fs_convert_category(const char* category_name, uint16_t* category) -{ - int i; - int cat = 0; - - // Is the name "Category" followed by a number? Use that number. - if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && - (1 == sscanf(category_name + 9, "%d", &i)) && - (i >= 1) && (i <= 16)) { - cat = (1 << --i); - } else if (global_opts.inifile != nullptr) { + if (global_opts.inifile != nullptr) { // Do we have a gpsbabel.ini that maps category names to category #'s? - for (i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) { QString key = QString::number(i + 1); QString c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); if (c.compare(category_name, Qt::CaseInsensitive) == 0) { - cat = (1 << i); - break; + *category = (1 << i); + return true; } } } - if (cat == 0) { - return 0; - } else { - *category = cat; - return 1; - } + return false; } -unsigned char -garmin_fs_merge_category(const char* category_name, Waypoint* waypt) +bool +garmin_fs_merge_category(const QString& category_name, Waypoint* waypt) { uint16_t cat; // Attempt to get a textual category name to a category number. if (!garmin_fs_convert_category(category_name, &cat)) { - return 0; + return false; } garmin_fs_t* gmsd = garmin_fs_t::find(waypt); @@ -210,5 +116,5 @@ garmin_fs_merge_category(const char* category_name, Waypoint* waypt) waypt->fs.FsChainAdd(gmsd); } garmin_fs_t::set_category(gmsd, cat); - return 1; + return true; } diff --git a/garmin_fs.h b/garmin_fs.h index fb39b5b90..0535d85ac 100644 --- a/garmin_fs.h +++ b/garmin_fs.h @@ -24,13 +24,12 @@ #ifndef GARMIN_FS_H #define GARMIN_FS_H -#include // for int32_t, int16_t, uint16_t +#include // for int32_t, int16_t, uint16_t -#include // for QString +#include // for QString #include "defs.h" -#include "formspec.h" // for FsChainFind, kFsGmsd, FormatSpecificData -#include "src/core/xmlstreamwriter.h" // for XmlStreamWriter +#include "formspec.h" // for FormatSpecificData, kFsGmsd, FormatSpecificDataList /* this order is used by most devices */ @@ -219,16 +218,11 @@ garmin_fs_t* garmin_fs_alloc(int protocol); void garmin_fs_destroy(void* fs); void garmin_fs_copy(void** dest, const void* src); -/* for GPX */ -void garmin_fs_xml_convert(int base_tag, int tag, const QString& qstr, Waypoint* waypt); +/* ..convert_category: returns true=OK; false=Unable to convert category */ +bool garmin_fs_convert_category(const QString& category_name, uint16_t* category); -/* common garmin_fs utilities */ - -/* ..convert_category: returns 1=OK; 0=Unable to convert category */ -unsigned char garmin_fs_convert_category(const char* category_name, uint16_t* category); - -/* ..merge_category: returns 1=OK; 0=Unable to convert category */ -unsigned char garmin_fs_merge_category(const char* category_name, Waypoint* waypt); +/* ..merge_category: returns true=OK; false=Unable to convert category */ +bool garmin_fs_merge_category(const QString& category_name, Waypoint* waypt); #define GMSD_SECTION_CATEGORIES "Garmin Categories" diff --git a/garmin_txt.cc b/garmin_txt.cc index 8720621a1..c49569445 100644 --- a/garmin_txt.cc +++ b/garmin_txt.cc @@ -965,7 +965,7 @@ parse_categories(const QString& str) QString cin = catstring.trimmed(); if (!cin.isEmpty()) { uint16_t val; - if (!garmin_fs_convert_category(CSTR(cin), &val)) { + if (!garmin_fs_convert_category(cin, &val)) { warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", qPrintable(cin), current_line); } else { res = res | val; diff --git a/gpx.cc b/gpx.cc index 45c7606e5..de176e454 100644 --- a/gpx.cc +++ b/gpx.cc @@ -47,7 +47,7 @@ #include // for qAsConst, QAddConst<>::Type #include "defs.h" -#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t, garmin_fs_xml_convert +#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t, garmin_fs_alloc, garmin_fs_merge_category #include "garmin_tables.h" // for gt_color_index_by_rgb, gt_color_name, gt_color_value_by_name #include "geocache.h" // for Geocache, Geocache::UtfSt... #include "mkshort.h" // for MakeShort @@ -213,6 +213,69 @@ GpxFormat::tag_gs_cache(const QXmlStreamAttributes& attr) const } } +void +GpxFormat::tag_garmin_fs(tag_type tag, const QString& text, Waypoint* waypt) +{ + garmin_fs_t* gmsd = garmin_fs_t::find(waypt); + if (gmsd == nullptr) { + gmsd = garmin_fs_alloc(-1); + waypt->fs.FsChainAdd(gmsd); + } + + switch (tag) { + case tag_type::garmin_wpt_proximity: + waypt->set_proximity(text.toDouble()); + break; + case tag_type::garmin_wpt_temperature: + waypt->set_temperature(text.toFloat()); + break; + case tag_type::garmin_wpt_depth: + waypt->set_depth(text.toDouble()); + break; + case tag_type::garmin_wpt_display_mode: + // element DispalyMode value is case sensitive. + if (text == u"SymbolOnly") { + garmin_fs_t::set_display(gmsd, gt_display_mode_symbol); + } else if (text == u"SymbolAndDescription") { + garmin_fs_t::set_display(gmsd, gt_display_mode_symbol_and_comment); + } else { + garmin_fs_t::set_display(gmsd, gt_display_mode_symbol_and_name); + } + break; + case tag_type::garmin_wpt_category: + if (!garmin_fs_merge_category(text, waypt)) { + // There's nothing a user can really do about this (well, they could + // create a gpsbabel.ini that mapped them to garmin category numbers + // but that feature is so obscure and used in so few outputs that + // there's no reason to alarm the user. Just silently disregard + // category names that don't map cleanly. + // warning(MYNAME ": Unable to convert category \"%s\"!\n", CSTR(text)); + } + break; + case tag_type::garmin_wpt_addr: + garmin_fs_t::set_addr(gmsd, text); + break; + case tag_type::garmin_wpt_city: + garmin_fs_t::set_city(gmsd, text); + break; + case tag_type::garmin_wpt_state: + garmin_fs_t::set_state(gmsd, text); + break; + case tag_type::garmin_wpt_country: + garmin_fs_t::set_country(gmsd, text); + break; + case tag_type::garmin_wpt_postal_code: + garmin_fs_t::set_postal_code(gmsd, text); + break; + case tag_type::garmin_wpt_phone_nr: + garmin_fs_t::set_phone_nr(gmsd, text); + break; + default: + // do nothing + break; + } +} + void GpxFormat::start_something_else(QStringView el, const QXmlStreamAttributes& attr) { @@ -318,69 +381,70 @@ GpxFormat::gpx_start(QStringView el, const QXmlStreamAttributes& attr) tag_mapping tag = get_tag(current_tag); switch (tag.type) { - case tt_gpx: + case tag_type::gpx: tag_gpx(attr); break; - case tt_link: + case tag_type::link: if (attr.hasAttribute(QLatin1String("href"))) { link_url = attr.value(QLatin1String("href")).toString(); } break; - case tt_wpt: + case tag_type::wpt: tag_wpt(attr); break; - case tt_wpttype_link: + case tag_type::wpttype_link: if (attr.hasAttribute(QLatin1String("href"))) { link_url = attr.value(QLatin1String("href")).toString(); } break; - case tt_rte: + case tag_type::rte: rte_head = new route_head; route_add_head(rte_head); rh_link_ = new UrlLink; fs_ptr = &rte_head->fs; break; - case tt_rte_rtept: + case tag_type::rte_rtept: tag_wpt(attr); break; - case tt_trk: + case tag_type::trk: trk_head = new route_head; track_add_head(trk_head); rh_link_ = new UrlLink; fs_ptr = &trk_head->fs; break; - case tt_trk_trkseg_trkpt: + case tag_type::trk_trkseg_trkpt: tag_wpt(attr); if (next_trkpt_is_new_seg) { wpt_tmp->wpt_flags.new_trkseg = 1; next_trkpt_is_new_seg = 0; } break; - case tt_rte_link: - case tt_trk_link: + case tag_type::rte_link: + case tag_type::trk_link: if (attr.hasAttribute(QLatin1String("href"))) { link_url = attr.value(QLatin1String("href")).toString(); } break; - case tt_unknown: + case tag_type::unknown: start_something_else(el, attr); return; - case tt_cache: + case tag_type::cache: tag_gs_cache(attr); break; - case tt_cache_log_wpt: + case tag_type::cache_log_wpt: if (opt_logpoint) { tag_log_wpt(attr); } break; - case tt_cache_desc_long: - case tt_cache_desc_short: + case tag_type::cache_desc_long: + case tag_type::cache_desc_short: tag_cache_desc(attr); break; - case tt_cache_placer: + case tag_type::cache_placer: if (attr.hasAttribute(QLatin1String("id"))) { wpt_tmp->AllocGCData()->placer_id = attr.value(QLatin1String("id")).toInt(); } + break; default: break; } @@ -470,44 +534,44 @@ GpxFormat::gpx_end(QStringView /*unused*/) /* * First, the tags that are file-global. */ - case tt_name: + case tag_type::name: gpx_add_to_global(gpx_global->name, cdatastr); break; - case tt_desc: + case tag_type::desc: gpx_add_to_global(gpx_global->desc, cdatastr); break; - case tt_author: + case tag_type::author: gpx_add_to_global(gpx_global->author, cdatastr); break; - case tt_email: + case tag_type::email: gpx_add_to_global(gpx_global->email, cdatastr); break; - case tt_url: + case tag_type::url: gpx_add_to_global(gpx_global->url, cdatastr); break; - case tt_urlname: + case tag_type::urlname: gpx_add_to_global(gpx_global->urlname, cdatastr); break; - case tt_keywords: + case tag_type::keywords: gpx_add_to_global(gpx_global->keywords, cdatastr); break; - case tt_link: + case tag_type::link: (gpx_global->link).AddUrlLink(UrlLink(link_url, link_text, link_type)); link_type.clear(); link_text.clear(); link_url.clear(); break; - case tt_link_text: + case tag_type::link_text: link_text = cdatastr; break; - case tt_link_type: + case tag_type::link_type: link_type = cdatastr; break; /* * Waypoint-specific tags. */ - case tt_wpt: + case tag_type::wpt: if (link_) { if (!link_->url_.isEmpty()) { wpt_tmp->AddUrlLink(*link_); @@ -525,40 +589,40 @@ GpxFormat::gpx_end(QStringView /*unused*/) wpt_tmp = nullptr; fs_ptr = nullptr; break; - case tt_cache_name: + case tag_type::cache_name: wpt_tmp->notes = cdatastr; break; - case tt_cache_container: + case tag_type::cache_container: wpt_tmp->AllocGCData()->set_container(cdatastr); break; - case tt_cache_type: + case tag_type::cache_type: wpt_tmp->AllocGCData()->set_type(cdatastr); break; - case tt_cache_difficulty: + case tag_type::cache_difficulty: wpt_tmp->AllocGCData()->diff = cdatastr.toFloat() * 10; break; - case tt_cache_hint: + case tag_type::cache_hint: wpt_tmp->AllocGCData()->hint = cdatastr; break; - case tt_cache_desc_long: { + case tag_type::cache_desc_long: { Geocache* gc_data = wpt_tmp->AllocGCData(); gc_data->desc_long.is_html = cache_descr_is_html; gc_data->desc_long.utf_string = cdatastr; } break; - case tt_cache_desc_short: { + case tag_type::cache_desc_short: { Geocache* gc_data = wpt_tmp->AllocGCData(); gc_data->desc_short.is_html = cache_descr_is_html; gc_data->desc_short.utf_string = cdatastr; } break; - case tt_cache_terrain: + case tag_type::cache_terrain: wpt_tmp->AllocGCData()->terr = cdatastr.toFloat() * 10; break; - case tt_cache_placer: + case tag_type::cache_placer: wpt_tmp->AllocGCData()->placer = cdatastr; break; - case tt_cache_log_date: + case tag_type::cache_log_date: gc_log_date = xml_parse_time(cdatastr); break; /* @@ -566,51 +630,51 @@ GpxFormat::gpx_end(QStringView /*unused*/) * if this is the first "found it" for this waypt, just use the * last date we saw in this log. */ - case tt_cache_log_type: + case tag_type::cache_log_type: if ((cdatastr.compare(u"Found it") == 0) && (!wpt_tmp->gc_data->last_found.isValid())) { wpt_tmp->AllocGCData()->last_found = gc_log_date; } gc_log_date = gpsbabel::DateTime(); break; - case tt_cache_favorite_points: + case tag_type::cache_favorite_points: wpt_tmp->AllocGCData()->favorite_points = cdatastr.toInt(); break; - case tt_cache_personal_note: + case tag_type::cache_personal_note: wpt_tmp->AllocGCData()->personal_note = cdatastr; break; /* * Garmin-waypoint-specific tags. */ - case tt_garmin_wpt_proximity: - case tt_garmin_wpt_temperature: - case tt_garmin_wpt_depth: - case tt_garmin_wpt_display_mode: - case tt_garmin_wpt_category: - case tt_garmin_wpt_addr: - case tt_garmin_wpt_city: - case tt_garmin_wpt_state: - case tt_garmin_wpt_country: - case tt_garmin_wpt_postal_code: - case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag.type, cdatastr, wpt_tmp); + case tag_type::garmin_wpt_proximity: + case tag_type::garmin_wpt_temperature: + case tag_type::garmin_wpt_depth: + case tag_type::garmin_wpt_display_mode: + case tag_type::garmin_wpt_category: + case tag_type::garmin_wpt_addr: + case tag_type::garmin_wpt_city: + case tag_type::garmin_wpt_state: + case tag_type::garmin_wpt_country: + case tag_type::garmin_wpt_postal_code: + case tag_type::garmin_wpt_phone_nr: + tag_garmin_fs(tag.type, cdatastr, wpt_tmp); break; /* * Humminbird-waypoint-specific tags. */ - case tt_humminbird_wpt_depth: - case tt_humminbird_trk_trkseg_trkpt_depth: + case tag_type::humminbird_wpt_depth: + case tag_type::humminbird_trk_trkseg_trkpt_depth: wpt_tmp->set_depth(cdatastr.toDouble() / 100.0); break; /* * Route-specific tags. */ - case tt_rte_name: + case tag_type::rte_name: rte_head->rte_name = cdatastr; break; - case tt_rte: + case tag_type::rte: if (rh_link_) { if (!rh_link_->url_.isEmpty()) { rte_head->rte_urls.AddUrlLink(*rh_link_); @@ -620,7 +684,7 @@ GpxFormat::gpx_end(QStringView /*unused*/) } fs_ptr = nullptr; break; - case tt_rte_rtept: + case tag_type::rte_rtept: if (link_) { if (!link_->url_.isEmpty()) { wpt_tmp->AddUrlLink(*link_); @@ -636,28 +700,28 @@ GpxFormat::gpx_end(QStringView /*unused*/) wpt_tmp = nullptr; fs_ptr = nullptr; break; - case tt_rte_desc: + case tag_type::rte_desc: rte_head->rte_desc = cdatastr; break; - case tt_garmin_rte_display_color: + case tag_type::garmin_rte_display_color: rte_head->line_color.bbggrr = gt_color_value_by_name(cdatastr); break; - case tt_rte_link: + case tag_type::rte_link: rte_head->rte_urls.AddUrlLink(UrlLink(link_url, link_text, link_type)); link_type.clear(); link_text.clear(); link_url.clear(); break; - case tt_rte_number: + case tag_type::rte_number: rte_head->rte_num = cdatastr.toInt(); break; /* * Track-specific tags. */ - case tt_trk_name: + case tag_type::trk_name: trk_head->rte_name = cdatastr; break; - case tt_trk: + case tag_type::trk: if (rh_link_) { if (!rh_link_->url_.isEmpty()) { trk_head->rte_urls.AddUrlLink(*rh_link_); @@ -667,11 +731,11 @@ GpxFormat::gpx_end(QStringView /*unused*/) } fs_ptr = nullptr; break; - case tt_trk_trkseg: + case tag_type::trk_trkseg: next_trkpt_is_new_seg = 1; fs_ptr = nullptr; break; - case tt_trk_trkseg_trkpt: + case tag_type::trk_trkseg_trkpt: if (link_) { if (!link_->url_.isEmpty()) { wpt_tmp->AddUrlLink(*link_); @@ -687,117 +751,117 @@ GpxFormat::gpx_end(QStringView /*unused*/) wpt_tmp = nullptr; fs_ptr = nullptr; break; - case tt_trk_desc: + case tag_type::trk_desc: trk_head->rte_desc = cdatastr; break; - case tt_garmin_trk_display_color: + case tag_type::garmin_trk_display_color: trk_head->line_color.bbggrr = gt_color_value_by_name(cdatastr); break; - case tt_trk_link: + case tag_type::trk_link: trk_head->rte_urls.AddUrlLink(UrlLink(link_url, link_text, link_type)); link_type.clear(); link_text.clear(); link_url.clear(); break; - case tt_trk_number: + case tag_type::trk_number: trk_head->rte_num = cdatastr.toInt(); break; - case tt_trk_trkseg_trkpt_course: + case tag_type::trk_trkseg_trkpt_course: wpt_tmp->set_course(cdatastr.toDouble()); break; - case tt_trk_trkseg_trkpt_speed: + case tag_type::trk_trkseg_trkpt_speed: wpt_tmp->set_speed(cdatastr.toDouble()); break; - case tt_trk_trkseg_trkpt_heartrate: + case tag_type::trk_trkseg_trkpt_heartrate: wpt_tmp->heartrate = cdatastr.toDouble(); break; - case tt_trk_trkseg_trkpt_cadence: + case tag_type::trk_trkseg_trkpt_cadence: wpt_tmp->cadence = cdatastr.toDouble(); break; /* * Items that are actually in multiple categories. */ - case tt_rte_url: - case tt_trk_url: + case tag_type::rte_url: + case tag_type::trk_url: rh_link_->url_ = cdatastr; break; - case tt_rte_urlname: - case tt_trk_urlname: + case tag_type::rte_urlname: + case tag_type::trk_urlname: rh_link_->url_link_text_ = cdatastr; break; - case tt_rte_link_text: - case tt_trk_link_text: + case tag_type::rte_link_text: + case tag_type::trk_link_text: link_text = cdatastr; break; - case tt_rte_link_type: - case tt_trk_link_type: + case tag_type::rte_link_type: + case tag_type::trk_link_type: link_type = cdatastr; break; - case tt_wpttype_ele: + case tag_type::wpttype_ele: wpt_tmp->altitude = cdatastr.toDouble(); break; - case tt_wpttype_name: + case tag_type::wpttype_name: wpt_tmp->shortname = cdatastr; break; - case tt_wpttype_sym: + case tag_type::wpttype_sym: wpt_tmp->icon_descr = cdatastr; break; - case tt_wpttype_time: + case tag_type::wpttype_time: wpt_tmp->SetCreationTime(xml_parse_time(cdatastr)); break; - case tt_wpttype_magvar: + case tag_type::wpttype_magvar: if (wpt_fsdata == nullptr) { wpt_fsdata = new gpx_wpt_fsdata; } wpt_fsdata->magvar = cdatastr; break; - case tt_wpttype_geoidheight: + case tag_type::wpttype_geoidheight: wpt_tmp->set_geoidheight(cdatastr.toDouble()); break; - case tt_wpttype_cmt: + case tag_type::wpttype_cmt: wpt_tmp->description = cdatastr; break; - case tt_wpttype_desc: + case tag_type::wpttype_desc: wpt_tmp->notes = cdatastr; break; - case tt_wpttype_src: + case tag_type::wpttype_src: if (wpt_fsdata == nullptr) { wpt_fsdata = new gpx_wpt_fsdata; } wpt_fsdata->src = cdatastr; break; - case tt_wpttype_type: + case tag_type::wpttype_type: if (wpt_fsdata == nullptr) { wpt_fsdata = new gpx_wpt_fsdata; } wpt_fsdata->type = cdatastr; break; - case tt_wpttype_pdop: + case tag_type::wpttype_pdop: wpt_tmp->pdop = cdatastr.toFloat(); break; - case tt_wpttype_hdop: + case tag_type::wpttype_hdop: wpt_tmp->hdop = cdatastr.toFloat(); break; - case tt_wpttype_vdop: + case tag_type::wpttype_vdop: wpt_tmp->vdop = cdatastr.toFloat(); break; - case tt_wpttype_ageofdgpsdata: + case tag_type::wpttype_ageofdgpsdata: if (wpt_fsdata == nullptr) { wpt_fsdata = new gpx_wpt_fsdata; } wpt_fsdata->ageofdgpsdata = cdatastr; break; - case tt_wpttype_dgpsid: + case tag_type::wpttype_dgpsid: if (wpt_fsdata == nullptr) { wpt_fsdata = new gpx_wpt_fsdata; } wpt_fsdata->dgpsid = cdatastr; break; - case tt_wpttype_sat: + case tag_type::wpttype_sat: wpt_tmp->sat = cdatastr.toInt(); break; - case tt_wpttype_fix: + case tag_type::wpttype_fix: if (cdatastr == QLatin1String("none")) { wpt_tmp->fix = fix_none; } else if (cdatastr == QLatin1String("2d")) { @@ -812,25 +876,25 @@ GpxFormat::gpx_end(QStringView /*unused*/) wpt_tmp->fix = fix_unknown; } break; - case tt_wpttype_url: + case tag_type::wpttype_url: link_->url_ = cdatastr; break; - case tt_wpttype_urlname: + case tag_type::wpttype_urlname: link_->url_link_text_ = cdatastr; break; - case tt_wpttype_link: + case tag_type::wpttype_link: waypt_add_url(wpt_tmp, link_url, link_text, link_type); link_type.clear(); link_text.clear(); link_url.clear(); break; - case tt_wpttype_link_text: + case tag_type::wpttype_link_text: link_text = cdatastr; break; - case tt_wpttype_link_type: + case tag_type::wpttype_link_type: link_type = cdatastr; break; - case tt_unknown: + case tag_type::unknown: end_something_else(); return; default: diff --git a/gpx.h b/gpx.h index a658404ba..c0d0218ac 100644 --- a/gpx.h +++ b/gpx.h @@ -95,112 +95,112 @@ class GpxFormat : public Format gpxpt_route }; - enum tag_type { - tt_unknown = 0, - tt_gpx, - - tt_name, /* Optional file-level info */ - tt_desc, - tt_author, - tt_email, - tt_url, - tt_urlname, - tt_keywords, - tt_link, - tt_link_text, - tt_link_type, - - tt_wpt, - tt_wpttype_ele, - tt_wpttype_time, - tt_wpttype_magvar, - tt_wpttype_geoidheight, - tt_wpttype_name, - tt_wpttype_cmt, - tt_wpttype_desc, - tt_wpttype_src, - tt_wpttype_url, /* Not in GPX 1.1 */ - tt_wpttype_urlname, /* Not in GPX 1.1 */ - tt_wpttype_link, /* New in GPX 1.1 */ - tt_wpttype_link_text, /* New in GPX 1.1 */ - tt_wpttype_link_type, /* New in GPX 1.1 */ - tt_wpttype_sym, - tt_wpttype_type, - tt_wpttype_fix, - tt_wpttype_sat, - tt_wpttype_hdop, /* HDOPS are common for all three */ - tt_wpttype_vdop, /* VDOPS are common for all three */ - tt_wpttype_pdop, /* PDOPS are common for all three */ - tt_wpttype_ageofdgpsdata, - tt_wpttype_dgpsid, - tt_cache, - tt_cache_name, - tt_cache_container, - tt_cache_type, - tt_cache_difficulty, - tt_cache_terrain, - tt_cache_hint, - tt_cache_desc_short, - tt_cache_desc_long, - tt_cache_log_wpt, - tt_cache_log_type, - tt_cache_log_date, - tt_cache_placer, - tt_cache_favorite_points, - tt_cache_personal_note, - - tt_wpt_extensions, - - tt_garmin_wpt_extensions, /* don't change this order */ - tt_garmin_wpt_proximity, - tt_garmin_wpt_temperature, - tt_garmin_wpt_depth, - tt_garmin_wpt_display_mode, - tt_garmin_wpt_categories, - tt_garmin_wpt_category, - tt_garmin_wpt_addr, - tt_garmin_wpt_city, - tt_garmin_wpt_state, - tt_garmin_wpt_country, - tt_garmin_wpt_postal_code, - tt_garmin_wpt_phone_nr, /* don't change this order */ - - tt_rte, - tt_rte_name, - tt_rte_desc, - tt_rte_cmt, - tt_rte_url, /* Not in GPX 1.1 */ - tt_rte_urlname, /* Not in GPX 1.1 */ - tt_rte_link, /* New in GPX 1.1 */ - tt_rte_link_text, /* New in GPX 1.1 */ - tt_rte_link_type, /* New in GPX 1.1 */ - tt_rte_number, - tt_garmin_rte_display_color, - tt_rte_rtept, - tt_trk, - tt_trk_desc, - tt_trk_name, - tt_trk_trkseg, - tt_trk_url, /* Not in GPX 1.1 */ - tt_trk_urlname, /* Not in GPX 1.1 */ - tt_trk_link, /* New in GPX 1.1 */ - tt_trk_link_text, /* New in GPX 1.1 */ - tt_trk_link_type, /* New in GPX 1.1 */ - tt_trk_number, - tt_garmin_trk_display_color, - tt_trk_trkseg_trkpt, - tt_trk_trkseg_trkpt_course, /* Not in GPX 1.1 */ - tt_trk_trkseg_trkpt_speed, /* Not in GPX 1.1 */ - tt_trk_trkseg_trkpt_heartrate, - tt_trk_trkseg_trkpt_cadence, - - tt_humminbird_wpt_depth, - tt_humminbird_wpt_status, - tt_humminbird_trk_trkseg_trkpt_depth, + enum class tag_type { + unknown = 0, + gpx, + + name, /* Optional file-level info */ + desc, + author, + email, + url, + urlname, + keywords, + link, + link_text, + link_type, + + wpt, + wpttype_ele, + wpttype_time, + wpttype_magvar, + wpttype_geoidheight, + wpttype_name, + wpttype_cmt, + wpttype_desc, + wpttype_src, + wpttype_url, /* Not in GPX 1.1 */ + wpttype_urlname, /* Not in GPX 1.1 */ + wpttype_link, /* New in GPX 1.1 */ + wpttype_link_text, /* New in GPX 1.1 */ + wpttype_link_type, /* New in GPX 1.1 */ + wpttype_sym, + wpttype_type, + wpttype_fix, + wpttype_sat, + wpttype_hdop, /* HDOPS are common for all three */ + wpttype_vdop, /* VDOPS are common for all three */ + wpttype_pdop, /* PDOPS are common for all three */ + wpttype_ageofdgpsdata, + wpttype_dgpsid, + cache, + cache_name, + cache_container, + cache_type, + cache_difficulty, + cache_terrain, + cache_hint, + cache_desc_short, + cache_desc_long, + cache_log_wpt, + cache_log_type, + cache_log_date, + cache_placer, + cache_favorite_points, + cache_personal_note, + + wpt_extensions, + + garmin_wpt_extensions, + garmin_wpt_proximity, + garmin_wpt_temperature, + garmin_wpt_depth, + garmin_wpt_display_mode, + garmin_wpt_categories, + garmin_wpt_category, + garmin_wpt_addr, + garmin_wpt_city, + garmin_wpt_state, + garmin_wpt_country, + garmin_wpt_postal_code, + garmin_wpt_phone_nr, + + rte, + rte_name, + rte_desc, + rte_cmt, + rte_url, /* Not in GPX 1.1 */ + rte_urlname, /* Not in GPX 1.1 */ + rte_link, /* New in GPX 1.1 */ + rte_link_text, /* New in GPX 1.1 */ + rte_link_type, /* New in GPX 1.1 */ + rte_number, + garmin_rte_display_color, + rte_rtept, + trk, + trk_desc, + trk_name, + trk_trkseg, + trk_url, /* Not in GPX 1.1 */ + trk_urlname, /* Not in GPX 1.1 */ + trk_link, /* New in GPX 1.1 */ + trk_link_text, /* New in GPX 1.1 */ + trk_link_type, /* New in GPX 1.1 */ + trk_number, + garmin_trk_display_color, + trk_trkseg_trkpt, + trk_trkseg_trkpt_course, /* Not in GPX 1.1 */ + trk_trkseg_trkpt_speed, /* Not in GPX 1.1 */ + trk_trkseg_trkpt_heartrate, + trk_trkseg_trkpt_cadence, + + humminbird_wpt_depth, + humminbird_wpt_status, + humminbird_trk_trkseg_trkpt_depth, }; struct tag_mapping { - tag_type type{tt_unknown}; /* enum from above for this tag */ + tag_type type{tag_type::unknown}; /* enum from above for this tag */ /* * passthrough should be true for * 1) The gpx 1.1 extensions element and any descendents. @@ -221,6 +221,7 @@ class GpxFormat : public Format void tag_wpt(const QXmlStreamAttributes& attr); void tag_cache_desc(const QXmlStreamAttributes& attr); void tag_gs_cache(const QXmlStreamAttributes& attr) const; + void tag_garmin_fs(tag_type tag, const QString& text, Waypoint* waypt); void start_something_else(QStringView el, const QXmlStreamAttributes& attr); void end_something_else(); void tag_log_wpt(const QXmlStreamAttributes& attr) const; @@ -346,117 +347,117 @@ class GpxFormat : public Format // Maintain a fast mapping from full tag names to the struct above. const QHash hash = { - {"/gpx", {tt_gpx, false}}, - METATAG(tt_name, "name"), - METATAG(tt_desc, "desc"), - {"/gpx/author", {tt_author, false}}, - {"/gpx/email", {tt_email, false}}, - {"/gpx/url", {tt_url, false}}, - {"/gpx/urlname", {tt_urlname, false}}, - METATAG(tt_keywords, "keywords"), - {"/gpx/metadata/link", {tt_link, false}}, - {"/gpx/metadata/link/text", {tt_link_text, false}}, - {"/gpx/metadata/link/type", {tt_link_type, false}}, - - {"/gpx/wpt", {tt_wpt, false}}, + {"/gpx", {tag_type::gpx, false}}, + METATAG(tag_type::name, "name"), + METATAG(tag_type::desc, "desc"), + {"/gpx/author", {tag_type::author, false}}, + {"/gpx/email", {tag_type::email, false}}, + {"/gpx/url", {tag_type::url, false}}, + {"/gpx/urlname", {tag_type::urlname, false}}, + METATAG(tag_type::keywords, "keywords"), + {"/gpx/metadata/link", {tag_type::link, false}}, + {"/gpx/metadata/link/text", {tag_type::link_text, false}}, + {"/gpx/metadata/link/type", {tag_type::link_type, false}}, + + {"/gpx/wpt", {tag_type::wpt, false}}, /* Double up the GPX 1.0 and GPX 1.1 styles */ // GEOTAG(tt_cache, "cache"), - {"/gpx/wpt/groundspeak:cache", {tt_cache, true}}, - - GEOTAG(tt_cache_name, "name"), - GEOTAG(tt_cache_container, "container"), - GEOTAG(tt_cache_type, "type"), - GEOTAG(tt_cache_difficulty, "difficulty"), - GEOTAG(tt_cache_terrain, "terrain"), - GEOTAG(tt_cache_hint, "encoded_hints"), - GEOTAG(tt_cache_desc_short, "short_description"), - GEOTAG(tt_cache_desc_long, "long_description"), - GEOTAG(tt_cache_placer, "owner"), - GEOTAG(tt_cache_favorite_points, "favorite_points"), - GEOTAG(tt_cache_personal_note, "personal_note"), - {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt", {tt_cache_log_wpt, true}}, - {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type", {tt_cache_log_type, true}}, - {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date", {tt_cache_log_date, true}}, - - {"/gpx/wpt/extensions", {tt_wpt_extensions, true}}, - - {GARMIN_WPT_EXT, {tt_garmin_wpt_extensions, true}}, - {GARMIN_WPT_EXT "/gpxx:Proximity", {tt_garmin_wpt_proximity, true}}, - {GARMIN_WPT_EXT "/gpxx:Temperature", {tt_garmin_wpt_temperature, true}}, - {GARMIN_TRKPT_EXT "/gpxtpx:atemp", {tt_garmin_wpt_temperature, true}}, - {GARMIN_WPT_EXT "/gpxx:Depth", {tt_garmin_wpt_depth, true}}, - {GARMIN_WPT_EXT "/gpxx:DisplayMode", {tt_garmin_wpt_display_mode, true}}, - {GARMIN_WPT_EXT "/gpxx:Categories", {tt_garmin_wpt_categories, true}}, - {GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", {tt_garmin_wpt_category, true}}, - {GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", {tt_garmin_wpt_addr, true}}, - {GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", {tt_garmin_wpt_city, true}}, - {GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", {tt_garmin_wpt_state, true}}, - {GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", {tt_garmin_wpt_country, true}}, - {GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", {tt_garmin_wpt_postal_code, true}}, - {GARMIN_WPT_EXT "/gpxx:PhoneNumber", {tt_garmin_wpt_phone_nr, true}}, + {"/gpx/wpt/groundspeak:cache", {tag_type::cache, true}}, + + GEOTAG(tag_type::cache_name, "name"), + GEOTAG(tag_type::cache_container, "container"), + GEOTAG(tag_type::cache_type, "type"), + GEOTAG(tag_type::cache_difficulty, "difficulty"), + GEOTAG(tag_type::cache_terrain, "terrain"), + GEOTAG(tag_type::cache_hint, "encoded_hints"), + GEOTAG(tag_type::cache_desc_short, "short_description"), + GEOTAG(tag_type::cache_desc_long, "long_description"), + GEOTAG(tag_type::cache_placer, "owner"), + GEOTAG(tag_type::cache_favorite_points, "favorite_points"), + GEOTAG(tag_type::cache_personal_note, "personal_note"), + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt", {tag_type::cache_log_wpt, true}}, + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type", {tag_type::cache_log_type, true}}, + {"/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date", {tag_type::cache_log_date, true}}, + + {"/gpx/wpt/extensions", {tag_type::wpt_extensions, true}}, + + {GARMIN_WPT_EXT, {tag_type::garmin_wpt_extensions, true}}, + {GARMIN_WPT_EXT "/gpxx:Proximity", {tag_type::garmin_wpt_proximity, true}}, + {GARMIN_WPT_EXT "/gpxx:Temperature", {tag_type::garmin_wpt_temperature, true}}, + {GARMIN_TRKPT_EXT "/gpxtpx:atemp", {tag_type::garmin_wpt_temperature, true}}, + {GARMIN_WPT_EXT "/gpxx:Depth", {tag_type::garmin_wpt_depth, true}}, + {GARMIN_WPT_EXT "/gpxx:DisplayMode", {tag_type::garmin_wpt_display_mode, true}}, + {GARMIN_WPT_EXT "/gpxx:Categories", {tag_type::garmin_wpt_categories, true}}, + {GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", {tag_type::garmin_wpt_category, true}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", {tag_type::garmin_wpt_addr, true}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", {tag_type::garmin_wpt_city, true}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", {tag_type::garmin_wpt_state, true}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", {tag_type::garmin_wpt_country, true}}, + {GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", {tag_type::garmin_wpt_postal_code, true}}, + {GARMIN_WPT_EXT "/gpxx:PhoneNumber", {tag_type::garmin_wpt_phone_nr, true}}, // In Garmin space, but in core of waypoint. - {GARMIN_TRKPT_EXT "/gpxtpx:hr", {tt_trk_trkseg_trkpt_heartrate, true}}, - {GARMIN_TRKPT_EXT "/gpxtpx:cad", {tt_trk_trkseg_trkpt_cadence, true}}, - - {"/gpx/wpt/extensions/h:depth", {tt_humminbird_wpt_depth, true}}, // in centimeters. - {"/gpx/wpt/extensions/h:status", {tt_humminbird_wpt_status, true}}, - - {"/gpx/rte", {tt_rte, false}}, - {"/gpx/rte/name", {tt_rte_name, false}}, - {"/gpx/rte/desc", {tt_rte_desc, false}}, - {"/gpx/rte/url", {tt_rte_url, false}}, /* GPX 1.0 */ - {"/gpx/rte/urlname", {tt_rte_urlname, false}}, /* GPX 1.0 */ - {"/gpx/rte/link", {tt_rte_link, false}}, /* GPX 1.1 */ - {"/gpx/rte/link/text", {tt_rte_link_text, false}}, /* GPX 1.1 */ - {"/gpx/rte/link/type", {tt_rte_link_type, false}}, /* GPX 1.1 */ - {"/gpx/rte/number", {tt_rte_number, false}}, - {GARMIN_RTE_EXT "/gpxx:DisplayColor", {tt_garmin_rte_display_color, true}}, - - {"/gpx/rte/rtept", {tt_rte_rtept, false}}, - - {"/gpx/trk", {tt_trk, false}}, - {"/gpx/trk/name", {tt_trk_name, false}}, - {"/gpx/trk/desc", {tt_trk_desc, false}}, - {"/gpx/trk/trkseg", {tt_trk_trkseg, false}}, - {"/gpx/trk/url", {tt_trk_url, false}}, /* GPX 1.0 */ - {"/gpx/trk/urlname", {tt_trk_urlname, false}}, /* GPX 1.0 */ - {"/gpx/trk/link", {tt_trk_link, false}}, /* GPX 1.1 */ - {"/gpx/trk/link/text", {tt_trk_link_text, false}}, /* GPX 1.1 */ - {"/gpx/trk/link/type", {tt_trk_link_type, false}}, /* GPX 1.1 */ - {"/gpx/trk/number", {tt_trk_number, false}}, - {GARMIN_TRK_EXT "/gpxx:DisplayColor", {tt_garmin_trk_display_color, true}}, - - {"/gpx/trk/trkseg/trkpt", {tt_trk_trkseg_trkpt, false}}, - {"/gpx/trk/trkseg/trkpt/course", {tt_trk_trkseg_trkpt_course, false}}, - {"/gpx/trk/trkseg/trkpt/speed", {tt_trk_trkseg_trkpt_speed, false}}, - - {"/gpx/trk/trkseg/trkpt/extensions/h:depth", {tt_humminbird_trk_trkseg_trkpt_depth, true}}, // in centimeters. + {GARMIN_TRKPT_EXT "/gpxtpx:hr", {tag_type::trk_trkseg_trkpt_heartrate, true}}, + {GARMIN_TRKPT_EXT "/gpxtpx:cad", {tag_type::trk_trkseg_trkpt_cadence, true}}, + + {"/gpx/wpt/extensions/h:depth", {tag_type::humminbird_wpt_depth, true}}, // in centimeters. + {"/gpx/wpt/extensions/h:status", {tag_type::humminbird_wpt_status, true}}, + + {"/gpx/rte", {tag_type::rte, false}}, + {"/gpx/rte/name", {tag_type::rte_name, false}}, + {"/gpx/rte/desc", {tag_type::rte_desc, false}}, + {"/gpx/rte/url", {tag_type::rte_url, false}}, /* GPX 1.0 */ + {"/gpx/rte/urlname", {tag_type::rte_urlname, false}}, /* GPX 1.0 */ + {"/gpx/rte/link", {tag_type::rte_link, false}}, /* GPX 1.1 */ + {"/gpx/rte/link/text", {tag_type::rte_link_text, false}}, /* GPX 1.1 */ + {"/gpx/rte/link/type", {tag_type::rte_link_type, false}}, /* GPX 1.1 */ + {"/gpx/rte/number", {tag_type::rte_number, false}}, + {GARMIN_RTE_EXT "/gpxx:DisplayColor", {tag_type::garmin_rte_display_color, true}}, + + {"/gpx/rte/rtept", {tag_type::rte_rtept, false}}, + + {"/gpx/trk", {tag_type::trk, false}}, + {"/gpx/trk/name", {tag_type::trk_name, false}}, + {"/gpx/trk/desc", {tag_type::trk_desc, false}}, + {"/gpx/trk/trkseg", {tag_type::trk_trkseg, false}}, + {"/gpx/trk/url", {tag_type::trk_url, false}}, /* GPX 1.0 */ + {"/gpx/trk/urlname", {tag_type::trk_urlname, false}}, /* GPX 1.0 */ + {"/gpx/trk/link", {tag_type::trk_link, false}}, /* GPX 1.1 */ + {"/gpx/trk/link/text", {tag_type::trk_link_text, false}}, /* GPX 1.1 */ + {"/gpx/trk/link/type", {tag_type::trk_link_type, false}}, /* GPX 1.1 */ + {"/gpx/trk/number", {tag_type::trk_number, false}}, + {GARMIN_TRK_EXT "/gpxx:DisplayColor", {tag_type::garmin_trk_display_color, true}}, + + {"/gpx/trk/trkseg/trkpt", {tag_type::trk_trkseg_trkpt, false}}, + {"/gpx/trk/trkseg/trkpt/course", {tag_type::trk_trkseg_trkpt_course, false}}, + {"/gpx/trk/trkseg/trkpt/speed", {tag_type::trk_trkseg_trkpt_speed, false}}, + + {"/gpx/trk/trkseg/trkpt/extensions/h:depth", {tag_type::humminbird_trk_trkseg_trkpt_depth, true}}, // in centimeters. /* Common to tracks, routes, and waypts */ - GPXWPTTYPETAG("ele", tt_wpttype_ele, false), - GPXWPTTYPETAG("time", tt_wpttype_time, false), - GPXWPTTYPETAG("magvar", tt_wpttype_magvar, false), - GPXWPTTYPETAG("geoidheight", tt_wpttype_geoidheight, false), - GPXWPTTYPETAG("name", tt_wpttype_name, false), - GPXWPTTYPETAG("cmt", tt_wpttype_cmt, false), - GPXWPTTYPETAG("desc", tt_wpttype_desc, false), - GPXWPTTYPETAG("src", tt_wpttype_src, false), - GPXWPTTYPETAG("url", tt_wpttype_url, false), /* GPX 1.0 */ - GPXWPTTYPETAG("urlname", tt_wpttype_urlname, false), /* GPX 1.0 */ - GPXWPTTYPETAG("link", tt_wpttype_link, false), /* GPX 1.1 */ - GPXWPTTYPETAG("link/text", tt_wpttype_link_text, false), /* GPX 1.1 */ - GPXWPTTYPETAG("link/type", tt_wpttype_link_type, false), /* GPX 1.1 */ - GPXWPTTYPETAG("sym", tt_wpttype_sym, false), - GPXWPTTYPETAG("type", tt_wpttype_type, false), - GPXWPTTYPETAG("fix", tt_wpttype_fix, false), - GPXWPTTYPETAG("sat", tt_wpttype_sat, false), - GPXWPTTYPETAG("hdop", tt_wpttype_hdop, false), - GPXWPTTYPETAG("vdop", tt_wpttype_vdop, false), - GPXWPTTYPETAG("pdop", tt_wpttype_pdop, false), - GPXWPTTYPETAG("ageofdgpsdata", tt_wpttype_ageofdgpsdata, false), - GPXWPTTYPETAG("dgpsid", tt_wpttype_dgpsid, false), + GPXWPTTYPETAG("ele", tag_type::wpttype_ele, false), + GPXWPTTYPETAG("time", tag_type::wpttype_time, false), + GPXWPTTYPETAG("magvar", tag_type::wpttype_magvar, false), + GPXWPTTYPETAG("geoidheight", tag_type::wpttype_geoidheight, false), + GPXWPTTYPETAG("name", tag_type::wpttype_name, false), + GPXWPTTYPETAG("cmt", tag_type::wpttype_cmt, false), + GPXWPTTYPETAG("desc", tag_type::wpttype_desc, false), + GPXWPTTYPETAG("src", tag_type::wpttype_src, false), + GPXWPTTYPETAG("url", tag_type::wpttype_url, false), /* GPX 1.0 */ + GPXWPTTYPETAG("urlname", tag_type::wpttype_urlname, false), /* GPX 1.0 */ + GPXWPTTYPETAG("link", tag_type::wpttype_link, false), /* GPX 1.1 */ + GPXWPTTYPETAG("link/text", tag_type::wpttype_link_text, false), /* GPX 1.1 */ + GPXWPTTYPETAG("link/type", tag_type::wpttype_link_type, false), /* GPX 1.1 */ + GPXWPTTYPETAG("sym", tag_type::wpttype_sym, false), + GPXWPTTYPETAG("type", tag_type::wpttype_type, false), + GPXWPTTYPETAG("fix", tag_type::wpttype_fix, false), + GPXWPTTYPETAG("sat", tag_type::wpttype_sat, false), + GPXWPTTYPETAG("hdop", tag_type::wpttype_hdop, false), + GPXWPTTYPETAG("vdop", tag_type::wpttype_vdop, false), + GPXWPTTYPETAG("pdop", tag_type::wpttype_pdop, false), + GPXWPTTYPETAG("ageofdgpsdata", tag_type::wpttype_ageofdgpsdata, false), + GPXWPTTYPETAG("dgpsid", tag_type::wpttype_dgpsid, false), }; QVector gpx_args = {