subsurface/divesite.c
Dirk Hohndel 8c3efd2a22 Improve parsing of older XML files in order to auto create dive sites
While the existing code worked with a couple of hand crafted examples it
turns out it did a poor job with most of my files. Oops.

Depending on whether we find name or coordinates first, we need to
identify existing sites in either case and do the right thing.

The challeng here are multiple dives at the same site with slightly
different GPS coordinates. If the name is read first, these all get merged
into one (and we warn about the different GPS data). But if GPS gets read
first, we create separate dive sites with the same name.

We need a sane UI to consolidate these - but we can't completely automate
this... it's possible that these ARE the same site and the GPS data is
just imprecise (for example, multiple dives at the same time with GPS
locations from the Subsurface companion app). The user should be able to
either pick one of the GPS locations, or keep multiple (for example,
different buoyes for the same site and you want to keep the different
markers).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2015-02-13 12:42:44 -08:00

73 lines
1.8 KiB
C

/* divesite.c */
#include "divesite.h"
#include "dive.h"
struct dive_site_table dive_site_table;
/* try to create a uniqe ID - fingers crossed */
static uint32_t dive_site_getUniqId()
{
uint32_t id = 0;
while (id == 0 || get_dive_site_by_uuid(id))
id = random() + random();
return id;
}
struct dive_site *alloc_dive_site()
{
int nr = dive_site_table.nr, allocated = dive_site_table.allocated;
struct dive_site **sites = dive_site_table.dive_sites;
if (nr >= allocated) {
allocated = (nr + 32) * 3 / 2;
sites = realloc(sites, allocated * sizeof(struct dive_site *));
if (!sites)
exit(1);
dive_site_table.dive_sites = sites;
dive_site_table.allocated = allocated;
}
struct dive_site *ds = calloc(1, sizeof(*ds));
if (!ds)
exit(1);
sites[nr] = ds;
dive_site_table.nr = nr + 1;
ds->uuid = dive_site_getUniqId();
return ds;
}
/* allocate a new site and add it to the table */
uint32_t create_dive_site(const char *name)
{
struct dive_site *ds = alloc_dive_site();
ds->name = copy_string(name);
return ds->uuid;
}
/* same as before, but with GPS data */
uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude)
{
struct dive_site *ds = alloc_dive_site();
ds->uuid = dive_site_getUniqId();
ds->name = copy_string(name);
ds->latitude = latitude;
ds->longitude = longitude;
return ds->uuid;
}
/* if the uuid is valid, just get the site, otherwise create it first;
* so you can call this with dive->dive_site_uuid and you'll either get the existing
* dive site or it will create a new one - so make sure you assign the uuid back to
* dive->dive_site_uuid when using this function! */
struct dive_site *get_or_create_dive_site_by_uuid(uint32_t uuid)
{
struct dive_site *ds = get_dive_site_by_uuid(uuid);
if (!ds)
ds = alloc_dive_site();
return ds;
}