[libgweather/wip/hadess/met-no-migration: 3/6] gweather: Only use 4 significant decimals for locations




commit e29f8a406176f8d12f321310f7b3240647254456
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Jan 7 12:46:34 2021 +0100

    gweather: Only use 4 significant decimals for locations
    
    1/1000th of a degree of longitude or latitude corresponds to around
    100 meters. There's no reason for the weather to be any more precise
    than this.
    
    See https://www.thoughtco.com/degree-of-latitude-and-longitude-distance-4070616
    
    Closes: #69

 libgweather/gweather-private.c | 16 ++++++++++++++++
 libgweather/gweather-private.h |  3 +++
 libgweather/test_libgweather.c | 15 +++++++++++++++
 libgweather/weather-iwin.c     |  7 ++++---
 libgweather/weather-metno.c    |  7 ++++---
 libgweather/weather-owm.c      |  7 ++++---
 6 files changed, 46 insertions(+), 9 deletions(-)
---
diff --git a/libgweather/gweather-private.c b/libgweather/gweather-private.c
index daa6468b..0a4e0cd0 100644
--- a/libgweather/gweather-private.c
+++ b/libgweather/gweather-private.c
@@ -22,3 +22,19 @@
 
 #include "gweather-private.h"
 
+/* sign, 3 digits, separator, 4 decimals, nul-char */
+#define DEGREES_STR_SIZE (1 + 3 + 1 + 4 + 1)
+
+char *
+_radians_to_degrees_str (gdouble radians)
+{
+  char *str;
+  double degrees;
+
+  str = g_malloc0 (DEGREES_STR_SIZE);
+  /* Max 4 decimals */
+  degrees = (double) ((int) (RADIANS_TO_DEGREES (radians) * 10000)) / 10000;
+  /* Too many digits */
+  g_return_val_if_fail (degrees <= 1000 || degrees >= -1000, NULL);
+  return g_ascii_formatd (str, G_ASCII_DTOSTR_BUF_SIZE, "%g", degrees);
+}
diff --git a/libgweather/gweather-private.h b/libgweather/gweather-private.h
index cdb586b6..5dbbdca6 100644
--- a/libgweather/gweather-private.h
+++ b/libgweather/gweather-private.h
@@ -194,6 +194,9 @@ struct _GWeatherInfoPrivate {
 #define RADIANS_TO_DEGREES(rad)                ((rad) * 180. / M_PI)
 #define RADIANS_TO_HOURS(rad)          ((rad) * 12. / M_PI)
 
+GWEATHER_EXTERN
+char           *_radians_to_degrees_str (gdouble radians);
+
 /*
  * Planetary Mean Orbit and their progressions from J2000 are based on the
  * values in http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf
diff --git a/libgweather/test_libgweather.c b/libgweather/test_libgweather.c
index 3d9ad67d..af6d5fca 100644
--- a/libgweather/test_libgweather.c
+++ b/libgweather/test_libgweather.c
@@ -849,6 +849,20 @@ test_walk_world (void)
     _gweather_location_reset_world ();
 }
 
+static void
+test_radians_to_degrees_str (void)
+{
+    char long_version[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *short_version = NULL;
+    double coord = 1.260765526077;
+
+    g_ascii_dtostr (long_version, G_ASCII_DTOSTR_BUF_SIZE, RADIANS_TO_DEGREES (coord));
+    short_version = _radians_to_degrees_str (coord);
+
+    g_assert_cmpint (strlen (long_version), >, strlen (short_version));
+    g_assert_cmpstr (short_version, ==, "72.2365");
+}
+
 static void
 log_handler (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer user_data)
 {
@@ -871,6 +885,7 @@ main (int argc, char *argv[])
                  FALSE);
        set_gsettings ();
 
+       g_test_add_func ("/weather/radians-to-degrees_str", test_radians_to_degrees_str);
        g_test_add_func ("/weather/named-timezones", test_named_timezones);
        g_test_add_func ("/weather/named-timezones-deserialized", test_named_timezones_deserialized);
        g_test_add_func ("/weather/no-code-serialize", test_no_code_serialize);
diff --git a/libgweather/weather-iwin.c b/libgweather/weather-iwin.c
index e19ba506..f6c7f2cb 100644
--- a/libgweather/weather-iwin.c
+++ b/libgweather/weather-iwin.c
@@ -353,7 +353,8 @@ iwin_start_open (GWeatherInfo *info)
     SoupMessage *msg;
     struct tm tm;
     time_t now;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     g_assert (info != NULL);
 
@@ -376,8 +377,8 @@ iwin_start_open (GWeatherInfo *info)
     now = time (NULL);
     localtime_r (&now, &tm);
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
     url = g_strdup_printf 
("https://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?&lat=%s&lon=%s&format=24+hourly&startDate=%04d-%02d-%02d&numDays=7";,
                           latstr, lonstr, 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
     g_debug ("iwin_start_open, requesting: %s", url);
diff --git a/libgweather/weather-metno.c b/libgweather/weather-metno.c
index 1b41c37a..81b14463 100644
--- a/libgweather/weather-metno.c
+++ b/libgweather/weather-metno.c
@@ -435,7 +435,8 @@ metno_start_open (GWeatherInfo *info)
     gchar *url;
     SoupMessage *message;
     WeatherLocation *loc;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     priv = info->priv;
     loc = &priv->location;
@@ -445,8 +446,8 @@ metno_start_open (GWeatherInfo *info)
 
     /* see the description here: https://api.met.no/ */
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
 
     url = g_strdup_printf("https://api.met.no/weatherapi/locationforecast/1.9/?lat=%s;lon=%s";, latstr, 
lonstr);
     g_debug ("metno_start_open, requesting: %s", url);
diff --git a/libgweather/weather-owm.c b/libgweather/weather-owm.c
index b8447f8e..a537a21d 100644
--- a/libgweather/weather-owm.c
+++ b/libgweather/weather-owm.c
@@ -444,7 +444,8 @@ owm_start_open (GWeatherInfo *info)
     gchar *url;
     SoupMessage *message;
     WeatherLocation *loc;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     priv = info->priv;
     loc = &priv->location;
@@ -454,8 +455,8 @@ owm_start_open (GWeatherInfo *info)
 
     /* see the description here: http://bugs.openweathermap.org/projects/api/wiki/Api_2_5_forecast */
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
 
 #define TEMPLATE_START "https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&mode=xml&units=metric";
 #ifdef OWM_APIKEY


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]