mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: convert taxonomy.c to C++
Since the taxonomy is now a real C++ struct with constructor and destructor, dive_site has to be converted to C++ as well. A bit hairy for now, but will ultimately be distinctly simpler. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
3c1401785b
commit
3f8b4604be
39 changed files with 259 additions and 336 deletions
|
|
@ -179,7 +179,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
|
|||
subsurfacesysinfo.h
|
||||
tag.cpp
|
||||
tag.h
|
||||
taxonomy.c
|
||||
taxonomy.cpp
|
||||
taxonomy.h
|
||||
time.cpp
|
||||
trip.c
|
||||
|
|
|
|||
|
|
@ -3335,10 +3335,10 @@ extern "C" struct dive_site *get_dive_site_for_dive(const struct dive *dive)
|
|||
return dive->dive_site;
|
||||
}
|
||||
|
||||
extern "C" const char *get_dive_country(const struct dive *dive)
|
||||
std::string get_dive_country(const struct dive *dive)
|
||||
{
|
||||
struct dive_site *ds = dive->dive_site;
|
||||
return ds ? taxonomy_get_country(&ds->taxonomy) : NULL;
|
||||
return ds ? taxonomy_get_country(ds->taxonomy) : std::string();
|
||||
}
|
||||
|
||||
extern "C" const char *get_dive_location(const struct dive *dive)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
|
@ -114,7 +115,11 @@ extern depth_t gas_mnd(struct gasmix mix, depth_t end, const struct dive *dive,
|
|||
extern struct dive *get_dive(int nr);
|
||||
extern struct dive *get_dive_from_table(int nr, const struct dive_table *dt);
|
||||
extern struct dive_site *get_dive_site_for_dive(const struct dive *dive);
|
||||
extern const char *get_dive_country(const struct dive *dive);
|
||||
#ifdef __cplusplus
|
||||
} // TODO: remove
|
||||
extern std::string get_dive_country(const struct dive *dive);
|
||||
extern "C" {
|
||||
#endif
|
||||
extern const char *get_dive_location(const struct dive *dive);
|
||||
extern unsigned int number_of_computers(const struct dive *dive);
|
||||
extern struct divecomputer *get_dive_dc(struct dive *dive, int nr);
|
||||
|
|
@ -227,7 +232,6 @@ extern void update_setpoint_events(const struct dive *dive, struct divecomputer
|
|||
* QVariants and through QML.
|
||||
*/
|
||||
#include <QObject>
|
||||
#include <string>
|
||||
Q_DECLARE_METATYPE(struct dive *);
|
||||
|
||||
extern std::string existing_filename;
|
||||
|
|
|
|||
|
|
@ -1144,7 +1144,7 @@ void process_imported_dives(struct divelog *import_log, int flags,
|
|||
|
||||
if (j == import_log->dives->nr) {
|
||||
/* Dive site not even used - free it and go to next. */
|
||||
free_dive_site(new_ds);
|
||||
delete new_ds;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1159,7 +1159,7 @@ void process_imported_dives(struct divelog *import_log, int flags,
|
|||
if (import_log->dives->dives[j]->dive_site == new_ds)
|
||||
import_log->dives->dives[j]->dive_site = old_ds;
|
||||
}
|
||||
free_dive_site(new_ds);
|
||||
delete new_ds;
|
||||
}
|
||||
import_log->sites->nr = 0; /* All dive sites were consumed */
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
#include "pref.h"
|
||||
#include "gettextfromc.h"
|
||||
|
||||
QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab)
|
||||
QString constructLocationTags(taxonomy_data &taxonomy, bool for_maintab)
|
||||
{
|
||||
QString locationTag;
|
||||
|
||||
if (!taxonomy->nr)
|
||||
if (taxonomy.empty())
|
||||
return locationTag;
|
||||
|
||||
/* Check if the user set any of the 3 geocoding categories */
|
||||
|
|
@ -33,11 +33,10 @@ QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab)
|
|||
for (int i = 0; i < 3; i++) {
|
||||
if (prefs.geocoding.category[i] == TC_NONE)
|
||||
continue;
|
||||
for (int j = 0; j < taxonomy->nr; j++) {
|
||||
if (taxonomy->category[j].category == prefs.geocoding.category[i]) {
|
||||
QString tag = taxonomy->category[j].value;
|
||||
if (!tag.isEmpty()) {
|
||||
locationTag += connector + tag;
|
||||
for (auto const &t: taxonomy) {
|
||||
if (t.category == prefs.geocoding.category[i]) {
|
||||
if (!t.value.empty()) {
|
||||
locationTag += connector + QString::fromStdString(t.value);
|
||||
connector = " / ";
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
extern "C" int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
const struct dive_site *d;
|
||||
|
|
@ -26,7 +26,7 @@ extern "C" int get_divesite_idx(const struct dive_site *ds, struct dive_site_tab
|
|||
}
|
||||
|
||||
// TODO: keep table sorted by UUID and do a binary search?
|
||||
extern "C" struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table)
|
||||
struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -37,7 +37,7 @@ extern "C" struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_si
|
|||
}
|
||||
|
||||
/* there could be multiple sites of the same name - return the first one */
|
||||
extern "C" struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table *ds_table)
|
||||
struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -49,7 +49,7 @@ extern "C" struct dive_site *get_dive_site_by_name(const char *name, struct dive
|
|||
}
|
||||
|
||||
/* there could be multiple sites at the same GPS fix - return the first one */
|
||||
extern "C" struct dive_site *get_dive_site_by_gps(const location_t *loc, struct dive_site_table *ds_table)
|
||||
struct dive_site *get_dive_site_by_gps(const location_t *loc, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -63,7 +63,7 @@ extern "C" struct dive_site *get_dive_site_by_gps(const location_t *loc, struct
|
|||
/* to avoid a bug where we have two dive sites with different name and the same GPS coordinates
|
||||
* and first get the gps coordinates (reading a V2 file) and happen to get back "the other" name,
|
||||
* this function allows us to verify if a very specific name/GPS combination already exists */
|
||||
extern "C" struct dive_site *get_dive_site_by_gps_and_name(const char *name, const location_t *loc, struct dive_site_table *ds_table)
|
||||
struct dive_site *get_dive_site_by_gps_and_name(const char *name, const location_t *loc, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -75,7 +75,7 @@ extern "C" struct dive_site *get_dive_site_by_gps_and_name(const char *name, con
|
|||
}
|
||||
|
||||
// Calculate the distance in meters between two coordinates.
|
||||
extern "C" unsigned int get_distance(const location_t *loc1, const location_t *loc2)
|
||||
unsigned int get_distance(const location_t *loc1, const location_t *loc2)
|
||||
{
|
||||
double lat1_r = udeg_to_radians(loc1->lat.udeg);
|
||||
double lat2_r = udeg_to_radians(loc2->lat.udeg);
|
||||
|
|
@ -93,7 +93,7 @@ extern "C" unsigned int get_distance(const location_t *loc1, const location_t *l
|
|||
}
|
||||
|
||||
/* find the closest one, no more than distance meters away - if more than one at same distance, pick the first */
|
||||
extern "C" struct dive_site *get_dive_site_by_gps_proximity(const location_t *loc, int distance, struct dive_site_table *ds_table)
|
||||
struct dive_site *get_dive_site_by_gps_proximity(const location_t *loc, int distance, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds, *res = NULL;
|
||||
|
|
@ -108,7 +108,7 @@ extern "C" struct dive_site *get_dive_site_by_gps_proximity(const location_t *lo
|
|||
return res;
|
||||
}
|
||||
|
||||
extern "C" int register_dive_site(struct dive_site *ds)
|
||||
int register_dive_site(struct dive_site *ds)
|
||||
{
|
||||
return add_dive_site_to_table(ds, divelog.sites);
|
||||
}
|
||||
|
|
@ -123,6 +123,11 @@ static int site_less_than(const struct dive_site *a, const struct dive_site *b)
|
|||
return compare_sites(a, b) < 0;
|
||||
}
|
||||
|
||||
static void free_dive_site(struct dive_site *ds)
|
||||
{
|
||||
delete ds;
|
||||
}
|
||||
|
||||
static MAKE_GROW_TABLE(dive_site_table, struct dive_site *, dive_sites)
|
||||
static MAKE_GET_INSERTION_INDEX(dive_site_table, struct dive_site *, dive_sites, site_less_than)
|
||||
static MAKE_ADD_TO(dive_site_table, struct dive_site *, dive_sites)
|
||||
|
|
@ -133,7 +138,7 @@ static MAKE_REMOVE(dive_site_table, struct dive_site *, dive_site)
|
|||
MAKE_CLEAR_TABLE(dive_site_table, dive_sites, dive_site)
|
||||
MAKE_MOVE_TABLE(dive_site_table, dive_sites)
|
||||
|
||||
extern "C" int add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
int add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
/* If the site doesn't yet have an UUID, create a new one.
|
||||
* Make this deterministic for testing. */
|
||||
|
|
@ -158,35 +163,35 @@ extern "C" int add_dive_site_to_table(struct dive_site *ds, struct dive_site_tab
|
|||
return idx;
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *alloc_dive_site()
|
||||
dive_site::dive_site()
|
||||
{
|
||||
return (struct dive_site *)calloc(1, sizeof(struct dive_site));
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *alloc_dive_site_with_name(const char *name)
|
||||
dive_site::dive_site(const char *name) : name(copy_string(name))
|
||||
{
|
||||
struct dive_site *ds = alloc_dive_site();
|
||||
ds->name = copy_string(name);
|
||||
return ds;
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *alloc_dive_site_with_gps(const char *name, const location_t *loc)
|
||||
dive_site::dive_site(const char *name, const location_t *loc) : name(copy_string(name)), location(*loc)
|
||||
{
|
||||
struct dive_site *ds = alloc_dive_site_with_name(name);
|
||||
ds->location = *loc;
|
||||
}
|
||||
|
||||
return ds;
|
||||
dive_site::~dive_site()
|
||||
{
|
||||
free(name);
|
||||
free(notes);
|
||||
free(description);
|
||||
free(dives.dives);
|
||||
}
|
||||
|
||||
/* when parsing, dive sites are identified by uuid */
|
||||
extern "C" struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table)
|
||||
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table)
|
||||
{
|
||||
struct dive_site *ds;
|
||||
|
||||
if (uuid && (ds = get_dive_site_by_uuid(uuid, ds_table)) != NULL)
|
||||
return ds;
|
||||
|
||||
ds = alloc_dive_site();
|
||||
ds = new dive_site;
|
||||
ds->uuid = uuid;
|
||||
|
||||
add_dive_site_to_table(ds, ds_table);
|
||||
|
|
@ -194,12 +199,12 @@ extern "C" struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_s
|
|||
return ds;
|
||||
}
|
||||
|
||||
extern "C" int nr_of_dives_at_dive_site(struct dive_site *ds)
|
||||
int nr_of_dives_at_dive_site(struct dive_site *ds)
|
||||
{
|
||||
return ds->dives.nr;
|
||||
}
|
||||
|
||||
extern "C" bool is_dive_site_selected(struct dive_site *ds)
|
||||
bool is_dive_site_selected(struct dive_site *ds)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -210,49 +215,37 @@ extern "C" bool is_dive_site_selected(struct dive_site *ds)
|
|||
return false;
|
||||
}
|
||||
|
||||
extern "C" void free_dive_site(struct dive_site *ds)
|
||||
{
|
||||
if (ds) {
|
||||
free(ds->name);
|
||||
free(ds->notes);
|
||||
free(ds->description);
|
||||
free(ds->dives.dives);
|
||||
free_taxonomy(&ds->taxonomy);
|
||||
free(ds);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int unregister_dive_site(struct dive_site *ds)
|
||||
int unregister_dive_site(struct dive_site *ds)
|
||||
{
|
||||
return remove_dive_site(ds, divelog.sites);
|
||||
}
|
||||
|
||||
extern "C" void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table)
|
||||
{
|
||||
if (!ds)
|
||||
return;
|
||||
remove_dive_site(ds, ds_table);
|
||||
free_dive_site(ds);
|
||||
delete ds;
|
||||
}
|
||||
|
||||
/* allocate a new site and add it to the table */
|
||||
extern "C" struct dive_site *create_dive_site(const char *name, struct dive_site_table *ds_table)
|
||||
struct dive_site *create_dive_site(const char *name, struct dive_site_table *ds_table)
|
||||
{
|
||||
struct dive_site *ds = alloc_dive_site_with_name(name);
|
||||
struct dive_site *ds = new dive_site(name);
|
||||
add_dive_site_to_table(ds, ds_table);
|
||||
return ds;
|
||||
}
|
||||
|
||||
/* same as before, but with GPS data */
|
||||
extern "C" struct dive_site *create_dive_site_with_gps(const char *name, const location_t *loc, struct dive_site_table *ds_table)
|
||||
struct dive_site *create_dive_site_with_gps(const char *name, const location_t *loc, struct dive_site_table *ds_table)
|
||||
{
|
||||
struct dive_site *ds = alloc_dive_site_with_gps(name, loc);
|
||||
struct dive_site *ds = new dive_site(name, loc);
|
||||
add_dive_site_to_table(ds, ds_table);
|
||||
return ds;
|
||||
}
|
||||
|
||||
/* if all fields are empty, the dive site is pointless */
|
||||
extern "C" bool dive_site_is_empty(struct dive_site *ds)
|
||||
bool dive_site_is_empty(struct dive_site *ds)
|
||||
{
|
||||
return !ds ||
|
||||
(empty_string(ds->name) &&
|
||||
|
|
@ -261,7 +254,7 @@ extern "C" bool dive_site_is_empty(struct dive_site *ds)
|
|||
!has_location(&ds->location));
|
||||
}
|
||||
|
||||
extern "C" void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
|
||||
void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
|
||||
{
|
||||
free(copy->name);
|
||||
free(copy->notes);
|
||||
|
|
@ -271,7 +264,7 @@ extern "C" void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
|
|||
copy->name = copy_string(orig->name);
|
||||
copy->notes = copy_string(orig->notes);
|
||||
copy->description = copy_string(orig->description);
|
||||
copy_taxonomy(&orig->taxonomy, ©->taxonomy);
|
||||
copy->taxonomy = orig->taxonomy;
|
||||
}
|
||||
|
||||
static void merge_string(char **a, char **b)
|
||||
|
|
@ -307,7 +300,7 @@ static bool same_dive_site(const struct dive_site *a, const struct dive_site *b)
|
|||
&& same_string(a->notes, b->notes);
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *get_same_dive_site(const struct dive_site *site)
|
||||
struct dive_site *get_same_dive_site(const struct dive_site *site)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -317,20 +310,18 @@ extern "C" struct dive_site *get_same_dive_site(const struct dive_site *site)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" void merge_dive_site(struct dive_site *a, struct dive_site *b)
|
||||
void merge_dive_site(struct dive_site *a, struct dive_site *b)
|
||||
{
|
||||
if (!has_location(&a->location)) a->location = b->location;
|
||||
merge_string(&a->name, &b->name);
|
||||
merge_string(&a->notes, &b->notes);
|
||||
merge_string(&a->description, &b->description);
|
||||
|
||||
if (!a->taxonomy.category) {
|
||||
a->taxonomy = b->taxonomy;
|
||||
memset(&b->taxonomy, 0, sizeof(b->taxonomy));
|
||||
}
|
||||
if (a->taxonomy.empty())
|
||||
a->taxonomy = std::move(b->taxonomy);
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table)
|
||||
struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table)
|
||||
{
|
||||
int i;
|
||||
struct dive_site *ds;
|
||||
|
|
@ -343,7 +334,7 @@ extern "C" struct dive_site *find_or_create_dive_site_with_name(const char *name
|
|||
return create_dive_site(name, ds_table);
|
||||
}
|
||||
|
||||
extern "C" void purge_empty_dive_sites(struct dive_site_table *ds_table)
|
||||
void purge_empty_dive_sites(struct dive_site_table *ds_table)
|
||||
{
|
||||
int i, j;
|
||||
struct dive *d;
|
||||
|
|
@ -360,7 +351,7 @@ extern "C" void purge_empty_dive_sites(struct dive_site_table *ds_table)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void add_dive_to_dive_site(struct dive *d, struct dive_site *ds)
|
||||
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds)
|
||||
{
|
||||
int idx;
|
||||
if (!d) {
|
||||
|
|
@ -382,7 +373,7 @@ extern "C" void add_dive_to_dive_site(struct dive *d, struct dive_site *ds)
|
|||
d->dive_site = ds;
|
||||
}
|
||||
|
||||
extern "C" struct dive_site *unregister_dive_from_dive_site(struct dive *d)
|
||||
struct dive_site *unregister_dive_from_dive_site(struct dive *d)
|
||||
{
|
||||
struct dive_site *ds = d->dive_site;
|
||||
if (!ds)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@
|
|||
#ifdef __cplusplus
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
struct dive_site
|
||||
{
|
||||
uint32_t uuid;
|
||||
char *name;
|
||||
struct dive_table dives;
|
||||
location_t location;
|
||||
char *description;
|
||||
char *notes;
|
||||
struct taxonomy_data taxonomy;
|
||||
uint32_t uuid = 0;
|
||||
char *name = nullptr;
|
||||
struct dive_table dives = { 0, 0, nullptr };
|
||||
location_t location = { { 9 }, { 0 } };
|
||||
char *description = nullptr;
|
||||
char *notes = nullptr;
|
||||
taxonomy_data taxonomy;
|
||||
dive_site();
|
||||
dive_site(const char *name);
|
||||
dive_site(const char *name, const location_t *loc);
|
||||
~dive_site();
|
||||
};
|
||||
|
||||
typedef struct dive_site_table {
|
||||
|
|
@ -50,11 +50,8 @@ void sort_dive_site_table(struct dive_site_table *ds_table);
|
|||
int add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table);
|
||||
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table);
|
||||
struct dive_site *alloc_dive_site();
|
||||
struct dive_site *alloc_dive_site_with_name(const char *name);
|
||||
struct dive_site *alloc_dive_site_with_gps(const char *name, const location_t *loc);
|
||||
int nr_of_dives_at_dive_site(struct dive_site *ds);
|
||||
bool is_dive_site_selected(struct dive_site *ds);
|
||||
void free_dive_site(struct dive_site *ds);
|
||||
int unregister_dive_site(struct dive_site *ds);
|
||||
int register_dive_site(struct dive_site *ds);
|
||||
void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table);
|
||||
|
|
@ -77,9 +74,7 @@ void move_dive_site_table(struct dive_site_table *src, struct dive_site_table *d
|
|||
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds);
|
||||
struct dive_site *unregister_dive_from_dive_site(struct dive *d);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab);
|
||||
QString constructLocationTags(taxonomy_data &taxonomy, bool for_maintab);
|
||||
|
||||
/* Make pointer-to-dive_site a "Qt metatype" so that we can pass it through QVariants */
|
||||
Q_DECLARE_METATYPE(dive_site *);
|
||||
|
|
|
|||
|
|
@ -84,14 +84,14 @@ taxonomy_data reverseGeoLookup(degrees_t latitude, degrees_t longitude)
|
|||
|
||||
QString url;
|
||||
QJsonObject obj;
|
||||
taxonomy_data taxonomy = { 0, 0 };
|
||||
taxonomy_data taxonomy;
|
||||
|
||||
// check the oceans API to figure out the body of water
|
||||
url = geonamesOceanURL.arg(getUiLanguage().section(QRegularExpression("[-_ ]"), 0, 0)).arg(latitude.udeg / 1000000.0).arg(longitude.udeg / 1000000.0);
|
||||
obj = doAsyncRESTGetRequest(url, 5000); // 5 secs. timeout
|
||||
QVariantMap oceanName = obj.value("ocean").toVariant().toMap();
|
||||
if (oceanName["name"].isValid())
|
||||
taxonomy_set_category(&taxonomy, TC_OCEAN, qPrintable(oceanName["name"].toString()), taxonomy_origin::GEOCODED);
|
||||
taxonomy_set_category(taxonomy, TC_OCEAN, oceanName["name"].toString().toStdString(), taxonomy_origin::GEOCODED);
|
||||
|
||||
// check the findNearbyPlaces API from geonames - that should give us country, state, city
|
||||
url = geonamesNearbyPlaceNameURL.arg(getUiLanguage().section(QRegularExpression("[-_ ]"), 0, 0)).arg(latitude.udeg / 1000000.0).arg(longitude.udeg / 1000000.0);
|
||||
|
|
@ -110,16 +110,16 @@ taxonomy_data reverseGeoLookup(degrees_t latitude, degrees_t longitude)
|
|||
for (int idx = TC_COUNTRY; idx < TC_NR_CATEGORIES; idx++) {
|
||||
if (firstData[taxonomy_api_names[idx]].isValid()) {
|
||||
QString value = firstData[taxonomy_api_names[idx]].toString();
|
||||
taxonomy_set_category(&taxonomy, (taxonomy_category)idx, qPrintable(value), taxonomy_origin::GEOCODED);
|
||||
taxonomy_set_category(taxonomy, (taxonomy_category)idx, value.toStdString(), taxonomy_origin::GEOCODED);
|
||||
}
|
||||
}
|
||||
const char *l3 = taxonomy_get_value(&taxonomy, TC_ADMIN_L3);
|
||||
const char *lt = taxonomy_get_value(&taxonomy, TC_LOCALNAME);
|
||||
if (empty_string(l3) && !empty_string(lt)) {
|
||||
std::string l3 = taxonomy_get_value(taxonomy, TC_ADMIN_L3);
|
||||
std::string lt = taxonomy_get_value(taxonomy, TC_LOCALNAME);
|
||||
if (!l3.empty() && !lt.empty()) {
|
||||
// basically this means we did get a local name (what we call town), but just like most places
|
||||
// we didn't get an adminName_3 - which in some regions is the actual city that town belongs to,
|
||||
// then we copy the town into the city
|
||||
taxonomy_set_category(&taxonomy, TC_ADMIN_L3, lt, taxonomy_origin::GEOCOPIED);
|
||||
taxonomy_set_category(taxonomy, TC_ADMIN_L3, lt, taxonomy_origin::GEOCOPIED);
|
||||
}
|
||||
} else {
|
||||
report_error("geonames.org did not provide reverse lookup information");
|
||||
|
|
|
|||
|
|
@ -141,9 +141,9 @@ static std::vector<QString> getWords(const dive *d)
|
|||
// take the tokens from a cache.
|
||||
if (d->dive_site) {
|
||||
tokenize(d->dive_site->name, res);
|
||||
const char *country = taxonomy_get_country(&d->dive_site->taxonomy);
|
||||
if (country)
|
||||
tokenize(country, res);
|
||||
std::string country = taxonomy_get_country(d->dive_site->taxonomy);
|
||||
if (!country.empty())
|
||||
tokenize(country.c_str(), res);
|
||||
}
|
||||
// TODO: We should index trips separately!
|
||||
if (d->divetrip)
|
||||
|
|
|
|||
|
|
@ -332,8 +332,8 @@ static void parse_site_geo(char *line, struct git_parser_state *state)
|
|||
int origin;
|
||||
int category;
|
||||
sscanf(line, "cat %d origin %d \"", &category, &origin);
|
||||
taxonomy_set_category(&state->active_site->taxonomy, (taxonomy_category)category,
|
||||
get_first_converted_string(state).c_str(), (taxonomy_origin)origin);
|
||||
taxonomy_set_category(state->active_site->taxonomy, (taxonomy_category)category,
|
||||
get_first_converted_string(state), (taxonomy_origin)origin);
|
||||
}
|
||||
|
||||
static std::string pop_cstring(struct git_parser_state *state, const char *err)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ struct event;
|
|||
|
||||
extern "C" void free_dive(struct dive *);
|
||||
extern "C" void free_trip(struct dive_trip *);
|
||||
extern "C" void free_dive_site(struct dive_site *);
|
||||
|
||||
// Classes used to automatically call the appropriate free_*() function for owning pointers that go out of scope.
|
||||
struct DiveDeleter {
|
||||
|
|
@ -25,9 +24,6 @@ struct DiveDeleter {
|
|||
struct TripDeleter {
|
||||
void operator()(dive_trip *t) { free_trip(t); }
|
||||
};
|
||||
struct DiveSiteDeleter {
|
||||
void operator()(dive_site *ds) { free_dive_site(ds); }
|
||||
};
|
||||
struct EventDeleter {
|
||||
void operator()(event *ev) { free(ev); }
|
||||
};
|
||||
|
|
@ -35,7 +31,6 @@ struct EventDeleter {
|
|||
// Owning pointers to dive, dive_trip, dive_site and event objects.
|
||||
using OwningDivePtr = std::unique_ptr<dive, DiveDeleter>;
|
||||
using OwningTripPtr = std::unique_ptr<dive_trip, TripDeleter>;
|
||||
using OwningDiveSitePtr = std::unique_ptr<dive_site, DiveSiteDeleter>;
|
||||
using OwningEventPtr = std::unique_ptr<event, EventDeleter>;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1410,7 +1410,7 @@ static void try_to_fill_trip(dive_trip_t *dive_trip, const char *name, char *buf
|
|||
/* We're processing a divesite entry - try to fill the components */
|
||||
static void try_to_fill_dive_site(struct parser_state *state, const char *name, char *buf)
|
||||
{
|
||||
struct dive_site *ds = state->cur_dive_site;
|
||||
auto &ds = state->cur_dive_site;
|
||||
std::string taxonomy_value;
|
||||
|
||||
start_match("divesite", name, buf);
|
||||
|
|
@ -1423,7 +1423,7 @@ static void try_to_fill_dive_site(struct parser_state *state, const char *name,
|
|||
return;
|
||||
if (MATCH("notes", utf8_string, &ds->notes))
|
||||
return;
|
||||
if (MATCH("gps", gps_location, ds))
|
||||
if (MATCH("gps", gps_location, ds.get()))
|
||||
return;
|
||||
if (MATCH("cat.geo", get_index, &state->taxonomy_category))
|
||||
return;
|
||||
|
|
@ -1436,8 +1436,8 @@ static void try_to_fill_dive_site(struct parser_state *state, const char *name,
|
|||
if (state->taxonomy_category < 0 || state->taxonomy_origin < 0) {
|
||||
report_error("Warning: taxonomy value without origin or category");
|
||||
} else {
|
||||
taxonomy_set_category(&ds->taxonomy, (taxonomy_category)state->taxonomy_category,
|
||||
taxonomy_value.c_str(), (taxonomy_origin)state->taxonomy_origin);
|
||||
taxonomy_set_category(ds->taxonomy, (taxonomy_category)state->taxonomy_category,
|
||||
taxonomy_value, (taxonomy_origin)state->taxonomy_origin);
|
||||
}
|
||||
state->taxonomy_category = state->taxonomy_origin = -1;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@
|
|||
#include "device.h"
|
||||
#include "gettext.h"
|
||||
|
||||
parser_state::parser_state()
|
||||
{
|
||||
}
|
||||
|
||||
parser_state::~parser_state()
|
||||
{
|
||||
free_dive(cur_dive);
|
||||
free_trip(cur_trip);
|
||||
free_dive_site(cur_dive_site);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -188,7 +191,7 @@ void dive_site_start(struct parser_state *state)
|
|||
return;
|
||||
state->taxonomy_category = -1;
|
||||
state->taxonomy_origin = -1;
|
||||
state->cur_dive_site = (dive_site *)calloc(1, sizeof(struct dive_site));
|
||||
state->cur_dive_site = std::make_unique<dive_site>();
|
||||
}
|
||||
|
||||
void dive_site_end(struct parser_state *state)
|
||||
|
|
@ -197,13 +200,12 @@ void dive_site_end(struct parser_state *state)
|
|||
return;
|
||||
|
||||
struct dive_site *ds = alloc_or_get_dive_site(state->cur_dive_site->uuid, state->log->sites);
|
||||
merge_dive_site(ds, state->cur_dive_site);
|
||||
merge_dive_site(ds, state->cur_dive_site.get());
|
||||
|
||||
if (verbose > 3)
|
||||
printf("completed dive site uuid %x8 name {%s}\n", ds->uuid, ds->name);
|
||||
|
||||
free_dive_site(state->cur_dive_site);
|
||||
state->cur_dive_site = NULL;
|
||||
state->cur_dive_site.reset();
|
||||
}
|
||||
|
||||
void filter_preset_start(struct parser_state *state)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ struct parser_state {
|
|||
|
||||
struct divecomputer *cur_dc = nullptr; /* non-owning */
|
||||
struct dive *cur_dive = nullptr; /* owning */
|
||||
struct dive_site *cur_dive_site = nullptr; /* owning */
|
||||
std::unique_ptr<dive_site> cur_dive_site; /* owning */
|
||||
location_t cur_location { 0 };
|
||||
struct dive_trip *cur_trip = nullptr; /* owning */
|
||||
struct sample *cur_sample = nullptr; /* non-owning */
|
||||
|
|
@ -96,6 +96,7 @@ struct parser_state {
|
|||
sqlite3 *sql_handle = nullptr; /* for SQL based parsers */
|
||||
bool event_active = false;
|
||||
event_allocation_t event_allocation;
|
||||
parser_state();
|
||||
~parser_state();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
#ifndef PREF_H
|
||||
#define PREF_H
|
||||
|
||||
#include "units.h"
|
||||
#include "taxonomy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include "units.h"
|
||||
#include "taxonomy.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool po2;
|
||||
|
|
|
|||
|
|
@ -933,11 +933,10 @@ static void save_divesites(git_repository *repo, struct dir *tree)
|
|||
show_utf8(&b, "description ", ds->description, "\n");
|
||||
show_utf8(&b, "notes ", ds->notes, "\n");
|
||||
put_location(&b, &ds->location, "gps ", "\n");
|
||||
for (int j = 0; j < ds->taxonomy.nr; j++) {
|
||||
struct taxonomy *t = &ds->taxonomy.category[j];
|
||||
if (t->category != TC_NONE && t->value) {
|
||||
put_format(&b, "geo cat %d origin %d ", t->category, t->origin);
|
||||
show_utf8(&b, "", t->value, "\n" );
|
||||
for (const auto &t: ds->taxonomy) {
|
||||
if (t.category != TC_NONE && !t.value.empty()) {
|
||||
put_format(&b, "geo cat %d origin %d ", t.category, t.origin);
|
||||
show_utf8(&b, "", t.value.c_str(), "\n" );
|
||||
}
|
||||
}
|
||||
blob_insert(repo, subdir, &b, mb_cstring(&site_file_name));
|
||||
|
|
|
|||
|
|
@ -716,15 +716,12 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
|
|||
show_utf8_blanked(b, ds->description, " description='", "'", 1, anonymize);
|
||||
put_format(b, ">\n");
|
||||
show_utf8_blanked(b, ds->notes, " <notes>", " </notes>\n", 0, anonymize);
|
||||
if (ds->taxonomy.nr) {
|
||||
for (int j = 0; j < ds->taxonomy.nr; j++) {
|
||||
struct taxonomy *t = &ds->taxonomy.category[j];
|
||||
if (t->category != TC_NONE && t->value) {
|
||||
put_format(b, " <geo cat='%d'", t->category);
|
||||
put_format(b, " origin='%d'", t->origin);
|
||||
show_utf8_blanked(b, t->value, " value='", "'", 1, anonymize);
|
||||
put_format(b, "/>\n");
|
||||
}
|
||||
for (auto const &t: ds->taxonomy) {
|
||||
if (t.category != TC_NONE && !t.value.empty()) {
|
||||
put_format(b, " <geo cat='%d'", t.category);
|
||||
put_format(b, " origin='%d'", t.origin);
|
||||
show_utf8_blanked(b, t.value.c_str(), " value='", "'", 1, anonymize);
|
||||
put_format(b, "/>\n");
|
||||
}
|
||||
}
|
||||
put_format(b, "</site>\n");
|
||||
|
|
@ -921,15 +918,12 @@ static void save_dive_sites_buffer(struct membuffer *b, const struct dive_site *
|
|||
show_utf8_blanked(b, ds->description, " description='", "'", 1, anonymize);
|
||||
put_format(b, ">\n");
|
||||
show_utf8_blanked(b, ds->notes, " <notes>", " </notes>\n", 0, anonymize);
|
||||
if (ds->taxonomy.nr) {
|
||||
for (int j = 0; j < ds->taxonomy.nr; j++) {
|
||||
struct taxonomy *t = &ds->taxonomy.category[j];
|
||||
if (t->category != TC_NONE && t->value) {
|
||||
put_format(b, " <geo cat='%d'", t->category);
|
||||
put_format(b, " origin='%d'", t->origin);
|
||||
show_utf8_blanked(b, t->value, " value='", "'", 1, anonymize);
|
||||
put_format(b, "/>\n");
|
||||
}
|
||||
for (const auto &t: ds->taxonomy) {
|
||||
if (t.category != TC_NONE && !t.value.empty()) {
|
||||
put_format(b, " <geo cat='%d'", t.category);
|
||||
put_format(b, " origin='%d'", t.origin);
|
||||
show_utf8_blanked(b, t.value.c_str(), " value='", "'", 1, anonymize);
|
||||
put_format(b, "/>\n");
|
||||
}
|
||||
}
|
||||
put_format(b, "</site>\n");
|
||||
|
|
|
|||
|
|
@ -133,6 +133,12 @@ static void addStringToSortedList(QStringList &l, const std::string &s)
|
|||
l.insert(it, qs);
|
||||
}
|
||||
|
||||
// Safely treat null-strings. Remove once everyhting is converted to std::string
|
||||
static std::string c_to_std(const char *s)
|
||||
{
|
||||
return s ? std::string(s) : std::string();
|
||||
}
|
||||
|
||||
QStringList formatFullCylinderList()
|
||||
{
|
||||
QStringList cylinders;
|
||||
|
|
@ -140,7 +146,7 @@ QStringList formatFullCylinderList()
|
|||
int i = 0;
|
||||
for_each_dive (i, d) {
|
||||
for (int j = 0; j < d->cylinders.nr; j++)
|
||||
addStringToSortedList(cylinders, get_cylinder(d, j)->type.description);
|
||||
addStringToSortedList(cylinders, c_to_std(get_cylinder(d, j)->type.description));
|
||||
}
|
||||
|
||||
for (const auto &ti: tank_info_table)
|
||||
|
|
|
|||
111
core/taxonomy.c
111
core/taxonomy.c
|
|
@ -1,111 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "taxonomy.h"
|
||||
#include "gettext.h"
|
||||
#include "subsurface-string.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char *taxonomy_category_names[TC_NR_CATEGORIES] = {
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "None"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Ocean"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Country"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "State"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "County"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Town"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "City")
|
||||
};
|
||||
|
||||
// these are the names for geoname.org
|
||||
char *taxonomy_api_names[TC_NR_CATEGORIES] = {
|
||||
"none",
|
||||
"name",
|
||||
"countryName",
|
||||
"adminName1",
|
||||
"adminName2",
|
||||
"toponymName",
|
||||
"adminName3"
|
||||
};
|
||||
|
||||
static void alloc_taxonomy_table(struct taxonomy_data *t)
|
||||
{
|
||||
if (!t->category)
|
||||
t->category = calloc(TC_NR_CATEGORIES, sizeof(struct taxonomy));
|
||||
}
|
||||
|
||||
void free_taxonomy(struct taxonomy_data *t)
|
||||
{
|
||||
if (t) {
|
||||
for (int i = 0; i < t->nr; i++)
|
||||
free((void *)t->category[i].value);
|
||||
free(t->category);
|
||||
t->category = NULL;
|
||||
t->nr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void copy_taxonomy(const struct taxonomy_data *orig, struct taxonomy_data *copy)
|
||||
{
|
||||
if (orig->category == NULL) {
|
||||
free_taxonomy(copy);
|
||||
} else {
|
||||
alloc_taxonomy_table(copy);
|
||||
for (int i = 0; i < TC_NR_CATEGORIES; i++) {
|
||||
if (i < copy->nr) {
|
||||
free((void *)copy->category[i].value);
|
||||
copy->category[i].value = NULL;
|
||||
}
|
||||
if (i < orig->nr) {
|
||||
copy->category[i] = orig->category[i];
|
||||
copy->category[i].value = copy_string(orig->category[i].value);
|
||||
}
|
||||
}
|
||||
copy->nr = orig->nr;
|
||||
}
|
||||
}
|
||||
|
||||
static int taxonomy_index_for_category(const struct taxonomy_data *t, enum taxonomy_category cat)
|
||||
{
|
||||
for (int i = 0; i < t->nr; i++) {
|
||||
if (t->category[i].category == cat)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *taxonomy_get_value(const struct taxonomy_data *t, enum taxonomy_category cat)
|
||||
{
|
||||
int idx = taxonomy_index_for_category(t, cat);
|
||||
return idx >= 0 ? t->category[idx].value : NULL;
|
||||
}
|
||||
|
||||
const char *taxonomy_get_country(const struct taxonomy_data *t)
|
||||
{
|
||||
return taxonomy_get_value(t, TC_COUNTRY);
|
||||
}
|
||||
|
||||
void taxonomy_set_category(struct taxonomy_data *t, enum taxonomy_category category, const char *value, enum taxonomy_origin origin)
|
||||
{
|
||||
int idx = taxonomy_index_for_category(t, category);
|
||||
|
||||
if (idx < 0) {
|
||||
alloc_taxonomy_table(t); // make sure we have taxonomy data allocated
|
||||
if (t->nr == TC_NR_CATEGORIES - 1) {
|
||||
// can't add another one
|
||||
fprintf(stderr, "Error adding taxonomy category\n");
|
||||
return;
|
||||
}
|
||||
idx = t->nr++;
|
||||
} else {
|
||||
free((void *)t->category[idx].value);
|
||||
t->category[idx].value = NULL;
|
||||
}
|
||||
t->category[idx].value = strdup(value);
|
||||
t->category[idx].origin = origin;
|
||||
t->category[idx].category = category;
|
||||
}
|
||||
|
||||
void taxonomy_set_country(struct taxonomy_data *t, const char *country, enum taxonomy_origin origin)
|
||||
{
|
||||
fprintf(stderr, "%s: set the taxonomy country to %s\n", __func__, country);
|
||||
taxonomy_set_category(t, TC_COUNTRY, country, origin);
|
||||
}
|
||||
59
core/taxonomy.cpp
Normal file
59
core/taxonomy.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "taxonomy.h"
|
||||
#include "errorhelper.h"
|
||||
#include "gettext.h"
|
||||
#include "subsurface-string.h"
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <QtGlobal> // for QT_TRANSLATE_NOOP
|
||||
|
||||
const char *taxonomy_category_names[TC_NR_CATEGORIES] = {
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "None"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Ocean"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Country"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "State"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "County"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "Town"),
|
||||
QT_TRANSLATE_NOOP("gettextFromC", "City")
|
||||
};
|
||||
|
||||
// these are the names for geoname.org
|
||||
const char *taxonomy_api_names[TC_NR_CATEGORIES] = {
|
||||
"none",
|
||||
"name",
|
||||
"countryName",
|
||||
"adminName1",
|
||||
"adminName2",
|
||||
"toponymName",
|
||||
"adminName3"
|
||||
};
|
||||
|
||||
std::string taxonomy_get_value(const taxonomy_data &t, enum taxonomy_category cat)
|
||||
{
|
||||
auto it = std::find_if(t.begin(), t.end(), [cat] (const taxonomy &tax) { return tax.category == cat; });
|
||||
return it != t.end() ? it->value : std::string();
|
||||
}
|
||||
|
||||
std::string taxonomy_get_country(const taxonomy_data &t)
|
||||
{
|
||||
return taxonomy_get_value(t, TC_COUNTRY);
|
||||
}
|
||||
|
||||
void taxonomy_set_category(taxonomy_data &t, enum taxonomy_category cat, const std::string &value, enum taxonomy_origin origin)
|
||||
{
|
||||
auto it = std::find_if(t.begin(), t.end(), [cat] (const taxonomy &tax) { return tax.category == cat; });
|
||||
if (it == t.end()) {
|
||||
t.emplace_back();
|
||||
it = std::prev(t.end());
|
||||
}
|
||||
it->value = value;
|
||||
it->origin = origin;
|
||||
it->category = cat;
|
||||
}
|
||||
|
||||
void taxonomy_set_country(taxonomy_data &t, const std::string &country, enum taxonomy_origin origin)
|
||||
{
|
||||
report_info("%s: set the taxonomy country to %s\n", __func__, country.c_str());
|
||||
taxonomy_set_category(t, TC_COUNTRY, country, origin);
|
||||
}
|
||||
|
|
@ -3,8 +3,9 @@
|
|||
#define TAXONOMY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum taxonomy_category {
|
||||
TC_NONE,
|
||||
|
|
@ -24,29 +25,22 @@ enum taxonomy_origin {
|
|||
GEOCOPIED
|
||||
};
|
||||
|
||||
extern char *taxonomy_category_names[TC_NR_CATEGORIES];
|
||||
extern char *taxonomy_api_names[TC_NR_CATEGORIES];
|
||||
extern const char *taxonomy_category_names[TC_NR_CATEGORIES];
|
||||
extern const char *taxonomy_api_names[TC_NR_CATEGORIES];
|
||||
|
||||
struct taxonomy {
|
||||
int category; /* the category for this tag: ocean, country, admin_l1, admin_l2, localname, etc */
|
||||
const char *value; /* the value returned, parsed, or manually entered for that category */
|
||||
enum taxonomy_origin origin;
|
||||
taxonomy_category category; /* the category for this tag: ocean, country, admin_l1, admin_l2, localname, etc */
|
||||
std::string value; /* the value returned, parsed, or manually entered for that category */
|
||||
taxonomy_origin origin;
|
||||
};
|
||||
|
||||
/* the data block contains 3 taxonomy structures - unused ones have a tag value of NONE */
|
||||
struct taxonomy_data {
|
||||
int nr;
|
||||
struct taxonomy *category;
|
||||
};
|
||||
/* the data block contains taxonomy structures - unused ones have a tag value of NONE */
|
||||
using taxonomy_data = std::vector<taxonomy>;
|
||||
|
||||
void free_taxonomy(struct taxonomy_data *t);
|
||||
void copy_taxonomy(const struct taxonomy_data *orig, struct taxonomy_data *copy);
|
||||
const char *taxonomy_get_value(const struct taxonomy_data *t, enum taxonomy_category cat);
|
||||
const char *taxonomy_get_country(const struct taxonomy_data *t);
|
||||
void taxonomy_set_category(struct taxonomy_data *t, enum taxonomy_category category, const char *value, enum taxonomy_origin origin);
|
||||
void taxonomy_set_country(struct taxonomy_data *t, const char *country, enum taxonomy_origin origin);
|
||||
std::string taxonomy_get_value(const taxonomy_data &t, enum taxonomy_category cat);
|
||||
std::string taxonomy_get_country(const taxonomy_data &t);
|
||||
void taxonomy_set_category(taxonomy_data &t, enum taxonomy_category category, const std::string &value, enum taxonomy_origin origin);
|
||||
void taxonomy_set_country(taxonomy_data &t, const std::string &country, enum taxonomy_origin origin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // TAXONOMY_H
|
||||
|
|
|
|||
|
|
@ -116,13 +116,14 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
|
|||
put_format(&mb, "'");
|
||||
put_location(&mb, &ds->location, " gps='", "'");
|
||||
put_format(&mb, ">\n");
|
||||
if (ds->taxonomy.nr) {
|
||||
for (int j = 0; j < ds->taxonomy.nr; j++) {
|
||||
struct taxonomy *t = &ds->taxonomy.category[j];
|
||||
if (t->category != TC_NONE && t->category == prefs.geocoding.category[j] && t->value) {
|
||||
put_format(&mb, " <geo cat='%d'", t->category);
|
||||
put_format(&mb, " origin='%d' value='", t->origin);
|
||||
put_quoted(&mb, t->value, 1, 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (prefs.geocoding.category[i] == TC_NONE)
|
||||
continue;
|
||||
for (auto const &t: ds->taxonomy) {
|
||||
if (t.category == prefs.geocoding.category[i] && !t.value.empty()) {
|
||||
put_format(&mb, " <geo cat='%d'", t.category);
|
||||
put_format(&mb, " origin='%d' value='", t.origin);
|
||||
put_quoted(&mb, t.value.c_str(), 1, 0);
|
||||
put_format(&mb, "'/>\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue