mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Avoid using float when dealing with GPS location
Float values have insufficient precision compared to the udeg we usually store - so we create a special callback function to use from osm-gps-map and everywhere else use integers. This patch also increases the decimal places displayed in the GPS text entry box - this way we can cut and paste the text without loss of precision. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
b12b2f1c85
commit
51f97a97ce
1 changed files with 21 additions and 15 deletions
36
info.c
36
info.c
|
@ -639,31 +639,32 @@ struct location_update {
|
||||||
void (*callback)(float, float);
|
void (*callback)(float, float);
|
||||||
} location_update;
|
} location_update;
|
||||||
|
|
||||||
static void print_gps_coordinates(char *buffer, int len, float lat, float lon)
|
/* take latitude and longitude in udeg and print them in a human readable
|
||||||
|
* form, without losing precision */
|
||||||
|
static void print_gps_coordinates(char *buffer, int len, int lat, int lon)
|
||||||
{
|
{
|
||||||
unsigned int latdeg, londeg;
|
unsigned int latdeg, londeg;
|
||||||
float latmin, lonmin;
|
double latmin, lonmin;
|
||||||
char *lath, *lonh;
|
char *lath, *lonh;
|
||||||
|
|
||||||
if (!lat && !lon) {
|
if (!lat && !lon) {
|
||||||
*buffer = 0;
|
*buffer = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
lath = lat >= 0 ? _("N") : _("S");
|
||||||
lath = lat >= 0.0 ? _("N") : _("S");
|
lonh = lon >= 0 ? _("E") : _("W");
|
||||||
lonh = lon >= 0.0 ? _("E") : _("W");
|
lat = abs(lat);
|
||||||
lat = fabs(lat);
|
lon = abs(lon);
|
||||||
lon = fabs(lon);
|
latdeg = lat / 1000000;
|
||||||
latdeg = lat;
|
londeg = lon / 1000000;
|
||||||
londeg = lon;
|
latmin = (lat % 1000000) * 60.0 / 1000000.0;
|
||||||
latmin = (lat - latdeg) * 60.0;
|
lonmin = (lon % 1000000) * 60.0 / 1000000.0;
|
||||||
lonmin = (lon - londeg) * 60.0;
|
|
||||||
snprintf(buffer, len, "%s%u%s %8.5f\' , %s%u%s %8.5f\'",
|
snprintf(buffer, len, "%s%u%s %8.5f\' , %s%u%s %8.5f\'",
|
||||||
lath, latdeg, UTF8_DEGREE, latmin,
|
lath, latdeg, UTF8_DEGREE, latmin,
|
||||||
lonh, londeg, UTF8_DEGREE, lonmin);
|
lonh, londeg, UTF8_DEGREE, lonmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_gps_entry(float lat, float lon)
|
static void update_gps_entry(int lat, int lon)
|
||||||
{
|
{
|
||||||
if (location_update.entry) {
|
if (location_update.entry) {
|
||||||
print_gps_coordinates(location_update.text, 45, lat, lon);
|
print_gps_coordinates(location_update.text, 45, lat, lon);
|
||||||
|
@ -671,6 +672,11 @@ static void update_gps_entry(float lat, float lon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_gps_entry_callback(float lat, float lon)
|
||||||
|
{
|
||||||
|
update_gps_entry(lat * 1000000, lon * 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_OSM_GPS_MAP
|
#if HAVE_OSM_GPS_MAP
|
||||||
static gboolean gps_map_callback(GtkWidget *w, gpointer data)
|
static gboolean gps_map_callback(GtkWidget *w, gpointer data)
|
||||||
{
|
{
|
||||||
|
@ -680,7 +686,7 @@ static gboolean gps_map_callback(GtkWidget *w, gpointer data)
|
||||||
gps_text = gtk_entry_get_text(location_update.entry);
|
gps_text = gtk_entry_get_text(location_update.entry);
|
||||||
(void)gps_changed(dive, NULL, gps_text);
|
(void)gps_changed(dive, NULL, gps_text);
|
||||||
}
|
}
|
||||||
show_gps_location(dive, update_gps_entry);
|
show_gps_location(dive, update_gps_entry_callback);
|
||||||
location_update.set_by_hand = 1;
|
location_update.set_by_hand = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -740,7 +746,7 @@ static void location_entry_change_cb(GtkComboBox *location, gpointer *userdata)
|
||||||
continue;
|
continue;
|
||||||
if (!dive->location || strcasecmp(dive->location, name))
|
if (!dive->location || strcasecmp(dive->location, name))
|
||||||
continue;
|
continue;
|
||||||
update_gps_entry(dive->latitude.udeg / 1000000.0, dive->longitude.udeg / 1000000.0);
|
update_gps_entry(dive->latitude.udeg, dive->longitude.udeg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
update_gps_entry(0, 0);
|
update_gps_entry(0, 0);
|
||||||
|
@ -770,7 +776,7 @@ static void dive_info_widget(GtkWidget *box, struct dive *dive, struct dive_info
|
||||||
|
|
||||||
location_update.entry = info->gps;
|
location_update.entry = info->gps;
|
||||||
location_update.dive = dive;
|
location_update.dive = dive;
|
||||||
update_gps_entry(dive->latitude.udeg / 1000000.0, dive->longitude.udeg / 1000000.0);
|
update_gps_entry(dive->latitude.udeg, dive->longitude.udeg);
|
||||||
location_update.set_by_hand = !!location_update.text[0];
|
location_update.set_by_hand = !!location_update.text[0];
|
||||||
|
|
||||||
gtk_widget_add_events(GTK_WIDGET(info->gps), GDK_FOCUS_CHANGE_MASK);
|
gtk_widget_add_events(GTK_WIDGET(info->gps), GDK_FOCUS_CHANGE_MASK);
|
||||||
|
|
Loading…
Add table
Reference in a new issue