core: move get_distance() from divesite.cpp to units.cpp

This gives the distance between to location_t objects. It is
unclear why this was in divesite.cpp.

Moreover pass by value, not raw pointer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-11 15:18:37 +02:00 committed by bstoeger
parent 2de6f69c19
commit 7d7766be9a
9 changed files with 30 additions and 30 deletions

View file

@ -50,32 +50,14 @@ dive_site *dive_site_table::get_by_gps_and_name(const std::string &name, const l
ds->name == name; });
}
// Calculate the distance in meters between two coordinates.
unsigned int get_distance(const location_t *loc1, const location_t *loc2)
{
double lat1_r = udeg_to_radians(loc1->lat.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(lat1_r) * cos(lat2_r) * sin(lon_d_r/2) * sin(lon_d_r/2);
if (a < 0.0) a = 0.0;
if (a > 1.0) a = 1.0;
double c = 2 * atan2(sqrt(a), sqrt(1.0 - a));
// Earth radius in metres
return lrint(6371000 * c);
}
/* find the closest one, no more than distance meters away - if more than one at same distance, pick the first */
dive_site *dive_site_table::get_by_gps_proximity(const location_t *loc, int distance) const
dive_site *dive_site_table::get_by_gps_proximity(location_t loc, int distance) const
{
struct dive_site *res = nullptr;
unsigned int cur_distance, min_distance = distance;
for (const auto &ds: *this) {
if (dive_site_has_gps_location(ds.get()) &&
(cur_distance = get_distance(&ds->location, loc)) < min_distance) {
(cur_distance = get_distance(ds->location, loc)) < min_distance) {
min_distance = cur_distance;
res = ds.get();
}

View file

@ -51,11 +51,10 @@ public:
dive_site *get_by_name(const std::string &name) const;
dive_site *get_by_gps(const location_t *) const;
dive_site *get_by_gps_and_name(const std::string &name, const location_t *) const;
dive_site *get_by_gps_proximity(const location_t *, int distance) const;
dive_site *get_by_gps_proximity(location_t, int distance) const;
void purge_empty();
};
unsigned int get_distance(const location_t *loc1, const location_t *loc2);
struct dive_site *unregister_dive_from_dive_site(struct dive *d);
struct dive_site *get_same_dive_site(const struct dive_site &); // accesses global dive list
std::string constructLocationTags(const taxonomy_data &taxonomy, bool for_maintab);

View file

@ -1197,7 +1197,7 @@ static void gps_in_dive(const char *buffer, struct dive *dive, struct parser_sta
parse_location(buffer, &location);
if (!ds) {
// check if we have a dive site within 20 meters of that gps fix
ds = state->log->sites->get_by_gps_proximity(&location, 20);
ds = state->log->sites->get_by_gps_proximity(location, 20);
if (ds) {
// found a site nearby; in case it turns out this one had a different name let's

View file

@ -180,3 +180,22 @@ const struct units *get_units()
{
return &prefs.units;
}
// Calculate the distance in meters between two coordinates.
unsigned int get_distance(location_t loc1, location_t loc2)
{
double lat1_r = udeg_to_radians(loc1.lat.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(lat1_r) * cos(lat2_r) * sin(lon_d_r/2) * sin(lon_d_r/2);
if (a < 0.0) a = 0.0;
if (a > 1.0) a = 1.0;
double c = 2 * atan2(sqrt(a), sqrt(1.0 - a));
// Earth radius in metres
return lrint(6371000 * c);
}

View file

@ -132,6 +132,7 @@ typedef struct pos {
} location_t;
extern void parse_location(const char *, location_t *);
extern unsigned int get_distance(location_t loc1, location_t loc2);
static inline bool has_location(const location_t *loc)
{