[libgweather] location: Make sure cities always have a weather station



commit 6d2b55b6711ebe0beb8ab2698d9f7eb6c8ed044b
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Dec 11 11:43:10 2017 +0100

    location: Make sure cities always have a weather station
    
    Following from changes to the locations database, we have a number of
    "major cities" without airports attached. Once the database has been
    filled up from the XML data, look for the closest airport in the same
    state or country and attach it to the city.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=791402
    
    See commit d2c3ea2f994f14c5cf0b9a90bb74b61d9507e45b

 libgweather/gweather-location.c |   53 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)
---
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index e5e28dc..34353e7 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -139,6 +139,58 @@ location_new (GWeatherLocationLevel level)
     return loc;
 }
 
+static void
+add_nearest_weather_station (GWeatherLocation *location)
+{
+    GWeatherLocation **siblings;
+    GWeatherLocation *closest = NULL;
+    double min_distance = G_MAXDOUBLE;
+    guint i;
+
+    g_assert (location->parent);
+    g_assert (gweather_location_get_level (location) == GWEATHER_LOCATION_CITY);
+
+    if (location->children != NULL)
+        return;
+
+    siblings = location->parent->children;
+    for (i = 0; siblings[i] != NULL; i++) {
+        double distance;
+
+        if (siblings[i] == location)
+            continue;
+
+        distance = gweather_location_get_distance (location, siblings[i]);
+        if (distance < min_distance)
+            closest = siblings[i];
+    }
+
+    if (!closest) {
+        g_critical ("Location '%s' has no valid airports attached", location->english_name);
+        return;
+    }
+
+    location->children = g_new0 (GWeatherLocation *, 2);
+    location->children[0] = g_memdup (closest, sizeof(GWeatherLocation));
+}
+
+static void
+add_nearest_weather_stations (GWeatherLocation *location)
+{
+    GWeatherLocation **children;
+    guint i;
+
+    /* For each city without a <location>, add the nearest airport in the
+     * same country or state to it */
+    children = gweather_location_get_children (location);
+    for (i = 0; children[i] != NULL; i++) {
+        if (gweather_location_get_level (children[i]) == GWEATHER_LOCATION_CITY)
+            add_nearest_weather_station (children[i]);
+        else
+            add_nearest_weather_stations (children[i]);
+    }
+}
+
 static GWeatherLocation *
 location_new_from_xml (GWeatherParser *parser, GWeatherLocationLevel level,
                       GWeatherLocation *parent)
@@ -359,6 +411,7 @@ gweather_location_get_world (void)
            return NULL;
 
        global_world = location_new_from_xml (parser, GWEATHER_LOCATION_WORLD, NULL);
+       add_nearest_weather_stations (global_world);
        _gweather_parser_free (parser);
     }
 


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