summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2018-10-20 14:12:15 -0400
committerGravatar Lubomir I. Ivanov <neolit123@gmail.com>2018-10-21 19:55:09 +0300
commit28e3413ff66552f392fecee25068d634cdfe59fc (patch)
tree5fe303d1e7dc1c371e13b534b85c232e29aea884 /core
parentc9869406301ff72f76b399097f0845fc1102ced1 (diff)
downloadsubsurface-28e3413ff66552f392fecee25068d634cdfe59fc.tar.gz
Add 'location_t' data structure
Instead of having people treat latitude and longitude as separate things, just add a 'location_t' data structure that contains both. Almost all cases want to always act on them together. This is really just prep-work for adding a few more locations that we track: I want to add a entry/exit location to each dive (independent of the dive site) because of how the Garmin Descent gives us the information (and hopefully, some day, other dive computers too). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'core')
-rw-r--r--core/dive.c12
-rw-r--r--core/dive.h3
-rw-r--r--core/divesite.c38
-rw-r--r--core/divesite.h12
-rw-r--r--core/gpslocation.cpp31
-rw-r--r--core/gpslocation.h3
-rw-r--r--core/libdivecomputer.c12
-rw-r--r--core/load-git.c26
-rw-r--r--core/membuffer.c8
-rw-r--r--core/membuffer.h1
-rw-r--r--core/metadata.cpp7
-rw-r--r--core/metadata.h3
-rw-r--r--core/parse-xml.c70
-rw-r--r--core/parse.c16
-rw-r--r--core/parse.h2
-rw-r--r--core/qthelper.cpp22
-rw-r--r--core/qthelper.h2
-rw-r--r--core/save-git.c12
-rw-r--r--core/save-html.c4
-rw-r--r--core/save-xml.c10
-rw-r--r--core/subsurface-qt/DiveObjectHelper.cpp2
-rw-r--r--core/uemis.c3
-rw-r--r--core/units.h23
-rw-r--r--core/worldmap-save.c4
24 files changed, 161 insertions, 165 deletions
diff --git a/core/dive.c b/core/dive.c
index 08ef5b6bd..e486d1a9a 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -4048,8 +4048,7 @@ void dive_create_picture(struct dive *dive, const char *filename, int shift_time
struct picture *picture = alloc_picture();
picture->filename = strdup(filename);
picture->offset.seconds = metadata.timestamp - dive->when + shift_time;
- picture->longitude = metadata.longitude;
- picture->latitude = metadata.latitude;
+ picture->location = metadata.location;
dive_add_picture(dive, picture);
dive_set_geodata_from_picture(dive, picture);
@@ -4078,12 +4077,11 @@ unsigned int dive_get_picture_count(struct dive *dive)
void dive_set_geodata_from_picture(struct dive *dive, struct picture *picture)
{
struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
- if (!dive_site_has_gps_location(ds) && (picture->latitude.udeg || picture->longitude.udeg)) {
+ if (!dive_site_has_gps_location(ds) && has_location(&picture->location)) {
if (ds) {
- ds->latitude = picture->latitude;
- ds->longitude = picture->longitude;
+ ds->location = picture->location;
} else {
- dive->dive_site_uuid = create_dive_site_with_gps("", picture->latitude, picture->longitude, dive->when);
+ dive->dive_site_uuid = create_dive_site_with_gps("", &picture->location, dive->when);
invalidate_dive_cache(dive);
}
}
@@ -4428,7 +4426,7 @@ int get_idx_by_uniq_id(int id)
bool dive_site_has_gps_location(const struct dive_site *ds)
{
- return ds && (ds->latitude.udeg || ds->longitude.udeg);
+ return ds && has_location(&ds->location);
}
int dive_has_gps_location(const struct dive *dive)
diff --git a/core/dive.h b/core/dive.h
index 659def142..e9ad1f502 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -363,8 +363,7 @@ extern enum divemode_t get_divemode_at_time(const struct divecomputer *dc, int d
struct picture {
char *filename;
offset_t offset;
- degrees_t latitude;
- degrees_t longitude;
+ location_t location;
struct picture *next;
};
diff --git a/core/divesite.c b/core/divesite.c
index c41b18220..ea9a3ed58 100644
--- a/core/divesite.c
+++ b/core/divesite.c
@@ -26,12 +26,12 @@ uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp)
}
/* there could be multiple sites at the same GPS fix - return the first one */
-uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp)
+uint32_t get_dive_site_uuid_by_gps(const location_t *loc, struct dive_site **dsp)
{
int i;
struct dive_site *ds;
for_each_dive_site (i, ds) {
- if (ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg) {
+ if (same_location(loc, &ds->location)) {
if (dsp)
*dsp = ds;
return ds->uuid;
@@ -43,23 +43,23 @@ uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, stru
/* 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 */
-uint32_t get_dive_site_uuid_by_gps_and_name(char *name, degrees_t latitude, degrees_t longitude)
+uint32_t get_dive_site_uuid_by_gps_and_name(char *name, const location_t *loc)
{
int i;
struct dive_site *ds;
for_each_dive_site (i, ds) {
- if (ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg && same_string(ds->name, name))
+ if (same_location(loc, &ds->location) && same_string(ds->name, name))
return ds->uuid;
}
return 0;
}
// Calculate the distance in meters between two coordinates.
-unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degrees_t lon2)
+unsigned int get_distance(const location_t *loc1, const location_t *loc2)
{
- double lat2_r = udeg_to_radians(lat2.udeg);
- double lat_d_r = udeg_to_radians(lat2.udeg-lat1.udeg);
- double lon_d_r = udeg_to_radians(lon2.udeg-lon1.udeg);
+ double lat2_r = udeg_to_radians(loc2->lat.udeg);
+ double lat_d_r = udeg_to_radians(loc2->lat.udeg - loc1->lat.udeg);
+ double lon_d_r = udeg_to_radians(loc2->lon.udeg - loc1->lon.udeg);
double a = sin(lat_d_r/2) * sin(lat_d_r/2) +
cos(lat2_r) * cos(lat2_r) * sin(lon_d_r/2) * sin(lon_d_r/2);
@@ -70,7 +70,7 @@ unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degree
}
/* find the closest one, no more than distance meters away - if more than one at same distance, pick the first */
-uint32_t get_dive_site_uuid_by_gps_proximity(degrees_t latitude, degrees_t longitude, int distance, struct dive_site **dsp)
+uint32_t get_dive_site_uuid_by_gps_proximity(const location_t *loc, int distance, struct dive_site **dsp)
{
int i;
int uuid = 0;
@@ -78,7 +78,7 @@ uint32_t get_dive_site_uuid_by_gps_proximity(degrees_t latitude, degrees_t longi
unsigned int cur_distance, min_distance = distance;
for_each_dive_site (i, ds) {
if (dive_site_has_gps_location(ds) &&
- (cur_distance = get_distance(ds->latitude, ds->longitude, latitude, longitude)) < min_distance) {
+ (cur_distance = get_distance(&ds->location, loc)) < min_distance) {
min_distance = cur_distance;
uuid = ds->uuid;
if (dsp)
@@ -232,13 +232,12 @@ uint32_t create_dive_site_from_current_dive(const char *name)
}
/* same as before, but with GPS data */
-uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude, timestamp_t divetime)
+uint32_t create_dive_site_with_gps(const char *name, const location_t *loc, timestamp_t divetime)
{
uint32_t uuid = create_divesite_uuid(name, divetime);
struct dive_site *ds = alloc_or_get_dive_site(uuid);
ds->name = copy_string(name);
- ds->latitude = latitude;
- ds->longitude = longitude;
+ ds->location = *loc;
return ds->uuid;
}
@@ -250,8 +249,7 @@ bool dive_site_is_empty(struct dive_site *ds)
(empty_string(ds->name) &&
empty_string(ds->description) &&
empty_string(ds->notes) &&
- ds->latitude.udeg == 0 &&
- ds->longitude.udeg == 0);
+ !has_location(&ds->location));
}
void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
@@ -260,8 +258,7 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
free(copy->notes);
free(copy->description);
- copy->latitude = orig->latitude;
- copy->longitude = orig->longitude;
+ copy->location = orig->location;
copy->name = copy_string(orig->name);
copy->notes = copy_string(orig->notes);
copy->description = copy_string(orig->description);
@@ -290,8 +287,7 @@ static void merge_string(char **a, char **b)
void merge_dive_site(struct dive_site *a, struct dive_site *b)
{
- if (!a->latitude.udeg) a->latitude.udeg = b->latitude.udeg;
- if (!a->longitude.udeg) a->longitude.udeg = b->longitude.udeg;
+ 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);
@@ -310,8 +306,8 @@ void clear_dive_site(struct dive_site *ds)
ds->name = NULL;
ds->notes = NULL;
ds->description = NULL;
- ds->latitude.udeg = 0;
- ds->longitude.udeg = 0;
+ ds->location.lat.udeg = 0;
+ ds->location.lon.udeg = 0;
ds->uuid = 0;
ds->taxonomy.nr = 0;
free_taxonomy(&ds->taxonomy);
diff --git a/core/divesite.h b/core/divesite.h
index f5fe1dbd5..d739c4520 100644
--- a/core/divesite.h
+++ b/core/divesite.h
@@ -18,7 +18,7 @@ struct dive_site
{
uint32_t uuid;
char *name;
- degrees_t latitude, longitude;
+ location_t location;
char *description;
char *notes;
struct taxonomy_data taxonomy;
@@ -60,17 +60,17 @@ void free_dive_site(struct dive_site *ds);
void delete_dive_site(uint32_t id);
uint32_t create_dive_site(const char *name, timestamp_t divetime);
uint32_t create_dive_site_from_current_dive(const char *name);
-uint32_t create_dive_site_with_gps(const char *name, degrees_t latitude, degrees_t longitude, timestamp_t divetime);
+uint32_t create_dive_site_with_gps(const char *name, const location_t *, timestamp_t divetime);
uint32_t get_dive_site_uuid_by_name(const char *name, struct dive_site **dsp);
-uint32_t get_dive_site_uuid_by_gps(degrees_t latitude, degrees_t longitude, struct dive_site **dsp);
-uint32_t get_dive_site_uuid_by_gps_and_name(char *name, degrees_t latitude, degrees_t longitude);
-uint32_t get_dive_site_uuid_by_gps_proximity(degrees_t latitude, degrees_t longitude, int distance, struct dive_site **dsp);
+uint32_t get_dive_site_uuid_by_gps(const location_t *, struct dive_site **dsp);
+uint32_t get_dive_site_uuid_by_gps_and_name(char *name, const location_t *);
+uint32_t get_dive_site_uuid_by_gps_proximity(const location_t *, int distance, struct dive_site **dsp);
bool dive_site_is_empty(struct dive_site *ds);
void copy_dive_site_taxonomy(struct dive_site *orig, struct dive_site *copy);
void copy_dive_site(struct dive_site *orig, struct dive_site *copy);
void merge_dive_site(struct dive_site *a, struct dive_site *b);
void clear_dive_site(struct dive_site *ds);
-unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degrees_t lon2);
+unsigned int get_distance(const location_t *loc1, const location_t *loc2);
uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t divetime);
void merge_dive_sites(uint32_t ref, uint32_t *uuids, int count);
diff --git a/core/gpslocation.cpp b/core/gpslocation.cpp
index 54015837b..485cbac56 100644
--- a/core/gpslocation.cpp
+++ b/core/gpslocation.cpp
@@ -137,7 +137,7 @@ QString GpsLocation::currentPosition()
if (delta < 300) {
// we can simply use the last position that we tracked
gpsTracker gt = m_trackers.last();
- QString gpsString = printGPSCoords(gt.latitude.udeg, gt.longitude.udeg);
+ QString gpsString = printGPSCoords(&gt.location);
qDebug() << "returning last position" << gpsString;
return gpsString;
} else {
@@ -159,8 +159,8 @@ void GpsLocation::newPosition(QGeoPositionInfo pos)
int nr = m_trackers.count();
if (nr) {
gpsTracker gt = m_trackers.last();
- lastCoord.setLatitude(gt.latitude.udeg / 1000000.0);
- lastCoord.setLongitude(gt.longitude.udeg / 1000000.0);
+ lastCoord.setLatitude(gt.location.lat.udeg / 1000000.0);
+ lastCoord.setLongitude(gt.location.lon.udeg / 1000000.0);
lastTime = gt.when;
}
// if we are waiting for a position update or
@@ -176,8 +176,7 @@ void GpsLocation::newPosition(QGeoPositionInfo pos)
gpsTracker gt;
gt.when = pos.timestamp().toTime_t();
gt.when += gettimezoneoffset(gt.when);
- gt.latitude.udeg = lrint(pos.coordinate().latitude() * 1000000);
- gt.longitude.udeg = lrint(pos.coordinate().longitude() * 1000000);
+ gt.location = create_location(pos.coordinate().latitude(), pos.coordinate().longitude());
addFixToStorage(gt);
gpsTracker gtNew = m_trackers.last();
qDebug() << "newest fix is now at" << QDateTime().fromMSecsSinceEpoch(gtNew.when - gettimezoneoffset(gtNew.when) * 1000).toString();
@@ -215,8 +214,7 @@ static void copy_gps_location(struct gpsTracker &gps, struct dive *d)
d->dive_site_uuid = create_dive_site(qPrintable(gps.name), gps.when);
ds = get_dive_site_by_uuid(d->dive_site_uuid);
}
- ds->latitude = gps.latitude;
- ds->longitude = gps.longitude;
+ ds->location = gps.location;
}
#define SAME_GROUP 6 * 3600 /* six hours */
@@ -331,8 +329,8 @@ void GpsLocation::loadFromStorage()
for (int i = 0; i < nr; i++) {
struct gpsTracker gt;
gt.when = geoSettings->value(QString("gpsFix%1_time").arg(i)).toLongLong();
- gt.latitude.udeg = geoSettings->value(QString("gpsFix%1_lat").arg(i)).toInt();
- gt.longitude.udeg = geoSettings->value(QString("gpsFix%1_lon").arg(i)).toInt();
+ gt.location.lat.udeg = geoSettings->value(QString("gpsFix%1_lat").arg(i)).toInt();
+ gt.location.lon.udeg = geoSettings->value(QString("gpsFix%1_lon").arg(i)).toInt();
gt.name = geoSettings->value(QString("gpsFix%1_name").arg(i)).toString();
gt.idx = i;
m_trackers.insert(gt.when, gt);
@@ -347,11 +345,10 @@ void GpsLocation::replaceFixToStorage(gpsTracker &gt)
}
gpsTracker replacedTracker = m_trackers.value(gt.when);
geoSettings->setValue(QString("gpsFix%1_time").arg(replacedTracker.idx), gt.when);
- geoSettings->setValue(QString("gpsFix%1_lat").arg(replacedTracker.idx), gt.latitude.udeg);
- geoSettings->setValue(QString("gpsFix%1_lon").arg(replacedTracker.idx), gt.longitude.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lat").arg(replacedTracker.idx), gt.location.lat.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lon").arg(replacedTracker.idx), gt.location.lon.udeg);
geoSettings->setValue(QString("gpsFix%1_name").arg(replacedTracker.idx), gt.name);
- replacedTracker.latitude = gt.latitude;
- replacedTracker.longitude = gt.longitude;
+ replacedTracker.location = gt.location;
replacedTracker.name = gt.name;
}
@@ -360,8 +357,8 @@ void GpsLocation::addFixToStorage(gpsTracker &gt)
int nr = m_trackers.count();
geoSettings->setValue("count", nr + 1);
geoSettings->setValue(QString("gpsFix%1_time").arg(nr), gt.when);
- geoSettings->setValue(QString("gpsFix%1_lat").arg(nr), gt.latitude.udeg);
- geoSettings->setValue(QString("gpsFix%1_lon").arg(nr), gt.longitude.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lat").arg(nr), gt.location.lat.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lon").arg(nr), gt.location.lon.udeg);
geoSettings->setValue(QString("gpsFix%1_name").arg(nr), gt.name);
gt.idx = nr;
geoSettings->sync();
@@ -389,8 +386,8 @@ void GpsLocation::deleteFixFromStorage(gpsTracker &gt)
m_trackers.remove(movedTracker.when);
m_trackers.insert(movedTracker.when, movedTracker);
geoSettings->setValue(QString("gpsFix%1_time").arg(movedTracker.idx), when);
- geoSettings->setValue(QString("gpsFix%1_lat").arg(movedTracker.idx), movedTracker.latitude.udeg);
- geoSettings->setValue(QString("gpsFix%1_lon").arg(movedTracker.idx), movedTracker.longitude.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lat").arg(movedTracker.idx), movedTracker.location.lat.udeg);
+ geoSettings->setValue(QString("gpsFix%1_lon").arg(movedTracker.idx), movedTracker.location.lon.udeg);
geoSettings->setValue(QString("gpsFix%1_name").arg(movedTracker.idx), movedTracker.name);
geoSettings->remove(QString("gpsFix%1_lat").arg(cnt - 1));
geoSettings->remove(QString("gpsFix%1_lon").arg(cnt - 1));
diff --git a/core/gpslocation.h b/core/gpslocation.h
index 70bb17404..02377bfca 100644
--- a/core/gpslocation.h
+++ b/core/gpslocation.h
@@ -14,8 +14,7 @@
#define GPS_CURRENT_POS gettextFromC::tr("Waiting to aquire GPS location")
struct gpsTracker {
- degrees_t latitude;
- degrees_t longitude;
+ location_t location;
qint64 when;
QString name;
int idx;
diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c
index acc6478b2..a4c21b423 100644
--- a/core/libdivecomputer.c
+++ b/core/libdivecomputer.c
@@ -569,7 +569,7 @@ static void set_dc_serial(struct divecomputer *dc, const char *serial)
dc->deviceid = calculate_string_hash(serial);
}
-extern degrees_t parse_degrees(char *buf, char **end);
+extern void parse_location(char *, location_t *);
static void parse_string_field(struct dive *dive, dc_field_string_t *str)
{
@@ -591,14 +591,12 @@ static void parse_string_field(struct dive *dive, dc_field_string_t *str)
/* GPS data? */
if (!strncmp(str->desc, "GPS", 3)) {
char *line = (char *) str->value;
- degrees_t latitude, longitude;
+ location_t location;
- latitude = parse_degrees(line, &line);
- if (*line == ',') line++;
- longitude = parse_degrees(line, &line);
+ parse_location(line, &location);
- if (latitude.udeg && longitude.udeg)
- dive->dive_site_uuid = create_dive_site_with_gps(str->value, latitude, longitude, time(NULL));
+ if (location.lat.udeg && location.lon.udeg)
+ dive->dive_site_uuid = create_dive_site_with_gps(str->value, &location, time(NULL));
}
}
#endif
diff --git a/core/load-git.c b/core/load-git.c
index 0abae4239..2040d2f70 100644
--- a/core/load-git.c
+++ b/core/load-git.c
@@ -31,7 +31,7 @@ struct keyword_action {
};
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
-extern degrees_t parse_degrees(char *buf, char **end);
+extern void parse_location(char *buf, location_t *);
git_blob *git_tree_entry_blob(git_repository *repo, const git_tree_entry *entry);
static char *get_utf8(struct membuffer *b)
@@ -152,25 +152,24 @@ static void parse_dive_gps(char *line, struct membuffer *str, void *_dive)
{
UNUSED(str);
uint32_t uuid;
- degrees_t latitude = parse_degrees(line, &line);
- degrees_t longitude = parse_degrees(line, &line);
+ location_t location;
struct dive *dive = _dive;
struct dive_site *ds = get_dive_site_for_dive(dive);
+
+ parse_location(line, &location);
if (!ds) {
- uuid = get_dive_site_uuid_by_gps(latitude, longitude, NULL);
+ uuid = get_dive_site_uuid_by_gps(&location, NULL);
if (!uuid)
- uuid = create_dive_site_with_gps("", latitude, longitude, dive->when);
+ uuid = create_dive_site_with_gps("", &location, dive->when);
dive->dive_site_uuid = uuid;
} else {
- if (dive_site_has_gps_location(ds) &&
- (ds->latitude.udeg != latitude.udeg || ds->longitude.udeg != longitude.udeg)) {
- const char *coords = printGPSCoords(latitude.udeg, longitude.udeg);
+ if (dive_site_has_gps_location(ds) && !same_location(&ds->location, &location)) {
+ const char *coords = printGPSCoords(&location);
// we have a dive site that already has GPS coordinates
ds->notes = add_to_string(ds->notes, translate("gettextFromC", "multiple GPS locations for this dive site; also %s\n"), coords);
free((void *)coords);
}
- ds->latitude = latitude;
- ds->longitude = longitude;
+ ds->location = location;
}
}
@@ -274,14 +273,12 @@ static void parse_site_name(char *line, struct membuffer *str, void *_ds)
static void parse_site_notes(char *line, struct membuffer *str, void *_ds)
{ UNUSED(line); struct dive_site *ds = _ds; ds->notes = strdup(mb_cstring(str)); }
-extern degrees_t parse_degrees(char *buf, char **end);
static void parse_site_gps(char *line, struct membuffer *str, void *_ds)
{
UNUSED(str);
struct dive_site *ds = _ds;
- ds->latitude = parse_degrees(line, &line);
- ds->longitude = parse_degrees(line, &line);
+ parse_location(line, &ds->location);
}
static void parse_site_geo(char *line, struct membuffer *str, void *_ds)
@@ -949,8 +946,7 @@ static void parse_picture_gps(char *line, struct membuffer *str, void *_pic)
UNUSED(str);
struct picture *pic = _pic;
- pic->latitude = parse_degrees(line, &line);
- pic->longitude = parse_degrees(line, &line);
+ parse_location(line, &pic->location);
}
static void parse_picture_hash(char *line, struct membuffer *str, void *_pic)
diff --git a/core/membuffer.c b/core/membuffer.c
index 1d486b3a6..46cb541f1 100644
--- a/core/membuffer.c
+++ b/core/membuffer.c
@@ -218,6 +218,14 @@ void put_degrees(struct membuffer *b, degrees_t value, const char *pre, const ch
put_format(b, "%s%s%u.%06u%s", pre, sign, FRACTION(udeg, 1000000), post);
}
+void put_location(struct membuffer *b, location_t *loc, const char *pre, const char *post)
+{
+ if (has_location(loc)) {
+ put_degrees(b, loc->lat, pre, " ");
+ put_degrees(b, loc->lon, "", post);
+ }
+}
+
void put_quoted(struct membuffer *b, const char *text, int is_attribute, int is_html)
{
const char *p = text;
diff --git a/core/membuffer.h b/core/membuffer.h
index 7bcb5b51f..cc441ba24 100644
--- a/core/membuffer.h
+++ b/core/membuffer.h
@@ -109,6 +109,7 @@ extern void put_duration(struct membuffer *, duration_t, const char *, const cha
extern void put_pressure(struct membuffer *, pressure_t, const char *, const char *);
extern void put_salinity(struct membuffer *, int, const char *, const char *);
extern void put_degrees(struct membuffer *b, degrees_t value, const char *, const char *);
+extern void put_location(struct membuffer *b, location_t *, const char *, const char *);
#ifdef __cplusplus
}
diff --git a/core/metadata.cpp b/core/metadata.cpp
index b549a5b3b..dae261b93 100644
--- a/core/metadata.cpp
+++ b/core/metadata.cpp
@@ -97,8 +97,7 @@ static bool parseExif(QFile &f, struct metadata *metadata)
easyexif::EXIFInfo exif;
if (exif.parseFromEXIFSegment(reinterpret_cast<const unsigned char *>(data.constData()), len) != PARSE_EXIF_SUCCESS)
return false;
- metadata->longitude.udeg = lrint(1000000.0 * exif.GeoLocation.Longitude);
- metadata->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude);
+ metadata->location = create_location(exif.GeoLocation.Latitude, exif.GeoLocation.Longitude);
metadata->timestamp = exif.epoch();
return true;
}
@@ -521,8 +520,8 @@ extern "C" mediatype_t get_metadata(const char *filename_in, metadata *data)
{
data->timestamp = 0;
data->duration.seconds = 0;
- data->latitude.udeg = 0;
- data->longitude.udeg = 0;
+ data->location.lat.udeg = 0;
+ data->location.lon.udeg = 0;
QString filename = localFilePath(QString(filename_in));
QFile f(filename);
diff --git a/core/metadata.h b/core/metadata.h
index 4470bdc88..253763ad8 100644
--- a/core/metadata.h
+++ b/core/metadata.h
@@ -6,8 +6,7 @@
struct metadata {
timestamp_t timestamp;
duration_t duration;
- degrees_t latitude;
- degrees_t longitude;
+ location_t location;
};
enum mediatype_t {
diff --git a/core/parse-xml.c b/core/parse-xml.c
index 6af570739..ccc66f336 100644
--- a/core/parse-xml.c
+++ b/core/parse-xml.c
@@ -1066,7 +1066,7 @@ static int uddf_dive_match(struct dive *dive, const char *name, char *buf)
* We don't do exponentials etc, if somebody does
* GPS locations in that format, they are insane.
*/
-degrees_t parse_degrees(char *buf, char **end)
+static degrees_t parse_degrees(char *buf, char **end)
{
int sign = 1, decimals = 6, value = 0;
degrees_t ret;
@@ -1112,86 +1112,90 @@ degrees_t parse_degrees(char *buf, char **end)
static void gps_lat(char *buffer, struct dive *dive)
{
char *end;
- degrees_t latitude = parse_degrees(buffer, &end);
+ location_t location = { };
struct dive_site *ds = get_dive_site_for_dive(dive);
+
+ location.lat = parse_degrees(buffer, &end);
if (!ds) {
- dive->dive_site_uuid = create_dive_site_with_gps(NULL, latitude, (degrees_t){0}, dive->when);
+ dive->dive_site_uuid = create_dive_site_with_gps(NULL, &location, dive->when);
} else {
- if (ds->latitude.udeg && ds->latitude.udeg != latitude.udeg)
+ if (ds->location.lat.udeg && ds->location.lat.udeg != location.lat.udeg)
fprintf(stderr, "Oops, changing the latitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)");
- ds->latitude = latitude;
+ ds->location.lat = location.lat;
}
}
static void gps_long(char *buffer, struct dive *dive)
{
char *end;
- degrees_t longitude = parse_degrees(buffer, &end);
+ location_t location = { };
struct dive_site *ds = get_dive_site_for_dive(dive);
+
+ location.lon = parse_degrees(buffer, &end);
if (!ds) {
- dive->dive_site_uuid = create_dive_site_with_gps(NULL, (degrees_t){0}, longitude, dive->when);
+ dive->dive_site_uuid = create_dive_site_with_gps(NULL, &location, dive->when);
} else {
- if (ds->longitude.udeg && ds->longitude.udeg != longitude.udeg)
+ if (ds->location.lon.udeg && ds->location.lon.udeg != location.lon.udeg)
fprintf(stderr, "Oops, changing the longitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)");
- ds->longitude = longitude;
+ ds->location.lon = location.lon;
}
}
-static void gps_location(char *buffer, struct dive_site *ds)
+/* We allow either spaces or a comma between the decimal degrees */
+void parse_location(char *buffer, location_t *loc)
{
char *end;
+ loc->lat = parse_degrees(buffer, &end);
+ if (*end == ',') end++;
+ loc->lon = parse_degrees(end, &end);
+}
- ds->latitude = parse_degrees(buffer, &end);
- ds->longitude = parse_degrees(end, &end);
+static void gps_location(char *buffer, struct dive_site *ds)
+{
+ parse_location(buffer, &ds->location);
}
static void gps_in_dive(char *buffer, struct dive *dive)
{
- char *end;
struct dive_site *ds = NULL;
- degrees_t latitude = parse_degrees(buffer, &end);
- degrees_t longitude = parse_degrees(end, &end);
+ location_t location;
uint32_t uuid = dive->dive_site_uuid;
+
+ parse_location(buffer, &location);
if (uuid == 0) {
// check if we have a dive site within 20 meters of that gps fix
- uuid = get_dive_site_uuid_by_gps_proximity(latitude, longitude, 20, &ds);
+ uuid = get_dive_site_uuid_by_gps_proximity(&location, 20, &ds);
if (ds) {
// found a site nearby; in case it turns out this one had a different name let's
// remember the original coordinates so we can create the correct dive site later
- cur_latitude = latitude;
- cur_longitude = longitude;
+ cur_location = location;
dive->dive_site_uuid = uuid;
} else {
- dive->dive_site_uuid = create_dive_site_with_gps("", latitude, longitude, dive->when);
+ dive->dive_site_uuid = create_dive_site_with_gps("", &location, dive->when);
ds = get_dive_site_by_uuid(dive->dive_site_uuid);
}
} else {
ds = get_dive_site_by_uuid(uuid);
if (dive_site_has_gps_location(ds) &&
- (latitude.udeg != 0 || longitude.udeg != 0) &&
- (ds->latitude.udeg != latitude.udeg || ds->longitude.udeg != longitude.udeg)) {
+ has_location(&location) && !same_location(&ds->location, &location)) {
// Houston, we have a problem
fprintf(stderr, "dive site uuid in dive, but gps location (%10.6f/%10.6f) different from dive location (%10.6f/%10.6f)\n",
- ds->latitude.udeg / 1000000.0, ds->longitude.udeg / 1000000.0,
- latitude.udeg / 1000000.0, longitude.udeg / 1000000.0);
- const char *coords = printGPSCoords(latitude.udeg, longitude.udeg);
+ ds->location.lat.udeg / 1000000.0, ds->location.lon.udeg / 1000000.0,
+ location.lat.udeg / 1000000.0, location.lon.udeg / 1000000.0);
+ const char *coords = printGPSCoords(&location);
ds->notes = add_to_string(ds->notes, translate("gettextFromC", "multiple GPS locations for this dive site; also %s\n"), coords);
free((void *)coords);
} else {
- ds->latitude = latitude;
- ds->longitude = longitude;
+ ds->location = location;
}
}
}
static void gps_picture_location(char *buffer, struct picture *pic)
{
- char *end;
-
- pic->latitude = parse_degrees(buffer, &end);
- pic->longitude = parse_degrees(end, &end);
+ parse_location(buffer, &pic->location);
}
/* We're in the top-level dive xml. Try to convert whatever value to a dive value */
@@ -2100,9 +2104,9 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct dive_table *tabl
break;
case 4:
/* Measure GPS */
- cur_latitude.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0));
- cur_longitude.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0));
- cur_dive->dive_site_uuid = create_dive_site_with_gps("DLF imported", cur_latitude, cur_longitude, cur_dive->when);
+ cur_location.lat.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0));
+ cur_location.lon.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0));
+ cur_dive->dive_site_uuid = create_dive_site_with_gps("DLF imported", &cur_location, cur_dive->when);
break;
default:
break;
diff --git a/core/parse.c b/core/parse.c
index 067008970..76b66733f 100644
--- a/core/parse.c
+++ b/core/parse.c
@@ -22,7 +22,7 @@ struct parser_settings cur_settings;
struct divecomputer *cur_dc = NULL;
struct dive *cur_dive = NULL;
struct dive_site *cur_dive_site = NULL;
-degrees_t cur_latitude, cur_longitude;
+location_t cur_location;
dive_trip_t *cur_trip = NULL;
struct sample *cur_sample = NULL;
struct picture *cur_picture = NULL;
@@ -258,8 +258,8 @@ void dive_end(void)
record_dive_to_table(cur_dive, target_table);
cur_dive = NULL;
cur_dc = NULL;
- cur_latitude.udeg = 0;
- cur_longitude.udeg = 0;
+ cur_location.lat.udeg = 0;
+ cur_location.lon.udeg = 0;
cur_cylinder_index = 0;
cur_ws_index = 0;
}
@@ -442,19 +442,17 @@ void add_dive_site(char *ds_name, struct dive *dive)
// but wait, we could have gotten this one based on GPS coords and could
// have had two different names for the same site... so let's search the other
// way around
- uint32_t exact_match_uuid = get_dive_site_uuid_by_gps_and_name(buffer, ds->latitude, ds->longitude);
+ uint32_t exact_match_uuid = get_dive_site_uuid_by_gps_and_name(buffer, &ds->location);
if (exact_match_uuid) {
dive->dive_site_uuid = exact_match_uuid;
} else {
dive->dive_site_uuid = create_dive_site(buffer, dive->when);
struct dive_site *newds = get_dive_site_by_uuid(dive->dive_site_uuid);
- if (cur_latitude.udeg || cur_longitude.udeg) {
+ if (has_location(&cur_location)) {
// we started this uuid with GPS data, so lets use those
- newds->latitude = cur_latitude;
- newds->longitude = cur_longitude;
+ newds->location = cur_location;
} else {
- newds->latitude = ds->latitude;
- newds->longitude = ds->longitude;
+ newds->location = ds->location;
}
newds->notes = add_to_string(newds->notes, translate("gettextFromC", "additional name for site: %s\n"), ds->name);
}
diff --git a/core/parse.h b/core/parse.h
index b2c2cbb96..8575fd46a 100644
--- a/core/parse.h
+++ b/core/parse.h
@@ -18,7 +18,7 @@ extern event_allocation_t event_allocation;
extern struct divecomputer *cur_dc;
extern struct dive *cur_dive;
extern struct dive_site *cur_dive_site;
-extern degrees_t cur_latitude, cur_longitude;
+extern location_t cur_location;
extern dive_trip_t *cur_trip;
extern struct sample *cur_sample;
extern struct picture *cur_picture;
diff --git a/core/qthelper.cpp b/core/qthelper.cpp
index fd7934885..23ccbfec0 100644
--- a/core/qthelper.cpp
+++ b/core/qthelper.cpp
@@ -75,14 +75,16 @@ QString distance_string(int distanceInMeters)
return str;
}
-extern "C" const char *printGPSCoords(int lat, int lon)
+extern "C" const char *printGPSCoords(const location_t *loc)
{
+ int lat = loc->lat.udeg;
+ int lon = loc->lon.udeg;
unsigned int latdeg, londeg;
unsigned int latmin, lonmin;
double latsec, lonsec;
QString lath, lonh, result;
- if (!lat && !lon)
+ if (!has_location(loc))
return strdup("");
if (prefs.coordinates_traditional) {
@@ -247,30 +249,24 @@ bool parseGpsText(const QString &gps_text, double *latitude, double *longitude)
#if 0 // we'll need something like this for the dive site management, eventually
bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_text, bool *parsed_out)
{
- double latitude, longitude;
- int latudeg, longudeg;
+ location_t location;
bool ignore;
bool *parsed = parsed_out ?: &ignore;
*parsed = true;
/* if we have a master and the dive's gps address is different from it,
* don't change the dive */
- if (master && (master->latitude.udeg != dive->latitude.udeg ||
- master->longitude.udeg != dive->longitude.udeg))
+ if (master && !same_location(&master->location, &dive->location))
return false;
- if (!(*parsed = parseGpsText(gps_text, &latitude, &longitude)))
+ if (!(*parsed = parseGpsText(gps_text, location)))
return false;
- latudeg = lrint(1000000 * latitude);
- longudeg = lrint(1000000 * longitude);
-
/* if dive gps didn't change, nothing changed */
- if (dive->latitude.udeg == latudeg && dive->longitude.udeg == longudeg)
+ if (same_location(&dive->location, location))
return false;
/* ok, update the dive and mark things changed */
- dive->latitude.udeg = latudeg;
- dive->longitude.udeg = longudeg;
+ dive->location = location;
return true;
}
#endif
diff --git a/core/qthelper.h b/core/qthelper.h
index fa41fd339..deb893634 100644
--- a/core/qthelper.h
+++ b/core/qthelper.h
@@ -124,7 +124,7 @@ void moveInVector(Vector &v, int rangeBegin, int rangeEnd, int destination)
extern "C" {
#endif
-const char *printGPSCoords(int lat, int lon);
+const char *printGPSCoords(const location_t *loc);
bool in_planner();
bool getProxyString(char **buffer);
bool canReachCloudServer();
diff --git a/core/save-git.c b/core/save-git.c
index 7db47dc94..938b7d3a5 100644
--- a/core/save-git.c
+++ b/core/save-git.c
@@ -38,14 +38,6 @@ static void cond_put_format(int cond, struct membuffer *b, const char *fmt, ...)
#define SAVE(str, x) cond_put_format(dive->x, b, str " %d\n", dive->x)
-static void show_gps(struct membuffer *b, degrees_t latitude, degrees_t longitude)
-{
- if (latitude.udeg || longitude.udeg) {
- put_degrees(b, latitude, "gps ", " ");
- put_degrees(b, longitude, "", "\n");
- }
-}
-
static void quote(struct membuffer *b, const char *text)
{
const char *p = text;
@@ -613,7 +605,7 @@ static int save_one_picture(git_repository *repo, struct dir *dir, struct pictur
unsigned h;
show_utf8(&buf, "filename ", pic->filename, "\n");
- show_gps(&buf, pic->latitude, pic->longitude);
+ put_location(&buf, &pic->location, "gps ", "\n");
/* Picture loading will load even negative offsets.. */
if (offset < 0) {
@@ -921,7 +913,7 @@ static void save_divesites(git_repository *repo, struct dir *tree)
show_utf8(&b, "name ", ds->name, "\n");
show_utf8(&b, "description ", ds->description, "\n");
show_utf8(&b, "notes ", ds->notes, "\n");
- show_gps(&b, ds->latitude, ds->longitude);
+ 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) {
diff --git a/core/save-html.c b/core/save-html.c
index 413718692..ea46d49ea 100644
--- a/core/save-html.c
+++ b/core/save-html.c
@@ -191,8 +191,8 @@ void put_HTML_coordinates(struct membuffer *b, struct dive *dive)
struct dive_site *ds = get_dive_site_for_dive(dive);
if (!ds)
return;
- degrees_t latitude = ds->latitude;
- degrees_t longitude = ds->longitude;
+ degrees_t latitude = ds->location.lat;
+ degrees_t longitude = ds->location.lon;
//don't put coordinates if in (0,0)
if (!latitude.udeg && !longitude.udeg)
diff --git a/core/save-xml.c b/core/save-xml.c
index 96932c900..fad5f584a 100644
--- a/core/save-xml.c
+++ b/core/save-xml.c
@@ -464,10 +464,7 @@ static void save_picture(struct membuffer *b, struct picture *pic)
}
put_format(b, " offset='%c%u:%02u min'", sign, FRACTION(offset, 60));
}
- if (pic->latitude.udeg || pic->longitude.udeg) {
- put_degrees(b, pic->latitude, " gps='", " ");
- put_degrees(b, pic->longitude, "", "'");
- }
+ put_location(b, &pic->location, " gps='","'");
put_string(b, "/>\n");
}
@@ -630,10 +627,7 @@ void save_dives_buffer(struct membuffer *b, const bool select_only, bool anonymi
put_format(b, "<site uuid='%8x'", ds->uuid);
show_utf8_blanked(b, ds->name, " name='", "'", 1, anonymize);
- if (ds->latitude.udeg || ds->longitude.udeg) {
- put_degrees(b, ds->latitude, " gps='", " ");
- put_degrees(b, ds->longitude, "", "'");
- }
+ put_location(b, &ds->location, " gps='", "'");
show_utf8_blanked(b, ds->description, " description='", "'", 1, anonymize);
put_format(b, ">\n");
show_utf8_blanked(b, ds->notes, " <notes>", " </notes>\n", 0, anonymize);
diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp
index a69c73ddc..a4d05f0ca 100644
--- a/core/subsurface-qt/DiveObjectHelper.cpp
+++ b/core/subsurface-qt/DiveObjectHelper.cpp
@@ -108,7 +108,7 @@ QString DiveObjectHelper::location() const
QString DiveObjectHelper::gps() const
{
struct dive_site *ds = get_dive_site_by_uuid(m_dive->dive_site_uuid);
- return ds ? QString(printGPSCoords(ds->latitude.udeg, ds->longitude.udeg)) : QString();
+ return ds ? QString(printGPSCoords(&ds->location)) : QString();
}
QString DiveObjectHelper::gps_decimal() const
diff --git a/core/uemis.c b/core/uemis.c
index 33005108b..7595131cf 100644
--- a/core/uemis.c
+++ b/core/uemis.c
@@ -173,8 +173,7 @@ void uemis_set_divelocation(int divespot, char *text, double longitude, double l
struct dive_site *ds = get_dive_site_by_uuid(hp->dive_site_uuid);
if (ds) {
ds->name = strdup(text);
- ds->longitude.udeg = lrint(longitude * 1000000);
- ds->latitude.udeg = lrint(latitude * 1000000);
+ ds->location = create_location(latitude, longitude);
}
}
hp = hp->next;
diff --git a/core/units.h b/core/units.h
index 6e9fe50d9..0e2c2b2e3 100644
--- a/core/units.h
+++ b/core/units.h
@@ -134,6 +134,29 @@ typedef struct
int udeg;
} degrees_t;
+typedef struct pos {
+ degrees_t lat, lon;
+} location_t;
+
+static inline bool has_location(const location_t *loc)
+{
+ return loc->lat.udeg || loc->lon.udeg;
+}
+
+static inline bool same_location(const location_t *a, const location_t *b)
+{
+ return (a->lat.udeg == b->lat.udeg) && (a->lon.udeg == b->lon.udeg);
+}
+
+static inline location_t create_location(double lat, double lon)
+{
+ location_t location = {
+ { (int) lrint(lat * 1000000) },
+ { (int) lrint(lon * 1000000) }
+ };
+ return location;
+}
+
static inline double udeg_to_radians(int udeg)
{
return (udeg * M_PI) / (1000000.0 * 180.0);
diff --git a/core/worldmap-save.c b/core/worldmap-save.c
index cbc232bc3..c12d27de2 100644
--- a/core/worldmap-save.c
+++ b/core/worldmap-save.c
@@ -35,8 +35,8 @@ void writeMarkers(struct membuffer *b, const bool selected_only)
struct dive_site *ds = get_dive_site_for_dive(dive);
if (!ds || !dive_site_has_gps_location(ds))
continue;
- put_degrees(b, ds->latitude, "temp = new google.maps.Marker({position: new google.maps.LatLng(", "");
- put_degrees(b, ds->longitude, ",", ")});\n");
+ put_degrees(b, ds->location.lat, "temp = new google.maps.Marker({position: new google.maps.LatLng(", "");
+ put_degrees(b, ds->location.lon, ",", ")});\n");
put_string(b, "markers.push(temp);\ntempinfowindow = new google.maps.InfoWindow({content: '<div id=\"content\">'+'<div id=\"siteNotice\">'+'</div>'+'<div id=\"bodyContent\">");
snprintf(pre, sizeof(pre), "<p>%s ", translate("gettextFromC", "Date:"));
put_HTML_date(b, dive, pre, "</p>");