Make location service reliable

Everything related to finding the users location is now in a seperate file to make the code more readable.
Furthermore, the error handling is improved and also a timeout is included now.
merge-requests/4/head
Zwarf 2022-09-11 23:13:36 +02:00
rodzic 4408d1db65
commit 827b730e80
5 zmienionych plików z 102 dodań i 84 usunięć

Wyświetl plik

@ -14,6 +14,7 @@ picplanner_sources = [
'search/search.c',
'map/draw-layer.c',
'map/marker.c',
'window/location-service.c'
]
picplanner_deps = [

Wyświetl plik

@ -0,0 +1,80 @@
#include "location-service.h"
/* GeoClue */
guint timer;
static GClueSimple *simple = NULL;
static GClueClient *client = NULL;
static GCancellable *cancellabel = NULL;
static void
stop_location_search (gpointer user_data)
{
(void) user_data;
g_clear_object (&client);
g_clear_object (&simple);
cancellabel = NULL;
g_source_remove (timer);
}
static gboolean
on_timeout (gpointer user_data)
{
(void) user_data;
g_cancellable_cancel (cancellabel);
return FALSE;
}
static void
set_user_location (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
(void) source_object;
(void) user_data;
double latitude;
double longitude;
GError *error = NULL;
static GClueLocation *location;
simple = gclue_simple_new_with_thresholds_finish (res, &error);
if (error == NULL)
{
location = gclue_simple_get_location (simple);
latitude = gclue_location_get_latitude (location);
longitude = gclue_location_get_longitude (location);
picplanner_set_location (latitude, longitude, PICPLANNER_WINDOW (user_data));
}
else
{
g_print ("Cannot receive location!\n");
g_error_free (error);
}
stop_location_search (NULL);
}
/*
* Get the users location
*/
void
get_user_location (GtkButton *self,
gpointer user_data)
{
(void) self;
if (cancellabel == NULL)
{
timer = g_timeout_add_seconds (30, on_timeout, NULL);
cancellabel = g_cancellable_new ();
gclue_simple_new ("picplanner",
GCLUE_ACCURACY_LEVEL_EXACT,
cancellabel,
set_user_location,
user_data);
}
}

Wyświetl plik

@ -0,0 +1,8 @@
#pragma once
#include <geoclue.h>
#include "picplanner-window.h"
void
get_user_location (GtkButton *self,
gpointer user_data);

Wyświetl plik

@ -24,7 +24,6 @@
#include "calculations/calculations_sun.h"
#include "calculations/calculations_moon.h"
#include "calculations/calculations_milky_way.h"
#include "search/search.h"
/*
@ -33,13 +32,6 @@
*/
#define INPUT_CHANGED_TIMEOUT_LENGTH 100
/*
* Definitions neccessary for GeoClue
*/
static gint timeout = 30; /* seconds */
static GClueAccuracyLevel accuracy_level = GCLUE_ACCURACY_LEVEL_EXACT;
static gint time_threshold;
struct _PicplannerWindow
{
@ -85,10 +77,6 @@ struct _PicplannerWindow
guint input_timeout_id;
gboolean input_new;
/* GeoClue */
GClueSimple *simple;
GClueClient *client;
/* All settings of PicPlanner */
GSettings *settings;
@ -241,71 +229,6 @@ search_location (GtkWidget *self,
g_free (search_string);
}
static gboolean
on_location_timeout (PicplannerWindow *window)
{
g_clear_object (&window->client);
g_clear_object (&window->simple);
return FALSE;
}
static void
set_user_location (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
g_print ("Gathering location information\n");
PicplannerWindow *window = PICPLANNER_WINDOW (user_data);
GError *error = NULL;
window->simple = gclue_simple_new_with_thresholds_finish (res, &error);
if (error == NULL)
{
GClueLocation *location;
location = gclue_simple_get_location (window->simple);
g_print ("\nNew location:\n");
g_print ("Latitude: %f°\nLongitude: %f°\nAccuracy: %f meters\n",
gclue_location_get_latitude (location),
gclue_location_get_longitude (location),
gclue_location_get_accuracy (location));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->north_entry),
gclue_location_get_latitude(location));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->east_entry),
gclue_location_get_longitude(location));
}
else
{
g_print ("Cannot receive location!\n");
}
on_location_timeout (window);
}
/*
* Get the users location
*/
static void
get_user_location (GtkButton *self,
PicplannerWindow *window)
{
(void) self;
(void) window;
g_print ("Looking for users location...\n");
gclue_simple_new_with_thresholds ("picplanner",
accuracy_level,
time_threshold,
0,
NULL,
set_user_location,
window);
}
/*
* Show the map in fullscreen
*/
@ -333,6 +256,13 @@ stack_changed (AdwViewStack *self,
gtk_widget_set_visible (window->map_button, FALSE);
}
void
picplanner_set_location (double latitude, double longitude, PicplannerWindow *window)
{
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->north_entry), latitude);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->east_entry), longitude);
}
/*
* Changing the date_time variable after a user input was recognized.
@ -802,12 +732,6 @@ picplanner_window_init (PicplannerWindow *window)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window->spin_button_minute),
g_date_time_get_minute (window->date_time));
/*
* Initialize GeoClue
*/
window->simple = NULL;
window->client = NULL;
/*
* Callbacks
*/

Wyświetl plik

@ -20,11 +20,12 @@
#include <gtk/gtk.h>
#include <adwaita.h>
#include <geoclue.h>
#include <glib/gi18n.h>
#include <libgweather/gweather.h>
#include "picplanner-config.h"
#include "picplanner-application.h"
#include "search/search.h"
#include "location-service.h"
G_BEGIN_DECLS
@ -35,6 +36,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (PicplannerWindow, picplanner_window, PICPLANNER, WINDOW, AdwApplicationWindow)
PicplannerWindow *picplanner_window_new (PicplannerApplication *app);
void picplanner_window_open (PicplannerWindow *win, GFile *file);
void
picplanner_set_location (double latitude, double longitude, PicplannerWindow *window);
G_END_DECLS