diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-20 14:12:15 -0400 |
---|---|---|
committer | Lubomir I. Ivanov <neolit123@gmail.com> | 2018-10-21 19:55:09 +0300 |
commit | 28e3413ff66552f392fecee25068d634cdfe59fc (patch) | |
tree | 5fe303d1e7dc1c371e13b534b85c232e29aea884 /core | |
parent | c9869406301ff72f76b399097f0845fc1102ced1 (diff) | |
download | subsurface-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.c | 12 | ||||
-rw-r--r-- | core/dive.h | 3 | ||||
-rw-r--r-- | core/divesite.c | 38 | ||||
-rw-r--r-- | core/divesite.h | 12 | ||||
-rw-r--r-- | core/gpslocation.cpp | 31 | ||||
-rw-r--r-- | core/gpslocation.h | 3 | ||||
-rw-r--r-- | core/libdivecomputer.c | 12 | ||||
-rw-r--r-- | core/load-git.c | 26 | ||||
-rw-r--r-- | core/membuffer.c | 8 | ||||
-rw-r--r-- | core/membuffer.h | 1 | ||||
-rw-r--r-- | core/metadata.cpp | 7 | ||||
-rw-r--r-- | core/metadata.h | 3 | ||||
-rw-r--r-- | core/parse-xml.c | 70 | ||||
-rw-r--r-- | core/parse.c | 16 | ||||
-rw-r--r-- | core/parse.h | 2 | ||||
-rw-r--r-- | core/qthelper.cpp | 22 | ||||
-rw-r--r-- | core/qthelper.h | 2 | ||||
-rw-r--r-- | core/save-git.c | 12 | ||||
-rw-r--r-- | core/save-html.c | 4 | ||||
-rw-r--r-- | core/save-xml.c | 10 | ||||
-rw-r--r-- | core/subsurface-qt/DiveObjectHelper.cpp | 2 | ||||
-rw-r--r-- | core/uemis.c | 3 | ||||
-rw-r--r-- | core/units.h | 23 | ||||
-rw-r--r-- | core/worldmap-save.c | 4 |
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(>.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 >) } 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 >) 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 >) 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>"); |