]> git.street.me.uk Git - andy/viking.git/blob - src/vikrouting.c
Prevent gcc 4.7.3 compiler warnings for new routing code.
[andy/viking.git] / src / vikrouting.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 /**
22  * SECTION:vikrouting
23  * @short_description: the routing framework
24  * 
25  * This module handles the list of #VikRoutingEngine.
26  * It also handles the "default" functions.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <glib.h>
34 #include <glib/gstdio.h>
35 #include <glib/gi18n.h>
36
37 #include "curl_download.h"
38 #include "babel.h"
39
40 #include "preferences.h"
41
42 #include "vikrouting.h"
43 #include "vikroutingengine.h"
44
45 /* params will be routing.default */
46 /* we have to make sure these don't collide. */
47 #define VIKING_ROUTING_PARAMS_GROUP_KEY "routing"
48 #define VIKING_ROUTING_PARAMS_NAMESPACE "routing."
49
50 /* List to register all routing engines */
51 static GList *routing_engine_list = NULL;
52
53 static VikLayerParam prefs[] = {
54   { VIK_LAYER_NUM_TYPES, VIKING_ROUTING_PARAMS_NAMESPACE "default", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, N_("Default engine:"), VIK_LAYER_WIDGET_COMBOBOX, NULL, NULL, NULL },
55 };
56
57 gchar **routing_engine_labels = NULL;
58 gchar **routing_engine_ids = NULL;
59
60 /**
61  * vik_routing_prefs_init:
62  * 
63  * Initialize the preferences of the routing feature.
64  */
65 void
66 vik_routing_prefs_init()
67 {
68   a_preferences_register_group ( VIKING_ROUTING_PARAMS_GROUP_KEY, "Routing" );
69
70   VikLayerParamData tmp;
71   tmp.s = NULL;
72   a_preferences_register(prefs, tmp, VIKING_ROUTING_PARAMS_GROUP_KEY);
73 }
74
75 static gint
76 search_by_id (gconstpointer a,
77               gconstpointer b)
78 {
79         const gchar *id = b;
80         VikRoutingEngine *engine = (VikRoutingEngine *)a;
81         gchar *engineId = vik_routing_engine_get_id (engine);
82         if (id && engine)
83                 return strcmp(id, engineId);
84         else
85                 return -1;
86 }
87
88 /**
89  * vik_routing_find_engine:
90  * @id: the id of the engine we are looking for
91  * 
92  * Returns: the found engine or %NULL
93  */
94 VikRoutingEngine *
95 vik_routing_find_engine ( const gchar *id )
96 {
97         VikRoutingEngine *engine = NULL;
98         GList *elem = g_list_find_custom (routing_engine_list, id, search_by_id);
99         if (elem)
100                 engine = elem->data;
101         return engine;
102 }
103
104 /**
105  * vik_routing_default:
106  * 
107  * Retrieve the default engine, based on user's preferences.
108  * 
109  * Returns: the default engine
110  */
111 static VikRoutingEngine *
112 vik_routing_default( void )
113 {
114   const gchar *id = a_preferences_get ( VIKING_ROUTING_PARAMS_NAMESPACE "default")->s;
115   VikRoutingEngine *engine = vik_routing_find_engine(id);
116   if (engine == NULL && routing_engine_list != NULL && g_list_first (routing_engine_list) != NULL)
117     /* Fallback to first element */
118     engine = g_list_first (routing_engine_list)->data;
119
120   return engine;
121 }
122
123 /**
124  * vik_routing_default_find:
125  * 
126  * Route computation with default engine.
127  */
128 void
129 vik_routing_default_find(VikTrwLayer *vt, struct LatLon start, struct LatLon end)
130 {
131   /* The engine */
132   VikRoutingEngine *engine = vik_routing_default ( );
133   /* The route computation */
134   vik_routing_engine_find ( engine, vt, start, end );
135 }
136
137 /**
138  * vik_routing_register:
139  * @engine: new routing engine to register
140  * 
141  * Register a new routing engine.
142  */
143 void
144 vik_routing_register( VikRoutingEngine *engine )
145 {
146   gchar *label = vik_routing_engine_get_label ( engine );
147   gchar *id = vik_routing_engine_get_id ( engine );
148   gsize len = 0;
149
150   /* check if id already exists in list */
151   GList *elem = g_list_find_custom (routing_engine_list, id, search_by_id);
152   if (elem != NULL) {
153     g_debug("%s: %s already exists: update", __FUNCTION__, id);
154
155     /* Update main list */
156     g_object_unref (elem->data);
157     elem->data = g_object_ref ( engine );
158
159     /* Update GUI arrays */
160     len = g_strv_length (routing_engine_labels);
161     for (; len > 0 ; len--) {
162       if (strcmp (routing_engine_ids[len-1], id) == 0)
163                         break;
164         }
165     /* Update the label (possibly different */
166     g_free (routing_engine_labels[len-1]);
167     routing_engine_labels[len-1] = g_strdup (label);
168     
169   } else {
170     g_debug("%s: %s is new: append", __FUNCTION__, id);
171     routing_engine_list = g_list_append ( routing_engine_list, g_object_ref ( engine ) );
172
173     if (routing_engine_labels)
174       len = g_strv_length (routing_engine_labels);
175   
176     /* Add the label */
177     routing_engine_labels = g_realloc (routing_engine_labels, (len+2)*sizeof(gchar*));
178     routing_engine_labels[len] = g_strdup (label);
179     routing_engine_labels[len+1] = NULL;
180
181     /* Add the id */
182     routing_engine_ids = g_realloc (routing_engine_ids, (len+2)*sizeof(gchar*));
183     routing_engine_ids[len] = g_strdup (id);
184     routing_engine_ids[len+1] = NULL;
185   
186     /* Hack
187        We have to ensure the mode LayerParam references the up-to-date
188        GLists.
189     */
190     /*
191     memcpy(&maps_layer_params[0].widget_data, &params_maptypes, sizeof(gpointer));
192     memcpy(&maps_layer_params[0].extra_widget_data, &params_maptypes_ids, sizeof(gpointer));
193     */
194     prefs[0].widget_data = routing_engine_labels;
195     prefs[0].extra_widget_data = routing_engine_ids;
196   }
197 }
198
199 /**
200  * vik_routing_unregister_all:
201  * 
202  * Unregister all registered routing engines.
203  */
204 void
205 vik_routing_unregister_all ()
206 {
207   g_list_foreach ( routing_engine_list, (GFunc) g_object_unref, NULL );
208   g_strfreev ( routing_engine_labels );
209   g_strfreev ( routing_engine_ids );
210 }