[gnome-clocks/wip/geolocation: 40/40] Port geolocation support to geoclue and geocode-glib
- From: Evgeny Bobkin <ebobkin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-clocks/wip/geolocation: 40/40] Port geolocation support to geoclue and geocode-glib
- Date: Fri, 6 Sep 2013 11:18:15 +0000 (UTC)
commit b644d9eb5e46574675f14ec7883edad63d384ad8
Author: Evgeny Bobkin <evgen ibqn gmail com>
Date: Fri Sep 6 13:13:03 2013 +0200
Port geolocation support to geoclue and geocode-glib
Makefile.am | 8 +-
configure.ac | 3 +-
src/geoclue.vala | 176 ++++++++++++++++++++++++++++++++++
src/geocode-glib-1.0.vapi | 214 ++++++++++++++++++++++++++++++++++++++++++
src/geolocation-info.vala | 61 ------------
src/geolocation-monitor.vala | 151 -----------------------------
src/geolocation-utils.vala | 61 ------------
src/world.vala | 48 +++++-----
8 files changed, 415 insertions(+), 307 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index de228bb..255a8c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -94,9 +94,6 @@ AM_VALAFLAGS = \
--pkg libcanberra \
--pkg libnotify \
--pkg gio-2.0 \
- --pkg libsoup-2.4 \
- --pkg json-glib-1.0 \
- --thread \
--gresources $(top_srcdir)/data/gnome-clocks.gresource.xml
bin_PROGRAMS = gnome-clocks
@@ -118,9 +115,7 @@ VALA_SOURCES = \
src/timer.vala \
src/utils.vala \
src/widgets.vala \
- src/geolocation-monitor.vala \
- src/geolocation-info.vala \
- src/geolocation-utils.vala \
+ src/geoclue.vala \
src/main.vala
gnome_clocks_SOURCES = \
@@ -128,6 +123,7 @@ gnome_clocks_SOURCES = \
$(VALA_SOURCES) \
src/cutils.c \
src/gnome-desktop-3.0.vapi \
+ src/geocode-glib-1.0.vapi \
src/config.vapi
AM_CFLAGS = \
diff --git a/configure.ac b/configure.ac
index aedd1e1..9fc5557 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,8 +56,7 @@ PKG_CHECK_MODULES(CLOCKS, [
gweather-3.0 >= 3.9.91
gnome-desktop-3.0 >= 3.7.90
libnotify >= 0.7.0
- libsoup-2.4 >= 2.43.90
- json-glib-1.0 >= 0.16.1
+ geocode-glib-1.0
])
AC_CONFIG_FILES([
diff --git a/src/geoclue.vala b/src/geoclue.vala
new file mode 100644
index 0000000..afb2769
--- /dev/null
+++ b/src/geoclue.vala
@@ -0,0 +1,176 @@
+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 (GWeather.Location location);
+ public GClue.Location? geo_location { get; private set; default = null; }
+ private string? country_code;
+
+ public GeoInfo () {
+ country_code = null;
+ }
+
+ 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) {
+ warning ("Failed to connect to GeoClue2 Manager service: %s", e.message);
+ return;
+ }
+
+ try {
+ yield manager.get_client (out client_path);
+ } catch (IOError e) {
+ warning ("Failed to connect to GeoClue2 Manager service: %s", e.message);
+ return;
+ }
+
+ if (client_path == null) {
+ warning ("The client path is not set");
+ return;
+ }
+
+ try {
+ client = yield Bus.get_proxy (GLib.BusType.SYSTEM,
+ "org.freedesktop.GeoClue2",
+ client_path);
+ } catch (IOError e) {
+ warning ("Failed to connect to GeoClue2 Client service: %s", e.message);
+ return;
+ }
+
+ client.location_updated.connect (on_location_updated);
+
+ try {
+ yield client.start ();
+ } catch (IOError e) {
+ warning ("Failed to start client: %s", e.message);
+ return;
+ }
+ }
+
+ 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 (IOError e) {
+ warning ("Failed to connect to GeoClue2 Location service: %s", e.message);
+ return;
+ }
+
+ this.geo_location = location;
+
+ yield seek_country_code ();
+
+ location_changed (search_locations ());
+ }
+
+ private async void seek_country_code () {
+ Geocode.Location location = new Geocode.Location (geo_location.latitude, geo_location.longitude);
+ Geocode.Reverse reverse = new Geocode.Reverse.for_location (location);
+
+ try {
+ Geocode.Place place = yield reverse.resolve_async ();
+
+ country_code = place.get_country_code ();
+
+ // Reverse geocoding returns country code which is not uppercased
+ country_code = country_code.up ();
+ } catch (IOError e) {
+ warning ("Failed to obtain country code: %s", e.message);
+ }
+ }
+
+ 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 (GWeather.Location location, ref double minimal_distance, ref
GWeather.Location? found_location) {
+ if (this.country_code != null) {
+ string? loc_country_code = location.get_country ();
+ if (loc_country_code != null) {
+ if (loc_country_code != this.country_code) {
+ return;
+ }
+ }
+ }
+
+ 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 (geo_location.latitude, geo_location.longitude, latitude,
longitude);
+
+ if (distance < minimal_distance) {
+ found_location = locations[i];
+ minimal_distance = distance;
+ }
+ }
+ }
+
+ search_locations_helper (locations[i], ref minimal_distance, ref found_location);
+ }
+ }
+ }
+
+ private GWeather.Location? search_locations () {
+ GWeather.Location locations = GWeather.Location.get_world ();
+ GWeather.Location? found_location = null;
+ double minimal_distance = 1000.0d;
+
+ search_locations_helper (locations, ref minimal_distance, ref found_location);
+
+ return found_location;
+ }
+}
+
+} // GClue
+
+} // Clocks
diff --git a/src/geocode-glib-1.0.vapi b/src/geocode-glib-1.0.vapi
new file mode 100644
index 0000000..54d029e
--- /dev/null
+++ b/src/geocode-glib-1.0.vapi
@@ -0,0 +1,214 @@
+/* geocode-glib-1.0.vapi generated by vapigen, AND modifyied by me!!! */
+
+[CCode (cprefix = "Geocode", gir_namespace = "GeocodeGlib", gir_version = "1.0", lower_case_cprefix =
"geocode__")]
+namespace Geocode {
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", type_id = "geocode_forward_get_type ()")]
+ public class Forward : GLib.Object {
+ [CCode (has_construct_function = false)]
+ protected Forward ();
+ [CCode (cname = "geocode_forward_new_for_params", has_construct_function = false)]
+ public Forward.for_params (GLib.HashTable<string,GLib.Value?> @params);
+ [CCode (cname = "geocode_forward_new_for_string", has_construct_function = false)]
+ public Forward.for_string (string str);
+ [CCode (cname = "geocode_forward_search")]
+ public GLib.List<weak Geocode.Place> search () throws GLib.IOError;
+ [CCode (cname = "geocode_forward_search_async")]
+ public async GLib.List<weak Geocode.Place> search_async (GLib.Cancellable? cancellable =
null) throws GLib.IOError;
+ [CCode (cname = "geocode_forward_set_answer_count")]
+ public void set_answer_count (uint count);
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", type_id = "geocode_location_get_type ()")]
+ public class Location : GLib.Object {
+ [CCode (cname = "geocode_location_new", has_construct_function = false)]
+ public Location (double latitude, double longitude, double accuracy =
Geocode.LOCATION_ACCURACY_UNKNOWN);
+ [CCode (cname = "geocode_location_get_accuracy")]
+ public double get_accuracy ();
+ [CCode (cname = "geocode_location_get_description")]
+ public unowned string get_description ();
+ [CCode (cname = "geocode_location_get_distance_from")]
+ public double get_distance_from (Geocode.Location locb);
+ [CCode (cname = "geocode_location_get_latitude")]
+ public double get_latitude ();
+ [CCode (cname = "geocode_location_get_longitude")]
+ public double get_longitude ();
+ [CCode (cname = "geocode_location_get_timestamp")]
+ public uint64 get_timestamp ();
+ [CCode (cname = "geocode_location_set_description")]
+ public void set_description (string description);
+ [CCode (cname = "geocode_location_new_with_description", has_construct_function = false)]
+ public Location.with_description (double latitude, double longitude, double accuracy, string
description);
+ [NoAccessorMethod]
+ public double accuracy { get; construct; }
+ [NoAccessorMethod]
+ public string description { owned get; set; }
+ [NoAccessorMethod]
+ public double latitude { get; construct; }
+ [NoAccessorMethod]
+ public double longitude { get; construct; }
+ [NoAccessorMethod]
+ public uint64 timestamp { get; }
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", type_id = "geocode_place_get_type ()")]
+ public class Place : GLib.Object {
+ [CCode (cname = "geocode_place_new", has_construct_function = false)]
+ public Place (string name, Geocode.PlaceType place_type);
+ [CCode (cname = "geocode_place_get_administrative_area")]
+ public unowned string get_administrative_area ();
+ [CCode (cname = "geocode_place_get_area")]
+ public unowned string get_area ();
+ [CCode (cname = "geocode_place_get_building")]
+ public unowned string get_building ();
+ [CCode (cname = "geocode_place_get_continent")]
+ public unowned string get_continent ();
+ [CCode (cname = "geocode_place_get_country")]
+ public unowned string get_country ();
+ [CCode (cname = "geocode_place_get_country_code")]
+ public unowned string get_country_code ();
+ [CCode (cname = "geocode_place_get_county")]
+ public unowned string get_county ();
+ [CCode (cname = "geocode_place_get_location")]
+ public unowned Geocode.Location get_location ();
+ [CCode (cname = "geocode_place_get_name")]
+ public unowned string get_name ();
+ [CCode (cname = "geocode_place_get_place_type")]
+ public Geocode.PlaceType get_place_type ();
+ [CCode (cname = "geocode_place_get_postal_code")]
+ public unowned string get_postal_code ();
+ [CCode (cname = "geocode_place_get_state")]
+ public unowned string get_state ();
+ [CCode (cname = "geocode_place_get_street")]
+ public unowned string get_street ();
+ [CCode (cname = "geocode_place_get_street_address")]
+ public unowned string get_street_address ();
+ [CCode (cname = "geocode_place_get_town")]
+ public unowned string get_town ();
+ [CCode (cname = "geocode_place_set_administrative_area")]
+ public void set_administrative_area (string admin_area);
+ [CCode (cname = "geocode_place_set_area")]
+ public void set_area (string area);
+ [CCode (cname = "geocode_place_set_building")]
+ public void set_building (string building);
+ [CCode (cname = "geocode_place_set_continent")]
+ public void set_continent (string continent);
+ [CCode (cname = "geocode_place_set_country")]
+ public void set_country (string country);
+ [CCode (cname = "geocode_place_set_country_code")]
+ public void set_country_code (string country_code);
+ [CCode (cname = "geocode_place_set_county")]
+ public void set_county (string county);
+ [CCode (cname = "geocode_place_set_location")]
+ public void set_location (Geocode.Location location);
+ [CCode (cname = "geocode_place_set_name")]
+ public void set_name (string name);
+ [CCode (cname = "geocode_place_set_postal_code")]
+ public void set_postal_code (string postal_code);
+ [CCode (cname = "geocode_place_set_state")]
+ public void set_state (string state);
+ [CCode (cname = "geocode_place_set_street")]
+ public void set_street (string street);
+ [CCode (cname = "geocode_place_set_street_address")]
+ public void set_street_address (string street_address);
+ [CCode (cname = "geocode_place_set_town")]
+ public void set_town (string town);
+ [CCode (cname = "geocode_place_new_with_location", has_construct_function = false)]
+ public Place.with_location (string name, Geocode.PlaceType place_type, Geocode.Location
location);
+ [NoAccessorMethod]
+ public string administrative_area { owned get; set; }
+ [NoAccessorMethod]
+ public string area { owned get; set; }
+ [NoAccessorMethod]
+ public string building { owned get; set; }
+ [NoAccessorMethod]
+ public string continent { owned get; set; }
+ [NoAccessorMethod]
+ public string country { owned get; set; }
+ [NoAccessorMethod]
+ public string country_code { owned get; set; }
+ [NoAccessorMethod]
+ public string county { owned get; set; }
+ [NoAccessorMethod]
+ public GLib.Icon icon { owned get; set; }
+ [NoAccessorMethod]
+ public Geocode.Location location { owned get; set; }
+ [NoAccessorMethod]
+ public string name { owned get; set; }
+ [NoAccessorMethod]
+ public Geocode.PlaceType place_type { get; construct; }
+ [NoAccessorMethod]
+ public string postal_code { owned get; set; }
+ [NoAccessorMethod]
+ public string state { owned get; set; }
+ [NoAccessorMethod]
+ public string street { owned get; set; }
+ [NoAccessorMethod]
+ public string street_address { owned get; set; }
+ [NoAccessorMethod]
+ public string town { owned get; set; }
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", type_id = "geocode_reverse_get_type ()")]
+ public class Reverse : GLib.Object {
+ [CCode (has_construct_function = false)]
+ protected Reverse ();
+ [CCode (cname = "geocode_reverse_new_for_location", has_construct_function = false)]
+ public Reverse.for_location (Geocode.Location location);
+ [CCode (cname = "geocode_reverse_resolve")]
+ public Geocode.Place resolve () throws GLib.Error;
+ [CCode (cname = "geocode_reverse_resolve_async")]
+ public async Geocode.Place resolve_async (GLib.Cancellable? cancellable = null) throws
GLib.IOError;
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cprefix = "GEOCODE_PLACE_TYPE_", type_id =
"geocode_place_type_get_type ()")]
+ public enum PlaceType {
+ UNKNOWN,
+ BUILDING,
+ STREET,
+ TOWN,
+ STATE,
+ COUNTY,
+ LOCAL_ADMINISTRATIVE_AREA,
+ POSTAL_CODE,
+ COUNTRY,
+ ISLAND,
+ AIRPORT,
+ RAILWAY_STATION,
+ BUS_STOP,
+ MOTORWAY,
+ DRAINAGE,
+ LAND_FEATURE,
+ MISCELLANEOUS,
+ SUPERNAME,
+ POINT_OF_INTEREST,
+ SUBURB,
+ COLLOQUIAL,
+ ZONE,
+ HISTORICAL_STATE,
+ HISTORICAL_COUNTY,
+ CONTINENT,
+ TIME_ZONE,
+ ESTATE,
+ HISTORICAL_TOWN,
+ OCEAN,
+ SEA
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cprefix = "GEOCODE_ERROR_")]
+ public errordomain Error {
+ PARSE,
+ NOT_SUPPORTED,
+ NO_MATCHES,
+ INVALID_ARGUMENTS,
+ INTERNAL_SERVER
+ }
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname = "GEOCODE_LOCATION_ACCURACY_CITY")]
+ public const int LOCATION_ACCURACY_CITY;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname =
"GEOCODE_LOCATION_ACCURACY_CONTINENT")]
+ public const int LOCATION_ACCURACY_CONTINENT;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname =
"GEOCODE_LOCATION_ACCURACY_COUNTRY")]
+ public const int LOCATION_ACCURACY_COUNTRY;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname = "GEOCODE_LOCATION_ACCURACY_REGION")]
+ public const int LOCATION_ACCURACY_REGION;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname = "GEOCODE_LOCATION_ACCURACY_STREET")]
+ public const int LOCATION_ACCURACY_STREET;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname =
"GEOCODE_LOCATION_ACCURACY_UNKNOWN")]
+ public const int LOCATION_ACCURACY_UNKNOWN;
+ [CCode (cheader_filename = "geocode-glib/geocode-glib.h", cname = "geocode_error_quark")]
+ public static GLib.Quark error_quark ();
+}
diff --git a/src/world.vala b/src/world.vala
index cb3d619..8f5674d 100644
--- a/src/world.vala
+++ b/src/world.vala
@@ -362,36 +362,32 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
}
private async void use_geolocation () {
- GeoInfo.LocationInfo? geo_location = null;
- GWeather.Location? found_location = null;
-
- GeoInfo.LocationMonitor monitor = new GeoInfo.LocationMonitor ();
-
- try {
- geo_location = yield monitor.search ();
-
- found_location = GeoInfo.Utils.search_locations (geo_location);
- } catch (IOError e) {
- warning ("obtaining geolocation: %s", e.message);
- }
-
- if (found_location != null) {
- bool not_included = true;
+ GClue.GeoInfo geo_info = new GClue.GeoInfo ();
+
+ geo_info.location_changed.connect ((found_location) => {
+ if (found_location != null) {
+ bool not_included = true;
+
+ stdout.printf ("name : %s\n", found_location.get_name());
+
+ foreach (Item i in locations) {
+ stdout.printf ("name : %s\n", i.location.get_name());
+ if (i.location == found_location) {
+ not_included = false;
+ }
+ }
- foreach (Item i in locations) {
- if (i.location == found_location) {
- not_included = false;
+ if (not_included) {
+ var item = new Item (found_location);
+
+ item.automatic = true;
+ locations.append (item);
+ content_view.add_first (item);
}
}
+ });
- if (not_included) {
- var item = new Item (found_location);
-
- item.automatic = true;
- locations.append (item);
- content_view.add_first (item);
- }
- }
+ yield geo_info.seek ();
}
public void activate_new () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]