Adapt GPS coordinate download from our companion app to dive sites

This is a bit awkward now. We are downloading what looks like fake dives
in the v2 format. So we create a dive site for every single fix.

After we merge those new dive sites into the existing dives we need to
throw away all the dive sites that weren't used.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2015-02-13 07:14:30 -08:00
parent be1b6c67c1
commit 6708e06872
2 changed files with 42 additions and 16 deletions

11
dive.h
View file

@ -389,17 +389,6 @@ extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic);
extern int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc);
static inline void copy_gps_location(struct dive *from, struct dive *to)
{
if (from && to) {
to->latitude.udeg = from->latitude.udeg;
to->longitude.udeg = from->longitude.udeg;
if (!to->location) {
to->location = strdup(from->location);
}
}
}
static inline int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null)
{
int mbar = dive->surface_pressure.mbar;

View file

@ -29,7 +29,25 @@
#endif
struct dive_table gps_location_table;
static bool merge_locations_into_dives(void);
// we don't overwrite any existing GPS info in the dive
// so get the dive site and if there is none or there is one without GPS fix, add it
static void copy_gps_location(struct dive *from, struct dive *to)
{
struct dive_site *ds = get_dive_site_for_dive(to);
if (!ds || !dive_site_has_gps_location(ds)) {
struct dive_site *gds = get_dive_site_for_dive(from);
if (!ds) {
// simply link to the one created for the fake dive
to->dive_site_uuid = gds->uuid;
} else {
ds->latitude = gds->latitude;
ds->longitude = gds->longitude;
if (same_string(ds->name, ""))
ds->name = copy_string(gds->name);
}
}
}
#define SAME_GROUP 6 * 3600 // six hours
//TODO: C Code. static functions are not good if we plan to have a test for them.
@ -49,7 +67,7 @@ static bool merge_locations_into_dives(void)
* Asign and mark position, and end gps_location loop
*/
if ((dive->when <= gpsfix->when && gpsfix->when <= dive->when + dive->duration.seconds)) {
copy_gps_location(gpsfix,dive);
copy_gps_location(gpsfix, dive);
changed++;
tracer = j;
break;
@ -65,7 +83,7 @@ static bool merge_locations_into_dives(void)
* If not, simply fail and nextgpsfix will be evaluated in next iteration.
*/
if ((dive->when + dive->duration.seconds - gpsfix->when) < (nextgpsfix->when - gpsfix->when)) {
copy_gps_location(gpsfix,dive);
copy_gps_location(gpsfix, dive);
tracer = j;
break;
}
@ -73,7 +91,7 @@ static bool merge_locations_into_dives(void)
* If no more positions in range, the actual is the one. Asign, mark and end loop.
*/
} else {
copy_gps_location(gpsfix,dive);
copy_gps_location(gpsfix, dive);
changed++;
tracer = j;
break;
@ -329,10 +347,19 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton *button)
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
switch (ui.buttonBox->buttonRole(button)) {
case QDialogButtonBox::ApplyRole: {
int i;
struct dive *d;
struct dive_site *ds;
clear_table(&gps_location_table);
QByteArray url = tr("Webservice").toLocal8Bit();
parse_xml_buffer(url.data(), downloadedData.data(), downloadedData.length(), &gps_location_table, NULL);
// make sure we mark all the dive sites that were created
for (i = 0; i < gps_location_table.nr; i++) {
d = get_dive_from_table(i, &gps_location_table);
ds = get_dive_site_by_uuid(d->dive_site_uuid);
if (ds)
ds->notes = strdup("SubsurfaceWebservice");
}
/* now merge the data in the gps_location table into the dive_table */
if (merge_locations_into_dives()) {
mark_divelist_changed(true);
@ -361,6 +388,16 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton *button)
hide();
close();
resetState();
/* and now clean up and remove all the extra dive sites that were created */
QSet<uint32_t> usedUuids;
for_each_dive(i, d) {
if (d->dive_site_uuid)
usedUuids.insert(d->dive_site_uuid);
}
for_each_dive_site(i, ds) {
if (!usedUuids.contains(ds->uuid) && same_string(ds->notes, "SubsurfaceWebservice"))
delete_dive_site(ds->uuid);
}
} break;
case QDialogButtonBox::RejectRole:
if (reply != NULL && reply->isOpen()) {