]> git.street.me.uk Git - andy/viking.git/blob - src/vikrouting.c
Generalize route finder
[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 = 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   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   if ( VIK_IS_ROUTING_ENGINE ( engine ) )
147     routing_engine_list = g_list_append ( routing_engine_list, g_object_ref ( engine ) );
148
149   gsize len = 0;
150   if (routing_engine_labels)
151     len = g_strv_length (routing_engine_labels);
152
153   gchar *label = vik_routing_engine_get_label ( engine );
154   gchar *id = vik_routing_engine_get_id ( engine );
155
156   /* Add the label */
157   routing_engine_labels = g_realloc (routing_engine_labels, (len+2)*sizeof(gchar*));
158   routing_engine_labels[len] = g_strdup (label);
159   routing_engine_labels[len+1] = NULL;
160
161   /* Add the id */
162   routing_engine_ids = g_realloc (routing_engine_ids, (len+2)*sizeof(gchar*));
163   routing_engine_ids[len] = g_strdup (id);
164   routing_engine_ids[len+1] = NULL;
165   
166   /* Hack
167      We have to ensure the mode LayerParam references the up-to-date
168      GLists.
169   */
170   /*
171   memcpy(&maps_layer_params[0].widget_data, &params_maptypes, sizeof(gpointer));
172   memcpy(&maps_layer_params[0].extra_widget_data, &params_maptypes_ids, sizeof(gpointer));
173   */
174   prefs[0].widget_data = routing_engine_labels;
175   prefs[0].extra_widget_data = routing_engine_ids;
176 }
177
178 /**
179  * vik_routing_unregister_all:
180  * 
181  * Unregister all registered routing engines.
182  */
183 void
184 vik_routing_unregister_all ()
185 {
186   g_list_foreach ( routing_engine_list, (GFunc) g_object_unref, NULL );
187   g_strfreev ( routing_engine_labels );
188   g_strfreev ( routing_engine_ids );
189 }