From c073dfa79c445ca24b22607795b09c178dea8fe7 Mon Sep 17 00:00:00 2001 From: Apertis CI <devel@lists.apertis.org> Date: Sat, 10 Aug 2019 12:10:51 +0000 Subject: [PATCH] Import Upstream version 2.5.2 --- NEWS | 33 + data/meson.build | 10 +- data/org.freedesktop.GeoClue2.conf.in | 5 + demo/gclue-service-agent.c | 15 +- demo/meson.build | 10 +- demo/where-am-i.c | 2 +- libgeoclue/gclue-simple.c | 15 +- libgeoclue/meson.build | 9 +- meson.build | 26 +- po/POTFILES.in | 1 - public-api/meson.build | 4 +- src/fi.w1.wpa_supplicant1.xml | 6 + src/gclue-3g.c | 7 +- src/gclue-cdma.c | 8 +- src/gclue-client-info.c | 15 +- src/gclue-compass.c | 8 +- src/gclue-config.c | 42 +- src/gclue-location-source.c | 21 +- src/gclue-location.c | 412 +++++- src/gclue-location.h | 73 +- src/gclue-locator.c | 24 +- src/gclue-min-uint.c | 13 +- src/gclue-modem-gps.c | 7 +- src/gclue-modem-manager.c | 11 +- src/gclue-mozilla.c | 14 +- src/gclue-nmea-source.c | 7 +- src/gclue-service-client.c | 31 +- src/gclue-service-location.c | 35 +- src/gclue-service-manager.c | 244 +++- src/gclue-web-source.c | 65 +- src/gclue-wifi.c | 213 ++- src/geocode-glib/geocode-bounding-box.c | 339 ----- src/geocode-glib/geocode-bounding-box.h | 79 -- src/geocode-glib/geocode-enum-types.c | 120 -- src/geocode-glib/geocode-enum-types.h | 68 - src/geocode-glib/geocode-error.c | 49 - src/geocode-glib/geocode-error.h | 61 - src/geocode-glib/geocode-forward.c | 1195 ---------------- src/geocode-glib/geocode-forward.h | 93 -- src/geocode-glib/geocode-glib-private.h | 62 - src/geocode-glib/geocode-glib.c | 257 ---- src/geocode-glib/geocode-glib.h | 36 - src/geocode-glib/geocode-location.c | 956 ------------- src/geocode-glib/geocode-location.h | 169 --- src/geocode-glib/geocode-place.c | 1270 ------------------ src/geocode-glib/geocode-place.h | 241 ---- src/geocode-glib/geocode-reverse.c | 554 -------- src/geocode-glib/geocode-reverse.h | 82 -- src/geocode-glib/meson.build | 30 - src/geocode-glib/update-from-geocode-glib.sh | 26 - src/meson.build | 13 +- src/org.freedesktop.GeoClue2.Client.xml | 18 +- src/org.freedesktop.GeoClue2.Manager.xml | 41 +- 53 files changed, 1104 insertions(+), 6041 deletions(-) delete mode 100644 src/geocode-glib/geocode-bounding-box.c delete mode 100644 src/geocode-glib/geocode-bounding-box.h delete mode 100644 src/geocode-glib/geocode-enum-types.c delete mode 100644 src/geocode-glib/geocode-enum-types.h delete mode 100644 src/geocode-glib/geocode-error.c delete mode 100644 src/geocode-glib/geocode-error.h delete mode 100644 src/geocode-glib/geocode-forward.c delete mode 100644 src/geocode-glib/geocode-forward.h delete mode 100644 src/geocode-glib/geocode-glib-private.h delete mode 100644 src/geocode-glib/geocode-glib.c delete mode 100644 src/geocode-glib/geocode-glib.h delete mode 100644 src/geocode-glib/geocode-location.c delete mode 100644 src/geocode-glib/geocode-location.h delete mode 100644 src/geocode-glib/geocode-place.c delete mode 100644 src/geocode-glib/geocode-place.h delete mode 100644 src/geocode-glib/geocode-reverse.c delete mode 100644 src/geocode-glib/geocode-reverse.h delete mode 100644 src/geocode-glib/meson.build delete mode 100755 src/geocode-glib/update-from-geocode-glib.sh diff --git a/NEWS b/NEWS index 0e6c5d0..db99b75 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,36 @@ +2.5.2 +===== + +- Scan for WiFi networks, greatly improving accuracy of WiFi source. +- Allow multiple clients on the same D-Bus connection and add API for it. This + is mainly targetted for Flatpak location portal. +- Add API for apps to explicitly delete their client objects. Long running + apps, like gnome-settings-daemon and Flatpak location portal, should use that + to ensure Geoclue knows when these apps are not actually using it and hence + it doesn't need to keep running needlessly. +- Restore accidently removed, build of modem sources. +- Update location on connectivity actually changing. +- Try not spamming Mozilla Location Service. +- Fix unexpected exit when non-active clients are connected. +- Fix a check for system apps. +- Use absolute paths for sysconfdir. +- Fix links in docs. +- More debug log. +- A bunch of internal and/or non-functional fixes & improvements. + +Dependency-related changes: + +- Require glib >= 2.44. + +Contributors: + +Bastien Nocera <hadess@hadess.net> +Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> +Laurent Bigonville <bigon@bigon.be> +Valentin Blot <freedesktop-devel@valentinblot.org> +Will Thompson <will@willthompson.co.uk> +Zeeshan Ali <zeenix@collabora.co.uk> + 2.5.1 ===== diff --git a/data/meson.build b/data/meson.build index 0de17d7..f826864 100644 --- a/data/meson.build +++ b/data/meson.build @@ -7,17 +7,17 @@ if get_option('enable-backend') conf.set('demo_agent', '') endif - conf_dir = join_paths(get_option('sysconfdir'), 'geoclue') + conf_dir = join_paths(sysconfdir, 'geoclue') configure_file(output: 'geoclue.conf', input: 'geoclue.conf.in', configuration: conf, install_dir: conf_dir) conf = configuration_data() - conf.set('libexecdir', join_paths(get_option('prefix'), get_option('libexecdir'))) + conf.set('libexecdir', libexecdir) conf.set('dbus_srv_user', get_option('dbus-srv-user')) - service_dir = join_paths(get_option('datadir'), 'dbus-1', 'system-services') + service_dir = join_paths(datadir, 'dbus-1', 'system-services') configure_file(output: 'org.freedesktop.GeoClue2.service', input: 'org.freedesktop.GeoClue2.service.in', configuration: conf, @@ -25,8 +25,8 @@ if get_option('enable-backend') # DBus Service policy file dbus_service_dir = get_option('dbus-sys-dir') - if dbus_service_dir == '' - dbus_service_dir = join_paths(get_option('sysconfdir'), 'dbus-1', 'system.d') + if dbus_service_dir == '' + dbus_service_dir = join_paths(sysconfdir, 'dbus-1', 'system.d') endif configure_file(output: 'org.freedesktop.GeoClue2.conf', input: 'org.freedesktop.GeoClue2.conf.in', diff --git a/data/org.freedesktop.GeoClue2.conf.in b/data/org.freedesktop.GeoClue2.conf.in index 94dfaab..ca23bed 100644 --- a/data/org.freedesktop.GeoClue2.conf.in +++ b/data/org.freedesktop.GeoClue2.conf.in @@ -26,6 +26,11 @@ <allow send_destination="fi.w1.wpa_supplicant1" send_interface="org.freedesktop.DBus.Introspectable"/> + + <allow send_destination="fi.w1.wpa_supplicant1" + send_interface="fi.w1.wpa_supplicant1.Interface" + send_type="method_call" + send_member="Scan"/> </policy> <policy user="root"> diff --git a/demo/gclue-service-agent.c b/demo/gclue-service-agent.c index 6f2e227..1530fd9 100644 --- a/demo/gclue-service-agent.c +++ b/demo/gclue-service-agent.c @@ -40,18 +40,19 @@ gclue_service_agent_agent_iface_init (GClueAgentIface *iface); static void gclue_service_agent_constructed (GObject *object); -G_DEFINE_TYPE_WITH_CODE (GClueServiceAgent, - gclue_service_agent, - GCLUE_TYPE_AGENT_SKELETON, - G_IMPLEMENT_INTERFACE (GCLUE_TYPE_AGENT, - gclue_service_agent_agent_iface_init)) - struct _GClueServiceAgentPrivate { GDBusConnection *connection; GDBusProxy *manager_proxy; }; +G_DEFINE_TYPE_WITH_CODE (GClueServiceAgent, + gclue_service_agent, + GCLUE_TYPE_AGENT_SKELETON, + G_IMPLEMENT_INTERFACE (GCLUE_TYPE_AGENT, + gclue_service_agent_agent_iface_init) + G_ADD_PRIVATE (GClueServiceAgent)) + enum { PROP_0, @@ -119,8 +120,6 @@ gclue_service_agent_class_init (GClueServiceAgentClass *klass) object_class->set_property = gclue_service_agent_set_property; object_class->constructed = gclue_service_agent_constructed; - g_type_class_add_private (object_class, sizeof (GClueServiceAgentPrivate)); - gParamSpecs[PROP_CONNECTION] = g_param_spec_object ("connection", "Connection", "DBus Connection", diff --git a/demo/meson.build b/demo/meson.build index a4837f0..99c094f 100644 --- a/demo/meson.build +++ b/demo/meson.build @@ -1,9 +1,9 @@ -desktop_dir = join_paths(get_option('datadir'), 'applications') -demo_dir = join_paths(get_option('libexecdir'), 'geoclue-2.0', 'demos') +desktop_dir = join_paths(datadir, 'applications') +demo_dir = join_paths(libexecdir, 'geoclue-2.0', 'demos') i18n = import('i18n') desktop_conf = configuration_data() -desktop_conf.set('libexecdir', join_paths(get_option('prefix'), get_option('libexecdir'))) +desktop_conf.set('libexecdir', libexecdir) if get_option('libgeoclue') include_dirs = [ configinc, @@ -56,9 +56,7 @@ if get_option('demo-agent') install_dir: desktop_dir) # Also install in the autostart directory. - autostart_dir = join_paths(get_option('prefix'), - get_option('sysconfdir'), - 'xdg', 'autostart') + autostart_dir = join_paths(sysconfdir, 'xdg', 'autostart') meson.add_install_script('install-file.py', desktop_file.full_path(), autostart_dir) diff --git a/demo/where-am-i.c b/demo/where-am-i.c index 70589bd..5934161 100644 --- a/demo/where-am-i.c +++ b/demo/where-am-i.c @@ -134,7 +134,7 @@ on_client_active_notify (GClueClient *client, if (gclue_client_get_active (client)) return; - g_print ("Geolocation disabled. Quiting..\n"); + g_print ("Geolocation disabled. Quitting..\n"); on_location_timeout (NULL); } diff --git a/libgeoclue/gclue-simple.c b/libgeoclue/gclue-simple.c index 2c5cfbb..8facc7e 100644 --- a/libgeoclue/gclue-simple.c +++ b/libgeoclue/gclue-simple.c @@ -52,12 +52,6 @@ static void gclue_simple_async_initable_init (GAsyncInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueSimple, - gclue_simple, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, - gclue_simple_async_initable_init)); - struct _GClueSimplePrivate { char *desktop_id; @@ -72,6 +66,13 @@ struct _GClueSimplePrivate GCancellable *cancellable; }; +G_DEFINE_TYPE_WITH_CODE (GClueSimple, + gclue_simple, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, + gclue_simple_async_initable_init) + G_ADD_PRIVATE (GClueSimple)); + enum { PROP_0, @@ -159,8 +160,6 @@ gclue_simple_class_init (GClueSimpleClass *klass) object_class->get_property = gclue_simple_get_property; object_class->set_property = gclue_simple_set_property; - g_type_class_add_private (object_class, sizeof (GClueSimplePrivate)); - /** * GClueSimple:desktop-id: * diff --git a/libgeoclue/meson.build b/libgeoclue/meson.build index bdf72e0..ef2761f 100644 --- a/libgeoclue/meson.build +++ b/libgeoclue/meson.build @@ -1,6 +1,3 @@ -header_dir = 'libgeoclue-' + gclue_api_version -abs_header_dir = join_paths(get_option('includedir'), header_dir) - # FIXME: meson 0.46 doesn't seem to be actually installing the headers # generated by gnome.gdbus_codegen: # @@ -12,21 +9,21 @@ gclue_client = gnome.gdbus_codegen('gclue-client', interface_prefix: 'org.freedesktop.GeoClue2.', namespace: 'GClue', install_header: true, - install_dir: abs_header_dir) + install_dir: include_subdir) # Location interface gclue_location = gnome.gdbus_codegen('gclue-location', '../src/org.freedesktop.GeoClue2.Location.xml', interface_prefix: 'org.freedesktop.GeoClue2.', namespace: 'GClue', install_header: true, - install_dir: abs_header_dir) + install_dir: include_subdir) # Manager interface gclue_manager = gnome.gdbus_codegen('gclue-manager', '../src/org.freedesktop.GeoClue2.Manager.xml', interface_prefix: 'org.freedesktop.GeoClue2.', namespace: 'GClue', install_header: true, - install_dir: abs_header_dir) + install_dir: include_subdir) libgeoclue_sources = files('gclue-helpers.c', 'gclue-simple.c') libgeoclue_sources += gclue_client[0] diff --git a/meson.build b/meson.build index 5ed6450..d738ef6 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('geoclue', 'c', version: '2.5.1', meson_version : '>= 0.47.2') +project('geoclue', 'c', version: '2.5.2', meson_version : '>= 0.47.2') gclue_version = meson.project_version() ver_arr = gclue_version.split('.') @@ -9,6 +9,15 @@ gclue_micro_version = ver_arr[2] gclue_api_version='2.0' +datadir = join_paths(get_option('prefix'), get_option('datadir')) +includedir = join_paths(get_option('prefix'), get_option('includedir')) +libexecdir = join_paths(get_option('prefix'), get_option('libexecdir')) +sysconfdir = join_paths(get_option('prefix'), get_option('sysconfdir')) +localedir = join_paths(datadir, 'locale') + +header_dir = 'libgeoclue-' + gclue_api_version +include_subdir = join_paths(includedir, header_dir) + conf = configuration_data() conf.set_quoted('VERSION', gclue_version) conf.set_quoted('PACKAGE_VERSION', gclue_version) @@ -19,9 +28,12 @@ conf.set_quoted('PACKAGE_STRING', 'geoclue ' + gclue_version) conf.set_quoted('PACKAGE_URL', 'http://www.freedesktop.org/wiki/Software/GeoClue') conf.set_quoted('PACKAGE_BUGREPORT', 'http://bugs.freedesktop.org/enter_bug.cgi?product=GeoClue') conf.set_quoted('TEST_SRCDIR', meson.source_root() + '/data/') -datadir = join_paths(get_option('prefix'), get_option('datadir')) -conf.set_quoted('LOCALEDIR', datadir + '/locale') -conf.set_quoted('SYSCONFDIR', get_option('sysconfdir')) +conf.set_quoted('LOCALEDIR', localedir) +conf.set_quoted('SYSCONFDIR', sysconfdir) +conf.set10('GCLUE_USE_3G_SOURCE', get_option('3g-source')) +conf.set10('GCLUE_USE_CDMA_SOURCE', get_option('cdma-source')) +conf.set10('GCLUE_USE_MODEM_GPS_SOURCE', get_option('modem-gps-source')) +conf.set10('GCLUE_USE_NMEA_SOURCE', get_option('nmea-source')) configure_file(output: 'config.h', configuration : conf) configinc = include_directories('.') @@ -29,9 +41,9 @@ configinc = include_directories('.') gnome = import('gnome') cc = meson.get_compiler('c') -base_deps = [ dependency('glib-2.0', version: '>= 2.34.0'), - dependency('gio-2.0', version: '>= 2.34.0'), - dependency('gio-unix-2.0', version: '>= 2.34.0') ] +base_deps = [ dependency('glib-2.0', version: '>= 2.44.0'), + dependency('gio-2.0', version: '>= 2.44.0'), + dependency('gio-unix-2.0', version: '>= 2.44.0') ] libm = cc.find_library('m', required: false) if libm.found() base_deps += [ libm ] diff --git a/po/POTFILES.in b/po/POTFILES.in index 4e69bf7..97aa501 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,4 +4,3 @@ demo/where-am-i.c demo/geoclue-demo-agent.desktop.in.in demo/geoclue-where-am-i.desktop.in.in src/gclue-main.c -src/geocode-glib/geocode-reverse.c diff --git a/public-api/meson.build b/public-api/meson.build index ccb0a9f..e5e23fe 100644 --- a/public-api/meson.build +++ b/public-api/meson.build @@ -1,8 +1,6 @@ headers = [ 'gclue-enums.h' ] -header_dir = 'libgeoclue-' + gclue_api_version install_headers(headers, subdir: header_dir) -install_dir = get_option('includedir') + '/' + header_dir libgeoclue_public_api_gen_sources = gnome.mkenums_simple( 'gclue-enum-types', @@ -10,7 +8,7 @@ libgeoclue_public_api_gen_sources = gnome.mkenums_simple( header_prefix: '#include <gclue-enums.h>', decorator : 'GCLUE_ENUMS_H', install_header: true, - install_dir: install_dir) + install_dir: include_subdir) libgeoclue_public_api_sources = [ libgeoclue_public_api_gen_sources, 'gclue-enums.c' ] diff --git a/src/fi.w1.wpa_supplicant1.xml b/src/fi.w1.wpa_supplicant1.xml index 7bd7313..a559c89 100644 --- a/src/fi.w1.wpa_supplicant1.xml +++ b/src/fi.w1.wpa_supplicant1.xml @@ -16,6 +16,9 @@ </interface> <interface name="fi.w1.wpa_supplicant1.Interface"> +<method name="Scan"> + <arg name="args" type="a{sv}" direction="in"/> +</method> <signal name="BSSAdded"> <arg name="path" type="o"/> <arg name="properties" type="a{sv}"/> @@ -23,6 +26,9 @@ <signal name="BSSRemoved"> <arg name="path" type="o"/> </signal> +<signal name="ScanDone"> +<arg name="success" type="b"/> +</signal> <property name="State" type="s" access="read"/> <property name="Ifname" type="s" access="read"/> <property name="BSSs" type="ao" access="read"/> diff --git a/src/gclue-3g.c b/src/gclue-3g.c index fd74b67..4473102 100644 --- a/src/gclue-3g.c +++ b/src/gclue-3g.c @@ -45,7 +45,10 @@ struct _GClue3GPrivate { GClue3GTower *tower; }; -G_DEFINE_TYPE (GClue3G, gclue_3g, GCLUE_TYPE_WEB_SOURCE) +G_DEFINE_TYPE_WITH_CODE (GClue3G, + gclue_3g, + GCLUE_TYPE_WEB_SOURCE, + G_ADD_PRIVATE (GClue3G)) static gboolean gclue_3g_start (GClueLocationSource *source); @@ -142,8 +145,6 @@ gclue_3g_class_init (GClue3GClass *klass) web_class->parse_response = gclue_3g_parse_response; web_class->get_available_accuracy_level = gclue_3g_get_available_accuracy_level; - - g_type_class_add_private (klass, sizeof (GClue3GPrivate)); } static void diff --git a/src/gclue-cdma.c b/src/gclue-cdma.c index aa1b2ef..8f4f129 100644 --- a/src/gclue-cdma.c +++ b/src/gclue-cdma.c @@ -42,8 +42,10 @@ struct _GClueCDMAPrivate { gulong cdma_notify_id; }; - -G_DEFINE_TYPE (GClueCDMA, gclue_cdma, GCLUE_TYPE_LOCATION_SOURCE) +G_DEFINE_TYPE_WITH_CODE (GClueCDMA, + gclue_cdma, + GCLUE_TYPE_LOCATION_SOURCE, + G_ADD_PRIVATE (GClueCDMA)) static gboolean gclue_cdma_start (GClueLocationSource *source); @@ -132,8 +134,6 @@ gclue_cdma_class_init (GClueCDMAClass *klass) source_class->start = gclue_cdma_start; source_class->stop = gclue_cdma_stop; - - g_type_class_add_private (klass, sizeof (GClueCDMAPrivate)); } static void diff --git a/src/gclue-client-info.c b/src/gclue-client-info.c index 64057c0..4aab453 100644 --- a/src/gclue-client-info.c +++ b/src/gclue-client-info.c @@ -29,12 +29,6 @@ static void gclue_client_info_async_initable_init (GAsyncInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueClientInfo, - gclue_client_info, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, - gclue_client_info_async_initable_init)); - struct _GClueClientInfoPrivate { char *bus_name; @@ -46,6 +40,13 @@ struct _GClueClientInfoPrivate char *xdg_id; }; +G_DEFINE_TYPE_WITH_CODE (GClueClientInfo, + gclue_client_info, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, + gclue_client_info_async_initable_init) + G_ADD_PRIVATE (GClueClientInfo)); + enum { PROP_0, @@ -135,8 +136,6 @@ gclue_client_info_class_init (GClueClientInfoClass *klass) object_class->get_property = gclue_client_info_get_property; object_class->set_property = gclue_client_info_set_property; - g_type_class_add_private (object_class, sizeof (GClueClientInfoPrivate)); - gParamSpecs[PROP_PEER] = g_param_spec_string ("bus-name", "BusName", "Bus name of client", diff --git a/src/gclue-compass.c b/src/gclue-compass.c index 4753ee1..0a60275 100644 --- a/src/gclue-compass.c +++ b/src/gclue-compass.c @@ -30,8 +30,6 @@ * @include: gclue-glib/gclue-compass.h **/ -G_DEFINE_TYPE (GClueCompass, gclue_compass, G_TYPE_OBJECT) - struct _GClueCompassPrivate { Compass *proxy; @@ -39,6 +37,11 @@ struct _GClueCompassPrivate GCancellable *cancellable; }; +G_DEFINE_TYPE_WITH_CODE (GClueCompass, + gclue_compass, + G_TYPE_OBJECT, + G_ADD_PRIVATE (GClueCompass)) + enum { PROP_0, @@ -100,7 +103,6 @@ gclue_compass_class_init (GClueCompassClass *klass) object_class = G_OBJECT_CLASS (klass); object_class->get_property = gclue_compass_get_property; object_class->finalize = gclue_compass_finalize; - g_type_class_add_private (object_class, sizeof (GClueCompassPrivate)); /** * GClueCompass:heading diff --git a/src/gclue-config.c b/src/gclue-config.c index de352ba..d259c71 100644 --- a/src/gclue-config.c +++ b/src/gclue-config.c @@ -29,25 +29,6 @@ /* This class will be responsible for fetching configuration. */ -G_DEFINE_TYPE (GClueConfig, gclue_config, G_TYPE_OBJECT) - -typedef struct -{ - char *id; - gboolean allowed; - gboolean system; - int* users; - gsize num_users; -} AppConfig; - -static void -app_config_free (AppConfig *app_config) -{ - g_free (app_config->id); - g_free (app_config->users); - g_slice_free (AppConfig, app_config); -} - struct _GClueConfigPrivate { GKeyFile *key_file; @@ -68,6 +49,28 @@ struct _GClueConfigPrivate GList *app_configs; }; +G_DEFINE_TYPE_WITH_CODE (GClueConfig, + gclue_config, + G_TYPE_OBJECT, + G_ADD_PRIVATE (GClueConfig)) + +typedef struct +{ + char *id; + gboolean allowed; + gboolean system; + int* users; + gsize num_users; +} AppConfig; + +static void +app_config_free (AppConfig *app_config) +{ + g_free (app_config->id); + g_free (app_config->users); + g_slice_free (AppConfig, app_config); +} + static void gclue_config_finalize (GObject *object) { @@ -93,7 +96,6 @@ gclue_config_class_init (GClueConfigClass *klass) object_class = G_OBJECT_CLASS (klass); object_class->finalize = gclue_config_finalize; - g_type_class_add_private (object_class, sizeof (GClueConfigPrivate)); } static void diff --git a/src/gclue-location-source.c b/src/gclue-location-source.c index c7d6c55..79c78b7 100644 --- a/src/gclue-location-source.c +++ b/src/gclue-location-source.c @@ -36,8 +36,6 @@ start_source (GClueLocationSource *source); static gboolean stop_source (GClueLocationSource *source); -G_DEFINE_ABSTRACT_TYPE (GClueLocationSource, gclue_location_source, G_TYPE_OBJECT) - struct _GClueLocationSourcePrivate { GClueLocation *location; @@ -55,6 +53,11 @@ struct _GClueLocationSourcePrivate guint heading_changed_id; }; +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GClueLocationSource, + gclue_location_source, + G_TYPE_OBJECT, + G_ADD_PRIVATE (GClueLocationSource)) + enum { PROP_0, @@ -205,7 +208,6 @@ gclue_location_source_class_init (GClueLocationSourceClass *klass) object_class->get_property = gclue_location_source_get_property; object_class->set_property = gclue_location_source_set_property; object_class->finalize = gclue_location_source_finalize; - g_type_class_add_private (object_class, sizeof (GClueLocationSourcePrivate)); gParamSpecs[PROP_LOCATION] = g_param_spec_object ("location", "Location", @@ -400,10 +402,8 @@ gclue_location_source_set_location (GClueLocationSource *source, if (priv->scramble_location) { gdouble latitude, distance, accuracy; - latitude = geocode_location_get_latitude - (GEOCODE_LOCATION (priv->location)); - accuracy = geocode_location_get_accuracy - (GEOCODE_LOCATION (priv->location)); + latitude = gclue_location_get_latitude (priv->location); + accuracy = gclue_location_get_accuracy (priv->location); /* Randomization is needed to stop apps from calculationg the * actual location. @@ -428,10 +428,9 @@ gclue_location_source_set_location (GClueLocationSource *source, if (cur_location != NULL && priv->compute_movement) { guint64 cur_timestamp, timestamp; - timestamp = geocode_location_get_timestamp - (GEOCODE_LOCATION (location)); - cur_timestamp = geocode_location_get_timestamp - (GEOCODE_LOCATION (cur_location)); + timestamp = gclue_location_get_timestamp (location); + cur_timestamp = gclue_location_get_timestamp + (cur_location); if (timestamp != cur_timestamp) gclue_location_set_speed_from_prev_location diff --git a/src/gclue-location.c b/src/gclue-location.c index f0487f5..3190f6e 100644 --- a/src/gclue-location.c +++ b/src/gclue-location.c @@ -29,8 +29,16 @@ #include <stdlib.h> #define TIME_DIFF_THRESHOLD 60000000 /* 60 seconds */ +#define EARTH_RADIUS_KM 6372.795 struct _GClueLocationPrivate { + char *description; + + gdouble longitude; + gdouble latitude; + gdouble altitude; + gdouble accuracy; + guint64 timestamp; gdouble speed; gdouble heading; }; @@ -38,11 +46,20 @@ struct _GClueLocationPrivate { enum { PROP_0, + PROP_LATITUDE, + PROP_LONGITUDE, + PROP_ACCURACY, + PROP_DESCRIPTION, + PROP_TIMESTAMP, + PROP_ALTITUDE, PROP_SPEED, PROP_HEADING, }; -G_DEFINE_TYPE (GClueLocation, gclue_location, GEOCODE_TYPE_LOCATION); +G_DEFINE_TYPE_WITH_CODE (GClueLocation, + gclue_location, + G_TYPE_OBJECT, + G_ADD_PRIVATE (GClueLocation)); static void gclue_location_get_property (GObject *object, @@ -53,6 +70,35 @@ gclue_location_get_property (GObject *object, GClueLocation *location = GCLUE_LOCATION (object); switch (property_id) { + case PROP_DESCRIPTION: + g_value_set_string (value, + gclue_location_get_description (location)); + break; + + case PROP_LATITUDE: + g_value_set_double (value, + gclue_location_get_latitude (location)); + break; + + case PROP_LONGITUDE: + g_value_set_double (value, + gclue_location_get_longitude (location)); + break; + + case PROP_ALTITUDE: + g_value_set_double (value, + gclue_location_get_altitude (location)); + break; + + case PROP_ACCURACY: + g_value_set_double (value, + gclue_location_get_accuracy (location)); + break; + + case PROP_TIMESTAMP: + g_value_set_uint64 (value, + gclue_location_get_timestamp (location)); + break; case PROP_SPEED: g_value_set_double (value, gclue_location_get_speed (location)); @@ -70,6 +116,59 @@ gclue_location_get_property (GObject *object, } } +static void +gclue_location_set_latitude (GClueLocation *loc, + gdouble latitude) +{ + g_return_if_fail (latitude >= -90.0 && latitude <= 90.0); + + loc->priv->latitude = latitude; +} + +static void +gclue_location_set_longitude (GClueLocation *loc, + gdouble longitude) +{ + g_return_if_fail (longitude >= -180.0 && longitude <= 180.0); + + loc->priv->longitude = longitude; +} + +static void +gclue_location_set_altitude (GClueLocation *loc, + gdouble altitude) +{ + loc->priv->altitude = altitude; +} + +static void +gclue_location_set_accuracy (GClueLocation *loc, + gdouble accuracy) +{ + g_return_if_fail (accuracy >= GCLUE_LOCATION_ACCURACY_UNKNOWN); + + loc->priv->accuracy = accuracy; +} + +static void +gclue_location_set_timestamp (GClueLocation *loc, + guint64 timestamp) +{ + g_return_if_fail (GCLUE_IS_LOCATION (loc)); + + loc->priv->timestamp = timestamp; +} + +void +gclue_location_set_description (GClueLocation *loc, + const char *description) +{ + g_return_if_fail (GCLUE_IS_LOCATION (loc)); + + g_free (loc->priv->description); + loc->priv->description = g_strdup (description); +} + static void gclue_location_set_property (GObject *object, guint property_id, @@ -79,6 +178,35 @@ gclue_location_set_property (GObject *object, GClueLocation *location = GCLUE_LOCATION (object); switch (property_id) { + case PROP_DESCRIPTION: + gclue_location_set_description (location, + g_value_get_string (value)); + break; + + case PROP_LATITUDE: + gclue_location_set_latitude (location, + g_value_get_double (value)); + break; + + case PROP_LONGITUDE: + gclue_location_set_longitude (location, + g_value_get_double (value)); + break; + + case PROP_ALTITUDE: + gclue_location_set_altitude (location, + g_value_get_double (value)); + break; + + case PROP_ACCURACY: + gclue_location_set_accuracy (location, + g_value_get_double (value)); + break; + + case PROP_TIMESTAMP: + gclue_location_set_timestamp (location, + g_value_get_uint64 (value)); + break; case PROP_SPEED: gclue_location_set_speed (location, g_value_get_double (value)); @@ -96,9 +224,25 @@ gclue_location_set_property (GObject *object, } } +static void +gclue_location_constructed (GObject *object) +{ + GClueLocation *location = GCLUE_LOCATION (object); + GTimeVal tv; + + if (location->priv->timestamp != 0) + return; + + g_get_current_time (&tv); + gclue_location_set_timestamp (location, tv.tv_sec); +} + static void gclue_location_finalize (GObject *glocation) { + g_clear_pointer (&GCLUE_LOCATION (glocation)->priv->description, + g_free); + G_OBJECT_CLASS (gclue_location_parent_class)->finalize (glocation); } @@ -108,11 +252,105 @@ gclue_location_class_init (GClueLocationClass *klass) GObjectClass *glocation_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; + glocation_class->constructed = gclue_location_constructed; glocation_class->finalize = gclue_location_finalize; glocation_class->get_property = gclue_location_get_property; glocation_class->set_property = gclue_location_set_property; - g_type_class_add_private (klass, sizeof (GClueLocationPrivate)); + /** + * GClueLocation:description: + * + * The description of this location. + */ + pspec = g_param_spec_string ("description", + "Description", + "Description of this location", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_DESCRIPTION, pspec); + + /** + * GClueLocation:latitude: + * + * The latitude of this location in degrees. + */ + pspec = g_param_spec_double ("latitude", + "Latitude", + "The latitude of this location in degrees", + -90.0, + 90.0, + 0.0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_LATITUDE, pspec); + + /** + * GClueLocation:longitude: + * + * The longitude of this location in degrees. + */ + pspec = g_param_spec_double ("longitude", + "Longitude", + "The longitude of this location in degrees", + -180.0, + 180.0, + 0.0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_LONGITUDE, pspec); + + /** + * GClueLocation:altitude: + * + * The altitude of this location in meters. + */ + pspec = g_param_spec_double ("altitude", + "Altitude", + "The altitude of this location in meters", + GCLUE_LOCATION_ALTITUDE_UNKNOWN, + G_MAXDOUBLE, + GCLUE_LOCATION_ALTITUDE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_ALTITUDE, pspec); + + /** + * GClueLocation:accuracy: + * + * The accuracy of this location in meters. + */ + pspec = g_param_spec_double ("accuracy", + "Accuracy", + "The accuracy of this location in meters", + GCLUE_LOCATION_ACCURACY_UNKNOWN, + G_MAXDOUBLE, + GCLUE_LOCATION_ACCURACY_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_ACCURACY, pspec); + + + /** + * GClueLocation:timestamp: + * + * A timestamp in seconds since + * <ulink url="http://en.wikipedia.org/wiki/Unix_epoch">Epoch</ulink>, + * giving when the location was resolved from an address. + * + * A value of 0 (zero) will be interpreted as the current time. + */ + pspec = g_param_spec_uint64 ("timestamp", + "Timestamp", + "The timestamp of this location " + "in seconds since Epoch", + 0, + G_MAXINT64, + 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (glocation_class, PROP_TIMESTAMP, pspec); /** * GClueLocation:speed @@ -156,6 +394,8 @@ gclue_location_init (GClueLocation *location) GCLUE_TYPE_LOCATION, GClueLocationPrivate); + location->priv->altitude = GCLUE_LOCATION_ALTITUDE_UNKNOWN; + location->priv->accuracy = GCLUE_LOCATION_ACCURACY_UNKNOWN; location->priv->speed = GCLUE_LOCATION_SPEED_UNKNOWN; location->priv->heading = GCLUE_LOCATION_HEADING_UNKNOWN; } @@ -228,13 +468,13 @@ parse_altitude_string (const char *altitude, const char *unit) { if (altitude[0] == '\0' || unit[0] == '\0') - return GEOCODE_LOCATION_ALTITUDE_UNKNOWN; + return GCLUE_LOCATION_ALTITUDE_UNKNOWN; if (unit[0] != 'M') { g_warning ("Unknown unit '%s' for altitude, ignoring..", unit); - return GEOCODE_LOCATION_ALTITUDE_UNKNOWN; + return GCLUE_LOCATION_ALTITUDE_UNKNOWN; } return g_ascii_strtod (altitude, NULL); @@ -408,7 +648,7 @@ gclue_location_create_from_gga (const char *gga, GError **error) "accuracy", accuracy, "timestamp", timestamp, NULL); - if (altitude != GEOCODE_LOCATION_ALTITUDE_UNKNOWN) + if (altitude != GCLUE_LOCATION_ALTITUDE_UNKNOWN) g_object_set (location, "altitude", altitude, NULL); out: @@ -429,22 +669,109 @@ gclue_location_duplicate (GClueLocation *location) { g_return_val_if_fail (GCLUE_IS_LOCATION (location), NULL); - GeocodeLocation *gloc = GEOCODE_LOCATION (location); - return g_object_new (GCLUE_TYPE_LOCATION, - "description", geocode_location_get_description (gloc), - "latitude", geocode_location_get_latitude (gloc), - "longitude", geocode_location_get_longitude (gloc), - "accuracy", geocode_location_get_accuracy (gloc), - "altitude", geocode_location_get_altitude (gloc), - "crs", geocode_location_get_crs (gloc), - "timestamp", geocode_location_get_timestamp (gloc), + "latitude", location->priv->latitude, + "longitude", location->priv->longitude, + "accuracy", location->priv->accuracy, + "altitude", location->priv->altitude, + "timestamp", location->priv->timestamp, "speed", location->priv->speed, "heading", location->priv->heading, NULL); } +const char * +gclue_location_get_description (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), NULL); + + return loc->priv->description; +} + +/** + * gclue_location_get_latitude: + * @loc: a #GClueLocation + * + * Gets the latitude of location @loc. + * + * Returns: The latitude of location @loc. + **/ +gdouble +gclue_location_get_latitude (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), 0.0); + + return loc->priv->latitude; +} + +/** + * gclue_location_get_longitude: + * @loc: a #GClueLocation + * + * Gets the longitude of location @loc. + * + * Returns: The longitude of location @loc. + **/ +gdouble +gclue_location_get_longitude (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), 0.0); + + return loc->priv->longitude; +} + +/** + * gclue_location_get_altitude: + * @loc: a #GClueLocation + * + * Gets the altitude of location @loc. + * + * Returns: The altitude of location @loc. + **/ +gdouble +gclue_location_get_altitude (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), + GCLUE_LOCATION_ALTITUDE_UNKNOWN); + + return loc->priv->altitude; +} + +/** + * gclue_location_get_accuracy: + * @loc: a #GClueLocation + * + * Gets the accuracy (in meters) of location @loc. + * + * Returns: The accuracy of location @loc. + **/ +gdouble +gclue_location_get_accuracy (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), + GCLUE_LOCATION_ACCURACY_UNKNOWN); + + return loc->priv->accuracy; +} + +/** + * gclue_location_get_timestamp: + * @loc: a #GClueLocation + * + * Gets the timestamp (in seconds since the Epoch) of location @loc. See + * #GClueLocation:timestamp. + * + * Returns: The timestamp of location @loc. + **/ +guint64 +gclue_location_get_timestamp (GClueLocation *loc) +{ + g_return_val_if_fail (GCLUE_IS_LOCATION (loc), 0); + + return loc->priv->timestamp; +} + /** * gclue_location_get_speed: * @location: a #GClueLocation @@ -492,7 +819,6 @@ gclue_location_set_speed_from_prev_location (GClueLocation *location, { gdouble speed; guint64 timestamp, prev_timestamp; - GeocodeLocation *gloc, *prev_gloc; g_return_if_fail (GCLUE_IS_LOCATION (location)); g_return_if_fail (prev_location == NULL || @@ -504,11 +830,8 @@ gclue_location_set_speed_from_prev_location (GClueLocation *location, goto out; } - gloc = GEOCODE_LOCATION (location); - prev_gloc = GEOCODE_LOCATION (prev_location); - - timestamp = geocode_location_get_timestamp (gloc); - prev_timestamp = geocode_location_get_timestamp (prev_gloc); + timestamp = gclue_location_get_timestamp (location); + prev_timestamp = gclue_location_get_timestamp (prev_location); if (timestamp <= prev_timestamp) { speed = GCLUE_LOCATION_SPEED_UNKNOWN; @@ -516,7 +839,7 @@ gclue_location_set_speed_from_prev_location (GClueLocation *location, goto out; } - speed = geocode_location_get_distance_from (gloc, prev_gloc) * + speed = gclue_location_get_distance_from (location, prev_location) * 1000.0 / (timestamp - prev_timestamp); out: @@ -573,7 +896,6 @@ gclue_location_set_heading_from_prev_location (GClueLocation *location, GClueLocation *prev_location) { gdouble dx, dy, angle, lat, lon, prev_lat, prev_lon; - GeocodeLocation *gloc, *prev_gloc; g_return_if_fail (GCLUE_IS_LOCATION (location)); g_return_if_fail (prev_location == NULL || @@ -585,13 +907,10 @@ gclue_location_set_heading_from_prev_location (GClueLocation *location, return; } - gloc = GEOCODE_LOCATION (location); - prev_gloc = GEOCODE_LOCATION (prev_location); - - lat = geocode_location_get_latitude(gloc); - lon = geocode_location_get_longitude(gloc); - prev_lat = geocode_location_get_latitude(prev_gloc); - prev_lon = geocode_location_get_longitude(prev_gloc); + lat = gclue_location_get_latitude (location); + lon = gclue_location_get_longitude (location); + prev_lat = gclue_location_get_latitude (prev_location); + prev_lon = gclue_location_get_longitude (prev_location); dx = (lat - prev_lat); dy = (lon - prev_lon); @@ -625,3 +944,38 @@ gclue_location_set_heading_from_prev_location (GClueLocation *location, g_object_notify (G_OBJECT (location), "heading"); } + +/** + * gclue_location_get_distance_from: + * @loca: a #GClueLocation + * @locb: a #GClueLocation + * + * Calculates the distance in km, along the curvature of the Earth, + * between 2 locations. Note that altitude changes are not + * taken into account. + * + * Returns: a distance in km. + **/ +double +gclue_location_get_distance_from (GClueLocation *loca, + GClueLocation *locb) +{ + gdouble dlat, dlon, lat1, lat2; + gdouble a, c; + + g_return_val_if_fail (GCLUE_IS_LOCATION (loca), 0.0); + g_return_val_if_fail (GCLUE_IS_LOCATION (locb), 0.0); + + /* Algorithm from: + * http://www.movable-type.co.uk/scripts/latlong.html */ + + dlat = (locb->priv->latitude - loca->priv->latitude) * M_PI / 180.0; + dlon = (locb->priv->longitude - loca->priv->longitude) * M_PI / 180.0; + lat1 = loca->priv->latitude * M_PI / 180.0; + lat2 = locb->priv->latitude * M_PI / 180.0; + + a = sin (dlat / 2) * sin (dlat / 2) + + sin (dlon / 2) * sin (dlon / 2) * cos (lat1) * cos (lat2); + c = 2 * atan2 (sqrt (a), sqrt (1-a)); + return EARTH_RADIUS_KM * c; +} diff --git a/src/gclue-location.h b/src/gclue-location.h index fa3918e..00b18bb 100644 --- a/src/gclue-location.h +++ b/src/gclue-location.h @@ -28,7 +28,6 @@ #include <glib-object.h> #include <gio/gio.h> -#include "geocode-glib/geocode-location.h" G_BEGIN_DECLS @@ -48,7 +47,7 @@ typedef struct _GClueLocationPrivate GClueLocationPrivate; struct _GClueLocation { /* Parent instance structure */ - GeocodeLocation parent_instance; + GObject parent_instance; GClueLocationPrivate *priv; }; @@ -56,11 +55,60 @@ struct _GClueLocation struct _GClueLocationClass { /* Parent class structure */ - GeocodeLocationClass parent_class; + GObjectClass parent_class; }; GType gclue_location_get_type (void); +/** + * GCLUE_LOCATION_ALTITUDE_UNKNOWN: + * + * Constant representing unknown altitude. + */ +#define GCLUE_LOCATION_ALTITUDE_UNKNOWN -G_MAXDOUBLE + +/** + * GCLUE_LOCATION_ACCURACY_UNKNOWN: + * + * Constant representing unknown accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_UNKNOWN -1 + +/** + * GCLUE_LOCATION_ACCURACY_STREET: + * + * Constant representing street-level accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_STREET 1000 /* 1 km */ + +/** + * GCLUE_LOCATION_ACCURACY_CITY: + * + * Constant representing city-level accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_CITY 15000 /* 15 km */ + +/** + * GCLUE_LOCATION_ACCURACY_REGION: + * + * Constant representing region-level accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_REGION 50000 /* 50 km */ + +/** + * GCLUE_LOCATION_ACCURACY_COUNTRY: + * + * Constant representing country-level accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_COUNTRY 300000 /* 300 km */ + +/** + * GCLUE_LOCATION_ACCURACY_CONTINENT: + * + * Constant representing continent-level accuracy. + */ +#define GCLUE_LOCATION_ACCURACY_CONTINENT 3000000 /* 3000 km */ + /** * GCLUE_LOCATION_HEADING_UNKNOWN: * @@ -96,6 +144,22 @@ GClueLocation *gclue_location_create_from_gga GClueLocation *gclue_location_duplicate (GClueLocation *location); +void gclue_location_set_description + (GClueLocation *loc, + const char *description); +const char *gclue_location_get_description + (GClueLocation *loc); + +gdouble gclue_location_get_latitude + (GClueLocation *loc); +gdouble gclue_location_get_longitude + (GClueLocation *loc); +gdouble gclue_location_get_altitude + (GClueLocation *loc); +gdouble gclue_location_get_accuracy + (GClueLocation *loc); +guint64 gclue_location_get_timestamp + (GClueLocation *loc); void gclue_location_set_speed (GClueLocation *loc, gdouble speed); @@ -115,5 +179,8 @@ void gclue_location_set_heading_from_prev_location gdouble gclue_location_get_heading (GClueLocation *loc); +double gclue_location_get_distance_from + (GClueLocation *loca, + GClueLocation *locb); #endif /* GCLUE_LOCATION_H */ diff --git a/src/gclue-locator.c b/src/gclue-locator.c index c89ee0b..a049fe5 100644 --- a/src/gclue-locator.c +++ b/src/gclue-locator.c @@ -54,8 +54,6 @@ gclue_locator_start (GClueLocationSource *source); static gboolean gclue_locator_stop (GClueLocationSource *source); -G_DEFINE_TYPE (GClueLocator, gclue_locator, GCLUE_TYPE_LOCATION_SOURCE) - struct _GClueLocatorPrivate { GList *sources; @@ -66,6 +64,11 @@ struct _GClueLocatorPrivate guint time_threshold; }; +G_DEFINE_TYPE_WITH_CODE (GClueLocator, + gclue_locator, + GCLUE_TYPE_LOCATION_SOURCE, + G_ADD_PRIVATE (GClueLocator)) + enum { PROP_0, @@ -80,26 +83,24 @@ set_location (GClueLocator *locator, GClueLocation *location) { GClueLocation *cur_location; - GeocodeLocation *gloc, *cur_gloc; cur_location = gclue_location_source_get_location (GCLUE_LOCATION_SOURCE (locator)); - gloc = GEOCODE_LOCATION (location); - cur_gloc = GEOCODE_LOCATION (cur_location); g_debug ("New location available"); if (cur_location != NULL) { - if (geocode_location_get_timestamp (gloc) < - geocode_location_get_timestamp (cur_gloc)) { + if (gclue_location_get_timestamp (location) < + gclue_location_get_timestamp (cur_location)) { g_debug ("New location older than current, ignoring."); return; } - if (geocode_location_get_distance_from (gloc, cur_gloc) * 1000 < - geocode_location_get_accuracy (gloc) && - geocode_location_get_accuracy (gloc) > - geocode_location_get_accuracy (cur_gloc)) { + if (gclue_location_get_distance_from (location, cur_location) + * 1000 < + gclue_location_get_accuracy (location) && + gclue_location_get_accuracy (location) > + gclue_location_get_accuracy (cur_location)) { /* We only take the new location if either the previous one * lies outside its accuracy circle or its more or as * accurate as previous one. @@ -409,7 +410,6 @@ gclue_locator_class_init (GClueLocatorClass *klass) object_class->set_property = gclue_locator_set_property; object_class->finalize = gclue_locator_finalize; object_class->constructed = gclue_locator_constructed; - g_type_class_add_private (object_class, sizeof (GClueLocatorPrivate)); gParamSpecs[PROP_ACCURACY_LEVEL] = g_param_spec_enum ("accuracy-level", "AccuracyLevel", diff --git a/src/gclue-min-uint.c b/src/gclue-min-uint.c index f63a87f..bc75e9a 100644 --- a/src/gclue-min-uint.c +++ b/src/gclue-min-uint.c @@ -33,8 +33,6 @@ * by different applications. **/ -G_DEFINE_TYPE (GClueMinUINT, gclue_min_uint, G_TYPE_OBJECT) - struct _GClueMinUINTPrivate { GHashTable *all_values; @@ -42,6 +40,11 @@ struct _GClueMinUINTPrivate gboolean notify_value; }; +G_DEFINE_TYPE_WITH_CODE (GClueMinUINT, + gclue_min_uint, + G_TYPE_OBJECT, + G_ADD_PRIVATE (GClueMinUINT)) + enum { PROP_0, @@ -116,11 +119,9 @@ gclue_min_uint_class_init (GClueMinUINTClass *klass) object_class->finalize = gclue_min_uint_finalize; object_class->get_property = gclue_min_uint_get_property; - g_type_class_add_private (object_class, sizeof (GClueMinUINTPrivate)); - gParamSpecs[PROP_VALUE] = g_param_spec_uint ("value", "Value", - "The mininum value", + "The minimum value", 0, G_MAXINT, 0, @@ -156,7 +157,7 @@ gclue_min_uint_new (void) * gclue_min_uint_get_value * @muint: a #GClueMinUINT * - * Returns: The current mininum value from the list. + * Returns: The current minimum value from the list. **/ guint gclue_min_uint_get_value (GClueMinUINT *muint) diff --git a/src/gclue-modem-gps.c b/src/gclue-modem-gps.c index 048f584..6045d6b 100644 --- a/src/gclue-modem-gps.c +++ b/src/gclue-modem-gps.c @@ -43,7 +43,10 @@ struct _GClueModemGPSPrivate { }; -G_DEFINE_TYPE (GClueModemGPS, gclue_modem_gps, GCLUE_TYPE_LOCATION_SOURCE) +G_DEFINE_TYPE_WITH_CODE (GClueModemGPS, + gclue_modem_gps, + GCLUE_TYPE_LOCATION_SOURCE, + G_ADD_PRIVATE (GClueModemGPS)) static gboolean gclue_modem_gps_start (GClueLocationSource *source); @@ -144,8 +147,6 @@ gclue_modem_gps_class_init (GClueModemGPSClass *klass) source_class->start = gclue_modem_gps_start; source_class->stop = gclue_modem_gps_stop; - - g_type_class_add_private (klass, sizeof (GClueModemGPSPrivate)); } static void diff --git a/src/gclue-modem-manager.c b/src/gclue-modem-manager.c index cbef2ff..66f883a 100644 --- a/src/gclue-modem-manager.c +++ b/src/gclue-modem-manager.c @@ -37,10 +37,6 @@ static void gclue_modem_interface_init (GClueModemInterface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueModemManager, gclue_modem_manager, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GCLUE_TYPE_MODEM, - gclue_modem_interface_init)) - struct _GClueModemManagerPrivate { MMManager *manager; MMObject *mm_object; @@ -56,6 +52,11 @@ struct _GClueModemManagerPrivate { guint time_threshold; }; +G_DEFINE_TYPE_WITH_CODE (GClueModemManager, gclue_modem_manager, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GCLUE_TYPE_MODEM, + gclue_modem_interface_init) + G_ADD_PRIVATE (GClueModemManager)) + enum { PROP_0, @@ -210,8 +211,6 @@ gclue_modem_manager_class_init (GClueModemManagerClass *klass) gmodem_class->finalize = gclue_modem_manager_finalize; gmodem_class->constructed = gclue_modem_manager_constructed; - g_type_class_add_private (klass, sizeof (GClueModemManagerPrivate)); - g_object_class_override_property (gmodem_class, PROP_IS_3G_AVAILABLE, "is-3g-available"); diff --git a/src/gclue-mozilla.c b/src/gclue-mozilla.c index 8a31acd..6d644a4 100644 --- a/src/gclue-mozilla.c +++ b/src/gclue-mozilla.c @@ -293,27 +293,27 @@ gclue_mozilla_create_submit_query (GClueLocation *location, json_builder_begin_object (builder); - lat = geocode_location_get_latitude (GEOCODE_LOCATION (location)); + lat = gclue_location_get_latitude (location); json_builder_set_member_name (builder, "lat"); json_builder_add_double_value (builder, lat); - lon = geocode_location_get_longitude (GEOCODE_LOCATION (location)); + lon = gclue_location_get_longitude (location); json_builder_set_member_name (builder, "lon"); json_builder_add_double_value (builder, lon); - accuracy = geocode_location_get_accuracy (GEOCODE_LOCATION (location)); - if (accuracy != GEOCODE_LOCATION_ACCURACY_UNKNOWN) { + accuracy = gclue_location_get_accuracy (location); + if (accuracy != GCLUE_LOCATION_ACCURACY_UNKNOWN) { json_builder_set_member_name (builder, "accuracy"); json_builder_add_double_value (builder, accuracy); } - altitude = geocode_location_get_altitude (GEOCODE_LOCATION (location)); - if (altitude != GEOCODE_LOCATION_ALTITUDE_UNKNOWN) { + altitude = gclue_location_get_altitude (location); + if (altitude != GCLUE_LOCATION_ALTITUDE_UNKNOWN) { json_builder_set_member_name (builder, "altitude"); json_builder_add_double_value (builder, altitude); } - tv.tv_sec = geocode_location_get_timestamp (GEOCODE_LOCATION (location)); + tv.tv_sec = gclue_location_get_timestamp (location); tv.tv_usec = 0; timestamp = g_time_val_to_iso8601 (&tv); json_builder_set_member_name (builder, "time"); diff --git a/src/gclue-nmea-source.c b/src/gclue-nmea-source.c index 9a52a83..c3a211b 100644 --- a/src/gclue-nmea-source.c +++ b/src/gclue-nmea-source.c @@ -51,7 +51,10 @@ struct _GClueNMEASourcePrivate { GList *all_services; }; -G_DEFINE_TYPE (GClueNMEASource, gclue_nmea_source, GCLUE_TYPE_LOCATION_SOURCE) +G_DEFINE_TYPE_WITH_CODE (GClueNMEASource, + gclue_nmea_source, + GCLUE_TYPE_LOCATION_SOURCE, + G_ADD_PRIVATE (GClueNMEASource)) static gboolean gclue_nmea_source_start (GClueLocationSource *source); @@ -612,8 +615,6 @@ gclue_nmea_source_class_init (GClueNMEASourceClass *klass) source_class->start = gclue_nmea_source_start; source_class->stop = gclue_nmea_source_stop; - - g_type_class_add_private (klass, sizeof (GClueNMEASourcePrivate)); } static void diff --git a/src/gclue-service-client.c b/src/gclue-service-client.c index bf6dfa6..247fdb6 100644 --- a/src/gclue-service-client.c +++ b/src/gclue-service-client.c @@ -36,20 +36,12 @@ gclue_service_client_client_iface_init (GClueDBusClientIface *iface); static void gclue_service_client_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueServiceClient, - gclue_service_client, - GCLUE_DBUS_TYPE_CLIENT_SKELETON, - G_IMPLEMENT_INTERFACE (GCLUE_DBUS_TYPE_CLIENT, - gclue_service_client_client_iface_init) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - gclue_service_client_initable_iface_init)); - typedef struct _StartData StartData; struct _GClueServiceClientPrivate { GClueClientInfo *client_info; - const char *path; + char *path; GDBusConnection *connection; GClueAgent *agent_proxy; StartData *pending_auth_start_data; @@ -68,6 +60,15 @@ struct _GClueServiceClientPrivate gboolean agent_stopped; /* Agent stopped client, not the app */ }; +G_DEFINE_TYPE_WITH_CODE (GClueServiceClient, + gclue_service_client, + GCLUE_DBUS_TYPE_CLIENT_SKELETON, + G_IMPLEMENT_INTERFACE (GCLUE_DBUS_TYPE_CLIENT, + gclue_service_client_client_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + gclue_service_client_initable_iface_init) + G_ADD_PRIVATE (GClueServiceClient)); + enum { PROP_0, @@ -133,8 +134,7 @@ distance_below_threshold (GClueServiceClient *client, g_object_get (priv->location, "location", &cur_location, NULL); - distance = geocode_location_get_distance_from - (GEOCODE_LOCATION (cur_location), GEOCODE_LOCATION (location)); + distance = gclue_location_get_distance_from (cur_location, location); g_object_unref (cur_location); threshold_km = priv->distance_threshold / 1000.0; @@ -164,9 +164,8 @@ time_below_threshold (GClueServiceClient *client, "location", &cur_location, NULL); - cur_ts = geocode_location_get_timestamp - (GEOCODE_LOCATION (cur_location)); - ts = geocode_location_get_timestamp (GEOCODE_LOCATION (location)); + cur_ts = gclue_location_get_timestamp (cur_location); + ts = gclue_location_get_timestamp (location); diff_ts = ABS (ts - cur_ts); g_object_unref (cur_location); @@ -340,7 +339,7 @@ on_agent_props_changed (GDBusProxy *agent_proxy, id = gclue_dbus_client_get_desktop_id (gdbus_client); max_accuracy = g_variant_get_uint32 (value); system_app = (gclue_client_info_get_xdg_id - (client->priv->client_info) != NULL); + (client->priv->client_info) == NULL); /* FIXME: We should be handling all values of max accuracy * level here, not just 0 and non-0. */ @@ -882,8 +881,6 @@ gclue_service_client_class_init (GClueServiceClientClass *klass) skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); skeleton_class->get_vtable = gclue_service_client_get_vtable; - g_type_class_add_private (object_class, sizeof (GClueServiceClientPrivate)); - gParamSpecs[PROP_CLIENT_INFO] = g_param_spec_object ("client-info", "ClientInfo", "Information on client", diff --git a/src/gclue-service-location.c b/src/gclue-service-location.c index 4d6fe26..c2c1991 100644 --- a/src/gclue-service-location.c +++ b/src/gclue-service-location.c @@ -27,19 +27,20 @@ static void gclue_service_location_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueServiceLocation, - gclue_service_location, - GCLUE_DBUS_TYPE_LOCATION_SKELETON, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - gclue_service_location_initable_iface_init)); - struct _GClueServiceLocationPrivate { GClueClientInfo *client_info; - const char *path; + char *path; GDBusConnection *connection; }; +G_DEFINE_TYPE_WITH_CODE (GClueServiceLocation, + gclue_service_location, + GCLUE_DBUS_TYPE_LOCATION_SKELETON, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + gclue_service_location_initable_iface_init) + G_ADD_PRIVATE (GClueServiceLocation)); + enum { PROP_0, @@ -143,32 +144,30 @@ gclue_service_location_set_property (GObject *object, GClueDBusLocation *location; GClueLocation *loc; gdouble altitude; - GeocodeLocation *g_loc; GVariant *timestamp; location = GCLUE_DBUS_LOCATION (object); loc = g_value_get_object (value); - g_loc = GEOCODE_LOCATION (loc); gclue_dbus_location_set_latitude - (location, geocode_location_get_latitude (g_loc)); + (location, gclue_location_get_latitude (loc)); gclue_dbus_location_set_longitude - (location, geocode_location_get_longitude (g_loc)); + (location, gclue_location_get_longitude (loc)); gclue_dbus_location_set_accuracy - (location, geocode_location_get_accuracy (g_loc)); + (location, gclue_location_get_accuracy (loc)); gclue_dbus_location_set_description - (location, geocode_location_get_description (g_loc)); + (location, gclue_location_get_description (loc)); gclue_dbus_location_set_speed (location, gclue_location_get_speed (loc)); gclue_dbus_location_set_heading (location, gclue_location_get_heading (loc)); timestamp = g_variant_new ("(tt)", - (guint64) geocode_location_get_timestamp (g_loc), + (guint64) gclue_location_get_timestamp (loc), (guint64) 0); gclue_dbus_location_set_timestamp (location, timestamp); - altitude = geocode_location_get_altitude (g_loc); - if (altitude != GEOCODE_LOCATION_ALTITUDE_UNKNOWN) + altitude = gclue_location_get_altitude (loc); + if (altitude != GCLUE_LOCATION_ALTITUDE_UNKNOWN) gclue_dbus_location_set_altitude (location, altitude); break; } @@ -306,8 +305,6 @@ gclue_service_location_class_init (GClueServiceLocationClass *klass) skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); skeleton_class->get_vtable = gclue_service_location_get_vtable; - g_type_class_add_private (object_class, sizeof (GClueServiceLocationPrivate)); - gParamSpecs[PROP_CLIENT_INFO] = g_param_spec_object ("client-info", "ClientInfo", "Information on client", @@ -355,7 +352,7 @@ gclue_service_location_init (GClueServiceLocation *location) GCLUE_TYPE_SERVICE_LOCATION, GClueServiceLocationPrivate); gclue_dbus_location_set_altitude (GCLUE_DBUS_LOCATION (location), - GEOCODE_LOCATION_ALTITUDE_UNKNOWN); + GCLUE_LOCATION_ALTITUDE_UNKNOWN); } static gboolean diff --git a/src/gclue-service-manager.c b/src/gclue-service-manager.c index 904f5f1..1d66ec4 100644 --- a/src/gclue-service-manager.c +++ b/src/gclue-service-manager.c @@ -41,28 +41,28 @@ gclue_service_manager_manager_iface_init (GClueDBusManagerIface *iface); static void gclue_service_manager_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GClueServiceManager, - gclue_service_manager, - GCLUE_DBUS_TYPE_MANAGER_SKELETON, - G_IMPLEMENT_INTERFACE (GCLUE_DBUS_TYPE_MANAGER, - gclue_service_manager_manager_iface_init) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - gclue_service_manager_initable_iface_init)) - struct _GClueServiceManagerPrivate { GDBusConnection *connection; - GHashTable *clients; + GList *clients; GHashTable *agents; + guint last_client_id; guint num_clients; gint64 init_time; GClueLocator *locator; - - gboolean active; }; +G_DEFINE_TYPE_WITH_CODE (GClueServiceManager, + gclue_service_manager, + GCLUE_DBUS_TYPE_MANAGER_SKELETON, + G_IMPLEMENT_INTERFACE (GCLUE_DBUS_TYPE_MANAGER, + gclue_service_manager_manager_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + gclue_service_manager_initable_iface_init) + G_ADD_PRIVATE (GClueServiceManager)) + enum { PROP_0, @@ -76,12 +76,11 @@ static GParamSpec *gParamSpecs[LAST_PROP]; static void sync_in_use_property (GClueServiceManager *manager) { - gboolean in_use = FALSE, active = FALSE; - GList *clients, *l; + gboolean in_use = FALSE; + GList *l; GClueDBusManager *gdbus_manager; - clients = g_hash_table_get_values (manager->priv->clients); - for (l = clients; l != NULL; l = l->next) { + for (l = manager->priv->clients; l != NULL; l = l->next) { GClueDBusClient *client = GCLUE_DBUS_CLIENT (l->data); GClueConfig *config; const char *id; @@ -89,7 +88,6 @@ sync_in_use_property (GClueServiceManager *manager) id = gclue_dbus_client_get_desktop_id (client); config = gclue_config_get_singleton (); - active |= gclue_dbus_client_get_active (client); if (gclue_dbus_client_get_active (client) && !gclue_config_is_system_component (config, id)) { in_use = TRUE; @@ -97,28 +95,64 @@ sync_in_use_property (GClueServiceManager *manager) break; } } - g_list_free (clients); - if (manager->priv->active != active) { - manager->priv->active = active; - g_object_notify (G_OBJECT (manager), "active"); - } gdbus_manager = GCLUE_DBUS_MANAGER (manager); if (in_use != gclue_dbus_manager_get_in_use (gdbus_manager)) gclue_dbus_manager_set_in_use (gdbus_manager, in_use); } +static int +compare_client_bus_name (gconstpointer a, + gconstpointer b) +{ + GClueClientInfo *info; + const char *bus_name = (const char *) b; + + info = gclue_service_client_get_client_info (GCLUE_SERVICE_CLIENT (a)); + + return g_strcmp0 (bus_name, gclue_client_info_get_bus_name (info)); +} + +static void +delete_client (GClueServiceManager *manager, + GCompareFunc compare_func, + gpointer compare_func_data) +{ + GClueServiceManagerPrivate *priv = manager->priv; + GList *l; + + l = priv->clients; + while (l != NULL) { + GList *next = l->next; + + if (compare_func (l->data, compare_func_data) == 0) { + g_object_unref (G_OBJECT (l->data)); + priv->clients = g_list_remove_link (priv->clients, l); + priv->num_clients--; + if (priv->num_clients == 0) { + g_object_notify (G_OBJECT (manager), "active"); + } + } + l = next; + } + + g_debug ("Number of connected clients: %u", priv->num_clients); + sync_in_use_property (manager); +} + static void on_peer_vanished (GClueClientInfo *info, gpointer user_data) { - GClueServiceManager *manager = GCLUE_SERVICE_MANAGER (user_data); + const char *bus_name; - g_hash_table_remove (manager->priv->clients, - gclue_client_info_get_bus_name (info)); - g_debug ("Number of connected clients: %u", - g_hash_table_size (manager->priv->clients)); - sync_in_use_property (manager); + bus_name = gclue_client_info_get_bus_name (info); + g_debug ("Client `%s` vanished. Dropping associated client objects", + bus_name); + + delete_client (GCLUE_SERVICE_MANAGER (user_data), + compare_client_bus_name, + (char *) bus_name); } typedef struct @@ -126,6 +160,8 @@ typedef struct GClueDBusManager *manager; GDBusMethodInvocation *invocation; GClueClientInfo *client_info; + gboolean reuse_client; + } OnClientInfoNewReadyData; static gboolean @@ -143,8 +179,27 @@ complete_get_client (OnClientInfoNewReadyData *data) agent_proxy = g_hash_table_lookup (priv->agents, GINT_TO_POINTER (user_id)); + if (data->reuse_client) { + GList *node; + const char *peer; + + peer = g_dbus_method_invocation_get_sender (data->invocation); + node = g_list_find_custom (priv->clients, + peer, + compare_client_bus_name); + if (node != NULL) { + GClueServiceClient *client; + + client = GCLUE_SERVICE_CLIENT (node->data); + path = g_strdup + (gclue_service_client_get_path (client)); + + goto client_created; + } + } + path = g_strdup_printf ("/org/freedesktop/GeoClue2/Client/%u", - ++priv->num_clients); + ++priv->last_client_id); client = gclue_service_client_new (info, path, @@ -154,24 +209,27 @@ complete_get_client (OnClientInfoNewReadyData *data) if (client == NULL) goto error_out; - g_hash_table_insert (priv->clients, - g_strdup (gclue_client_info_get_bus_name (info)), - client); - g_debug ("Number of connected clients: %u", - g_hash_table_size (priv->clients)); + priv->clients = g_list_prepend (priv->clients, client); + priv->num_clients++; + if (priv->num_clients == 1) { + g_object_notify (G_OBJECT (data->manager), "active"); + } + g_debug ("Number of connected clients: %u", priv->num_clients); g_signal_connect (info, "peer-vanished", G_CALLBACK (on_peer_vanished), data->manager); - g_signal_connect_swapped (client, - "notify::active", - G_CALLBACK (sync_in_use_property), - data->manager); - - gclue_dbus_manager_complete_get_client (data->manager, - data->invocation, - path); + +client_created: + if (data->reuse_client) + gclue_dbus_manager_complete_get_client (data->manager, + data->invocation, + path); + else + gclue_dbus_manager_complete_create_client (data->manager, + data->invocation, + path); goto out; error_out: @@ -234,36 +292,89 @@ on_client_info_new_ready (GObject *source_object, complete_get_client (data); } -static gboolean -gclue_service_manager_handle_get_client (GClueDBusManager *manager, - GDBusMethodInvocation *invocation) +static void +handle_get_client (GClueDBusManager *manager, + GDBusMethodInvocation *invocation, + gboolean reuse_client) { GClueServiceManager *self = GCLUE_SERVICE_MANAGER (manager); GClueServiceManagerPrivate *priv = self->priv; - GClueServiceClient *client; const char *peer; OnClientInfoNewReadyData *data; peer = g_dbus_method_invocation_get_sender (invocation); - client = g_hash_table_lookup (priv->clients, peer); - if (client != NULL) { - const gchar *existing_path; - - existing_path = gclue_service_client_get_path (client); - gclue_dbus_manager_complete_get_client (manager, - invocation, - existing_path); - return TRUE; - } data = g_slice_new (OnClientInfoNewReadyData); data->manager = manager; data->invocation = invocation; + data->reuse_client = reuse_client; gclue_client_info_new_async (peer, priv->connection, NULL, on_client_info_new_ready, data); +} + +static gboolean +gclue_service_manager_handle_get_client (GClueDBusManager *manager, + GDBusMethodInvocation *invocation) +{ + handle_get_client (manager, invocation, TRUE); + + return TRUE; +} + +static gboolean +gclue_service_manager_handle_create_client (GClueDBusManager *manager, + GDBusMethodInvocation *invocation) +{ + handle_get_client (manager, invocation, FALSE); + + return TRUE; +} + +typedef struct +{ + const char *path; + const char *bus_name; +} CompareClientPathNBusNameData; + +static int +compare_client_path_n_bus_name (gconstpointer a, + gconstpointer b) +{ + GClueServiceClient *client = GCLUE_SERVICE_CLIENT (a); + CompareClientPathNBusNameData *data = + (CompareClientPathNBusNameData *) b; + GClueClientInfo *info; + + info = gclue_service_client_get_client_info (client); + + if (g_strcmp0 (data->bus_name, + gclue_client_info_get_bus_name (info)) == 0 && + g_strcmp0 (data->path, + gclue_service_client_get_path (client)) == 0) + return 0; + else + return 1; +} + +static gboolean +gclue_service_manager_handle_delete_client (GClueDBusManager *manager, + GDBusMethodInvocation *invocation, + const char *path) +{ + CompareClientPathNBusNameData data; + + data.path = path; + data.bus_name = g_dbus_method_invocation_get_sender (invocation); + + delete_client (GCLUE_SERVICE_MANAGER (manager), + compare_client_path_n_bus_name, + &data); + + gclue_dbus_manager_complete_delete_client (manager, invocation); + return TRUE; } @@ -413,7 +524,10 @@ gclue_service_manager_finalize (GObject *object) g_clear_object (&priv->locator); g_clear_object (&priv->connection); - g_clear_pointer (&priv->clients, g_hash_table_unref); + if (priv->clients != NULL) { + g_list_free_full (priv->clients, g_object_unref); + priv->clients = NULL; + } g_clear_pointer (&priv->agents, g_hash_table_unref); /* Chain up to the parent class */ @@ -434,7 +548,7 @@ gclue_service_manager_get_property (GObject *object, break; case PROP_ACTIVE: - g_value_set_boolean (value, manager->priv->active); + g_value_set_boolean (value, (manager->priv->num_clients != 0)); break; default: @@ -502,8 +616,6 @@ gclue_service_manager_class_init (GClueServiceManagerClass *klass) object_class->set_property = gclue_service_manager_set_property; object_class->constructed = gclue_service_manager_constructed; - g_type_class_add_private (object_class, sizeof (GClueServiceManagerPrivate)); - gParamSpecs[PROP_CONNECTION] = g_param_spec_object ("connection", "Connection", "DBus Connection", @@ -517,8 +629,8 @@ gclue_service_manager_class_init (GClueServiceManagerClass *klass) /** * GClueServiceManager:active: * - * Unlike the D-Bus 'InUse' property, this doesn't differentiate - * between system components and apps. + * Unlike the D-Bus 'InUse' property, this indicates wether or not + * currently we have connected clients. */ gParamSpecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "Active", @@ -537,10 +649,6 @@ gclue_service_manager_init (GClueServiceManager *manager) GCLUE_TYPE_SERVICE_MANAGER, GClueServiceManagerPrivate); - manager->priv->clients = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); manager->priv->agents = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, @@ -564,6 +672,10 @@ static void gclue_service_manager_manager_iface_init (GClueDBusManagerIface *iface) { iface->handle_get_client = gclue_service_manager_handle_get_client; + iface->handle_create_client = + gclue_service_manager_handle_create_client; + iface->handle_delete_client = + gclue_service_manager_handle_delete_client; iface->handle_add_agent = gclue_service_manager_handle_add_agent; } @@ -587,5 +699,5 @@ gclue_service_manager_new (GDBusConnection *connection, gboolean gclue_service_manager_get_active (GClueServiceManager *manager) { - return manager->priv->active; + return (manager->priv->num_clients != 0); } diff --git a/src/gclue-web-source.c b/src/gclue-web-source.c index 4f7ad30..98e95e8 100644 --- a/src/gclue-web-source.c +++ b/src/gclue-web-source.c @@ -45,13 +45,17 @@ struct _GClueWebSourcePrivate { SoupMessage *query; gulong network_changed_id; + gulong connectivity_changed_id; guint64 last_submitted; gboolean internet_available; }; -G_DEFINE_ABSTRACT_TYPE (GClueWebSource, gclue_web_source, GCLUE_TYPE_LOCATION_SOURCE) +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GClueWebSource, + gclue_web_source, + GCLUE_TYPE_LOCATION_SOURCE, + G_ADD_PRIVATE (GClueWebSource)) static void query_callback (SoupSession *session, @@ -105,20 +109,8 @@ get_internet_available (void) GNetworkMonitor *monitor = g_network_monitor_get_default (); gboolean available; -#if GLIB_CHECK_VERSION(2, 44, 0) available = (g_network_monitor_get_connectivity (monitor) == G_NETWORK_CONNECTIVITY_FULL); -#else - GSocketConnectable *connectable; - - connectable = g_network_address_new ("location.services.mozilla.com", - 80); - available = g_network_monitor_can_reach (monitor, - connectable, - NULL, - NULL); - g_object_unref (connectable); -#endif return available; } @@ -127,13 +119,11 @@ static void refresh_accuracy_level (GClueWebSource *web) { GClueAccuracyLevel new, existing; - gboolean available; - available = get_internet_available (); existing = gclue_location_source_get_available_accuracy_level (GCLUE_LOCATION_SOURCE (web)); new = GCLUE_WEB_SOURCE_GET_CLASS (web)->get_available_accuracy_level - (web, available); + (web, web->priv->internet_available); if (new != existing) { g_debug ("Available accuracy level from %s: %u", G_OBJECT_TYPE_NAME (web), new); @@ -152,14 +142,15 @@ on_network_changed (GNetworkMonitor *monitor G_GNUC_UNUSED, GError *error = NULL; gboolean last_available = web->priv->internet_available; + web->priv->internet_available = get_internet_available (); + if (last_available == web->priv->internet_available) + return; /* We already reacted to network change */ + refresh_accuracy_level (web); if (!gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (user_data))) return; - web->priv->internet_available = get_internet_available (); - if (last_available == web->priv->internet_available) - return; /* We already reacted to network change */ if (!web->priv->internet_available) { g_debug ("Network unavailable"); return; @@ -185,6 +176,14 @@ on_network_changed (GNetworkMonitor *monitor G_GNUC_UNUSED, web); } +static void +on_connectivity_changed (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + on_network_changed (NULL, FALSE, user_data); +} + static void gclue_web_source_finalize (GObject *gsource) { @@ -196,6 +195,12 @@ gclue_web_source_finalize (GObject *gsource) priv->network_changed_id = 0; } + if (priv->connectivity_changed_id) { + g_signal_handler_disconnect (g_network_monitor_get_default (), + priv->connectivity_changed_id); + priv->connectivity_changed_id = 0; + } + if (priv->query != NULL) { g_debug ("Cancelling query"); soup_session_cancel_message (priv->soup_session, @@ -228,6 +233,11 @@ gclue_web_source_constructed (GObject *object) "network-changed", G_CALLBACK (on_network_changed), object); + priv->connectivity_changed_id = + g_signal_connect (monitor, + "notify::connectivity", + G_CALLBACK (on_connectivity_changed), + object); on_network_changed (NULL, TRUE, object); @@ -243,8 +253,6 @@ gclue_web_source_class_init (GClueWebSourceClass *klass) gsource_class->finalize = gclue_web_source_finalize; gsource_class->constructed = gclue_web_source_constructed; - - g_type_class_add_private (klass, sizeof (GClueWebSourcePrivate)); } static void @@ -266,10 +274,10 @@ gclue_web_source_refresh (GClueWebSource *source) { g_return_if_fail (GCLUE_IS_WEB_SOURCE (source)); - if (get_internet_available ()) { - source->priv->internet_available = FALSE; - on_network_changed (NULL, TRUE, source); - } + /* Make sure ->internet_available is different from + * the real availability of internet access */ + source->priv->internet_available = FALSE; + on_network_changed (NULL, TRUE, source); } static gboolean @@ -320,14 +328,13 @@ on_submit_source_location_notify (GObject *source_object, location = gclue_location_source_get_location (source); if (location == NULL || - geocode_location_get_accuracy (GEOCODE_LOCATION (location)) > + gclue_location_get_accuracy (location) > SUBMISSION_ACCURACY_THRESHOLD || - geocode_location_get_timestamp (GEOCODE_LOCATION (location)) < + gclue_location_get_timestamp (location) < web->priv->last_submitted + SUBMISSION_TIME_THRESHOLD) return; - web->priv->last_submitted = geocode_location_get_timestamp - (GEOCODE_LOCATION (location)); + web->priv->last_submitted = gclue_location_get_timestamp (location); if (!get_internet_available ()) return; diff --git a/src/gclue-wifi.c b/src/gclue-wifi.c index cf8b04e..4dbfc7c 100644 --- a/src/gclue-wifi.c +++ b/src/gclue-wifi.c @@ -28,6 +28,12 @@ #include "gclue-error.h" #include "gclue-mozilla.h" +#define WIFI_SCAN_TIMEOUT_HIGH_ACCURACY 10 +/* Since this is only used for city-level accuracy, 5 minutes betweeen each + * scan is more than enough. + */ +#define WIFI_SCAN_TIMEOUT_LOW_ACCURACY 300 + /** * SECTION:gclue-wifi * @short_description: WiFi-based geolocation @@ -46,11 +52,13 @@ struct _GClueWifiPrivate { WPAInterface *interface; GHashTable *bss_proxies; GHashTable *ignored_bss_proxies; + gboolean bss_list_changed; gulong bss_added_id; gulong bss_removed_id; + gulong scan_done_id; - guint refresh_timeout; + guint scan_timeout; GClueAccuracyLevel accuracy_level; }; @@ -78,10 +86,21 @@ static GClueAccuracyLevel gclue_wifi_get_available_accuracy_level (GClueWebSource *source, gboolean net_available); -G_DEFINE_TYPE (GClueWifi, gclue_wifi, GCLUE_TYPE_WEB_SOURCE) +G_DEFINE_TYPE_WITH_CODE (GClueWifi, + gclue_wifi, + GCLUE_TYPE_WEB_SOURCE, + G_ADD_PRIVATE (GClueWifi)) static void disconnect_bss_signals (GClueWifi *wifi); +static void +on_scan_call_done (GObject *source_object, + GAsyncResult *res, + gpointer user_data); +static void +on_scan_done (WPAInterface *object, + gboolean success, + gpointer user_data); static void gclue_wifi_finalize (GObject *gwifi) @@ -155,8 +174,6 @@ gclue_wifi_class_init (GClueWifiClass *klass) gwifi_class->finalize = gclue_wifi_finalize; gwifi_class->constructed = gclue_wifi_constructed; - g_type_class_add_private (klass, sizeof (GClueWifiPrivate)); - gParamSpecs[PROP_ACCURACY_LEVEL] = g_param_spec_enum ("accuracy-level", "AccuracyLevel", "Max accuracy level", @@ -169,16 +186,6 @@ gclue_wifi_class_init (GClueWifiClass *klass) gParamSpecs[PROP_ACCURACY_LEVEL]); } -static gboolean -on_refresh_timeout (gpointer user_data) -{ - g_debug ("Refreshing location.."); - gclue_web_source_refresh (GCLUE_WEB_SOURCE (user_data)); - GCLUE_WIFI (user_data)->priv->refresh_timeout = 0; - - return FALSE; -} - static void on_bss_added (WPAInterface *object, const gchar *path, @@ -244,25 +251,18 @@ add_bss_proxy (GClueWifi *wifi, WPABSS *bss) { const char *path; - char *ssid; - - ssid = get_ssid_from_bss (bss); - g_debug ("WiFi AP '%s' added.", ssid); - g_free (ssid); - - /* There could be multiple devices being added/removed at the same time - * so we don't immediately call refresh but rather wait 1 second. - */ - if (wifi->priv->refresh_timeout != 0) - g_source_remove (wifi->priv->refresh_timeout); - wifi->priv->refresh_timeout = g_timeout_add_seconds (1, - on_refresh_timeout, - wifi); path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (bss)); - g_hash_table_replace (wifi->priv->bss_proxies, - g_strdup (path), - bss); + if (g_hash_table_replace (wifi->priv->bss_proxies, + g_strdup (path), + bss)) { + char *ssid; + + wifi->priv->bss_list_changed = TRUE; + ssid = get_ssid_from_bss (bss); + g_debug ("WiFi AP '%s' added.", ssid); + g_free (ssid); + } } static void @@ -357,6 +357,25 @@ on_bss_added (WPAInterface *object, user_data); } +static gboolean +remove_bss_from_hashtable (const gchar *path, GHashTable *hash_table) +{ + char *ssid; + WPABSS *bss = NULL; + + bss = g_hash_table_lookup (hash_table, path); + if (bss == NULL) + return FALSE; + + ssid = get_ssid_from_bss (bss); + g_debug ("WiFi AP '%s' removed.", ssid); + g_free (ssid); + + g_hash_table_remove (hash_table, path); + + return TRUE; +} + static void on_bss_removed (WPAInterface *object, const gchar *path, @@ -364,8 +383,123 @@ on_bss_removed (WPAInterface *object, { GClueWifiPrivate *priv = GCLUE_WIFI (user_data)->priv; - g_hash_table_remove (priv->bss_proxies, path); - g_hash_table_remove (priv->ignored_bss_proxies, path); + if (remove_bss_from_hashtable (path, priv->bss_proxies)) + priv->bss_list_changed = TRUE; + remove_bss_from_hashtable (path, priv->ignored_bss_proxies); +} + +static void +cancel_wifi_scan (GClueWifi *wifi) +{ + GClueWifiPrivate *priv = wifi->priv; + + if (priv->scan_timeout != 0) { + g_source_remove (priv->scan_timeout); + priv->scan_timeout = 0; + } + + if (priv->scan_done_id != 0) { + g_signal_handler_disconnect (priv->interface, + priv->scan_done_id); + priv->scan_done_id = 0; + } +} + +static gboolean +on_scan_timeout (gpointer user_data) +{ + GClueWifi *wifi = GCLUE_WIFI (user_data); + GClueWifiPrivate *priv = wifi->priv; + GVariantBuilder builder; + GVariant *args; + + if (priv->interface == NULL) + return FALSE; + + g_debug ("WiFi scan timeout. Restarting-scan.."); + priv->scan_timeout = 0; + + if (priv->scan_done_id == 0) + priv->scan_done_id = g_signal_connect + (priv->interface, + "scan-done", + G_CALLBACK (on_scan_done), + wifi); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, + "{sv}", + "Type", g_variant_new ("s", "passive")); + args = g_variant_builder_end (&builder); + + wpa_interface_call_scan (WPA_INTERFACE (priv->interface), + args, + NULL, + on_scan_call_done, + wifi); + + return FALSE; +} + +static void +on_scan_done (WPAInterface *object, + gboolean success, + gpointer user_data) +{ + GClueWifi *wifi = GCLUE_WIFI (user_data); + GClueWifiPrivate *priv = wifi->priv; + guint timeout; + + if (!success) { + g_warning ("WiFi scan failed"); + + return; + } + g_debug ("WiFi scan completed"); + + if (priv->interface == NULL) + return; + + if (priv->bss_list_changed) { + priv->bss_list_changed = FALSE; + g_debug ("Refreshing location.."); + gclue_web_source_refresh (GCLUE_WEB_SOURCE (wifi)); + } + + /* With high-enough accuracy requests, we need to scan more often since + * user's location can change quickly. With low accuracy, we don't since + * we wouldn't want to drain power unnecessarily. + */ + if (priv->accuracy_level >= GCLUE_ACCURACY_LEVEL_STREET) + timeout = WIFI_SCAN_TIMEOUT_HIGH_ACCURACY; + else + timeout = WIFI_SCAN_TIMEOUT_LOW_ACCURACY; + priv->scan_timeout = g_timeout_add_seconds (timeout, + on_scan_timeout, + wifi); + g_debug ("Next scan scheduled in %u seconds", timeout); +} + +static void +on_scan_call_done (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GClueWifi *wifi = GCLUE_WIFI (user_data); + GError *error = NULL; + + if (!wpa_interface_call_scan_finish + (WPA_INTERFACE (source_object), + res, + &error)) { + g_warning ("Scanning of WiFi networks failed: %s", + error->message); + g_error_free (error); + + cancel_wifi_scan (wifi); + + return; + } } static void @@ -383,6 +517,9 @@ connect_bss_signals (GClueWifi *wifi) return; } + on_scan_timeout (wifi); + + priv->bss_list_changed = TRUE; priv->bss_added_id = g_signal_connect (priv->interface, "bss-added", G_CALLBACK (on_bss_added), @@ -411,18 +548,14 @@ disconnect_bss_signals (GClueWifi *wifi) if (priv->bss_added_id == 0 || priv->interface == NULL) return; + cancel_wifi_scan (wifi); g_signal_handler_disconnect (priv->interface, priv->bss_added_id); priv->bss_added_id = 0; g_signal_handler_disconnect (priv->interface, priv->bss_removed_id); priv->bss_removed_id = 0; - if (priv->refresh_timeout != 0) { - g_source_remove (priv->refresh_timeout); - priv->refresh_timeout = 0; - } - - g_hash_table_remove_all (wifi->priv->bss_proxies); - g_hash_table_remove_all (wifi->priv->ignored_bss_proxies); + g_hash_table_remove_all (priv->bss_proxies); + g_hash_table_remove_all (priv->ignored_bss_proxies); } static gboolean diff --git a/src/geocode-glib/geocode-bounding-box.c b/src/geocode-glib/geocode-bounding-box.c deleted file mode 100644 index 5d39e37..0000000 --- a/src/geocode-glib/geocode-bounding-box.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - Copyright 2013 Jonas Danielsson - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Jonas Danielsson <jonas@threetimestwo.org> - - */ - -#include <geocode-glib/geocode-bounding-box.h> - -/** - * SECTION:geocode-bounding-box - * @short_description: Geocode BoundingBox object - * @include: geocode-glib/geocode-bounding-box.h - * - * The #GeocodeBoundingBox represents a geographical area on earth, bounded - * by top, bottom, left and right coordinates. - **/ - -struct _GeocodeBoundingBoxPrivate { - gdouble top; - gdouble bottom; - gdouble left; - gdouble right; -}; - -enum { - PROP_0, - - PROP_TOP, - PROP_BOTTOM, - PROP_LEFT, - PROP_RIGHT -}; - -G_DEFINE_TYPE (GeocodeBoundingBox, geocode_bounding_box, G_TYPE_OBJECT) - -static void -geocode_bounding_box_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GeocodeBoundingBox *bbox = GEOCODE_BOUNDING_BOX (object); - - switch (property_id) { - case PROP_TOP: - g_value_set_double (value, - geocode_bounding_box_get_top (bbox)); - break; - - case PROP_BOTTOM: - g_value_set_double (value, - geocode_bounding_box_get_bottom (bbox)); - break; - - case PROP_LEFT: - g_value_set_double (value, - geocode_bounding_box_get_left (bbox)); - break; - - case PROP_RIGHT: - g_value_set_double (value, - geocode_bounding_box_get_right (bbox)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_bounding_box_set_top (GeocodeBoundingBox *bbox, - gdouble top) -{ - g_return_if_fail (top >= -90.0 && top <= 90.0); - - bbox->priv->top = top; -} - -static void -geocode_bounding_box_set_bottom (GeocodeBoundingBox *bbox, - gdouble bottom) -{ - g_return_if_fail (bottom >= -90.0 && bottom <= 90.0); - - bbox->priv->bottom = bottom; -} - -static void -geocode_bounding_box_set_left (GeocodeBoundingBox *bbox, - gdouble left) -{ - g_return_if_fail (left >= -180.0 && left <= 180.0); - - bbox->priv->left = left; -} - -static void -geocode_bounding_box_set_right (GeocodeBoundingBox *bbox, - gdouble right) -{ - g_return_if_fail (right >= -180.0 && right <= 180.0); - - bbox->priv->right = right; -} - -static void -geocode_bounding_box_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GeocodeBoundingBox *bbox = GEOCODE_BOUNDING_BOX (object); - - switch (property_id) { - case PROP_TOP: - geocode_bounding_box_set_top (bbox, - g_value_get_double (value)); - break; - - case PROP_BOTTOM: - geocode_bounding_box_set_bottom (bbox, - g_value_get_double (value)); - break; - - case PROP_LEFT: - geocode_bounding_box_set_left (bbox, - g_value_get_double (value)); - break; - - case PROP_RIGHT: - geocode_bounding_box_set_right (bbox, - g_value_get_double (value)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_bounding_box_finalize (GObject *gbbox) -{ - G_OBJECT_CLASS (geocode_bounding_box_parent_class)->finalize (gbbox); -} - -static void -geocode_bounding_box_class_init (GeocodeBoundingBoxClass *klass) -{ - GObjectClass *gbbox_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gbbox_class->finalize = geocode_bounding_box_finalize; - gbbox_class->get_property = geocode_bounding_box_get_property; - gbbox_class->set_property = geocode_bounding_box_set_property; - - g_type_class_add_private (klass, sizeof (GeocodeBoundingBoxPrivate)); - - /** - * GeocodeBoundingBox:top: - * - * Top coordinate. - */ - pspec = g_param_spec_double ("top", - "Top", - "Top coordinate", - -90, - 90, - 0.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gbbox_class, PROP_TOP, pspec); - - /** - * GeocodeBoundingBox:bottom: - * - * Bottom coordinate. - */ - pspec = g_param_spec_double ("bottom", - "Bottom", - "Bottom coordinate", - -90, - 90, - 0.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gbbox_class, PROP_BOTTOM, pspec); - - /** - * GeocodeBoundingBox:left: - * - * Left coordinate. - */ - pspec = g_param_spec_double ("left", - "Left", - "Left coordinate", - -180, - 180, - 0.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gbbox_class, PROP_LEFT, pspec); - - /** - * GeocodeBoundingBox:right: - * - * Right coordinate. - */ - pspec = g_param_spec_double ("right", - "Right", - "Right coordinate", - -180, - 180, - 0.0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gbbox_class, PROP_RIGHT, pspec); - -} - -static void -geocode_bounding_box_init (GeocodeBoundingBox *bbox) -{ - bbox->priv = G_TYPE_INSTANCE_GET_PRIVATE ((bbox), - GEOCODE_TYPE_BOUNDING_BOX, - GeocodeBoundingBoxPrivate); -} - -/** - * geocode_bounding_box_new: - * @top: The left coordinate - * @bottom: The bottom coordinate - * @left: The left coordinate - * @right: The right coordinate - * - * Creates a new #GeocodeBoundingBox object. - * - * Returns: a new #GeocodeBoundingBox object. Use g_object_unref() when done. - **/ -GeocodeBoundingBox * -geocode_bounding_box_new (gdouble top, - gdouble bottom, - gdouble left, - gdouble right) -{ - return g_object_new (GEOCODE_TYPE_BOUNDING_BOX, - "top", top, - "bottom", bottom, - "left", left, - "right", right, - NULL); -} - -/** - * geocode_bounding_box_get_top: - * @bbox: a #GeocodeBoundingBox - * - * Gets the top coordinate of @bbox. - * - * Returns: the top coordinate of @bbox. - **/ -gdouble -geocode_bounding_box_get_top (GeocodeBoundingBox *bbox) -{ - g_return_val_if_fail (GEOCODE_IS_BOUNDING_BOX (bbox), 0.0); - - return bbox->priv->top; -} - -/** - * geocode_bounding_box_get_bottom: - * @bbox: a #GeocodeBoundingBox - * - * Gets the bottom coordinate of @bbox. - * - * Returns: the bottom coordinate of @bbox. - **/ -gdouble -geocode_bounding_box_get_bottom (GeocodeBoundingBox *bbox) -{ - g_return_val_if_fail (GEOCODE_IS_BOUNDING_BOX (bbox), 0.0); - - return bbox->priv->bottom; -} - -/** - * geocode_bounding_box_get_left: - * @bbox: a #GeocodeBoundingBox - * - * Gets the left coordinate of @bbox. - * - * Returns: the left coordinate of @bbox. - **/ -gdouble -geocode_bounding_box_get_left (GeocodeBoundingBox *bbox) -{ - g_return_val_if_fail (GEOCODE_IS_BOUNDING_BOX (bbox), 0.0); - - return bbox->priv->left; -} - -/** - * geocode_bounding_box_get_right: - * @bbox: a #GeocodeBoundingBox - * - * Gets the right coordinate of @bbox. - * - * Returns: the right coordinate of @bbox. - **/ -gdouble -geocode_bounding_box_get_right (GeocodeBoundingBox *bbox) -{ - g_return_val_if_fail (GEOCODE_IS_BOUNDING_BOX (bbox), 0.0); - - return bbox->priv->right; -} diff --git a/src/geocode-glib/geocode-bounding-box.h b/src/geocode-glib/geocode-bounding-box.h deleted file mode 100644 index e6b267c..0000000 --- a/src/geocode-glib/geocode-bounding-box.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright 2013 Jonas Danielsson - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Jonas Danielsson <jonas@threetimestwo.org> - - */ - -#ifndef GEOCODE_BOUNDING_BOX_H -#define GEOCODE_BOUNDING_BOX_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -GType geocode_bounding_box_get_type (void) G_GNUC_CONST; - -#define GEOCODE_TYPE_BOUNDING_BOX (geocode_bounding_box_get_type ()) -#define GEOCODE_BOUNDING_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_BOUNDING_BOX, GeocodeBoundingBox)) -#define GEOCODE_IS_BOUNDING_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_BOUNDING_BOX)) -#define GEOCODE_BOUNDING_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_BOUNDING_BOX, GeocodeBoundingBoxClass)) -#define GEOCODE_IS_BOUNDING_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_BOUNDING_BOX)) -#define GEOCODE_BOUNDING_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_BOUNDING_BOX, GeocodeBoundingBoxClass)) - - -typedef struct _GeocodeBoundingBox GeocodeBoundingBox; -typedef struct _GeocodeBoundingBoxClass GeocodeBoundingBoxClass; -typedef struct _GeocodeBoundingBoxPrivate GeocodeBoundingBoxPrivate; - -/** - * GeocodeBoundingBox: - * - * All the fields in the #GeocodeLocation structure are private and should - * never be accessed directly. -**/ -struct _GeocodeBoundingBox { - /* <private> */ - GObject parent_instance; - GeocodeBoundingBoxPrivate *priv; -}; - -/** - * GeocodeBoundingBoxClass: - * - * All the fields in the #GeocodeBoundingBoxClass structure are private and - * should never be accessed directly. -**/ -struct _GeocodeBoundingBoxClass { - /* <private> */ - GObjectClass parent_class; -}; - -GeocodeBoundingBox *geocode_bounding_box_new (gdouble top, - gdouble bottom, - gdouble left, - gdouble right); - -gdouble geocode_bounding_box_get_top (GeocodeBoundingBox *bbox); -gdouble geocode_bounding_box_get_bottom (GeocodeBoundingBox *bbox); -gdouble geocode_bounding_box_get_left (GeocodeBoundingBox *bbox); -gdouble geocode_bounding_box_get_right (GeocodeBoundingBox *bbox); - -G_END_DECLS - -#endif /* GEOCODE_BOUNDING_BOX_H */ diff --git a/src/geocode-glib/geocode-enum-types.c b/src/geocode-glib/geocode-enum-types.c deleted file mode 100644 index 9422774..0000000 --- a/src/geocode-glib/geocode-enum-types.c +++ /dev/null @@ -1,120 +0,0 @@ - - - -#include <geocode-glib/geocode-glib.h> -#include <geocode-glib/geocode-enum-types.h> - -/* enumerations from "geocode-location.h" */ -GType -geocode_location_uri_scheme_get_type (void) -{ - static GType etype = 0; - if (etype == 0) { - static const GEnumValue values[] = { - { GEOCODE_LOCATION_URI_SCHEME_GEO, "GEOCODE_LOCATION_URI_SCHEME_GEO", "geo" }, - { 0, NULL, NULL } - }; - etype = g_enum_register_static ("GeocodeLocationURIScheme", values); - } - return etype; -} -GType -geocode_location_crs_get_type (void) -{ - static GType etype = 0; - if (etype == 0) { - static const GEnumValue values[] = { - { GEOCODE_LOCATION_CRS_WGS84, "GEOCODE_LOCATION_CRS_WGS84", "wgs84" }, - { 0, NULL, NULL } - }; - etype = g_enum_register_static ("GeocodeLocationCRS", values); - } - return etype; -} - -/* enumerations from "geocode-error.h" */ -GType -geocode_error_get_type (void) -{ - static GType etype = 0; - if (etype == 0) { - static const GEnumValue values[] = { - { GEOCODE_ERROR_PARSE, "GEOCODE_ERROR_PARSE", "parse" }, - { GEOCODE_ERROR_NOT_SUPPORTED, "GEOCODE_ERROR_NOT_SUPPORTED", "not-supported" }, - { GEOCODE_ERROR_NO_MATCHES, "GEOCODE_ERROR_NO_MATCHES", "no-matches" }, - { GEOCODE_ERROR_INVALID_ARGUMENTS, "GEOCODE_ERROR_INVALID_ARGUMENTS", "invalid-arguments" }, - { GEOCODE_ERROR_INTERNAL_SERVER, "GEOCODE_ERROR_INTERNAL_SERVER", "internal-server" }, - { 0, NULL, NULL } - }; - etype = g_enum_register_static ("GeocodeError", values); - } - return etype; -} - -/* enumerations from "geocode-place.h" */ -GType -geocode_place_type_get_type (void) -{ - static GType etype = 0; - if (etype == 0) { - static const GEnumValue values[] = { - { GEOCODE_PLACE_TYPE_UNKNOWN, "GEOCODE_PLACE_TYPE_UNKNOWN", "unknown" }, - { GEOCODE_PLACE_TYPE_BUILDING, "GEOCODE_PLACE_TYPE_BUILDING", "building" }, - { GEOCODE_PLACE_TYPE_STREET, "GEOCODE_PLACE_TYPE_STREET", "street" }, - { GEOCODE_PLACE_TYPE_TOWN, "GEOCODE_PLACE_TYPE_TOWN", "town" }, - { GEOCODE_PLACE_TYPE_STATE, "GEOCODE_PLACE_TYPE_STATE", "state" }, - { GEOCODE_PLACE_TYPE_COUNTY, "GEOCODE_PLACE_TYPE_COUNTY", "county" }, - { GEOCODE_PLACE_TYPE_LOCAL_ADMINISTRATIVE_AREA, "GEOCODE_PLACE_TYPE_LOCAL_ADMINISTRATIVE_AREA", "local-administrative-area" }, - { GEOCODE_PLACE_TYPE_POSTAL_CODE, "GEOCODE_PLACE_TYPE_POSTAL_CODE", "postal-code" }, - { GEOCODE_PLACE_TYPE_COUNTRY, "GEOCODE_PLACE_TYPE_COUNTRY", "country" }, - { GEOCODE_PLACE_TYPE_ISLAND, "GEOCODE_PLACE_TYPE_ISLAND", "island" }, - { GEOCODE_PLACE_TYPE_AIRPORT, "GEOCODE_PLACE_TYPE_AIRPORT", "airport" }, - { GEOCODE_PLACE_TYPE_RAILWAY_STATION, "GEOCODE_PLACE_TYPE_RAILWAY_STATION", "railway-station" }, - { GEOCODE_PLACE_TYPE_BUS_STOP, "GEOCODE_PLACE_TYPE_BUS_STOP", "bus-stop" }, - { GEOCODE_PLACE_TYPE_MOTORWAY, "GEOCODE_PLACE_TYPE_MOTORWAY", "motorway" }, - { GEOCODE_PLACE_TYPE_DRAINAGE, "GEOCODE_PLACE_TYPE_DRAINAGE", "drainage" }, - { GEOCODE_PLACE_TYPE_LAND_FEATURE, "GEOCODE_PLACE_TYPE_LAND_FEATURE", "land-feature" }, - { GEOCODE_PLACE_TYPE_MISCELLANEOUS, "GEOCODE_PLACE_TYPE_MISCELLANEOUS", "miscellaneous" }, - { GEOCODE_PLACE_TYPE_SUPERNAME, "GEOCODE_PLACE_TYPE_SUPERNAME", "supername" }, - { GEOCODE_PLACE_TYPE_POINT_OF_INTEREST, "GEOCODE_PLACE_TYPE_POINT_OF_INTEREST", "point-of-interest" }, - { GEOCODE_PLACE_TYPE_SUBURB, "GEOCODE_PLACE_TYPE_SUBURB", "suburb" }, - { GEOCODE_PLACE_TYPE_COLLOQUIAL, "GEOCODE_PLACE_TYPE_COLLOQUIAL", "colloquial" }, - { GEOCODE_PLACE_TYPE_ZONE, "GEOCODE_PLACE_TYPE_ZONE", "zone" }, - { GEOCODE_PLACE_TYPE_HISTORICAL_STATE, "GEOCODE_PLACE_TYPE_HISTORICAL_STATE", "historical-state" }, - { GEOCODE_PLACE_TYPE_HISTORICAL_COUNTY, "GEOCODE_PLACE_TYPE_HISTORICAL_COUNTY", "historical-county" }, - { GEOCODE_PLACE_TYPE_CONTINENT, "GEOCODE_PLACE_TYPE_CONTINENT", "continent" }, - { GEOCODE_PLACE_TYPE_TIME_ZONE, "GEOCODE_PLACE_TYPE_TIME_ZONE", "time-zone" }, - { GEOCODE_PLACE_TYPE_ESTATE, "GEOCODE_PLACE_TYPE_ESTATE", "estate" }, - { GEOCODE_PLACE_TYPE_HISTORICAL_TOWN, "GEOCODE_PLACE_TYPE_HISTORICAL_TOWN", "historical-town" }, - { GEOCODE_PLACE_TYPE_OCEAN, "GEOCODE_PLACE_TYPE_OCEAN", "ocean" }, - { GEOCODE_PLACE_TYPE_SEA, "GEOCODE_PLACE_TYPE_SEA", "sea" }, - { GEOCODE_PLACE_TYPE_SCHOOL, "GEOCODE_PLACE_TYPE_SCHOOL", "school" }, - { GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP, "GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP", "place-of-worship" }, - { GEOCODE_PLACE_TYPE_RESTAURANT, "GEOCODE_PLACE_TYPE_RESTAURANT", "restaurant" }, - { GEOCODE_PLACE_TYPE_BAR, "GEOCODE_PLACE_TYPE_BAR", "bar" }, - { GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION, "GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION", "light-rail-station" }, - { 0, NULL, NULL } - }; - etype = g_enum_register_static ("GeocodePlaceType", values); - } - return etype; -} -GType -geocode_place_osm_type_get_type (void) -{ - static GType etype = 0; - if (etype == 0) { - static const GEnumValue values[] = { - { GEOCODE_PLACE_OSM_TYPE_UNKNOWN, "GEOCODE_PLACE_OSM_TYPE_UNKNOWN", "unknown" }, - { GEOCODE_PLACE_OSM_TYPE_NODE, "GEOCODE_PLACE_OSM_TYPE_NODE", "node" }, - { GEOCODE_PLACE_OSM_TYPE_RELATION, "GEOCODE_PLACE_OSM_TYPE_RELATION", "relation" }, - { GEOCODE_PLACE_OSM_TYPE_WAY, "GEOCODE_PLACE_OSM_TYPE_WAY", "way" }, - { 0, NULL, NULL } - }; - etype = g_enum_register_static ("GeocodePlaceOsmType", values); - } - return etype; -} - - - diff --git a/src/geocode-glib/geocode-enum-types.h b/src/geocode-glib/geocode-enum-types.h deleted file mode 100644 index 663e105..0000000 --- a/src/geocode-glib/geocode-enum-types.h +++ /dev/null @@ -1,68 +0,0 @@ - - - -#ifndef __GEOCODE_ENUM_TYPES_H__ -#define __GEOCODE_ENUM_TYPES_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS -/* enumerations from "geocode-location.h" */ -GType geocode_location_uri_scheme_get_type (void) G_GNUC_CONST; -#define GEOCODE_TYPE_LOCATION_URI_SCHEME (geocode_location_uri_scheme_get_type()) - -/** - * SECTION:geocode-enum-types - * @short_description: Geocode enumerated types - * @include: geocode-glib/geocode-glib.h - * - * The enumerated types defined and used by geocode-glib. - **/ -GType geocode_location_crs_get_type (void) G_GNUC_CONST; -#define GEOCODE_TYPE_LOCATION_CRS (geocode_location_crs_get_type()) - -/** - * SECTION:geocode-enum-types - * @short_description: Geocode enumerated types - * @include: geocode-glib/geocode-glib.h - * - * The enumerated types defined and used by geocode-glib. - **/ -/* enumerations from "geocode-error.h" */ -GType geocode_error_get_type (void) G_GNUC_CONST; -#define GEOCODE_TYPE_ERROR (geocode_error_get_type()) - -/** - * SECTION:geocode-enum-types - * @short_description: Geocode enumerated types - * @include: geocode-glib/geocode-glib.h - * - * The enumerated types defined and used by geocode-glib. - **/ -/* enumerations from "geocode-place.h" */ -GType geocode_place_type_get_type (void) G_GNUC_CONST; -#define GEOCODE_TYPE_PLACE_TYPE (geocode_place_type_get_type()) - -/** - * SECTION:geocode-enum-types - * @short_description: Geocode enumerated types - * @include: geocode-glib/geocode-glib.h - * - * The enumerated types defined and used by geocode-glib. - **/ -GType geocode_place_osm_type_get_type (void) G_GNUC_CONST; -#define GEOCODE_TYPE_PLACE_OSM_TYPE (geocode_place_osm_type_get_type()) - -/** - * SECTION:geocode-enum-types - * @short_description: Geocode enumerated types - * @include: geocode-glib/geocode-glib.h - * - * The enumerated types defined and used by geocode-glib. - **/ -G_END_DECLS - -#endif /* __GEOCODE_ENUM_TYPES_H__ */ - - - diff --git a/src/geocode-glib/geocode-error.c b/src/geocode-glib/geocode-error.c deleted file mode 100644 index edc1321..0000000 --- a/src/geocode-glib/geocode-error.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#include <geocode-glib/geocode-error.h> - -/** - * SECTION:geocode-error - * @short_description: Error helper functions - * @include: geocode-glib/geocode-glib.h - * - * Contains helper functions for reporting errors to the user. - **/ - -/** - * geocode_error_quark: - * - * Gets the geocode-glib error quark. - * - * Return value: a #GQuark. - **/ -GQuark -geocode_error_quark (void) -{ - static GQuark quark; - if (!quark) - quark = g_quark_from_static_string ("geocode_error"); - - return quark; -} - diff --git a/src/geocode-glib/geocode-error.h b/src/geocode-glib/geocode-error.h deleted file mode 100644 index 50d1bce..0000000 --- a/src/geocode-glib/geocode-error.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#ifndef GEOCODE_ERROR_H -#define GEOCODE_ERROR_H - -#include <glib.h> - -G_BEGIN_DECLS - -/** - * GEOCODE_ERROR: - * - * Error domain for geocode-glib. Errors from this domain will be from - * the #GeocodeError enumeration. - * See #GError for more information on error domains. - **/ -#define GEOCODE_ERROR (geocode_error_quark ()) - -/** - * GeocodeError: - * @GEOCODE_ERROR_PARSE: An error occured parsing the response from the web service. - * @GEOCODE_ERROR_NOT_SUPPORTED: The request made was not supported. - * @GEOCODE_ERROR_NO_MATCHES: The requests made didn't have any matches. - * @GEOCODE_ERROR_INVALID_ARGUMENTS: The request made contained invalid arguments. - * @GEOCODE_ERROR_INTERNAL_SERVER: The server encountered an (possibly unrecoverable) internal error. - * - * Error codes returned by geocode-glib functions. - **/ -typedef enum { - GEOCODE_ERROR_PARSE, - GEOCODE_ERROR_NOT_SUPPORTED, - GEOCODE_ERROR_NO_MATCHES, - GEOCODE_ERROR_INVALID_ARGUMENTS, - GEOCODE_ERROR_INTERNAL_SERVER -} GeocodeError; - -GQuark geocode_error_quark (void); - -G_END_DECLS - -#endif /* GEOCODE_ERROR_H */ diff --git a/src/geocode-glib/geocode-forward.c b/src/geocode-glib/geocode-forward.c deleted file mode 100644 index e5ab429..0000000 --- a/src/geocode-glib/geocode-forward.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#include <string.h> -#include <stdlib.h> -#include <locale.h> -#include <gio/gio.h> -#include <json-glib/json-glib.h> -#include <libsoup/soup.h> -#include <geocode-glib/geocode-forward.h> -#include <geocode-glib/geocode-bounding-box.h> -#include <geocode-glib/geocode-error.h> -#include <geocode-glib/geocode-glib-private.h> - -/** - * SECTION:geocode-forward - * @short_description: Geocode forward geocoding object - * @include: geocode-glib/geocode-glib.h - * - * Contains functions for geocoding using the - * <ulink url="http://wiki.openstreetmap.org/wiki/Nominatim">OSM Nominatim APIs</ulink> - **/ - -struct _GeocodeForwardPrivate { - GHashTable *ht; - SoupSession *soup_session; - guint answer_count; - GeocodeBoundingBox *search_area; - gboolean bounded; -}; - -enum { - PROP_0, - - PROP_ANSWER_COUNT, - PROP_SEARCH_AREA, - PROP_BOUNDED -}; - -G_DEFINE_TYPE (GeocodeForward, geocode_forward, G_TYPE_OBJECT) - -static void -geocode_forward_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GeocodeForward *forward = GEOCODE_FORWARD (object); - - switch (property_id) { - case PROP_ANSWER_COUNT: - g_value_set_uint (value, - geocode_forward_get_answer_count (forward)); - break; - - case PROP_SEARCH_AREA: - g_value_set_object (value, - geocode_forward_get_search_area (forward)); - break; - - case PROP_BOUNDED: - g_value_set_boolean (value, - geocode_forward_get_bounded (forward)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_forward_set_property(GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GeocodeForward *forward = GEOCODE_FORWARD (object); - - switch (property_id) { - case PROP_ANSWER_COUNT: - geocode_forward_set_answer_count (forward, - g_value_get_uint (value)); - break; - - case PROP_SEARCH_AREA: - geocode_forward_set_search_area (forward, - g_value_get_object (value)); - break; - - case PROP_BOUNDED: - geocode_forward_set_bounded (forward, - g_value_get_boolean (value)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -static void geocode_forward_add (GeocodeForward *forward, - const char *key, - const char *value); - -static void -geocode_forward_finalize (GObject *gforward) -{ - GeocodeForward *forward = (GeocodeForward *) gforward; - - g_clear_pointer (&forward->priv->ht, g_hash_table_destroy); - g_clear_object (&forward->priv->soup_session); - - G_OBJECT_CLASS (geocode_forward_parent_class)->finalize (gforward); -} - -static void -geocode_forward_class_init (GeocodeForwardClass *klass) -{ - GObjectClass *gforward_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gforward_class->finalize = geocode_forward_finalize; - gforward_class->get_property = geocode_forward_get_property; - gforward_class->set_property = geocode_forward_set_property; - - - g_type_class_add_private (klass, sizeof (GeocodeForwardPrivate)); - - /** - * GeocodeForward:answer-count: - * - * The number of requested results to a search query. - */ - pspec = g_param_spec_uint ("answer-count", - "Answer count", - "The number of requested results", - 0, - G_MAXINT, - DEFAULT_ANSWER_COUNT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gforward_class, PROP_ANSWER_COUNT, pspec); - - /** - * GeocodeForward:search-area: - * - * The bounding box that limits the search area. - * If #GeocodeForward:bounded property is set to #TRUE only results from - * this area is returned. - */ - pspec = g_param_spec_object ("search-area", - "Search area", - "The area to limit search within", - GEOCODE_TYPE_BOUNDING_BOX, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gforward_class, PROP_SEARCH_AREA, pspec); - - /** - * GeocodeForward:bounded: - * - * If set to #TRUE then only results in the #GeocodeForward:search-area - * bounding box are returned. - * If set to #FALSE the #GeocodeForward:search-area is treated like a - * preferred area for results. - */ - pspec = g_param_spec_boolean ("bounded", - "Bounded", - "Bind search results to search-area", - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gforward_class, PROP_BOUNDED, pspec); -} - -static void -geocode_forward_init (GeocodeForward *forward) -{ - forward->priv = G_TYPE_INSTANCE_GET_PRIVATE ((forward), GEOCODE_TYPE_FORWARD, GeocodeForwardPrivate); - forward->priv->ht = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - forward->priv->soup_session = _geocode_glib_build_soup_session (); - forward->priv->answer_count = DEFAULT_ANSWER_COUNT; - forward->priv->search_area = NULL; - forward->priv->bounded = FALSE; -} - -static struct { - const char *tp_attr; - const char *gc_attr; /* NULL to ignore */ -} attrs_map[] = { - { "countrycode", NULL }, - { "country", "country" }, - { "region", "state" }, - { "county", "county" }, - { "locality", "city" }, - { "area", NULL }, - { "postalcode", "postalcode" }, - { "street", "street" }, - { "building", NULL }, - { "floor", NULL }, - { "room", NULL }, - { "text", NULL }, - { "description", NULL }, - { "uri", NULL }, - { "language", "accept-language" }, -}; - -static const char * -tp_attr_to_gc_attr (const char *attr, - gboolean *found) -{ - guint i; - - *found = FALSE; - - for (i = 0; i < G_N_ELEMENTS (attrs_map); i++) { - if (g_str_equal (attr, attrs_map[i].tp_attr)){ - *found = TRUE; - return attrs_map[i].gc_attr; - } - } - - return NULL; -} - -static void -geocode_forward_fill_params (GeocodeForward *forward, - GHashTable *params) -{ - GHashTableIter iter; - GValue *value; - const char *key; - - g_hash_table_iter_init (&iter, params); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) { - gboolean found; - const char *gc_attr; - const char *str; - - gc_attr = tp_attr_to_gc_attr (key, &found); - if (found == FALSE) { - g_warning ("XEP attribute '%s' unhandled", key); - continue; - } - if (gc_attr == NULL) - continue; - - str = g_value_get_string (value); - if (str == NULL) - continue; - - geocode_forward_add (forward, gc_attr, str); - } -} - -/** - * geocode_forward_new_for_params: - * @params: (transfer none) (element-type utf8 GValue): a #GHashTable with string keys, and #GValue values. - * - * Creates a new #GeocodeForward to perform geocoding with. The - * #GHashTable is in the format used by Telepathy, and documented - * on <ulink url="http://telepathy.freedesktop.org/spec/Connection_Interface_Location.html#Mapping:Location">Telepathy's specification site</ulink>. - * - * See also: <ulink url="http://xmpp.org/extensions/xep-0080.html">XEP-0080 specification</ulink>. - * - * Returns: a new #GeocodeForward. Use g_object_unref() when done. - **/ -GeocodeForward * -geocode_forward_new_for_params (GHashTable *params) -{ - GeocodeForward *forward; - - g_return_val_if_fail (params != NULL, NULL); - - if (g_hash_table_lookup (params, "lat") != NULL && - g_hash_table_lookup (params, "long") != NULL) { - g_warning ("You already have longitude and latitude in those parameters"); - } - - forward = g_object_new (GEOCODE_TYPE_FORWARD, NULL); - geocode_forward_fill_params (forward, params); - - return forward; -} - -/** - * geocode_forward_new_for_string: - * @str: a string containing a free-form description of the location - * - * Creates a new #GeocodeForward to perform forward geocoding with. The - * string is in free-form format. - * - * Returns: a new #GeocodeForward. Use g_object_unref() when done. - **/ -GeocodeForward * -geocode_forward_new_for_string (const char *location) -{ - GeocodeForward *forward; - - g_return_val_if_fail (location != NULL, NULL); - - forward = g_object_new (GEOCODE_TYPE_FORWARD, NULL); - geocode_forward_add (forward, "location", location); - - return forward; -} - -static void -geocode_forward_add (GeocodeForward *forward, - const char *key, - const char *value) -{ - g_return_if_fail (GEOCODE_IS_FORWARD (forward)); - g_return_if_fail (key != NULL); - g_return_if_fail (value == NULL || g_utf8_validate (value, -1, NULL)); - - g_hash_table_insert (forward->priv->ht, - g_strdup (key), - g_strdup (value)); -} - -static void -on_query_data_loaded (SoupSession *session, - SoupMessage *query, - gpointer user_data) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); - GError *error = NULL; - char *contents; - gpointer ret; - - if (query->status_code != SOUP_STATUS_OK) { - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - query->reason_phrase ? query->reason_phrase : "Query failed"); - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - contents = g_strndup (query->response_body->data, query->response_body->length); - ret = _geocode_parse_search_json (contents, &error); - - if (ret == NULL) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - g_free (contents); - return; - } - - /* Now that we can parse the result, save it to cache */ - _geocode_glib_cache_save (query, contents); - g_free (contents); - - g_simple_async_result_set_op_res_gpointer (simple, ret, NULL); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); -} - -static void -on_cache_data_loaded (GObject *source_forward, - GAsyncResult *res, - gpointer user_data) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); - GFile *cache; - GError *error = NULL; - char *contents; - gpointer ret; - - cache = G_FILE (source_forward); - if (g_file_load_contents_finish (cache, - res, - &contents, - NULL, - NULL, - NULL) == FALSE) { - GObject *object; - SoupMessage *query; - - object = g_async_result_get_source_object (G_ASYNC_RESULT (simple)); - query = g_object_get_data (G_OBJECT (cache), "query"); - g_object_ref (query); /* soup_session_queue_message steals ref */ - soup_session_queue_message (GEOCODE_FORWARD (object)->priv->soup_session, - query, - on_query_data_loaded, - simple); - return; - } - - ret = _geocode_parse_search_json (contents, &error); - g_free (contents); - - if (ret == NULL) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gpointer (simple, ret, NULL); - - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); -} - -static SoupMessage * -get_search_query_for_params (GeocodeForward *forward, - GError **error) -{ - SoupMessage *ret; - GHashTable *ht; - char *lang; - char *params; - char *search_term; - char *uri; - guint8 i; - gboolean query_possible = FALSE; - char *location; - const char *allowed_attributes[] = { "country", - "region", - "county", - "locality", - "postalcode", - "street", - "location", - NULL }; - - /* Make sure we have at least one parameter that Nominatim allows querying for */ - for (i = 0; allowed_attributes[i] != NULL; i++) { - if (g_hash_table_lookup (forward->priv->ht, - allowed_attributes[i]) != NULL) { - query_possible = TRUE; - break; - } - } - - if (!query_possible) { - char *str; - - str = g_strjoinv (", ", (char **) allowed_attributes); - g_set_error (error, GEOCODE_ERROR, GEOCODE_ERROR_INVALID_ARGUMENTS, - "Only following parameters supported: %s", str); - g_free (str); - - return NULL; - } - - /* Prepare the query parameters */ - ht = _geocode_glib_dup_hash_table (forward->priv->ht); - g_hash_table_insert (ht, (gpointer) "format", (gpointer) "jsonv2"); - g_hash_table_insert (ht, (gpointer) "email", (gpointer) "zeeshanak@gnome.org"); - g_hash_table_insert (ht, (gpointer) "addressdetails", (gpointer) "1"); - - lang = NULL; - if (g_hash_table_lookup (ht, "accept-language") == NULL) { - lang = _geocode_object_get_lang (); - if (lang) - g_hash_table_insert (ht, (gpointer) "accept-language", lang); - } - - location = g_strdup (g_hash_table_lookup (ht, "location")); - g_hash_table_remove (ht, "location"); - params = soup_form_encode_hash (ht); - g_hash_table_destroy (ht); - if (lang) - g_free (lang); - - if (location != NULL) { - /* Prepare the search term */ - search_term = soup_uri_encode (location, NULL); - uri = g_strdup_printf ("https://nominatim.gnome.org/search?q=%s&limit=%u&bounded=%d&%s", - search_term, - forward->priv->answer_count, - !!forward->priv->bounded, - params); - g_free (search_term); - g_free (location); - } else { - uri = g_strdup_printf ("https://nominatim.gnome.org/search?limit=1&%s", - params); - } - g_free (params); - - ret = soup_message_new ("GET", uri); - g_free (uri); - - return ret; -} - -/** - * geocode_forward_search_async: - * @forward: a #GeocodeForward representing a query - * @cancellable: optional #GCancellable forward, %NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the request is satisfied - * @user_data: the data to pass to callback function - * - * Asynchronously performs a forward geocoding - * query using a web service. Use geocode_forward_search() to do the same - * thing synchronously. - * - * When the operation is finished, @callback will be called. You can then call - * geocode_forward_search_finish() to get the result of the operation. - **/ -void -geocode_forward_search_async (GeocodeForward *forward, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - SoupMessage *query; - char *cache_path; - GError *error = NULL; - - g_return_if_fail (GEOCODE_IS_FORWARD (forward)); - - simple = g_simple_async_result_new (G_OBJECT (forward), - callback, - user_data, - geocode_forward_search_async); - g_simple_async_result_set_check_cancellable (simple, cancellable); - - query = get_search_query_for_params (forward, &error); - if (!query) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - cache_path = _geocode_glib_cache_path_for_query (query); - if (cache_path == NULL) { - soup_session_queue_message (forward->priv->soup_session, - query, - on_query_data_loaded, - simple); - } else { - GFile *cache; - - cache = g_file_new_for_path (cache_path); - g_object_set_data_full (G_OBJECT (cache), "query", query, (GDestroyNotify) g_object_unref); - g_file_load_contents_async (cache, - cancellable, - on_cache_data_loaded, - simple); - g_object_unref (cache); - g_free (cache_path); - } -} - -/** - * geocode_forward_search_finish: - * @forward: a #GeocodeForward representing a query - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes a forward geocoding operation. See geocode_forward_search_async(). - * - * Returns: (element-type GeocodePlace) (transfer container): A list of - * places or %NULL in case of errors. Free the returned list with - * g_list_free() when done. - **/ -GList * -geocode_forward_search_finish (GeocodeForward *forward, - GAsyncResult *res, - GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); - - g_return_val_if_fail (GEOCODE_IS_FORWARD (forward), NULL); - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == geocode_forward_search_async); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - return g_simple_async_result_get_op_res_gpointer (simple); -} - -static struct { - const char *nominatim_attr; - const char *place_prop; /* NULL to ignore */ -} nominatim_to_place_map[] = { - { "license", NULL }, - { "osm_id", "osm-id" }, - { "lat", NULL }, - { "lon", NULL }, - { "display_name", NULL }, - { "house_number", "building" }, - { "road", "street" }, - { "suburb", "area" }, - { "city", "town" }, - { "village", "town" }, - { "county", "county" }, - { "state_district", "administrative-area" }, - { "state", "state" }, - { "postcode", "postal-code" }, - { "country", "country" }, - { "country_code", "country-code" }, - { "continent", "continent" }, - { "address", NULL }, -}; - -static void -fill_place_from_entry (const char *key, - const char *value, - GeocodePlace *place) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (nominatim_to_place_map); i++) { - if (g_str_equal (key, nominatim_to_place_map[i].nominatim_attr)){ - g_object_set (G_OBJECT (place), - nominatim_to_place_map[i].place_prop, - value, - NULL); - break; - } - } - - if (g_str_equal (key, "osm_type")) { - gpointer ref = g_type_class_ref (geocode_place_osm_type_get_type ()); - GEnumClass *class = G_ENUM_CLASS (ref); - GEnumValue *evalue = g_enum_get_value_by_nick (class, value); - - if (evalue) - g_object_set (G_OBJECT (place), "osm-type", evalue->value, NULL); - else - g_warning ("Unsupported osm-type %s", value); - - g_type_class_unref (ref); - } -} - -static gboolean -node_free_func (GNode *node, - gpointer user_data) -{ - /* Leaf nodes are GeocodeLocation objects - * which we reuse for the results */ - if (G_NODE_IS_LEAF (node) == FALSE) - g_free (node->data); - - return FALSE; -} - -static const char const *attributes[] = { - "country", - "state", - "county", - "state_district", - "postcode", - "city", - "suburb", - "village", -}; - -static GeocodePlaceType -get_place_type_from_attributes (GHashTable *ht) -{ - char *category, *type; - GeocodePlaceType place_type = GEOCODE_PLACE_TYPE_UNKNOWN; - - category = g_hash_table_lookup (ht, "category"); - type = g_hash_table_lookup (ht, "type"); - - if (g_strcmp0 (category, "place") == 0) { - if (g_strcmp0 (type, "house") == 0 || - g_strcmp0 (type, "building") == 0 || - g_strcmp0 (type, "residential") == 0 || - g_strcmp0 (type, "plaza") == 0 || - g_strcmp0 (type, "office") == 0) - place_type = GEOCODE_PLACE_TYPE_BUILDING; - else if (g_strcmp0 (type, "estate") == 0) - place_type = GEOCODE_PLACE_TYPE_ESTATE; - else if (g_strcmp0 (type, "town") == 0 || - g_strcmp0 (type, "city") == 0 || - g_strcmp0 (type, "hamlet") == 0 || - g_strcmp0 (type, "isolated_dwelling") == 0 || - g_strcmp0 (type, "village") == 0) - place_type = GEOCODE_PLACE_TYPE_TOWN; - else if (g_strcmp0 (type, "suburb") == 0 || - g_strcmp0 (type, "neighbourhood") == 0) - place_type = GEOCODE_PLACE_TYPE_SUBURB; - else if (g_strcmp0 (type, "state") == 0 || - g_strcmp0 (type, "region") == 0) - place_type = GEOCODE_PLACE_TYPE_STATE; - else if (g_strcmp0 (type, "farm") == 0 || - g_strcmp0 (type, "forest") == 0 || - g_strcmp0 (type, "valey") == 0 || - g_strcmp0 (type, "park") == 0 || - g_strcmp0 (type, "hill") == 0) - place_type = GEOCODE_PLACE_TYPE_LAND_FEATURE; - else if (g_strcmp0 (type, "island") == 0 || - g_strcmp0 (type, "islet") == 0) - place_type = GEOCODE_PLACE_TYPE_ISLAND; - else if (g_strcmp0 (type, "country") == 0) - place_type = GEOCODE_PLACE_TYPE_COUNTRY; - else if (g_strcmp0 (type, "continent") == 0) - place_type = GEOCODE_PLACE_TYPE_CONTINENT; - else if (g_strcmp0 (type, "lake") == 0 || - g_strcmp0 (type, "bay") == 0 || - g_strcmp0 (type, "river") == 0) - place_type = GEOCODE_PLACE_TYPE_DRAINAGE; - else if (g_strcmp0 (type, "sea") == 0) - place_type = GEOCODE_PLACE_TYPE_SEA; - else if (g_strcmp0 (type, "ocean") == 0) - place_type = GEOCODE_PLACE_TYPE_OCEAN; - } else if (g_strcmp0 (category, "highway") == 0) { - if (g_strcmp0 (type, "motorway") == 0) - place_type = GEOCODE_PLACE_TYPE_MOTORWAY; - else if (g_strcmp0 (type, "bus_stop") == 0) - place_type = GEOCODE_PLACE_TYPE_BUS_STOP; - else - place_type = GEOCODE_PLACE_TYPE_STREET; - } else if (g_strcmp0 (category, "railway") == 0) { - if (g_strcmp0 (type, "station") == 0 || - g_strcmp0 (type, "halt") == 0) - place_type = GEOCODE_PLACE_TYPE_RAILWAY_STATION; - else if (g_strcmp0 (type, "tram_stop") == 0) - place_type = GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION; - } else if (g_strcmp0 (category, "waterway") == 0) { - place_type = GEOCODE_PLACE_TYPE_DRAINAGE; - } else if (g_strcmp0 (category, "boundary") == 0) { - if (g_strcmp0 (type, "administrative") == 0) { - int rank; - - rank = atoi (g_hash_table_lookup (ht, "place_rank")); - if (rank < 2) - place_type = GEOCODE_PLACE_TYPE_UNKNOWN; - - if (rank == 28) - place_type = GEOCODE_PLACE_TYPE_BUILDING; - else if (rank == 16) - place_type = GEOCODE_PLACE_TYPE_TOWN; - else if (rank == 12) - place_type = GEOCODE_PLACE_TYPE_COUNTY; - else if (rank == 10 || rank == 8) - place_type = GEOCODE_PLACE_TYPE_STATE; - else if (rank == 4) - place_type = GEOCODE_PLACE_TYPE_COUNTRY; - } - } else if (g_strcmp0 (category, "amenity") == 0) { - if (g_strcmp0 (type, "school") == 0) - place_type = GEOCODE_PLACE_TYPE_SCHOOL; - else if (g_strcmp0 (type, "place_of_worship") == 0) - place_type = GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP; - else if (g_strcmp0 (type, "restaurant") == 0) - place_type = GEOCODE_PLACE_TYPE_RESTAURANT; - else if (g_strcmp0 (type, "bar") == 0 || - g_strcmp0 (type, "pub") == 0) - place_type = GEOCODE_PLACE_TYPE_BAR; - } else if (g_strcmp0 (category, "aeroway") == 0) { - if (g_strcmp0 (type, "aerodrome") == 0) - place_type = GEOCODE_PLACE_TYPE_AIRPORT; - } - - return place_type; -} - -GeocodePlace * -_geocode_create_place_from_attributes (GHashTable *ht) -{ - GeocodePlace *place; - GeocodeLocation *loc = NULL; - const char *name, *street, *building, *bbox_corner; - GeocodePlaceType place_type; - gdouble longitude, latitude; - - place_type = get_place_type_from_attributes (ht); - - name = g_hash_table_lookup (ht, "name"); - if (name == NULL) - name = g_hash_table_lookup (ht, "display_name"); - - place = geocode_place_new (name, place_type); - - /* If one corner exists, then all exists */ - bbox_corner = g_hash_table_lookup (ht, "boundingbox-top"); - if (bbox_corner != NULL) { - GeocodeBoundingBox *bbox; - gdouble top, bottom, left, right; - - top = g_ascii_strtod (bbox_corner, NULL); - - bbox_corner = g_hash_table_lookup (ht, "boundingbox-bottom"); - bottom = g_ascii_strtod (bbox_corner, NULL); - - bbox_corner = g_hash_table_lookup (ht, "boundingbox-left"); - left = g_ascii_strtod (bbox_corner, NULL); - - bbox_corner = g_hash_table_lookup (ht, "boundingbox-right"); - right = g_ascii_strtod (bbox_corner, NULL); - - bbox = geocode_bounding_box_new (top, bottom, left, right); - geocode_place_set_bounding_box (place, bbox); - g_object_unref (bbox); - } - - /* Nominatim doesn't give us street addresses as such */ - street = g_hash_table_lookup (ht, "road"); - building = g_hash_table_lookup (ht, "house_number"); - if (street != NULL && building != NULL) { - char *address; - gboolean number_after; - - number_after = _geocode_object_is_number_after_street (); - address = g_strdup_printf ("%s %s", - number_after ? street : building, - number_after ? building : street); - geocode_place_set_street_address (place, address); - g_free (address); - } - - g_hash_table_foreach (ht, (GHFunc) fill_place_from_entry, place); - - /* Get latitude and longitude and create GeocodeLocation object. */ - longitude = g_ascii_strtod (g_hash_table_lookup (ht, "lon"), NULL); - latitude = g_ascii_strtod (g_hash_table_lookup (ht, "lat"), NULL); - name = geocode_place_get_name (place); - - loc = geocode_location_new_with_description (latitude, - longitude, - GEOCODE_LOCATION_ACCURACY_UNKNOWN, - name); - geocode_place_set_location (place, loc); - g_object_unref (loc); - - return place; -} - -static void -insert_place_into_tree (GNode *place_tree, GHashTable *ht) -{ - GNode *start = place_tree; - GeocodePlace *place = NULL; - char *attr_val = NULL; - guint i; - - for (i = 0; i < G_N_ELEMENTS(attributes); i++) { - GNode *child = NULL; - - attr_val = g_hash_table_lookup (ht, attributes[i]); - if (!attr_val) { - /* Add a dummy node if the attribute value is not - * available for the place */ - child = g_node_insert_data (start, -1, NULL); - } else { - /* If the attr value (eg for country United States) - * already exists, then keep on adding other attributes under that node. */ - child = g_node_first_child (start); - while (child && - child->data && - g_ascii_strcasecmp (child->data, attr_val) != 0) { - child = g_node_next_sibling (child); - } - if (!child) { - /* create a new node */ - child = g_node_insert_data (start, -1, g_strdup (attr_val)); - } - } - start = child; - } - - place = _geocode_create_place_from_attributes (ht); - - /* The leaf node of the tree is the GeocodePlace object, containing - * associated GeocodePlace object */ - g_node_insert_data (start, -1, place); -} - -static void -make_place_list_from_tree (GNode *node, - char **s_array, - GList **place_list, - int i) -{ - GNode *child; - - if (node == NULL) - return; - - if (G_NODE_IS_LEAF (node)) { - GPtrArray *rev_s_array; - GeocodePlace *place; - GeocodeLocation *loc; - char *name; - int counter = 0; - - rev_s_array = g_ptr_array_new (); - - /* If leaf node, then add all the attributes in the s_array - * and set it to the description of the loc object */ - place = (GeocodePlace *) node->data; - name = (char *) geocode_place_get_name (place); - loc = geocode_place_get_location (place); - - /* To print the attributes in a meaningful manner - * reverse the s_array */ - g_ptr_array_add (rev_s_array, (gpointer) name); - for (counter = 1; counter <= i; counter++) - g_ptr_array_add (rev_s_array, s_array[i - counter]); - g_ptr_array_add (rev_s_array, NULL); - name = g_strjoinv (", ", (char **) rev_s_array->pdata); - g_ptr_array_unref (rev_s_array); - - geocode_place_set_name (place, name); - geocode_location_set_description (loc, name); - g_free (name); - - *place_list = g_list_prepend (*place_list, place); - } else { - GNode *prev, *next; - - prev = g_node_prev_sibling (node); - next = g_node_next_sibling (node); - - /* If there are other attributes with a different value, - * add those attributes to the string to differentiate them */ - if (node->data && ((prev && prev->data) || (next && next->data))) { - s_array[i] = node->data; - i++; - } - } - - for (child = node->children; child != NULL; child = child->next) - make_place_list_from_tree (child, s_array, place_list, i); -} - -GList * -_geocode_parse_search_json (const char *contents, - GError **error) -{ - GList *ret; - JsonParser *parser; - JsonNode *root; - JsonReader *reader; - const GError *err = NULL; - int num_places, i; - GNode *place_tree; - char *s_array[G_N_ELEMENTS (attributes)]; - - ret = NULL; - - parser = json_parser_new (); - if (json_parser_load_from_data (parser, contents, -1, error) == FALSE) { - g_object_unref (parser); - return ret; - } - - root = json_parser_get_root (parser); - reader = json_reader_new (root); - - num_places = json_reader_count_elements (reader); - if (num_places < 0) - goto parse; - if (num_places == 0) { - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_NO_MATCHES, - "No matches found for request"); - goto no_results; - } - - place_tree = g_node_new (NULL); - - for (i = 0; i < num_places; i++) { - GHashTable *ht; - - json_reader_read_element (reader, i); - - ht = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - _geocode_read_nominatim_attributes (reader, ht); - - /* Populate the tree with place details */ - insert_place_into_tree (place_tree, ht); - - g_hash_table_destroy (ht); - - json_reader_end_element (reader); - } - - make_place_list_from_tree (place_tree, s_array, &ret, 0); - - g_node_traverse (place_tree, - G_IN_ORDER, - G_TRAVERSE_ALL, - -1, - (GNodeTraverseFunc) node_free_func, - NULL); - - g_node_destroy (place_tree); - - g_object_unref (parser); - g_object_unref (reader); - ret = g_list_reverse (ret); - - return ret; -parse: - err = json_reader_get_error (reader); - g_set_error_literal (error, GEOCODE_ERROR, GEOCODE_ERROR_PARSE, err->message); -no_results: - g_object_unref (parser); - g_object_unref (reader); - return NULL; -} - -/** - * geocode_forward_search: - * @forward: a #GeocodeForward representing a query - * @error: a #GError - * - * Gets the result of a forward geocoding - * query using a web service. - * - * Returns: (element-type GeocodePlace) (transfer container): A list of - * places or %NULL in case of errors. Free the returned list with - * g_list_free() when done. - **/ -GList * -geocode_forward_search (GeocodeForward *forward, - GError **error) -{ - SoupMessage *query; - char *contents; - GList *ret; - gboolean to_cache = FALSE; - - g_return_val_if_fail (GEOCODE_IS_FORWARD (forward), NULL); - - query = get_search_query_for_params (forward, error); - if (!query) - return NULL; - - if (_geocode_glib_cache_load (query, &contents) == FALSE) { - if (soup_session_send_message (forward->priv->soup_session, - query) != SOUP_STATUS_OK) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - query->reason_phrase ? query->reason_phrase : "Query failed"); - g_object_unref (query); - return NULL; - } - contents = g_strndup (query->response_body->data, query->response_body->length); - - to_cache = TRUE; - } - - ret = _geocode_parse_search_json (contents, error); - if (to_cache && ret != NULL) - _geocode_glib_cache_save (query, contents); - - g_free (contents); - g_object_unref (query); - - return ret; -} - -/** - * geocode_forward_set_answer_count: - * @forward: a #GeocodeForward representing a query - * @count: the number of requested results - * - * Sets the number of requested results to @count. - **/ -void -geocode_forward_set_answer_count (GeocodeForward *forward, - guint count) -{ - g_return_if_fail (GEOCODE_IS_FORWARD (forward)); - - forward->priv->answer_count = count; -} - -/** - * geocode_forward_set_search_area: - * @forward: a #GeocodeForward representing a query - * @box: a bounding box to limit the search area. - * - * Sets the area to limit searches within. - **/ -void -geocode_forward_set_search_area (GeocodeForward *forward, - GeocodeBoundingBox *bbox) -{ - char *area; - char top[G_ASCII_DTOSTR_BUF_SIZE]; - char left[G_ASCII_DTOSTR_BUF_SIZE]; - char bottom[G_ASCII_DTOSTR_BUF_SIZE]; - char right[G_ASCII_DTOSTR_BUF_SIZE]; - - g_return_if_fail (GEOCODE_IS_FORWARD (forward)); - - forward->priv->search_area = bbox; - - /* need to convert with g_ascii_dtostr to be locale safe */ - g_ascii_dtostr (top, G_ASCII_DTOSTR_BUF_SIZE, - geocode_bounding_box_get_top (bbox)); - - g_ascii_dtostr (bottom, G_ASCII_DTOSTR_BUF_SIZE, - geocode_bounding_box_get_bottom (bbox)); - - g_ascii_dtostr (left, G_ASCII_DTOSTR_BUF_SIZE, - geocode_bounding_box_get_left (bbox)); - - g_ascii_dtostr (right, G_ASCII_DTOSTR_BUF_SIZE, - geocode_bounding_box_get_right (bbox)); - - area = g_strdup_printf ("%s,%s,%s,%s", left, top, right, bottom); - geocode_forward_add (forward, "viewbox", area); - g_free (area); -} - -/** - * geocode_forward_set_bounded: - * @forward: a #GeocodeForward representing a query - * @bounded: #TRUE to restrict results to only items contained within the - * #GeocodeForward:search-area bounding box. - * - * Set the #GeocodeForward:bounded property that regulates whether the - * #GeocodeForward:search-area property acts restricting or not. - **/ -void -geocode_forward_set_bounded (GeocodeForward *forward, - gboolean bounded) -{ - g_return_if_fail (GEOCODE_IS_FORWARD (forward)); - - forward->priv->bounded = bounded; -} - -/** - * geocode_forward_get_answer_count: - * @forward: a #GeocodeForward representing a query - * - * Gets the number of requested results for searches. - **/ -guint -geocode_forward_get_answer_count (GeocodeForward *forward) -{ - g_return_val_if_fail (GEOCODE_IS_FORWARD (forward), 0); - - return forward->priv->answer_count; -} - -/** - * geocode_forward_get_search_area: - * @forward: a #GeocodeForward representing a query - * - * Gets the area to limit searches within. - **/ -GeocodeBoundingBox * -geocode_forward_get_search_area (GeocodeForward *forward) -{ - g_return_val_if_fail (GEOCODE_IS_FORWARD (forward), NULL); - - return forward->priv->search_area; -} - -/** - * geocode_forward_get_bounded: - * @forward: a #GeocodeForward representing a query - * - * Gets the #GeocodeForward:bounded property that regulates whether the - * #GeocodeForward:search-area property acts restricting or not. - **/ -gboolean -geocode_forward_get_bounded (GeocodeForward *forward) -{ - g_return_val_if_fail (GEOCODE_IS_FORWARD (forward), FALSE); - - return forward->priv->bounded; -} diff --git a/src/geocode-glib/geocode-forward.h b/src/geocode-glib/geocode-forward.h deleted file mode 100644 index e176f4d..0000000 --- a/src/geocode-glib/geocode-forward.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright 2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#ifndef GEOCODE_FORWARD_H -#define GEOCODE_FORWARD_H - -#include <glib.h> -#include <gio/gio.h> -#include <geocode-glib/geocode-glib.h> -#include <geocode-glib/geocode-bounding-box.h> - -G_BEGIN_DECLS - -GType geocode_forward_get_type (void) G_GNUC_CONST; - -#define GEOCODE_TYPE_FORWARD (geocode_forward_get_type ()) -#define GEOCODE_FORWARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_FORWARD, GeocodeForward)) -#define GEOCODE_IS_FORWARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_FORWARD)) -#define GEOCODE_FORWARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_FORWARD, GeocodeForwardClass)) -#define GEOCODE_IS_FORWARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_FORWARD)) -#define GEOCODE_FORWARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_FORWARD, GeocodeForwardClass)) - -/** - * GeocodeForward: - * - * All the fields in the #GeocodeForward structure are private and should never be accessed directly. -**/ -typedef struct _GeocodeForward GeocodeForward; -typedef struct _GeocodeForwardClass GeocodeForwardClass; -typedef struct _GeocodeForwardPrivate GeocodeForwardPrivate; - -struct _GeocodeForward { - /* <private> */ - GObject parent_instance; - GeocodeForwardPrivate *priv; -}; - -/** - * GeocodeForwardClass: - * - * All the fields in the #GeocodeForwardClass structure are private and should never be accessed directly. -**/ -struct _GeocodeForwardClass { - /* <private> */ - GObjectClass parent_class; -}; - -GeocodeForward *geocode_forward_new_for_string (const char *str); -GeocodeForward *geocode_forward_new_for_params (GHashTable *params); -guint geocode_forward_get_answer_count (GeocodeForward *forward); -void geocode_forward_set_answer_count (GeocodeForward *forward, - guint count); -GeocodeBoundingBox * geocode_forward_get_search_area (GeocodeForward *forward); -void geocode_forward_set_search_area (GeocodeForward *forward, - GeocodeBoundingBox *box); -gboolean geocode_forward_get_bounded (GeocodeForward *forward); -void geocode_forward_set_bounded (GeocodeForward *forward, - gboolean bounded); - -void geocode_forward_search_async (GeocodeForward *forward, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GList *geocode_forward_search_finish (GeocodeForward *forward, - GAsyncResult *res, - GError **error); - -GList *geocode_forward_search (GeocodeForward *forward, - GError **error); - -G_END_DECLS - -#endif /* GEOCODE_FORWARD_H */ diff --git a/src/geocode-glib/geocode-glib-private.h b/src/geocode-glib/geocode-glib-private.h deleted file mode 100644 index 3a60683..0000000 --- a/src/geocode-glib/geocode-glib-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright 2010 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#ifndef GEOCODE_GLIB_PRIVATE_H -#define GEOCODE_GLIB_PRIVATE_H - -#include <glib.h> -#include <libsoup/soup.h> -#include <json-glib/json-glib.h> -#include <geocode-glib/geocode-location.h> -#include <geocode-glib/geocode-place.h> - -G_BEGIN_DECLS - -#define DEFAULT_ANSWER_COUNT 10 - -typedef enum { - GEOCODE_GLIB_RESOLVE_FORWARD, - GEOCODE_GLIB_RESOLVE_REVERSE -} GeocodeLookupType; - -GList *_geocode_parse_search_json (const char *contents, - GError **error); -void -_geocode_read_nominatim_attributes (JsonReader *reader, - GHashTable *ht); -GeocodePlace * -_geocode_create_place_from_attributes (GHashTable *ht); - -char *_geocode_object_get_lang (void); - -char *_geocode_glib_cache_path_for_query (SoupMessage *query); -gboolean _geocode_glib_cache_save (SoupMessage *query, - const char *contents); -gboolean _geocode_glib_cache_load (SoupMessage *query, - char **contents); -GHashTable *_geocode_glib_dup_hash_table (GHashTable *ht); -gboolean _geocode_object_is_number_after_street (void); -SoupSession *_geocode_glib_build_soup_session (void); - -G_END_DECLS - -#endif /* GEOCODE_GLIB_PRIVATE_H */ diff --git a/src/geocode-glib/geocode-glib.c b/src/geocode-glib/geocode-glib.c deleted file mode 100644 index fb4160c..0000000 --- a/src/geocode-glib/geocode-glib.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#include <string.h> -#include <errno.h> -#include <locale.h> -#include <gio/gio.h> -#include <libsoup/soup.h> -#include <langinfo.h> -#include <geocode-glib/geocode-glib-private.h> - -/** - * SECTION:geocode-glib - * @short_description: Geocode glib main functions - * @include: geocode-glib/geocode-glib.h - * - * Contains functions for geocoding and reverse geocoding using the - * <ulink url="http://wiki.openstreetmap.org/wiki/Nominatim">OSM Nominatim APIs</ulink> - **/ - -SoupSession * -_geocode_glib_build_soup_session (void) -{ - GApplication *application; - SoupSession *session; - char *user_agent; - - application = g_application_get_default (); - if (application) { - const char *id = g_application_get_application_id (application); - user_agent = g_strdup_printf ("geocode-glib/%s (%s)", - PACKAGE_VERSION, id); - } else { - user_agent = g_strdup_printf ("geocode-glib/%s", - PACKAGE_VERSION); - } - - session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, - user_agent, NULL); - g_free (user_agent); - return session; -} - -char * -_geocode_glib_cache_path_for_query (SoupMessage *query) -{ - const char *filename; - char *path; - SoupURI *soup_uri; - char *uri; - GChecksum *sum; - - /* Create cache directory */ - path = g_build_filename (g_get_user_cache_dir (), - "geocode-glib", - NULL); - if (g_mkdir_with_parents (path, 0700) < 0) { - g_warning ("Failed to mkdir path '%s': %s", path, g_strerror (errno)); - g_free (path); - return NULL; - } - g_free (path); - - /* Create path for query */ - soup_uri = soup_message_get_uri (query); - uri = soup_uri_to_string (soup_uri, FALSE); - - sum = g_checksum_new (G_CHECKSUM_SHA256); - g_checksum_update (sum, (const guchar *) uri, strlen (uri)); - - filename = g_checksum_get_string (sum); - - path = g_build_filename (g_get_user_cache_dir (), - "geocode-glib", - filename, - NULL); - - g_checksum_free (sum); - g_free (uri); - - return path; -} - -gboolean -_geocode_glib_cache_save (SoupMessage *query, - const char *contents) -{ - char *path; - gboolean ret; - - path = _geocode_glib_cache_path_for_query (query); - g_debug ("Saving cache file '%s'", path); - ret = g_file_set_contents (path, contents, -1, NULL); - - g_free (path); - return ret; -} - -gboolean -_geocode_glib_cache_load (SoupMessage *query, - char **contents) -{ - char *path; - gboolean ret; - - path = _geocode_glib_cache_path_for_query (query); - g_debug ("Loading cache file '%s'", path); - ret = g_file_get_contents (path, contents, NULL, NULL); - - g_free (path); - return ret; -} - -static gboolean -parse_lang (const char *locale, - char **language_codep, - char **territory_codep) -{ - GRegex *re; - GMatchInfo *match_info; - gboolean res; - GError *error; - gboolean retval; - - match_info = NULL; - retval = FALSE; - - error = NULL; - re = g_regex_new ("^(?P<language>[^_.@[:space:]]+)" - "(_(?P<territory>[[:upper:]]+))?" - "(\\.(?P<codeset>[-_0-9a-zA-Z]+))?" - "(@(?P<modifier>[[:ascii:]]+))?$", - 0, 0, &error); - if (re == NULL) { - g_warning ("%s", error->message); - goto out; - } - - if (!g_regex_match (re, locale, 0, &match_info) || - g_match_info_is_partial_match (match_info)) { - g_warning ("locale '%s' isn't valid\n", locale); - goto out; - } - - res = g_match_info_matches (match_info); - if (! res) { - g_warning ("Unable to parse locale: %s", locale); - goto out; - } - - retval = TRUE; - - *language_codep = g_match_info_fetch_named (match_info, "language"); - - *territory_codep = g_match_info_fetch_named (match_info, "territory"); - - if (*territory_codep != NULL && - *territory_codep[0] == '\0') { - g_free (*territory_codep); - *territory_codep = NULL; - } - -out: - g_match_info_free (match_info); - g_regex_unref (re); - - return retval; -} - -static char * -geocode_object_get_lang_for_locale (const char *locale) -{ - char *lang; - char *territory; - char *ret; - - if (parse_lang (locale, &lang, &territory) == FALSE) - return NULL; - - ret = g_strdup_printf ("%s%s%s", - lang, - territory ? "-" : "", - territory ? territory : ""); - - g_free (lang); - g_free (territory); - - return ret; -} - -char * -_geocode_object_get_lang (void) -{ - return geocode_object_get_lang_for_locale (setlocale (LC_MESSAGES, NULL)); -} - -#ifdef __GLIBC__ -static gpointer -is_number_after_street (gpointer data) -{ - gboolean retval; - gchar *addr_format; - gchar *s; - gchar *h; - - addr_format = nl_langinfo (_NL_ADDRESS_POSTAL_FMT); - if (addr_format == NULL) { - retval = FALSE; - goto out; - } - - /* %s denotes street or block and %h denotes house number. - * See: http://lh.2xlibre.net/values/postal_fmt */ - s = g_strstr_len (addr_format, -1, "%s"); - h = g_strstr_len (addr_format, -1, "%h"); - - if (s != NULL && h != NULL) - retval = (h > s); - else - retval = FALSE; - - out: - return GINT_TO_POINTER (retval); -} -#endif - -gboolean -_geocode_object_is_number_after_street (void) -{ -#ifndef __GLIBC__ - return FALSE; -#else - static GOnce once = G_ONCE_INIT; - - g_once (&once, is_number_after_street, NULL); - return GPOINTER_TO_INT (once.retval); -#endif -} diff --git a/src/geocode-glib/geocode-glib.h b/src/geocode-glib/geocode-glib.h deleted file mode 100644 index 5b5302b..0000000 --- a/src/geocode-glib/geocode-glib.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#ifndef GEOCODE_GLIB_H -#define GEOCODE_GLIB_H - -#include <glib.h> -#include <gio/gio.h> -#include <geocode-glib/geocode-location.h> -#include <geocode-glib/geocode-place.h> -#include <geocode-glib/geocode-forward.h> -#include <geocode-glib/geocode-reverse.h> -#include <geocode-glib/geocode-bounding-box.h> -#include <geocode-glib/geocode-error.h> -#include <geocode-glib/geocode-enum-types.h> - -#endif /* GEOCODE_GLIB_H */ diff --git a/src/geocode-glib/geocode-location.c b/src/geocode-glib/geocode-location.c deleted file mode 100644 index 723550c..0000000 --- a/src/geocode-glib/geocode-location.c +++ /dev/null @@ -1,956 +0,0 @@ -/* - Copyright 2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - Zeeshan Ali (Khattak) <zeeshanak@gnome.org> - - */ - -#include <geocode-glib/geocode-error.h> -#include <geocode-glib/geocode-enum-types.h> -#include <math.h> -#include <string.h> -#include "geocode-location.h" - -#define EARTH_RADIUS_KM 6372.795 - -/** - * SECTION:geocode-location - * @short_description: Geocode location object - * @include: geocode-glib/geocode-glib.h - * - * The #GeocodeLocation instance represents a location on earth, with an - * optional description. - **/ - -struct _GeocodeLocationPrivate { - gdouble longitude; - gdouble latitude; - gdouble altitude; - gdouble accuracy; - guint64 timestamp; - char *description; - GeocodeLocationCRS crs; -}; - -enum { - PROP_0, - - PROP_LATITUDE, - PROP_LONGITUDE, - PROP_ACCURACY, - PROP_DESCRIPTION, - PROP_TIMESTAMP, - PROP_ALTITUDE, - PROP_CRS, -}; - -G_DEFINE_TYPE (GeocodeLocation, geocode_location, G_TYPE_OBJECT) - -static void -geocode_location_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GeocodeLocation *location = GEOCODE_LOCATION (object); - - switch (property_id) { - case PROP_DESCRIPTION: - g_value_set_string (value, - geocode_location_get_description (location)); - break; - - case PROP_LATITUDE: - g_value_set_double (value, - geocode_location_get_latitude (location)); - break; - - case PROP_LONGITUDE: - g_value_set_double (value, - geocode_location_get_longitude (location)); - break; - - case PROP_ALTITUDE: - g_value_set_double (value, - geocode_location_get_altitude (location)); - break; - - case PROP_ACCURACY: - g_value_set_double (value, - geocode_location_get_accuracy (location)); - break; - - case PROP_CRS: - g_value_set_enum (value, - geocode_location_get_crs (location)); - break; - - case PROP_TIMESTAMP: - g_value_set_uint64 (value, - geocode_location_get_timestamp (location)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_location_set_latitude (GeocodeLocation *loc, - gdouble latitude) -{ - g_return_if_fail (latitude >= -90.0 && latitude <= 90.0); - - loc->priv->latitude = latitude; -} - -static void -geocode_location_set_longitude (GeocodeLocation *loc, - gdouble longitude) -{ - g_return_if_fail (longitude >= -180.0 && longitude <= 180.0); - - loc->priv->longitude = longitude; -} - -static void -geocode_location_set_altitude (GeocodeLocation *loc, - gdouble altitude) -{ - loc->priv->altitude = altitude; -} - -static void -geocode_location_set_accuracy (GeocodeLocation *loc, - gdouble accuracy) -{ - g_return_if_fail (accuracy >= GEOCODE_LOCATION_ACCURACY_UNKNOWN); - - loc->priv->accuracy = accuracy; -} - -static void -geocode_location_set_crs(GeocodeLocation *loc, - GeocodeLocationCRS crs) -{ - g_return_if_fail (GEOCODE_IS_LOCATION (loc)); - - loc->priv->crs = crs; -} - -static void -geocode_location_set_timestamp (GeocodeLocation *loc, - guint64 timestamp) -{ - g_return_if_fail (GEOCODE_IS_LOCATION (loc)); - - loc->priv->timestamp = timestamp; -} - -static void -geocode_location_constructed (GObject *object) -{ - GeocodeLocation *location = GEOCODE_LOCATION (object); - GTimeVal tv; - - if (location->priv->timestamp != 0) - return; - - g_get_current_time (&tv); - geocode_location_set_timestamp (location, tv.tv_sec); -} - -static void -geocode_location_set_property(GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GeocodeLocation *location = GEOCODE_LOCATION (object); - - switch (property_id) { - case PROP_DESCRIPTION: - geocode_location_set_description (location, - g_value_get_string (value)); - break; - - case PROP_LATITUDE: - geocode_location_set_latitude (location, - g_value_get_double (value)); - break; - - case PROP_LONGITUDE: - geocode_location_set_longitude (location, - g_value_get_double (value)); - break; - - case PROP_ALTITUDE: - geocode_location_set_altitude (location, - g_value_get_double (value)); - break; - - case PROP_ACCURACY: - geocode_location_set_accuracy (location, - g_value_get_double (value)); - break; - - case PROP_CRS: - geocode_location_set_crs (location, - g_value_get_enum (value)); - break; - - case PROP_TIMESTAMP: - geocode_location_set_timestamp (location, - g_value_get_uint64 (value)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gboolean -parse_geo_uri_special_parameters (GeocodeLocation *loc, - const char *params, - GError **error) -{ - char *end_ptr; - char *next_token; - char *description; - char *token_end; - int description_len; - - if (loc->priv->latitude != 0 || loc->priv->longitude != 0) - goto err; - - if (strncmp (params, "q=", 2) != 0) - goto err; - - next_token = ((char *)params) + 2; - - loc->priv->latitude = g_ascii_strtod (next_token, &end_ptr); - if (*end_ptr != ',' || *end_ptr == *params) - goto err; - next_token = end_ptr + 1; - - loc->priv->longitude = g_ascii_strtod (next_token, &end_ptr); - if (*end_ptr == *next_token) - goto err; - - if (*end_ptr != '(' || *end_ptr == *next_token) - goto err; - next_token = end_ptr + 1; - - if ((token_end = strchr (next_token, ')')) == NULL) - goto err; - - description_len = token_end - next_token; - if (description_len <= 0) - goto err; - - description = g_uri_unescape_segment (next_token, - next_token + description_len, - NULL); - geocode_location_set_description (loc, description); - g_free (description); - return TRUE; - - err: - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_PARSE, - "Failed to parse geo URI parameters"); - return FALSE; -} - -/* - From RFC 5870: - Both 'crs' and 'u' parameters MUST NOT appear more than once each. - The 'crs' and 'u' parameters MUST be given before any other - parameters that may be defined in future extensions. The 'crs' - parameter MUST be given first if both 'crs' and 'u' are used. - */ -static gboolean -parse_geo_uri_parameters (GeocodeLocation *loc, - const char *params, - GError **error) -{ - char **parameters; - char *endptr; - char *val; - char *u = NULL; - char *crs = NULL; - int ret = TRUE; - - parameters = g_strsplit (params, ";", 2); - if (parameters[0] == NULL) - goto err; - - if (g_str_has_prefix (parameters[0], "u=")) { - /* - * if u parameter is first, then there should not be any more - * parameters. - */ - if (parameters[1] != NULL) - goto err; - - u = parameters[0]; - } else if (g_str_has_prefix (parameters[0], "crs=")) { - /* - * if crs parameter is first, then the next should be the u - * parameter or none. - */ - crs = parameters[0]; - if (parameters[1] != NULL){ - - if (!g_str_has_prefix (parameters[1], "u=")) - goto err; - - u = parameters[1]; - } - } else { - goto err; - } - - if (u != NULL) { - val = u + 2; /* len of 'u=' */ - loc->priv->accuracy = g_ascii_strtod (val, &endptr); - if (*endptr != '\0') - goto err; - } - - if (crs != NULL) { - val = crs + 4; /* len of 'crs=' */ - if (g_strcmp0 (val, "wgs84")) - goto err; - } - goto out; - - err: - ret = FALSE; - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_PARSE, - "Failed to parse geo URI parameters"); - out: - g_strfreev (parameters); - return ret; -} - -/* - From RFC 5870: - geo-URI = geo-scheme ":" geo-path - geo-scheme = "geo" - geo-path = coordinates p - coordinates = coord-a "," coord-b [ "," coord-c ] - - [...] - - The value of "-0" for <num> is allowed and is identical to "0". - - In case the URI identifies a location in the default CRS of WGS-84, - the <coordinates> sub-components are further restricted as follows: - - coord-a = latitude - coord-b = longitude - coord-c = altitude - - latitude = [ "-" ] 1*2DIGIT [ "." 1*DIGIT ] - longitude = [ "-" ] 1*3DIGIT [ "." 1*DIGIT ] - altitude = [ "-" ] 1*DIGIT [ "." 1*DIGIT ] - - p = [ crsp ] [ uncp ] *parameter - crsp = ";crs=" crslabel - crslabel = "wgs84" / labeltext - uncp = ";u=" uval - uval = pnum - - parameter = ";" pname [ "=" pvalue ] - pname = labeltext - pvalue = 1*paramchar - paramchar = p-unreserved / unreserved / pct-encoded - - labeltext = 1*( alphanum / "-" ) - pnum = 1*DIGIT [ "." 1*DIGIT ] - num = [ "-" ] pnum - unreserved = alphanum / mark - mark = "-" / "_" / "." / "!" / "~" / "*" / - "'" / "(" / ")" - pct-encoded = "%" HEXDIG HEXDIG -*/ -static gboolean -parse_geo_uri (GeocodeLocation *loc, - const char *uri, - GError **error) -{ - const char *uri_part; - char *end_ptr; - char *next_token; - const char *s; - - /* bail out if we encounter whitespace in uri */ - s = uri; - while (*s) { - if (g_ascii_isspace (*s++)) - goto err; - } - - uri_part = (const char *) uri + strlen("geo") + 1; - - /* g_ascii_strtod is locale safe */ - loc->priv->latitude = g_ascii_strtod (uri_part, &end_ptr); - if (*end_ptr != ',' || *end_ptr == *uri_part) { - goto err; - } - next_token = end_ptr + 1; - - loc->priv->longitude = g_ascii_strtod (next_token, &end_ptr); - if (*end_ptr == *next_token) { - goto err; - } - if (*end_ptr == ',') { - next_token = end_ptr + 1; - loc->priv->altitude = g_ascii_strtod (next_token, &end_ptr); - if (*end_ptr == *next_token) { - goto err; - } - } - if (*end_ptr == ';') { - next_token = end_ptr + 1; - return parse_geo_uri_parameters (loc, next_token, error); - } else if (*end_ptr == '?') { - next_token = end_ptr + 1; - return parse_geo_uri_special_parameters (loc, - next_token, - error); - } else if (*end_ptr == '\0') { - return TRUE; - } - err: - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_PARSE, - "Failed to parse geo URI"); - return FALSE; -} - -static gboolean -parse_uri (GeocodeLocation *location, - const char *uri, - GError **error) -{ - char *scheme; - int ret = TRUE; - - scheme = g_uri_parse_scheme (uri); - if (scheme == NULL) { - ret = FALSE; - goto err; - } - - if (g_strcmp0 (scheme, "geo") == 0) { - if (!parse_geo_uri (location, uri, error)) - ret = FALSE; - goto out; - } else { - ret = FALSE; - goto err; - } - - err: - if (error) { - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_NOT_SUPPORTED, - "Unsupported or invalid URI scheme"); - } - out: - g_free (scheme); - return ret; -} - -static void -geocode_location_finalize (GObject *glocation) -{ - GeocodeLocation *location = (GeocodeLocation *) glocation; - - g_clear_pointer (&location->priv->description, g_free); - - G_OBJECT_CLASS (geocode_location_parent_class)->finalize (glocation); -} - -static void -geocode_location_class_init (GeocodeLocationClass *klass) -{ - GObjectClass *glocation_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - glocation_class->finalize = geocode_location_finalize; - glocation_class->get_property = geocode_location_get_property; - glocation_class->set_property = geocode_location_set_property; - glocation_class->constructed = geocode_location_constructed; - - g_type_class_add_private (klass, sizeof (GeocodeLocationPrivate)); - - /** - * GeocodeLocation:description: - * - * The description of this location. - */ - pspec = g_param_spec_string ("description", - "Description", - "Description of this location", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_DESCRIPTION, pspec); - - /** - * GeocodeLocation:latitude: - * - * The latitude of this location in degrees. - */ - pspec = g_param_spec_double ("latitude", - "Latitude", - "The latitude of this location in degrees", - -90.0, - 90.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_LATITUDE, pspec); - - /** - * GeocodeLocation:longitude: - * - * The longitude of this location in degrees. - */ - pspec = g_param_spec_double ("longitude", - "Longitude", - "The longitude of this location in degrees", - -180.0, - 180.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_LONGITUDE, pspec); - - /** - * GeocodeLocation:altitude: - * - * The altitude of this location in meters. - */ - pspec = g_param_spec_double ("altitude", - "Altitude", - "The altitude of this location in meters", - GEOCODE_LOCATION_ALTITUDE_UNKNOWN, - G_MAXDOUBLE, - GEOCODE_LOCATION_ALTITUDE_UNKNOWN, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_ALTITUDE, pspec); - - /** - * GeocodeLocation:accuracy: - * - * The accuracy of this location in meters. - */ - pspec = g_param_spec_double ("accuracy", - "Accuracy", - "The accuracy of this location in meters", - GEOCODE_LOCATION_ACCURACY_UNKNOWN, - G_MAXDOUBLE, - GEOCODE_LOCATION_ACCURACY_UNKNOWN, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_ACCURACY, pspec); - - - /** - * GeocodeLocation:crs: - * - * The Coordinate Reference System Identification of this location. - * Only the value 'wgs84' is currently valid. - */ - pspec = g_param_spec_enum ("crs", - "Coordinate Reference System Identification", - "Coordinate Reference System Identification", - GEOCODE_TYPE_LOCATION_CRS, - GEOCODE_LOCATION_CRS_WGS84, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_CRS, pspec); - - /** - * GeocodeLocation:timestamp: - * - * A timestamp in seconds since - * <ulink url="http://en.wikipedia.org/wiki/Unix_epoch">Epoch</ulink>, - * giving when the location was resolved from an address. - * - * A value of 0 (zero) will be interpreted as the current time. - */ - pspec = g_param_spec_uint64 ("timestamp", - "Timestamp", - "The timestamp of this location " - "in seconds since Epoch", - 0, - G_MAXINT64, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (glocation_class, PROP_TIMESTAMP, pspec); -} - -static void -geocode_location_init (GeocodeLocation *location) -{ - location->priv = G_TYPE_INSTANCE_GET_PRIVATE ((location), - GEOCODE_TYPE_LOCATION, - GeocodeLocationPrivate); - - location->priv->altitude = GEOCODE_LOCATION_ALTITUDE_UNKNOWN; - location->priv->accuracy = GEOCODE_LOCATION_ACCURACY_UNKNOWN; - location->priv->crs = GEOCODE_LOCATION_CRS_WGS84; -} - -/** - * geocode_location_new: - * @latitude: a valid latitude - * @longitude: a valid longitude - * @accuracy: accuracy of location in meters - * - * Creates a new #GeocodeLocation object. - * - * Returns: a new #GeocodeLocation object. Use g_object_unref() when done. - **/ -GeocodeLocation * -geocode_location_new (gdouble latitude, - gdouble longitude, - gdouble accuracy) -{ - return g_object_new (GEOCODE_TYPE_LOCATION, - "latitude", latitude, - "longitude", longitude, - "accuracy", accuracy, - NULL); -} - -/** - * geocode_location_new_with_description: - * @latitude: a valid latitude - * @longitude: a valid longitude - * @accuracy: accuracy of location in meters - * @description: a description for the location - * - * Creates a new #GeocodeLocation object. - * - * Returns: a new #GeocodeLocation object. Use g_object_unref() when done. - **/ -GeocodeLocation * -geocode_location_new_with_description (gdouble latitude, - gdouble longitude, - gdouble accuracy, - const char *description) -{ - return g_object_new (GEOCODE_TYPE_LOCATION, - "latitude", latitude, - "longitude", longitude, - "accuracy", accuracy, - "description", description, - NULL); -} - -/** - * geocode_location_set_from_uri: - * @loc: a #GeocodeLocation - * @uri: a URI mapping out a location - * @error: #GError for error reporting, or %NULL to ignore - * - * Initialize a #GeocodeLocation object with the given @uri. - * - * The URI should be in the geo scheme (RFC 5870) which in its simplest form - * looks like: - * - * - geo:latitude,longitude - * - * An <ulink - * url="http://developer.android.com/guide/components/intents-common.html#Maps"> - * Android extension</ulink> to set a description is also supported in the form of: - * - * - geo:0,0?q=latitude,longitude(description) - * - * Returns: %TRUE on success and %FALSE on error. - **/ -gboolean -geocode_location_set_from_uri (GeocodeLocation *loc, - const char *uri, - GError **error) -{ - return parse_uri (loc, uri, error); -} - -/** - * geocode_location_set_description: - * @loc: a #GeocodeLocation - * @description: a description for the location - * - * Sets the description of @loc to @description. - **/ -void -geocode_location_set_description (GeocodeLocation *loc, - const char *description) -{ - g_return_if_fail (GEOCODE_IS_LOCATION (loc)); - - g_free (loc->priv->description); - loc->priv->description = g_strdup (description); -} - -/** - * geocode_location_get_description: - * @loc: a #GeocodeLocation - * - * Gets the description of location @loc. - * - * Returns: The description of location @loc. - **/ -const char * -geocode_location_get_description (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), NULL); - - return loc->priv->description; -} - -/** - * geocode_location_get_latitude: - * @loc: a #GeocodeLocation - * - * Gets the latitude of location @loc. - * - * Returns: The latitude of location @loc. - **/ -gdouble -geocode_location_get_latitude (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), 0.0); - - return loc->priv->latitude; -} - -/** - * geocode_location_get_longitude: - * @loc: a #GeocodeLocation - * - * Gets the longitude of location @loc. - * - * Returns: The longitude of location @loc. - **/ -gdouble -geocode_location_get_longitude (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), 0.0); - - return loc->priv->longitude; -} - -/** - * geocode_location_get_altitude: - * @loc: a #GeocodeLocation - * - * Gets the altitude of location @loc. - * - * Returns: The altitude of location @loc. - **/ -gdouble -geocode_location_get_altitude (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), - GEOCODE_LOCATION_ALTITUDE_UNKNOWN); - - return loc->priv->altitude; -} - -/** - * geocode_location_get_accuracy: - * @loc: a #GeocodeLocation - * - * Gets the accuracy (in meters) of location @loc. - * - * Returns: The accuracy of location @loc. - **/ -gdouble -geocode_location_get_accuracy (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), - GEOCODE_LOCATION_ACCURACY_UNKNOWN); - - return loc->priv->accuracy; -} - -/** - * geocode_location_get_crs: - * @loc: a #GeocodeLocation - * - * Gets the Coordinate Reference System Identification of location @loc. - * - * Returns: The CRS of location @loc. - **/ -GeocodeLocationCRS -geocode_location_get_crs (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), - GEOCODE_LOCATION_CRS_WGS84); - - return loc->priv->crs; -} - -/** - * geocode_location_get_timestamp: - * @loc: a #GeocodeLocation - * - * Gets the timestamp (in seconds since the Epoch) of location @loc. See - * #GeocodeLocation:timestamp. - * - * Returns: The timestamp of location @loc. - **/ -guint64 -geocode_location_get_timestamp (GeocodeLocation *loc) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), 0); - - return loc->priv->timestamp; -} - -static gdouble -round_coord_n (gdouble coord, guint n) -{ - gdouble fac = pow (10, n); - - return round (coord * fac) / fac; -} - -static char * -geo_uri_from_location (GeocodeLocation *loc) -{ - guint precision = 6; /* 0.1 meter precision */ - char *uri; - char *coords; - char *params; - char *crs = "wgs84"; - char lat[G_ASCII_DTOSTR_BUF_SIZE]; - char lon[G_ASCII_DTOSTR_BUF_SIZE]; - char alt[G_ASCII_DTOSTR_BUF_SIZE]; - char acc[G_ASCII_DTOSTR_BUF_SIZE]; - - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), NULL); - - g_ascii_formatd (lat, - G_ASCII_DTOSTR_BUF_SIZE, - "%.6f", - round_coord_n (loc->priv->latitude, precision)); - g_ascii_formatd (lon, - G_ASCII_DTOSTR_BUF_SIZE, - "%.6f", - round_coord_n (loc->priv->longitude, precision)); - - if (loc->priv->altitude != GEOCODE_LOCATION_ALTITUDE_UNKNOWN) { - g_ascii_dtostr (alt, G_ASCII_DTOSTR_BUF_SIZE, - loc->priv->altitude); - coords = g_strdup_printf ("%s,%s,%s", lat, lon, alt); - } else { - coords = g_strdup_printf ("%s,%s", lat, lon); - } - - if (loc->priv->accuracy != GEOCODE_LOCATION_ACCURACY_UNKNOWN) { - g_ascii_dtostr (acc, G_ASCII_DTOSTR_BUF_SIZE, - loc->priv->accuracy); - params = g_strdup_printf (";crs=%s;u=%s", crs, acc); - } else { - params = g_strdup_printf (";crs=%s", crs); - } - - uri = g_strconcat ("geo:", coords, params, NULL); - g_free (coords); - g_free (params); - - return uri; -} - -/** - * geocode_location_to_uri: - * @loc: a #GeocodeLocation - * @scheme: the scheme of the requested URI - * - * Creates a URI representing @loc in the scheme specified in @scheme. - * - * Returns: a URI representing the location. The returned string should be freed - * with g_free() when no longer needed. - **/ -char * -geocode_location_to_uri (GeocodeLocation *loc, - GeocodeLocationURIScheme scheme) -{ - g_return_val_if_fail (GEOCODE_IS_LOCATION (loc), NULL); - g_return_val_if_fail (scheme == GEOCODE_LOCATION_URI_SCHEME_GEO, NULL); - - return geo_uri_from_location (loc); -} - -/** - * geocode_location_get_distance_from: - * @loca: a #GeocodeLocation - * @locb: a #GeocodeLocation - * - * Calculates the distance in km, along the curvature of the Earth, - * between 2 locations. Note that altitude changes are not - * taken into account. - * - * Returns: a distance in km. - **/ -double -geocode_location_get_distance_from (GeocodeLocation *loca, - GeocodeLocation *locb) -{ - gdouble dlat, dlon, lat1, lat2; - gdouble a, c; - - g_return_val_if_fail (GEOCODE_IS_LOCATION (loca), 0.0); - g_return_val_if_fail (GEOCODE_IS_LOCATION (locb), 0.0); - - /* Algorithm from: - * http://www.movable-type.co.uk/scripts/latlong.html */ - - dlat = (locb->priv->latitude - loca->priv->latitude) * M_PI / 180.0; - dlon = (locb->priv->longitude - loca->priv->longitude) * M_PI / 180.0; - lat1 = loca->priv->latitude * M_PI / 180.0; - lat2 = locb->priv->latitude * M_PI / 180.0; - - a = sin (dlat / 2) * sin (dlat / 2) + - sin (dlon / 2) * sin (dlon / 2) * cos (lat1) * cos (lat2); - c = 2 * atan2 (sqrt (a), sqrt (1-a)); - return EARTH_RADIUS_KM * c; -} diff --git a/src/geocode-glib/geocode-location.h b/src/geocode-glib/geocode-location.h deleted file mode 100644 index 3eb3517..0000000 --- a/src/geocode-glib/geocode-location.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright 2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - Zeeshan Ali (Khattak) <zeeshanak@gnome.org> - - */ - -#ifndef GEOCODE_LOCATION_H -#define GEOCODE_LOCATION_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -GType geocode_location_get_type (void) G_GNUC_CONST; - -#define GEOCODE_TYPE_LOCATION (geocode_location_get_type ()) -#define GEOCODE_LOCATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_LOCATION, GeocodeLocation)) -#define GEOCODE_IS_LOCATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_LOCATION)) -#define GEOCODE_LOCATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_LOCATION, GeocodeLocationClass)) -#define GEOCODE_IS_LOCATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_LOCATION)) -#define GEOCODE_LOCATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_LOCATION, GeocodeLocationClass)) - -typedef struct _GeocodeLocation GeocodeLocation; -typedef struct _GeocodeLocationClass GeocodeLocationClass; -typedef struct _GeocodeLocationPrivate GeocodeLocationPrivate; - -/** - * GeocodeLocation: - * - * All the fields in the #GeocodeLocation structure are private and should never be accessed directly. -**/ -struct _GeocodeLocation { - /* <private> */ - GObject parent_instance; - GeocodeLocationPrivate *priv; -}; - -/** - * GeocodeLocationClass: - * - * All the fields in the #GeocodeLocationClass structure are private and should never be accessed directly. -**/ -struct _GeocodeLocationClass { - /* <private> */ - GObjectClass parent_class; -}; - -/** - * GeocodeLocationURIScheme: - * @GEOCODE_LOCATION_URI_SCHEME_GEO: The 'geo' URI scheme, RFC 5870 - * - * The URI scheme for this location. - */ -typedef enum { - GEOCODE_LOCATION_URI_SCHEME_GEO = 0 -} GeocodeLocationURIScheme; - -/** - * GeocodeLocationCRS: - * @GEOCODE_LOCATION_CRS_WGS84: CRS is World Geodetic System, standard for Earth. - * - * Coordinate Reference System Identification for a location. - */ -typedef enum { - GEOCODE_LOCATION_CRS_WGS84 = 0 -} GeocodeLocationCRS; - -/** - * GEOCODE_LOCATION_ALTITUDE_UNKNOWN: - * - * Constant representing unknown altitude. - */ -#define GEOCODE_LOCATION_ALTITUDE_UNKNOWN -G_MAXDOUBLE - -/** - * GEOCODE_LOCATION_ACCURACY_UNKNOWN: - * - * Constant representing unknown accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_UNKNOWN -1 - -/** - * GEOCODE_LOCATION_ACCURACY_STREET: - * - * Constant representing street-level accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_STREET 1000 /* 1 km */ - -/** - * GEOCODE_LOCATION_ACCURACY_CITY: - * - * Constant representing city-level accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_CITY 15000 /* 15 km */ - -/** - * GEOCODE_LOCATION_ACCURACY_REGION: - * - * Constant representing region-level accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_REGION 50000 /* 50 km */ - -/** - * GEOCODE_LOCATION_ACCURACY_COUNTRY: - * - * Constant representing country-level accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_COUNTRY 300000 /* 300 km */ - -/** - * GEOCODE_LOCATION_ACCURACY_CONTINENT: - * - * Constant representing continent-level accuracy. - */ -#define GEOCODE_LOCATION_ACCURACY_CONTINENT 3000000 /* 3000 km */ - -#define GEOCODE_TYPE_LOCATION (geocode_location_get_type ()) - -GeocodeLocation *geocode_location_new (gdouble latitude, - gdouble longitude, - gdouble accuracy); - -GeocodeLocation *geocode_location_new_with_description (gdouble latitude, - gdouble longitude, - gdouble accuracy, - const char *description); - -gboolean geocode_location_set_from_uri (GeocodeLocation *loc, - const char *uri, - GError **error); - -char * geocode_location_to_uri (GeocodeLocation *loc, - GeocodeLocationURIScheme scheme); - -double geocode_location_get_distance_from (GeocodeLocation *loca, - GeocodeLocation *locb); - -void geocode_location_set_description (GeocodeLocation *loc, - const char *description); - -const char *geocode_location_get_description (GeocodeLocation *loc); - -gdouble geocode_location_get_latitude (GeocodeLocation *loc); -gdouble geocode_location_get_longitude (GeocodeLocation *loc); -gdouble geocode_location_get_altitude (GeocodeLocation *loc); -GeocodeLocationCRS geocode_location_get_crs (GeocodeLocation *loc); -gdouble geocode_location_get_accuracy (GeocodeLocation *loc); -guint64 geocode_location_get_timestamp (GeocodeLocation *loc); - -G_END_DECLS - -#endif /* GEOCODE_LOCATION_H */ diff --git a/src/geocode-glib/geocode-place.c b/src/geocode-glib/geocode-place.c deleted file mode 100644 index c6010df..0000000 --- a/src/geocode-glib/geocode-place.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* - Copyright 2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - Zeeshan Ali (Khattak) <zeeshanak@gnome.org> - - */ - -#include <gio/gio.h> -#include <geocode-glib/geocode-place.h> -#include <geocode-glib/geocode-bounding-box.h> -#include <geocode-glib/geocode-enum-types.h> -#include <geocode-glib/geocode-glib-private.h> - -/** - * SECTION:geocode-place - * @short_description: Geocode place object - * @include: geocode-glib/geocode-glib.h - * - * The #GeocodePlace instance represents a place on earth. While - * #GeocodeLocation represents a point on the planet, #GeocodePlace represents - * places, e.g street, town, village, county, country or points of interest - * (POI) etc. - **/ - -struct _GeocodePlacePrivate { - char *name; - GeocodePlaceType place_type; - GeocodeLocation *location; - GeocodeBoundingBox *bbox; - - char *street_address; - char *street; - char *building; - char *postal_code; - char *area; - char *town; - char *county; - char *state; - char *admin_area; - char *country_code; - char *country; - char *continent; - char *osm_id; - GeocodePlaceOsmType osm_type; -}; - -enum { - PROP_0, - - PROP_NAME, - PROP_PLACE_TYPE, - PROP_LOCATION, - PROP_STREET_ADDRESS, - PROP_STREET, - PROP_BUILDING, - PROP_POSTAL_CODE, - PROP_AREA, - PROP_TOWN, - PROP_COUNTY, - PROP_STATE, - PROP_ADMINISTRATIVE_AREA, - PROP_COUNTRY_CODE, - PROP_COUNTRY, - PROP_CONTINENT, - PROP_ICON, - PROP_BBOX, - PROP_OSM_ID, - PROP_OSM_TYPE -}; - -G_DEFINE_TYPE (GeocodePlace, geocode_place, G_TYPE_OBJECT) - -static void -geocode_place_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GeocodePlace *place = GEOCODE_PLACE (object); - - switch (property_id) { - case PROP_NAME: - g_value_set_string (value, - geocode_place_get_name (place)); - break; - - case PROP_PLACE_TYPE: - g_value_set_enum (value, - geocode_place_get_place_type (place)); - break; - - case PROP_LOCATION: - g_value_set_object (value, - geocode_place_get_location (place)); - break; - - case PROP_STREET_ADDRESS: - g_value_set_string (value, - geocode_place_get_street_address (place)); - break; - - case PROP_STREET: - g_value_set_string (value, - geocode_place_get_street (place)); - break; - - case PROP_BUILDING: - g_value_set_string (value, - geocode_place_get_building (place)); - break; - - case PROP_POSTAL_CODE: - g_value_set_string (value, - geocode_place_get_postal_code (place)); - break; - - case PROP_AREA: - g_value_set_string (value, - geocode_place_get_area (place)); - break; - - case PROP_TOWN: - g_value_set_string (value, - geocode_place_get_town (place)); - break; - - case PROP_COUNTY: - g_value_set_string (value, - geocode_place_get_county (place)); - break; - - case PROP_STATE: - g_value_set_string (value, - geocode_place_get_state (place)); - break; - - case PROP_ADMINISTRATIVE_AREA: - g_value_set_string (value, - geocode_place_get_administrative_area (place)); - break; - - case PROP_COUNTRY_CODE: - g_value_set_string (value, - geocode_place_get_country_code (place)); - break; - - case PROP_COUNTRY: - g_value_set_string (value, - geocode_place_get_country (place)); - break; - - case PROP_CONTINENT: - g_value_set_string (value, - geocode_place_get_continent (place)); - break; - - case PROP_ICON: - g_value_set_object (value, - geocode_place_get_icon (place)); - break; - - case PROP_BBOX: - g_value_set_object (value, - geocode_place_get_bounding_box (place)); - break; - - case PROP_OSM_ID: - g_value_set_string (value, - geocode_place_get_osm_id (place)); - break; - - case PROP_OSM_TYPE: - g_value_set_enum (value, - geocode_place_get_osm_type (place)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_place_set_property(GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GeocodePlace *place = GEOCODE_PLACE (object); - - switch (property_id) { - case PROP_NAME: - place->priv->name = g_value_dup_string (value); - break; - - case PROP_PLACE_TYPE: - place->priv->place_type = g_value_get_enum (value); - break; - - case PROP_LOCATION: - place->priv->location = g_value_dup_object (value); - break; - - case PROP_STREET_ADDRESS: - geocode_place_set_street_address (place, - g_value_get_string (value)); - break; - - case PROP_STREET: - geocode_place_set_street (place, g_value_get_string (value)); - break; - - case PROP_BUILDING: - geocode_place_set_building (place, g_value_get_string (value)); - break; - - case PROP_POSTAL_CODE: - geocode_place_set_postal_code (place, - g_value_get_string (value)); - break; - - case PROP_AREA: - geocode_place_set_area (place, g_value_get_string (value)); - break; - - case PROP_TOWN: - geocode_place_set_town (place, g_value_get_string (value)); - break; - - case PROP_COUNTY: - geocode_place_set_county (place, g_value_get_string (value)); - break; - - case PROP_STATE: - geocode_place_set_state (place, g_value_get_string (value)); - break; - - case PROP_ADMINISTRATIVE_AREA: - geocode_place_set_administrative_area (place, - g_value_get_string (value)); - break; - - case PROP_COUNTRY_CODE: - geocode_place_set_country_code (place, - g_value_get_string (value)); - break; - - case PROP_COUNTRY: - geocode_place_set_country (place, - g_value_get_string (value)); - break; - - case PROP_CONTINENT: - geocode_place_set_continent (place, g_value_get_string (value)); - break; - - case PROP_BBOX: - place->priv->bbox = g_value_dup_object (value); - break; - - case PROP_OSM_ID: - place->priv->osm_id = g_value_dup_string (value); - break; - - case PROP_OSM_TYPE: - place->priv->osm_type = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -geocode_place_dispose (GObject *gplace) -{ - GeocodePlace *place = (GeocodePlace *) gplace; - - g_clear_object (&place->priv->location); - g_clear_object (&place->priv->bbox); - - g_clear_pointer (&place->priv->name, g_free); - g_clear_pointer (&place->priv->osm_id, g_free); - g_clear_pointer (&place->priv->street_address, g_free); - g_clear_pointer (&place->priv->street, g_free); - g_clear_pointer (&place->priv->building, g_free); - g_clear_pointer (&place->priv->postal_code, g_free); - g_clear_pointer (&place->priv->area, g_free); - g_clear_pointer (&place->priv->town, g_free); - g_clear_pointer (&place->priv->county, g_free); - g_clear_pointer (&place->priv->state, g_free); - g_clear_pointer (&place->priv->admin_area, g_free); - g_clear_pointer (&place->priv->country_code, g_free); - g_clear_pointer (&place->priv->country, g_free); - g_clear_pointer (&place->priv->continent, g_free); - - G_OBJECT_CLASS (geocode_place_parent_class)->dispose (gplace); -} - -static void -geocode_place_class_init (GeocodePlaceClass *klass) -{ - GObjectClass *gplace_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gplace_class->dispose = geocode_place_dispose; - gplace_class->get_property = geocode_place_get_property; - gplace_class->set_property = geocode_place_set_property; - - g_type_class_add_private (klass, sizeof (GeocodePlacePrivate)); - - /** - * GeocodePlace:name: - * - * The name of the place. - */ - pspec = g_param_spec_string ("name", - "Name", - "Name", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_NAME, pspec); - - /** - * GeocodePlace:place-type: - * - * The type of the place. - */ - pspec = g_param_spec_enum ("place-type", - "PlaceType", - "Place Type", - GEOCODE_TYPE_PLACE_TYPE, - GEOCODE_PLACE_TYPE_UNKNOWN, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_PLACE_TYPE, pspec); - - /** - * GeocodePlace:location: - * - * The location info for the place. - */ - pspec = g_param_spec_object ("location", - "Location", - "Location Info", - GEOCODE_TYPE_LOCATION, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_LOCATION, pspec); - - /** - * GeocodePlace:street-address: - * - * The street address. - */ - pspec = g_param_spec_string ("street-address", - "StreetAddress", - "Street Address", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_STREET_ADDRESS, pspec); - - /** - * GeocodePlace:street: - * - * The street name. - */ - pspec = g_param_spec_string ("street", - "Street", - "Street name", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_STREET, pspec); - - /** - * GeocodePlace:building: - * - * A specific building on a street or in an area. - */ - pspec = g_param_spec_string ("building", - "Building", - "A specific building on a street or in an area", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_BUILDING, pspec); - - /** - * GeocodePlace:postal-code: - * - * The postal code. - */ - pspec = g_param_spec_string ("postal-code", - "PostalCode", - "Postal Code", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_POSTAL_CODE, pspec); - - /** - * GeocodePlace:area: - * - * A named area such as a campus or neighborhood. - */ - pspec = g_param_spec_string ("area", - "Area", - "A named area such as a campus or neighborhood", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_AREA, pspec); - - /** - * GeocodePlace:town: - * - * The town. - */ - pspec = g_param_spec_string ("town", - "Town", - "Town", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_TOWN, pspec); - - /** - * GeocodePlace:state: - * - * The state. - */ - pspec = g_param_spec_string ("state", - "State", - "State", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_STATE, pspec); - - /** - * GeocodePlace:county: - * - * The county. - */ - pspec = g_param_spec_string ("county", - "County", - "County", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_COUNTY, pspec); - - /** - * GeocodePlace:administrative-area: - * - * The local administrative area. - */ - pspec = g_param_spec_string ("administrative-area", - "AdministrativeArea", - "Local administrative area", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_ADMINISTRATIVE_AREA, pspec); - - /** - * GeocodePlace:country-code: - * - * The country code. - */ - pspec = g_param_spec_string ("country-code", - "CountryCode", - "ISO Country Code", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_COUNTRY_CODE, pspec); - - /** - * GeocodePlace:country: - * - * The country. - */ - pspec = g_param_spec_string ("country", - "Country", - "Country", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_COUNTRY, pspec); - - /** - * GeocodePlace:continent: - * - * The continent. - */ - pspec = g_param_spec_string ("continent", - "Continent", - "Continent", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_CONTINENT, pspec); - - /** - * GeocodePlace:icon: - * - * #GIcon representing the @GeocodePlace. - */ - pspec = g_param_spec_object ("icon", - "Icon", - "An icon representing the the place", - G_TYPE_ICON, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_ICON, pspec); - - /** - * GeocodePlace:bounding-box: - * - * The bounding box for the place. - */ - pspec = g_param_spec_object ("bounding-box", - "Bounding Box", - "The bounding box for the place", - GEOCODE_TYPE_BOUNDING_BOX, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_BBOX, pspec); - - /** - * GeocodePlace:osm-id: - * - * The OpenStreetMap id of the place. - */ - pspec = g_param_spec_string ("osm-id", - "OSM ID", - "The OpenStreetMap ID of the place", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_OSM_ID, pspec); - - /** - * GeocodePlace:osm-type: - * - * The OpenStreetMap type of the place. - */ - pspec = g_param_spec_enum ("osm-type", - "OSM Type", - "The OpenStreetMap type of the place", - GEOCODE_TYPE_PLACE_OSM_TYPE, - GEOCODE_PLACE_OSM_TYPE_UNKNOWN, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gplace_class, PROP_OSM_TYPE, pspec); -} - -static void -geocode_place_init (GeocodePlace *place) -{ - place->priv = G_TYPE_INSTANCE_GET_PRIVATE ((place), - GEOCODE_TYPE_PLACE, - GeocodePlacePrivate); - place->priv->bbox = NULL; - place->priv->osm_type = GEOCODE_PLACE_OSM_TYPE_UNKNOWN; -} - -/** - * geocode_place_new: - * @name: the name of place - * @place_type: the type of place - * - * Creates a new #GeocodePlace object. - * - * Returns: a new #GeocodePlace object. Use g_object_unref() when done. - **/ -GeocodePlace * -geocode_place_new (const char *name, - GeocodePlaceType place_type) -{ - return g_object_new (GEOCODE_TYPE_PLACE, - "name", name, - "place-type", place_type, - NULL); -} - -/** - * geocode_place_new_with_location: - * @name: the name of place - * @place_type: the type of place - * @location: the location info for the place - * - * Creates a new #GeocodePlace object. - * - * Returns: a new #GeocodePlace object. Use g_object_unref() when done. - **/ -GeocodePlace * -geocode_place_new_with_location (const char *name, - GeocodePlaceType place_type, - GeocodeLocation *location) -{ - return g_object_new (GEOCODE_TYPE_PLACE, - "name", name, - "place-type", place_type, - "location", location, - NULL); -} - -/** - * geocode_place_set_name: - * @place: A place - * @name: the name of place - * - * Sets the name of the @place to @name. - **/ -void -geocode_place_set_name (GeocodePlace *place, - const char *name) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (name != NULL); - - g_free (place->priv->name); - place->priv->name = g_strdup (name); -} - -/** - * geocode_place_get_name: - * @place: A place - * - * Gets the name of the @place. - * - * Returns: The name of the @place. - **/ -const char * -geocode_place_get_name (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->name; - -} - -/** - * geocode_place_get_place_type: - * @place: A place - * - * Gets the type of the @place. - * - * Returns: The type of the @place. - **/ -GeocodePlaceType -geocode_place_get_place_type (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), - GEOCODE_PLACE_TYPE_UNKNOWN); - - return place->priv->place_type; -} - -/** - * geocode_place_set_location: - * @place: A place - * @location: A location - * - * Sets the location of @place to @location. - **/ -void -geocode_place_set_location (GeocodePlace *place, - GeocodeLocation *location) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (GEOCODE_IS_LOCATION (location)); - - g_clear_object (&place->priv->location); - place->priv->location = g_object_ref (location); -} - -/** - * geocode_place_get_location: - * @place: A place - * - * Gets the associated location object. - * - * Returns: (transfer none): The associated location object. - **/ -GeocodeLocation * -geocode_place_get_location (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->location; -} - -/** - * geocode_place_set_street_address: - * @place: A place - * @street_address: a street address for the place - * - * Sets the street address of @place to @street_address. - **/ -void -geocode_place_set_street_address (GeocodePlace *place, - const char *street_address) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (street_address != NULL); - - g_free (place->priv->street_address); - place->priv->street_address = g_strdup (street_address); -} - -/** - * geocode_place_get_street_address: - * @place: A place - * - * Gets the street address of the @place. - * - * Returns: The street address of the @place. - **/ -const char * -geocode_place_get_street_address (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->street_address; -} - -/** - * geocode_place_set_street: - * @place: A place - * @street: a street - * - * Sets the street of @place to @street. - **/ -void -geocode_place_set_street (GeocodePlace *place, - const char *street) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (street != NULL); - - g_free (place->priv->street); - place->priv->street = g_strdup (street); -} - -/** - * geocode_place_get_street: - * @place: A place - * - * Gets the street of the @place. - * - * Returns: The street of the @place. - **/ -const char * -geocode_place_get_street (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->street; -} - -/** - * geocode_place_set_building: - * @place: A place - * @building: a building - * - * Sets the building of @place to @building. - **/ -void -geocode_place_set_building (GeocodePlace *place, - const char *building) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (building != NULL); - - g_free (place->priv->building); - place->priv->building = g_strdup (building); -} - -/** - * geocode_place_get_building: - * @place: A place - * - * Gets the building of the @place. - * - * Returns: The building of the @place. - **/ -const char * -geocode_place_get_building (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->building; -} - -/** - * geocode_place_set_postal_code: - * @place: A place - * @postal_code: a postal code for the place - * - * Sets the postal code of @place to @postal_code. - **/ -void -geocode_place_set_postal_code (GeocodePlace *place, - const char *postal_code) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (postal_code != NULL); - - g_free (place->priv->postal_code); - place->priv->postal_code = g_strdup (postal_code); -} - -/** - * geocode_place_get_postal_code: - * @place: A place - * - * Gets the postal code of the @place. - * - * Returns: The postal code of the @place. - **/ -const char * -geocode_place_get_postal_code (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->postal_code; -} - -/** - * geocode_place_set_area: - * @place: A place - * @area: a area - * - * Sets the area of @place to @area. - **/ -void -geocode_place_set_area (GeocodePlace *place, - const char *area) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (area != NULL); - - g_free (place->priv->area); - place->priv->area = g_strdup (area); -} - -/** - * geocode_place_get_area: - * @place: A place - * - * Gets the area of the @place. - * - * Returns: The area of the @place. - **/ -const char * -geocode_place_get_area (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->area; -} - -/** - * geocode_place_set_town: - * @place: A place - * @town: a town for the place - * - * Sets the town of @place to @town. - **/ -void -geocode_place_set_town (GeocodePlace *place, - const char *town) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (town != NULL); - - g_free (place->priv->town); - place->priv->town = g_strdup (town); -} - -/** - * geocode_place_get_town: - * @place: A place - * - * Gets the town of the @place. - * - * Returns: The town of the @place. - **/ -const char * -geocode_place_get_town (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->town; -} - -/** - * geocode_place_set_county: - * @place: A place - * @county: a county for the place - * - * Sets the county of @place to @county. - **/ -void -geocode_place_set_county (GeocodePlace *place, - const char *county) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (county != NULL); - - g_free (place->priv->county); - place->priv->county = g_strdup (county); -} - -/** - * geocode_place_get_county: - * @place: A place - * - * Gets the county of the @place. - * - * Returns: The country of the @place. - **/ -const char * -geocode_place_get_county (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->county; -} - -/** - * geocode_place_set_state: - * @place: A place - * @state: a state for the place - * - * Sets the state of @place to @state. - **/ -void -geocode_place_set_state (GeocodePlace *place, - const char *state) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (state != NULL); - - g_free (place->priv->state); - place->priv->state = g_strdup (state); -} - -/** - * geocode_place_get_state: - * @place: A place - * - * Gets the state of the @place. - * - * Returns: The state of the @place. - **/ -const char * -geocode_place_get_state (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->state; -} - -/** - * geocode_place_set_administrative_area: - * @place: A place - * @admin_area: an administrative area for the place - * - * Sets the local administrative area of @place to @admin_area. - **/ -void -geocode_place_set_administrative_area (GeocodePlace *place, - const char *admin_area) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (admin_area != NULL); - - g_free (place->priv->admin_area); - place->priv->admin_area = g_strdup (admin_area); -} - -/** - * geocode_place_get_administrative_area: - * @place: A place - * - * Gets the local administrative area of the @place. - * - * Returns: The local administrative area of the @place. - **/ -const char * -geocode_place_get_administrative_area (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->admin_area; -} - -/** - * geocode_place_set_country_code: - * @place: A place - * @country_code: an ISO country code for the place - * - * Sets the ISO country code of @place to @country_code. - **/ -void -geocode_place_set_country_code (GeocodePlace *place, - const char *country_code) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (country_code != NULL); - - g_free (place->priv->country_code); - place->priv->country_code = g_utf8_strup (country_code, -1); -} - -/** - * geocode_place_get_country_code: - * @place: A place - * - * Gets the ISO-3166 country code of the @place. - * - * Returns: The ISO-3166 country code of the @place, in upper case. - **/ -const char * -geocode_place_get_country_code (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->country_code; -} - -/** - * geocode_place_set_country: - * @place: A place - * @country: a country for the place - * - * Sets the country of @place to @country. - **/ -void -geocode_place_set_country (GeocodePlace *place, - const char *country) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (country != NULL); - - g_free (place->priv->country); - place->priv->country = g_strdup (country); -} - -/** - * geocode_place_get_country: - * @place: A place - * - * Gets the country of the @place. - * - * Returns: The country of the @place. - **/ -const char * -geocode_place_get_country (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->country; -} - -/** - * geocode_place_set_continent: - * @place: A place - * @continent: a continent for the place - * - * Sets the continent of @place to @continent. - **/ -void -geocode_place_set_continent (GeocodePlace *place, - const char *continent) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (continent != NULL); - - g_free (place->priv->continent); - place->priv->continent = g_strdup (continent); -} - -/** - * geocode_place_get_continent: - * @place: A place - * - * Gets the continent of the @place. - * - * Returns: The continent of the @place. - **/ -const char * -geocode_place_get_continent (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->continent; -} - -static char * -get_icon_name (GeocodePlace *place) -{ - char *icon_name; - - switch (place->priv->place_type) { - - case GEOCODE_PLACE_TYPE_BUILDING: - icon_name = "poi-building"; - break; - - case GEOCODE_PLACE_TYPE_TOWN: - icon_name = "poi-town"; - break; - - case GEOCODE_PLACE_TYPE_AIRPORT: - icon_name = "poi-airport"; - break; - - case GEOCODE_PLACE_TYPE_RAILWAY_STATION: - icon_name = "poi-railway-station"; - break; - - case GEOCODE_PLACE_TYPE_BUS_STOP: - icon_name = "poi-bus-stop"; - break; - - case GEOCODE_PLACE_TYPE_STREET: - icon_name = "poi-car"; - break; - - case GEOCODE_PLACE_TYPE_SCHOOL: - icon_name = "poi-school"; - break; - - case GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP: - icon_name = "poi-place-of-worship"; - break; - - case GEOCODE_PLACE_TYPE_RESTAURANT: - icon_name = "poi-restaurant"; - break; - - case GEOCODE_PLACE_TYPE_BAR: - icon_name = "poi-bar"; - break; - - case GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION: - icon_name = "poi-light-rail-station"; - break; - - default: - icon_name = "poi-marker"; /* generic marker */ - break; - } - - return icon_name; -} - -/** - * geocode_place_get_icon: - * @place: A place - * - * Gets the #GIcon representing the @place. - * - * Returns: (transfer none): The #GIcon representing the @place. - **/ -GIcon * -geocode_place_get_icon (GeocodePlace *place) -{ - char *icon_name; - - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - icon_name = get_icon_name (place); - - return g_icon_new_for_string (icon_name, NULL); -} - -/** - * geocode_place_get_bounding_box: - * @place: A place - * - * Gets the bounding box for the place @place. - * - * Returns: (transfer none): A #GeocodeBoundingBox, or NULL if boundaries are - * unknown. - **/ -GeocodeBoundingBox * -geocode_place_get_bounding_box (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->bbox; -} - -/** - * geocode_place_set_bounding_box: - * @place: A place - * @bbox: A #GeocodeBoundingBox for the place - * - * Sets the #GeocodeBoundingBox for the place @place. - * - **/ -void -geocode_place_set_bounding_box (GeocodePlace *place, - GeocodeBoundingBox *bbox) -{ - g_return_if_fail (GEOCODE_IS_PLACE (place)); - g_return_if_fail (GEOCODE_IS_BOUNDING_BOX (bbox)); - - g_clear_object (&place->priv->bbox); - place->priv->bbox = g_object_ref (bbox); -} - -/** - * geocode_place_get_osm_id: - * @place: A place - * - * Gets the OpenStreetMap ID of the @place. - * - * Returns: The osm ID of the @place. - **/ -const char * -geocode_place_get_osm_id (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), NULL); - - return place->priv->osm_id; -} - -/** - * geocode_place_get_osm_type: - * @place: A place - * - * Gets the OpenStreetMap type of the @place. - * - * Returns: The osm type of the @place. - **/ -GeocodePlaceOsmType -geocode_place_get_osm_type (GeocodePlace *place) -{ - g_return_val_if_fail (GEOCODE_IS_PLACE (place), GEOCODE_PLACE_OSM_TYPE_UNKNOWN); - - return place->priv->osm_type; -} diff --git a/src/geocode-glib/geocode-place.h b/src/geocode-glib/geocode-place.h deleted file mode 100644 index 3580bc6..0000000 --- a/src/geocode-glib/geocode-place.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - Copyright 2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - Zeeshan Ali (Khattak) <zeeshanak@gnome.org> - - */ - -#ifndef GEOCODE_PLACE_H -#define GEOCODE_PLACE_H - -#include <glib-object.h> -#include <gio/gio.h> -#include <geocode-glib/geocode-location.h> -#include <geocode-glib/geocode-bounding-box.h> - -G_BEGIN_DECLS - -GType geocode_place_get_type (void) G_GNUC_CONST; - -#define GEOCODE_TYPE_PLACE (geocode_place_get_type ()) -#define GEOCODE_PLACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_PLACE, GeocodePlace)) -#define GEOCODE_IS_PLACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_PLACE)) -#define GEOCODE_PLACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_PLACE, GeocodePlaceClass)) -#define GEOCODE_IS_PLACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_PLACE)) -#define GEOCODE_PLACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_PLACE, GeocodePlaceClass)) - -typedef struct _GeocodePlace GeocodePlace; -typedef struct _GeocodePlaceClass GeocodePlaceClass; -typedef struct _GeocodePlacePrivate GeocodePlacePrivate; - -/** - * GeocodePlace: - * - * All the fields in the #GeocodePlace structure are private and should never be accessed directly. -**/ -struct _GeocodePlace { - /* <private> */ - GObject parent_instance; - GeocodePlacePrivate *priv; -}; - -/** - * GeocodePlaceClass: - * - * All the fields in the #GeocodePlaceClass structure are private and should never be accessed directly. -**/ -struct _GeocodePlaceClass { - /* <private> */ - GObjectClass parent_class; -}; - -/** - * GeocodePlaceType: - * @GEOCODE_PLACE_TYPE_UNKNOWN: Type is unknown for this place. - * @GEOCODE_PLACE_TYPE_BUILDING: A building or house. - * @GEOCODE_PLACE_TYPE_STREET: A street. - * @GEOCODE_PLACE_TYPE_TOWN: A populated settlement such as a city, town, village. - * @GEOCODE_PLACE_TYPE_STATE: One of the primary administrative areas within a country. - * @GEOCODE_PLACE_TYPE_COUNTY: One of the secondary administrative areas within a country. - * @GEOCODE_PLACE_TYPE_LOCAL_ADMINISTRATIVE_AREA: One of the tertiary administrative areas within a country. - * @GEOCODE_PLACE_TYPE_POSTAL_CODE: A partial or full postal code. - * @GEOCODE_PLACE_TYPE_COUNTRY: One of the countries or dependent territories defined by the ISO 3166-1 standard. - * @GEOCODE_PLACE_TYPE_ISLAND: An island. - * @GEOCODE_PLACE_TYPE_AIRPORT: An airport. - * @GEOCODE_PLACE_TYPE_RAILWAY_STATION: A railway station. - * @GEOCODE_PLACE_TYPE_BUS_STOP: A bus stop. - * @GEOCODE_PLACE_TYPE_MOTORWAY: A high capacity highways designed to safely carry fast motor traffic. - * @GEOCODE_PLACE_TYPE_DRAINAGE: A water feature such as a river, canal, lake, bay or ocean. - * @GEOCODE_PLACE_TYPE_LAND_FEATURE: A land feature such as a park, mountain or beach. - * @GEOCODE_PLACE_TYPE_MISCELLANEOUS: A uncategorized place. - * @GEOCODE_PLACE_TYPE_SUPERNAME: An area covering multiple countries. - * @GEOCODE_PLACE_TYPE_POINT_OF_INTEREST: A point of interest such as a school, hospital or tourist attraction. - * @GEOCODE_PLACE_TYPE_SUBURB: A subdivision of a town such as a suburb or neighborhood. - * @GEOCODE_PLACE_TYPE_COLLOQUIAL: A place known by a colloquial name. - * @GEOCODE_PLACE_TYPE_ZONE: An area known within a specific context such as MSA or area code. - * @GEOCODE_PLACE_TYPE_HISTORICAL_STATE: A historical primary administrative area within a country. - * @GEOCODE_PLACE_TYPE_HISTORICAL_COUNTY: A historical secondary administrative area within a country. - * @GEOCODE_PLACE_TYPE_CONTINENT: One of the major land masses on the Earth. - * @GEOCODE_PLACE_TYPE_TIME_ZONE: An area defined by the Olson standard (tz database). - * @GEOCODE_PLACE_TYPE_ESTATE: A housing development or subdivision known by name. - * @GEOCODE_PLACE_TYPE_HISTORICAL_TOWN: A historical populated settlement that is no longer known by its original name. - * @GEOCODE_PLACE_TYPE_OCEAN: One of the five major bodies of water on the Earth. - * @GEOCODE_PLACE_TYPE_SEA: An area of open water smaller than an ocean. - * @GEOCODE_PLACE_TYPE_SCHOOL: Institution designed for learning under the supervision of teachers. - * @GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP: All places of worship independently of the religion or denomination. - * @GEOCODE_PLACE_TYPE_RESTAURANT: Generally formal place with sit-down facilities selling full meals served by waiters. - * @GEOCODE_PLACE_TYPE_BAR: A bar or pub. - * @GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION: A light rail station or tram stop. - * - * Type of the place. - */ -typedef enum { - GEOCODE_PLACE_TYPE_UNKNOWN = 0, - GEOCODE_PLACE_TYPE_BUILDING, - GEOCODE_PLACE_TYPE_STREET, - GEOCODE_PLACE_TYPE_TOWN, - GEOCODE_PLACE_TYPE_STATE, - GEOCODE_PLACE_TYPE_COUNTY, - GEOCODE_PLACE_TYPE_LOCAL_ADMINISTRATIVE_AREA, - GEOCODE_PLACE_TYPE_POSTAL_CODE, - GEOCODE_PLACE_TYPE_COUNTRY, - GEOCODE_PLACE_TYPE_ISLAND, - GEOCODE_PLACE_TYPE_AIRPORT, - GEOCODE_PLACE_TYPE_RAILWAY_STATION, - GEOCODE_PLACE_TYPE_BUS_STOP, - GEOCODE_PLACE_TYPE_MOTORWAY, - GEOCODE_PLACE_TYPE_DRAINAGE, - GEOCODE_PLACE_TYPE_LAND_FEATURE, - GEOCODE_PLACE_TYPE_MISCELLANEOUS, - GEOCODE_PLACE_TYPE_SUPERNAME, - GEOCODE_PLACE_TYPE_POINT_OF_INTEREST, - GEOCODE_PLACE_TYPE_SUBURB, - GEOCODE_PLACE_TYPE_COLLOQUIAL, - GEOCODE_PLACE_TYPE_ZONE, - GEOCODE_PLACE_TYPE_HISTORICAL_STATE, - GEOCODE_PLACE_TYPE_HISTORICAL_COUNTY, - GEOCODE_PLACE_TYPE_CONTINENT, - GEOCODE_PLACE_TYPE_TIME_ZONE, - GEOCODE_PLACE_TYPE_ESTATE, - GEOCODE_PLACE_TYPE_HISTORICAL_TOWN, - GEOCODE_PLACE_TYPE_OCEAN, - GEOCODE_PLACE_TYPE_SEA, - GEOCODE_PLACE_TYPE_SCHOOL, - GEOCODE_PLACE_TYPE_PLACE_OF_WORSHIP, - GEOCODE_PLACE_TYPE_RESTAURANT, - GEOCODE_PLACE_TYPE_BAR, - GEOCODE_PLACE_TYPE_LIGHT_RAIL_STATION -} GeocodePlaceType; - - -/** - * GeocodePlaceOsmType: - * @GEOCODE_PLACE_OSM_TYPE_UNKNOWN: Unknown type - * @GEOCODE_PLACE_OSM_TYPE_NODE: Defines a point in space. - * @GEOCODE_PLACE_OSM_TYPE_RELATION: Used to explain how other elements work together. - * @GEOCODE_PLACE_OSM_TYPE_WAY: Defines a linear feature and area boundaries. - * - * Osm type of the place. - */ -typedef enum { - GEOCODE_PLACE_OSM_TYPE_UNKNOWN, - GEOCODE_PLACE_OSM_TYPE_NODE, - GEOCODE_PLACE_OSM_TYPE_RELATION, - GEOCODE_PLACE_OSM_TYPE_WAY -} GeocodePlaceOsmType; - -#define GEOCODE_TYPE_PLACE (geocode_place_get_type ()) - -GeocodePlace *geocode_place_new (const char *name, - GeocodePlaceType place_type); -GeocodePlace *geocode_place_new_with_location (const char *name, - GeocodePlaceType place_type, - GeocodeLocation *location); - -void geocode_place_set_name (GeocodePlace *place, - const char *name); -const char *geocode_place_get_name (GeocodePlace *place); - -GeocodePlaceType geocode_place_get_place_type (GeocodePlace *place); - -GeocodeBoundingBox *geocode_place_get_bounding_box (GeocodePlace *place); - -void geocode_place_set_bounding_box (GeocodePlace *place, - GeocodeBoundingBox *bbox); - -void geocode_place_set_location (GeocodePlace *place, - GeocodeLocation *location); -GeocodeLocation *geocode_place_get_location (GeocodePlace *place); - -void geocode_place_set_street_address (GeocodePlace *place, - const char *street_address); -const char *geocode_place_get_street_address (GeocodePlace *place); - -void geocode_place_set_street (GeocodePlace *place, - const char *street); -const char *geocode_place_get_street (GeocodePlace *place); - -void geocode_place_set_building (GeocodePlace *place, - const char *building); -const char *geocode_place_get_building (GeocodePlace *place); - -void geocode_place_set_postal_code (GeocodePlace *place, - const char *postal_code); -const char *geocode_place_get_postal_code (GeocodePlace *place); - -void geocode_place_set_area (GeocodePlace *place, - const char *area); -const char *geocode_place_get_area (GeocodePlace *place); - -void geocode_place_set_town (GeocodePlace *place, - const char *town); -const char *geocode_place_get_town (GeocodePlace *place); - -void geocode_place_set_county (GeocodePlace *place, - const char *county); -const char *geocode_place_get_county (GeocodePlace *place); - -void geocode_place_set_state (GeocodePlace *place, - const char *state); -const char *geocode_place_get_state (GeocodePlace *place); - -void geocode_place_set_administrative_area (GeocodePlace *place, - const char *admin_area); -const char *geocode_place_get_administrative_area (GeocodePlace *place); - -void geocode_place_set_country_code (GeocodePlace *place, - const char *country_code); -const char *geocode_place_get_country_code (GeocodePlace *place); - -void geocode_place_set_country (GeocodePlace *place, - const char *country); -const char *geocode_place_get_country (GeocodePlace *place); - -void geocode_place_set_continent (GeocodePlace *place, - const char *continent); -const char *geocode_place_get_continent (GeocodePlace *place); - -GIcon *geocode_place_get_icon (GeocodePlace *place); - -const char *geocode_place_get_osm_id (GeocodePlace *place); -GeocodePlaceOsmType geocode_place_get_osm_type (GeocodePlace *place); - -G_END_DECLS - -#endif /* GEOCODE_PLACE_H */ diff --git a/src/geocode-glib/geocode-reverse.c b/src/geocode-glib/geocode-reverse.c deleted file mode 100644 index 4b3c78c..0000000 --- a/src/geocode-glib/geocode-reverse.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - Copyright 2011-2012 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#include <string.h> -#include <errno.h> -#include <locale.h> -#include <gio/gio.h> -#include <json-glib/json-glib.h> -#include <libsoup/soup.h> -#include <config.h> -#include <glib/gi18n-lib.h> -#include <geocode-glib/geocode-glib.h> -#include <geocode-glib/geocode-error.h> -#include <geocode-glib/geocode-reverse.h> -#include <geocode-glib/geocode-glib-private.h> - -/** - * SECTION:geocode-reverse - * @short_description: Geocode reverse geocoding object - * @include: geocode-glib/geocode-glib.h - * - * Contains functions for reverse geocoding using the - * <ulink url="http://wiki.openstreetmap.org/wiki/Nominatim">OSM Nominatim APIs</ulink> - **/ - -struct _GeocodeReversePrivate { - GHashTable *ht; - SoupSession *soup_session; -}; - -G_DEFINE_TYPE (GeocodeReverse, geocode_reverse, G_TYPE_OBJECT) - -static void -geocode_reverse_finalize (GObject *gobject) -{ - GeocodeReverse *object = (GeocodeReverse *) gobject; - - g_clear_pointer (&object->priv->ht, g_hash_table_destroy); - g_clear_object (&object->priv->soup_session); - - G_OBJECT_CLASS (geocode_reverse_parent_class)->finalize (gobject); -} - -static void -geocode_reverse_class_init (GeocodeReverseClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - bindtextdomain (GETTEXT_PACKAGE, GEOCODE_LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - - gobject_class->finalize = geocode_reverse_finalize; - - g_type_class_add_private (klass, sizeof (GeocodeReversePrivate)); -} - -static void -geocode_reverse_init (GeocodeReverse *object) -{ - object->priv = G_TYPE_INSTANCE_GET_PRIVATE ((object), GEOCODE_TYPE_REVERSE, GeocodeReversePrivate); - object->priv->ht = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - object->priv->soup_session = _geocode_glib_build_soup_session (); -} - -/** - * geocode_reverse_new_for_location: - * @location: a #GeocodeLocation object - * - * Creates a new #GeocodeReverse to perform reverse geocoding with. - * Use geocode_reverse_resolve_async() to perform the resolution. - * - * Returns: a new #GeocodeReverse. Use g_object_unref() when done. - **/ -GeocodeReverse * -geocode_reverse_new_for_location (GeocodeLocation *location) -{ - GeocodeReverse *object; - char coord[G_ASCII_DTOSTR_BUF_SIZE]; - char *lat; - char *lon; - - lat = g_strdup (g_ascii_dtostr (coord, - G_ASCII_DTOSTR_BUF_SIZE, - geocode_location_get_latitude (location))); - - lon = g_strdup (g_ascii_dtostr (coord, - G_ASCII_DTOSTR_BUF_SIZE, - geocode_location_get_longitude (location))); - object = g_object_new (GEOCODE_TYPE_REVERSE, NULL); - - g_hash_table_insert (object->priv->ht, g_strdup ("lat"), lat); - g_hash_table_insert (object->priv->ht, g_strdup ("lon"), lon); - - return object; -} - -static void -insert_bounding_box_element (GHashTable *ht, - GType value_type, - const char *name, - JsonReader *reader) -{ - if (value_type == G_TYPE_STRING) { - const char *bbox_val; - - bbox_val = json_reader_get_string_value (reader); - g_hash_table_insert (ht, g_strdup (name), g_strdup (bbox_val)); - } else if (value_type == G_TYPE_DOUBLE) { - gdouble bbox_val; - - bbox_val = json_reader_get_double_value (reader); - g_hash_table_insert(ht, g_strdup (name), g_strdup_printf ("%lf", bbox_val)); - } else if (value_type == G_TYPE_INT64) { - gint64 bbox_val; - - bbox_val = json_reader_get_double_value (reader); - g_hash_table_insert(ht, g_strdup (name), g_strdup_printf ("%"G_GINT64_FORMAT, bbox_val)); - } else { - g_debug ("Unhandled node type %s for %s", g_type_name (value_type), name); - } -} - -void -_geocode_read_nominatim_attributes (JsonReader *reader, - GHashTable *ht) -{ - char **members; - guint i; - gboolean is_address; - const char *house_number = NULL; - - is_address = (g_strcmp0 (json_reader_get_member_name (reader), "address") == 0); - - members = json_reader_list_members (reader); - if (members == NULL) { - json_reader_end_member (reader); - return; - } - - for (i = 0; members[i] != NULL; i++) { - const char *value = NULL; - - json_reader_read_member (reader, members[i]); - - if (json_reader_is_value (reader)) { - JsonNode *node = json_reader_get_value (reader); - if (json_node_get_value_type (node) == G_TYPE_STRING) { - value = json_node_get_string (node); - if (value && *value == '\0') - value = NULL; - } - } - - if (value != NULL) { - g_hash_table_insert (ht, g_strdup (members[i]), g_strdup (value)); - - if (i == 0 && is_address) { - if (g_strcmp0 (members[i], "house_number") != 0) - /* Since Nominatim doesn't give us a short name, - * we use the first component of address as name. - */ - g_hash_table_insert (ht, g_strdup ("name"), g_strdup (value)); - else - house_number = value; - } else if (house_number != NULL && g_strcmp0 (members[i], "road") == 0) { - gboolean number_after; - char *name; - - number_after = _geocode_object_is_number_after_street (); - name = g_strdup_printf ("%s %s", - number_after ? value : house_number, - number_after ? house_number : value); - g_hash_table_insert (ht, g_strdup ("name"), name); - } - } else if (g_strcmp0 (members[i], "boundingbox") == 0) { - JsonNode *node; - GType value_type; - - json_reader_read_element (reader, 0); - node = json_reader_get_value (reader); - value_type = json_node_get_value_type (node); - - insert_bounding_box_element (ht, value_type, "boundingbox-bottom", reader); - json_reader_end_element (reader); - - json_reader_read_element (reader, 1); - insert_bounding_box_element (ht, value_type, "boundingbox-top", reader); - json_reader_end_element (reader); - - json_reader_read_element (reader, 2); - insert_bounding_box_element (ht, value_type, "boundingbox-left", reader); - json_reader_end_element (reader); - - json_reader_read_element (reader, 3); - insert_bounding_box_element (ht, value_type, "boundingbox-right", reader); - json_reader_end_element (reader); - } - json_reader_end_member (reader); - } - - g_strfreev (members); - - if (json_reader_read_member (reader, "address")) - _geocode_read_nominatim_attributes (reader, ht); - json_reader_end_member (reader); -} - -static GHashTable * -resolve_json (const char *contents, - GError **error) -{ - GHashTable *ret; - JsonParser *parser; - JsonNode *root; - JsonReader *reader; - - ret = NULL; - - parser = json_parser_new (); - if (json_parser_load_from_data (parser, contents, -1, error) == FALSE) { - g_object_unref (parser); - return ret; - } - - root = json_parser_get_root (parser); - reader = json_reader_new (root); - - if (json_reader_read_member (reader, "error")) { - const char *msg; - - msg = json_reader_get_string_value (reader); - json_reader_end_member (reader); - if (msg && *msg == '\0') - msg = NULL; - - g_set_error_literal (error, - GEOCODE_ERROR, - GEOCODE_ERROR_NOT_SUPPORTED, - msg ? msg : "Query not supported"); - g_object_unref (parser); - g_object_unref (reader); - return NULL; - } - - ret = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - - _geocode_read_nominatim_attributes (reader, ret); - - g_object_unref (parser); - g_object_unref (reader); - - return ret; -} - -static void -on_query_data_loaded (SoupSession *session, - SoupMessage *query, - gpointer user_data) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); - GError *error = NULL; - char *contents; - GeocodePlace *ret; - GHashTable *attributes; - - if (query->status_code != SOUP_STATUS_OK) { - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - query->reason_phrase ? query->reason_phrase : "Query failed"); - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - - contents = g_strndup (query->response_body->data, query->response_body->length); - attributes = resolve_json (contents, &error); - - if (attributes == NULL) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - g_free (contents); - return; - } - - /* Now that we can parse the result, save it to cache */ - _geocode_glib_cache_save (query, contents); - g_free (contents); - - ret = _geocode_create_place_from_attributes (attributes); - g_hash_table_destroy (attributes); - g_simple_async_result_set_op_res_gpointer (simple, ret, NULL); - - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); -} - -static void -on_cache_data_loaded (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); - GFile *cache; - GError *error = NULL; - char *contents; - GHashTable *result; - - cache = G_FILE (source_object); - if (g_file_load_contents_finish (cache, - res, - &contents, - NULL, - NULL, - NULL) == FALSE) { - GObject *object; - SoupMessage *query; - - object = g_async_result_get_source_object (G_ASYNC_RESULT (simple)); - query = g_object_get_data (G_OBJECT (cache), "query"); - g_object_ref (query); /* soup_session_queue_message steals ref */ - soup_session_queue_message (GEOCODE_REVERSE (object)->priv->soup_session, - query, - on_query_data_loaded, - simple); - return; - } - - result = resolve_json (contents, &error); - g_free (contents); - - if (result == NULL) { - g_simple_async_result_take_error (simple, error); - } else { - GeocodePlace *place; - - place = _geocode_create_place_from_attributes (result); - g_hash_table_destroy (result); - g_simple_async_result_set_op_res_gpointer (simple, place, NULL); - } - - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); -} - -static void -copy_item (char *key, - char *value, - GHashTable *ret) -{ - g_hash_table_insert (ret, key, value); -} - -GHashTable * -_geocode_glib_dup_hash_table (GHashTable *ht) -{ - GHashTable *ret; - - ret = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_foreach (ht, (GHFunc) copy_item, ret); - - return ret; -} - -static SoupMessage * -get_resolve_query_for_params (GHashTable *orig_ht) -{ - SoupMessage *ret; - GHashTable *ht; - char *locale; - char *params, *uri; - - ht = _geocode_glib_dup_hash_table (orig_ht); - - g_hash_table_insert (ht, (gpointer) "format", (gpointer) "json"); - g_hash_table_insert (ht, (gpointer) "email", (gpointer) "zeeshanak@gnome.org"); - g_hash_table_insert (ht, (gpointer) "addressdetails", (gpointer) "1"); - - locale = NULL; - if (g_hash_table_lookup (ht, "accept-language") == NULL) { - locale = _geocode_object_get_lang (); - if (locale) - g_hash_table_insert (ht, (gpointer) "accept-language", locale); - } - - params = soup_form_encode_hash (ht); - g_hash_table_destroy (ht); - g_free (locale); - - uri = g_strdup_printf ("https://nominatim.gnome.org/reverse?%s", params); - g_free (params); - - ret = soup_message_new ("GET", uri); - g_free (uri); - - return ret; -} - -/** - * geocode_reverse_resolve_async: - * @object: a #GeocodeReverse representing a query - * @cancellable: optional #GCancellable object, %NULL to ignore. - * @callback: a #GAsyncReadyCallback to call when the request is satisfied - * @user_data: the data to pass to callback function - * - * Asynchronously gets the result of a reverse geocoding - * query using a web service. Use geocode_reverse_resolve() to do the same - * thing synchronously. - * - * When the operation is finished, @callback will be called. You can then call - * geocode_reverse_resolve_finish() to get the result of the operation. - **/ -void -geocode_reverse_resolve_async (GeocodeReverse *object, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - SoupMessage *query; - char *cache_path; - - g_return_if_fail (GEOCODE_IS_REVERSE (object)); - - simple = g_simple_async_result_new (G_OBJECT (object), - callback, - user_data, - geocode_reverse_resolve_async); - g_simple_async_result_set_check_cancellable (simple, cancellable); - - query = get_resolve_query_for_params (object->priv->ht); - - cache_path = _geocode_glib_cache_path_for_query (query); - if (cache_path == NULL) { - soup_session_queue_message (object->priv->soup_session, - query, - on_query_data_loaded, - simple); - } else { - GFile *cache; - - cache = g_file_new_for_path (cache_path); - g_object_set_data_full (G_OBJECT (cache), "query", query, (GDestroyNotify) g_object_unref); - g_file_load_contents_async (cache, - cancellable, - on_cache_data_loaded, - simple); - g_object_unref (cache); - g_free (cache_path); - } -} - -/** - * geocode_reverse_resolve_finish: - * @object: a #GeocodeReverse representing a query - * @res: a #GAsyncResult. - * @error: a #GError. - * - * Finishes a reverse geocoding operation. See geocode_reverse_resolve_async(). - * - * Returns: (transfer full): A #GeocodePlace instance, or %NULL in case of - * errors. Free the returned instance with #g_object_unref() when done. - **/ -GeocodePlace * -geocode_reverse_resolve_finish (GeocodeReverse *object, - GAsyncResult *res, - GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); - - g_return_val_if_fail (GEOCODE_IS_REVERSE (object), NULL); - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == geocode_reverse_resolve_async); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - return g_simple_async_result_get_op_res_gpointer (simple); -} - -/** - * geocode_reverse_resolve: - * @object: a #GeocodeReverse representing a query - * @error: a #GError - * - * Gets the result of a reverse geocoding - * query using a web service. - * - * Returns: (transfer full): A #GeocodePlace instance, or %NULL in case of - * errors. Free the returned instance with #g_object_unref() when done. - **/ -GeocodePlace * -geocode_reverse_resolve (GeocodeReverse *object, - GError **error) -{ - SoupMessage *query; - char *contents; - GHashTable *result; - GeocodePlace *place; - gboolean to_cache = FALSE; - - g_return_val_if_fail (GEOCODE_IS_REVERSE (object), NULL); - - query = get_resolve_query_for_params (object->priv->ht); - - if (_geocode_glib_cache_load (query, &contents) == FALSE) { - if (soup_session_send_message (object->priv->soup_session, - query) != SOUP_STATUS_OK) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - query->reason_phrase ? query->reason_phrase : "Query failed"); - g_object_unref (query); - return NULL; - } - contents = g_strndup (query->response_body->data, query->response_body->length); - - to_cache = TRUE; - } - - result = resolve_json (contents, error); - if (to_cache && result != NULL) - _geocode_glib_cache_save (query, contents); - - g_free (contents); - g_object_unref (query); - - if (result == NULL) - return NULL; - - place = _geocode_create_place_from_attributes (result); - g_hash_table_destroy (result); - - return place; -} diff --git a/src/geocode-glib/geocode-reverse.h b/src/geocode-glib/geocode-reverse.h deleted file mode 100644 index a51718b..0000000 --- a/src/geocode-glib/geocode-reverse.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright 2011 Bastien Nocera - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. - - Authors: Bastien Nocera <hadess@hadess.net> - - */ - -#ifndef GEOCODE_REVERSE_H -#define GEOCODE_REVERSE_H - -#include <glib.h> -#include <gio/gio.h> -#include "geocode-place.h" - -G_BEGIN_DECLS - -GType geocode_reverse_get_type (void) G_GNUC_CONST; - -#define GEOCODE_TYPE_REVERSE (geocode_reverse_get_type ()) -#define GEOCODE_REVERSE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_REVERSE, GeocodeReverse)) -#define GEOCODE_IS_REVERSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_REVERSE)) -#define GEOCODE_REVERSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_REVERSE, GeocodeReverseClass)) -#define GEOCODE_IS_REVERSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_REVERSE)) -#define GEOCODE_REVERSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_REVERSE, GeocodeReverseClass)) - -/** - * GeocodeReverse: - * - * All the fields in the #GeocodeReverse structure are private and should never be accessed directly. -**/ -typedef struct _GeocodeReverse GeocodeReverse; -typedef struct _GeocodeReverseClass GeocodeReverseClass; -typedef struct _GeocodeReversePrivate GeocodeReversePrivate; - -struct _GeocodeReverse { - /* <private> */ - GObject parent_instance; - GeocodeReversePrivate *priv; -}; - -/** - * GeocodeReverseClass: - * - * All the fields in the #GeocodeReverseClass structure are private and should never be accessed directly. -**/ -struct _GeocodeReverseClass { - /* <private> */ - GObjectClass parent_class; -}; - -GeocodeReverse *geocode_reverse_new_for_location (GeocodeLocation *location); - -void geocode_reverse_resolve_async (GeocodeReverse *object, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GeocodePlace *geocode_reverse_resolve_finish (GeocodeReverse *object, - GAsyncResult *res, - GError **error); - -GeocodePlace *geocode_reverse_resolve (GeocodeReverse *object, - GError **error); - -G_END_DECLS - -#endif /* GEOCODE_REVERSE_H */ diff --git a/src/geocode-glib/meson.build b/src/geocode-glib/meson.build deleted file mode 100644 index a29b8a2..0000000 --- a/src/geocode-glib/meson.build +++ /dev/null @@ -1,30 +0,0 @@ -sources = [ 'geocode-location.h', - 'geocode-location.c', - 'geocode-forward.h', - 'geocode-forward.c', - 'geocode-reverse.h', - 'geocode-reverse.c', - 'geocode-glib.h', - 'geocode-glib.c', - 'geocode-error.h', - 'geocode-error.c', - 'geocode-enum-types.h', - 'geocode-enum-types.c', - 'geocode-place.h', - 'geocode-place.c', - 'geocode-bounding-box.h', - 'geocode-bounding-box.c', - 'geocode-glib-private.h' ] - -datadir = join_paths(get_option('prefix'), get_option('datadir')) -localedir = join_paths(datadir, 'locale') - -c_args = [ '-DPACKAGE_VERSION="' + gclue_version + '"', - '-DGEOCODE_LOCALEDIR="' + localedir + '"' ] -libgeocode_glib_inc = include_directories('.', '..', '../..') -libgeocode_glib = static_library('geocode-glib', - sources, - dependencies: geoclue_deps, - include_directories: libgeocode_glib_inc, - c_args: c_args, - install: false) diff --git a/src/geocode-glib/update-from-geocode-glib.sh b/src/geocode-glib/update-from-geocode-glib.sh deleted file mode 100755 index 6eccb4c..0000000 --- a/src/geocode-glib/update-from-geocode-glib.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -function die() { - echo $* - exit 1 -} - -if test -z "$DIR"; then - echo "Must set DIR" - exit 1 -fi - -if test -z "$FILES"; then - echo "Must set FILES" - exit 1 -fi - -for FILE in $FILES; do - if cmp -s $DIR/$FILE $FILE; then - echo "File $FILE is unchanged" - else - cp $DIR/$FILE $FILE || die "Could not move $DIR/$FILE to $FILE" - echo "Updated $FILE" - git add $FILE - fi -done diff --git a/src/meson.build b/src/meson.build index 9343447..c0955de 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,11 +1,9 @@ -dbus_interface_dir = join_paths(get_option('datadir'), 'dbus-1', 'interfaces') -abs_dbus_interface_dir = join_paths(get_option('prefix'), dbus_interface_dir) +dbus_interface_dir = join_paths(datadir, 'dbus-1', 'interfaces') subdir('agent') geoclue_deps = base_deps + [ dependency('json-glib-1.0', version: '>= 0.14.0'), dependency('libsoup-2.4', version: '>= 2.42.0') ] -subdir('geocode-glib') dbus_gen_src = [] @@ -118,8 +116,7 @@ if get_option('nmea-source') endif c_args = [ '-DG_LOG_DOMAIN="Geoclue"' ] -link_with = [ libgeoclue_public_api, libgeoclue_agent, libgeocode_glib ] -install_dir = get_option('libexecdir') +link_with = [ libgeoclue_public_api, libgeoclue_agent ] executable('geoclue', sources, link_with: link_with, @@ -127,10 +124,10 @@ executable('geoclue', c_args: c_args, dependencies: geoclue_deps, install: true, - install_dir: install_dir) + install_dir: libexecdir) -dbus_interface = join_paths(abs_dbus_interface_dir, 'org.freedesktop.GeoClue2.xml') -agent_dbus_interface = join_paths(abs_dbus_interface_dir, 'org.freedesktop.GeoClue2.Agent.xml') +dbus_interface = join_paths(dbus_interface_dir, 'org.freedesktop.GeoClue2.xml') +agent_dbus_interface = join_paths(dbus_interface_dir, 'org.freedesktop.GeoClue2.Agent.xml') pkgconf = import('pkgconfig') pkgconf.generate(version: gclue_version, name: 'Geoclue', diff --git a/src/org.freedesktop.GeoClue2.Client.xml b/src/org.freedesktop.GeoClue2.Client.xml index c539170..aae1d43 100644 --- a/src/org.freedesktop.GeoClue2.Client.xml +++ b/src/org.freedesktop.GeoClue2.Client.xml @@ -15,19 +15,21 @@ This is the interface you use to retrieve location information and receive location update signals from GeoClue service. You get the client object to - use this interface on from org.freedesktop.GeoClue2.Manager.GetClient() - method. + use this interface on from + <link linkend="gdbus-method-org-freedesktop-GeoClue2-Manager.GetClient"> + org.freedesktop.GeoClue2.Manager.GetClient()</link> method. --> <interface name="org.freedesktop.GeoClue2.Client"> <!-- Location: - Current location as path to a #org.freedesktop.GeoClue2.Location object. - Please note that this property will be set to "/" (D-Bus equivalent of - null) initially, until Geoclue finds user's location. You want to delay - reading this property until your callback to - #org.freedesktop.GeoClue2.Client::LocationUpdated signal is called for - the first time after starting the client. + Current location as path to a + <link linkend="gdbus-org.freedesktop.GeoClue2.Location"> + org.freedesktop.GeoClue2.Location</link> object. Please note that this + property will be set to "/" (D-Bus equivalent of null) initially, until + Geoclue finds user's location. You want to delay reading this property + until your callback to #org.freedesktop.GeoClue2.Client::LocationUpdated + signal is called for the first time after starting the client. --> <property name="Location" type="o" access="read"/> diff --git a/src/org.freedesktop.GeoClue2.Manager.xml b/src/org.freedesktop.GeoClue2.Manager.xml index cf9590f..8e8f142 100644 --- a/src/org.freedesktop.GeoClue2.Manager.xml +++ b/src/org.freedesktop.GeoClue2.Manager.xml @@ -15,8 +15,9 @@ This is the interface you use to talk to main GeoClue2 manager object at path "/org/freedesktop/GeoClue2/Manager". The only thing you do with this - interface is to call org.freedesktop.GeoClue2.Manager.GetClient() on it - to get your application specific client object. + interface is to call org.freedesktop.GeoClue2.Manager.GetClient() or + org.freedesktop.GeoClue2.Manager.CreateClient() on it to get your + application specific client object(s). --> <interface name="org.freedesktop.GeoClue2.Manager"> <!-- @@ -36,15 +37,47 @@ <!-- GetClient: - @client: The path for newly created client object + @client: The path for the client object Retrieves a client object which can only be used by the calling - application only. + application only. On the first call from a specific D-Bus peer, this + method will create the client object but subsequent calls will return + the path of the existing client. --> <method name="GetClient"> <arg name="client" type="o" direction="out"/> </method> + <!-- + CreateClient: + @client: The path for the newly created client object + + Creates and retrieves a client object which can only be used by the + calling application only. Unlike + org.freedesktop.GeoClue2.Manager.GetClient(), thid method always + creates a new client. + --> + <method name="CreateClient"> + <arg name="client" type="o" direction="out"/> + </method> + + <!-- + DeleteClient: + @client: The path of the client object to delete + + Use this method to explicitly destroy a client, created using + org.freedesktop.GeoClue2.Manager.GetClient() or + org.freedesktop.GeoClue2.Manager.CreateClient(). + + Long-running applications, should either use this to delete associated + client(s) when not needed, or disconnect from the D-Bus connection used + for communicating with Geoclue (which is implicit on client process + termination). + --> + <method name="DeleteClient"> + <arg name="client" type="o" direction="in"/> + </method> + <!-- AddAgent: @id: The Desktop ID (excluding .desktop) of the agent -- GitLab