summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2015-07-13 15:18:52 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-07-13 15:21:30 -0700
commite82f8ea565a68aa1fa980cb12c1f136b1d4a57f9 (patch)
treebf6e7eedb5132ea1920636ed7943be10ce823ecc
parent94d3aa04dccc3c10980188bd357618e2a9f2fa83 (diff)
downloadsubsurface-e82f8ea565a68aa1fa980cb12c1f136b1d4a57f9.tar.gz
Geo taxonomy: correctly store / update the categories
Don't throw away data unless new data has been received. And don't store multiple copies of the same category. And most importantly, never write past the end of the array. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--divesitehelpers.cpp41
-rw-r--r--taxonomy.c8
-rw-r--r--taxonomy.h1
3 files changed, 37 insertions, 13 deletions
diff --git a/divesitehelpers.cpp b/divesitehelpers.cpp
index 775951855..15946c49d 100644
--- a/divesitehelpers.cpp
+++ b/divesitehelpers.cpp
@@ -86,8 +86,20 @@ void ReverseGeoLookupThread::run() {
if (geoNames.count() > 0) {
QVariantMap firstData = geoNames.at(0).toMap();
int ri = 0, l3 = -1, lt = -1;
- if (ds->taxonomy.category == NULL)
+ if (ds->taxonomy.category == NULL) {
ds->taxonomy.category = alloc_taxonomy();
+ } else {
+ // clear out the data (except for the ocean data)
+ int ocean;
+ if ((ocean = taxonomy_index_for_category(&ds->taxonomy, TC_OCEAN)) > 0) {
+ ds->taxonomy.category[0] = ds->taxonomy.category[ocean];
+ ds->taxonomy.nr = 1;
+ } else {
+ // ocean is -1 if there is no such entry, and we didn't copy above
+ // if ocean is 0, so the following gets us the correct count
+ ds->taxonomy.nr = ocean + 1;
+ }
+ }
// get all the data - OCEAN is special, so start at COUNTRY
for (int j = TC_COUNTRY; j < TC_NR_CATEGORIES; j++) {
if (firstData[taxonomy_api_names[j]].isValid()) {
@@ -98,12 +110,9 @@ void ReverseGeoLookupThread::run() {
ri++;
}
}
- for (int j = ri - 1; j >= 0; j--) {
- if (ds->taxonomy.category[j].category == TC_ADMIN_L3)
- l3 = j;
- else if (ds->taxonomy.category[j].category == TC_LOCALNAME)
- lt = j;
- }
+ ds->taxonomy.nr = ri;
+ l3 = taxonomy_index_for_category(&ds->taxonomy, TC_ADMIN_L3);
+ lt = taxonomy_index_for_category(&ds->taxonomy, TC_LOCALNAME);
if (l3 == -1 && lt != -1) {
// 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,
@@ -111,9 +120,8 @@ void ReverseGeoLookupThread::run() {
ds->taxonomy.category[ri].value = copy_string(ds->taxonomy.category[lt].value);
ds->taxonomy.category[ri].origin = taxonomy::COPIED;
ds->taxonomy.category[ri].category = TC_ADMIN_L3;
- ri++;
+ ds->taxonomy.nr++;
}
- ds->taxonomy.nr = ri;
mark_divelist_changed(true);
} else {
report_error("geonames.org did not provide reverse lookup information");
@@ -150,12 +158,19 @@ void ReverseGeoLookupThread::run() {
QVariant oceanObject = obj.value("ocean").toVariant();
QVariantMap oceanName = oceanObject.toMap();
if (oceanName["name"].isValid()) {
+ int idx;
if (ds->taxonomy.category == NULL)
ds->taxonomy.category = alloc_taxonomy();
- ds->taxonomy.category[ds->taxonomy.nr].category = TC_OCEAN;
- ds->taxonomy.category[ds->taxonomy.nr].origin = taxonomy::GEOCODED;
- ds->taxonomy.category[ds->taxonomy.nr].value = copy_string(qPrintable(oceanName["name"].toString()));
- ds->taxonomy.nr++;
+ idx = taxonomy_index_for_category(&ds->taxonomy, TC_OCEAN);
+ if (idx == -1)
+ idx = ds->taxonomy.nr;
+ if (idx < TC_NR_CATEGORIES) {
+ ds->taxonomy.category[idx].category = TC_OCEAN;
+ ds->taxonomy.category[idx].origin = taxonomy::GEOCODED;
+ ds->taxonomy.category[idx].value = copy_string(qPrintable(oceanName["name"].toString()));
+ if (idx == ds->taxonomy.nr)
+ ds->taxonomy.nr++;
+ }
mark_divelist_changed(true);
}
} else {
diff --git a/taxonomy.c b/taxonomy.c
index 40af9fd44..670d85ad0 100644
--- a/taxonomy.c
+++ b/taxonomy.c
@@ -38,3 +38,11 @@ void free_taxonomy(struct taxonomy_data *t)
t->nr = 0;
}
}
+
+int taxonomy_index_for_category(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;
+}
diff --git a/taxonomy.h b/taxonomy.h
index bc42c6119..51245d562 100644
--- a/taxonomy.h
+++ b/taxonomy.h
@@ -33,6 +33,7 @@ struct taxonomy_data {
struct taxonomy *alloc_taxonomy();
void free_taxonomy(struct taxonomy_data *t);
+int taxonomy_index_for_category(struct taxonomy_data *t, enum taxonomy_category cat);
#ifdef __cplusplus
}