mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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:
parent
2de6f69c19
commit
7d7766be9a
9 changed files with 30 additions and 30 deletions
|
@ -50,32 +50,14 @@ dive_site *dive_site_table::get_by_gps_and_name(const std::string &name, const l
|
||||||
ds->name == name; });
|
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 */
|
/* 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;
|
struct dive_site *res = nullptr;
|
||||||
unsigned int cur_distance, min_distance = distance;
|
unsigned int cur_distance, min_distance = distance;
|
||||||
for (const auto &ds: *this) {
|
for (const auto &ds: *this) {
|
||||||
if (dive_site_has_gps_location(ds.get()) &&
|
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;
|
min_distance = cur_distance;
|
||||||
res = ds.get();
|
res = ds.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,11 +51,10 @@ public:
|
||||||
dive_site *get_by_name(const std::string &name) const;
|
dive_site *get_by_name(const std::string &name) const;
|
||||||
dive_site *get_by_gps(const location_t *) 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_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();
|
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 *unregister_dive_from_dive_site(struct dive *d);
|
||||||
struct dive_site *get_same_dive_site(const struct dive_site &); // accesses global dive list
|
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);
|
std::string constructLocationTags(const taxonomy_data &taxonomy, bool for_maintab);
|
||||||
|
|
|
@ -1197,7 +1197,7 @@ static void gps_in_dive(const char *buffer, struct dive *dive, struct parser_sta
|
||||||
parse_location(buffer, &location);
|
parse_location(buffer, &location);
|
||||||
if (!ds) {
|
if (!ds) {
|
||||||
// check if we have a dive site within 20 meters of that gps fix
|
// 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) {
|
if (ds) {
|
||||||
// found a site nearby; in case it turns out this one had a different name let's
|
// found a site nearby; in case it turns out this one had a different name let's
|
||||||
|
|
|
@ -180,3 +180,22 @@ const struct units *get_units()
|
||||||
{
|
{
|
||||||
return &prefs.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ typedef struct pos {
|
||||||
} location_t;
|
} location_t;
|
||||||
|
|
||||||
extern void parse_location(const char *, 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)
|
static inline bool has_location(const location_t *loc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -390,7 +390,7 @@ bool DiveLocationFilterProxyModel::lessThan(const QModelIndex &source_left, cons
|
||||||
// The dive sites are -2 because of the first two items.
|
// The dive sites are -2 because of the first two items.
|
||||||
auto loc1 = (*divelog.sites)[source_left.row() - 2]->location;
|
auto loc1 = (*divelog.sites)[source_left.row() - 2]->location;
|
||||||
auto loc2 = (*divelog.sites)[source_right.row() - 2]->location;
|
auto loc2 = (*divelog.sites)[source_right.row() - 2]->location;
|
||||||
return get_distance(&loc1, ¤tLocation) < get_distance(&loc2, ¤tLocation);
|
return get_distance(loc1, currentLocation) < get_distance(loc2, currentLocation);
|
||||||
}
|
}
|
||||||
return source_left.data().toString().compare(source_right.data().toString(), Qt::CaseInsensitive) < 0;
|
return source_left.data().toString().compare(source_right.data().toString(), Qt::CaseInsensitive) < 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,7 +478,7 @@ void LocationFilterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||||
if (ds->location == currentLocation) {
|
if (ds->location == currentLocation) {
|
||||||
bottomText += tr(" (same GPS fix)");
|
bottomText += tr(" (same GPS fix)");
|
||||||
} else {
|
} else {
|
||||||
int distanceMeters = get_distance(&ds->location, ¤tLocation);
|
int distanceMeters = get_distance(ds->location, currentLocation);
|
||||||
QString distance = distance_string(distanceMeters);
|
QString distance = distance_string(distanceMeters);
|
||||||
size_t nr = ds->nr_of_dives();
|
size_t nr = ds->nr_of_dives();
|
||||||
bottomText += tr(" (~%1 away").arg(distance);
|
bottomText += tr(" (~%1 away").arg(distance);
|
||||||
|
|
|
@ -298,7 +298,7 @@ bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIn
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return distance <= 0 ? ds->location == location
|
return distance <= 0 ? ds->location == location
|
||||||
: (int64_t)get_distance(&ds->location, &location) * 1000 <= distance; // We need 64 bit to represent distances in mm
|
: (int64_t)get_distance(ds->location, location) * 1000 <= distance; // We need 64 bit to represent distances in mm
|
||||||
}
|
}
|
||||||
|
|
||||||
GPSLocationInformationModel::GPSLocationInformationModel(QObject *parent) : QSortFilterProxyModel(parent),
|
GPSLocationInformationModel::GPSLocationInformationModel(QObject *parent) : QSortFilterProxyModel(parent),
|
||||||
|
|
|
@ -67,7 +67,7 @@ QVariant DivesiteImportedModel::data(const QModelIndex &index, int role) const
|
||||||
case NEAREST: {
|
case NEAREST: {
|
||||||
// 40075000 is circumference of the earth in meters
|
// 40075000 is circumference of the earth in meters
|
||||||
struct dive_site *nearest_ds =
|
struct dive_site *nearest_ds =
|
||||||
divelog.sites->get_by_gps_proximity(&ds->location, 40075000);
|
divelog.sites->get_by_gps_proximity(ds->location, 40075000);
|
||||||
if (nearest_ds)
|
if (nearest_ds)
|
||||||
return QString::fromStdString(nearest_ds->name);
|
return QString::fromStdString(nearest_ds->name);
|
||||||
else
|
else
|
||||||
|
@ -76,10 +76,9 @@ QVariant DivesiteImportedModel::data(const QModelIndex &index, int role) const
|
||||||
case DISTANCE: {
|
case DISTANCE: {
|
||||||
unsigned int distance = 0;
|
unsigned int distance = 0;
|
||||||
struct dive_site *nearest_ds =
|
struct dive_site *nearest_ds =
|
||||||
divelog.sites->get_by_gps_proximity(&ds->location, 40075000);
|
divelog.sites->get_by_gps_proximity(ds->location, 40075000);
|
||||||
if (nearest_ds)
|
if (nearest_ds)
|
||||||
distance = get_distance(&ds->location,
|
distance = get_distance(ds->location, nearest_ds->location);
|
||||||
&nearest_ds->location);
|
|
||||||
return distance_string(distance);
|
return distance_string(distance);
|
||||||
}
|
}
|
||||||
case SELECTED:
|
case SELECTED:
|
||||||
|
|
Loading…
Add table
Reference in a new issue