[gnome-clocks/wip/geoclue] Add geoclue support



commit 564220ee32abd16c303fbd8d2d69feddfbbe0260
Author: Evgeny Bobkin <evgen ibqn gmail com>
Date:   Mon Aug 26 17:35:02 2013 +0200

    Add geoclue support

 src/geoclue.vala |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 144 insertions(+), 0 deletions(-)
---
diff --git a/src/geoclue.vala b/src/geoclue.vala
new file mode 100644
index 0000000..a115358
--- /dev/null
+++ b/src/geoclue.vala
@@ -0,0 +1,144 @@
+namespace Clocks {
+
+namespace GClue {
+
+[DBus (name = "org.freedesktop.GeoClue2.Manager")]
+private interface Manager : Object {
+    public abstract async void get_client (out string client_path) throws IOError;
+}
+
+[DBus (name = "org.freedesktop.GeoClue2.Client")]
+private interface Client : Object {
+    public abstract string location { owned get; }
+    public abstract uint distance_threshold { get; set; }
+    public abstract async void start () throws IOError;
+    public abstract async void stop () throws IOError;
+    public signal void location_updated (string old_path, string new_path);
+}
+
+[DBus (name = "org.freedesktop.GeoClue2.Location")]
+public interface Location : Object {
+    public abstract double latitude { get; }
+    public abstract double longitude { get; }
+    public abstract double accuracy { get; }
+    public abstract string description { owned get; }
+}
+
+public class GeoInfo : Object {
+    public signal void location_changed (GClue.Location location);
+    public GClue.Location? location { get; private set; default = null; }
+    
+    public GeoInfo () {
+    }
+    
+    public async void seek () {
+        GClue.Manager manager;
+        GClue.Client client;
+
+        string? client_path = null;
+
+        try {
+            manager = yield Bus.get_proxy (GLib.BusType.SYSTEM,
+                                           "org.freedesktop.GeoClue2",
+                                           "/org/freedesktop/GeoClue2/Manager");
+        } catch (IOError e) {
+            error ("Failed to connect to GeoClue2 Manager service: %s", e.message); 
+        }
+
+        try {
+            yield manager.get_client (out client_path);
+        } catch (IOError e) {
+            error ("Failed to connect to GeoClue2 Manager service: %s", e.message); 
+        }
+
+        if (client_path == null) {
+            error ("The client path is not set");
+        }
+
+        try {
+            client = yield Bus.get_proxy (GLib.BusType.SYSTEM,
+                                          "org.freedesktop.GeoClue2",
+                                          client_path);
+        } catch (IOError e) {
+            error ("Failed to connect to GeoClue2 Client service: %s", e.message); 
+        }
+
+        client.location_updated.connect (on_location_updated);
+
+        try {               
+            yield client.start ();
+        } catch (IOError e) {
+            error ("Failed to start client: %s", e.message);
+        }
+    } 
+
+    public async void on_location_updated (string old_path, string new_path) {
+        GClue.Location location;
+        try {
+            location = yield Bus.get_proxy (GLib.BusType.SYSTEM,
+                                            "org.freedesktop.GeoClue2",
+                                            new_path);
+        } catch (Error e) {
+            error ("Failed to connect to GeoClue2 Location service: %s", e.message); 
+        }
+
+        this.location = location;
+        location_changed (location);
+    }
+}
+
+} // GClue
+
+namespace Utils {
+private double deg_to_rad (double deg) {
+    return Math.PI / 180.0d * deg;
+}
+
+private double get_distance (double latitude1, double longitude1, double latitude2, double longitude2) {
+    const double radius = 6372.795;
+
+    double lat1 = deg_to_rad (latitude1);
+    double lat2 = deg_to_rad (latitude2);
+    double lon1 = deg_to_rad (longitude1);
+    double lon2 = deg_to_rad (longitude2);
+
+    return Math.acos (Math.cos (lat1) * Math.cos (lat2) * Math.cos (lon1 - lon2) + Math.sin (lat1) * 
Math.sin (lat2)) * radius;
+}
+
+private void search_locations_helper (double lat, double lon, GWeather.Location location, ref double 
minimal_distance,  ref GWeather.Location? found_location) {
+    GWeather.Location? [] locations = location.get_children ();
+
+    if (locations != null) {
+        for (int i = 0; i < locations.length; i++) {
+            if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
+                if (locations[i].has_coords ()) {
+                    double latitude, longitude, distance;
+
+                    locations[i].get_coords (out latitude, out longitude);
+                    distance = get_distance (lat, lon, latitude, longitude);
+
+                    if (distance < minimal_distance) {
+                        found_location = locations[i];
+                        minimal_distance = distance;
+                    }
+                }
+            }
+
+            search_locations_helper (lat, lon, locations[i], ref minimal_distance, ref found_location);
+        }
+    }
+}
+
+public GWeather.Location? search_locations (double lat, double lon) {
+    GWeather.Location locations = new GWeather.Location.world (true);
+    GWeather.Location? found_location = null;
+    double minimal_distance = 1000.0d;
+
+    search_locations_helper (lat, lon, locations, ref minimal_distance, ref found_location);
+
+    return found_location;
+}
+
+} // Utils
+
+} // Clocks


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