Since we have a generic routing framework, we can replace Google Routing feature by a more generic solution.
The user is now able to select the engine for the route computation. Signed-off-by: Guilhem Bonnefille <guilhem.bonnefi...@gmail.com> --- help/C/viking.xml | 20 ++++++ po/POTFILES.in | 2 +- src/Makefile.am | 2 +- src/babel.c | 43 ++++++++++++ src/babel.h | 1 + src/datasource_google.c | 128 ------------------------------------ src/datasource_routing.c | 159 +++++++++++++++++++++++++++++++++++++++++++++ src/datasources.h | 4 +- src/google.c | 2 + src/menu.xml.h | 4 +- src/vikrouting.c | 14 ++++ src/vikrouting.h | 2 +- src/vikroutingengine.c | 32 ++++++++- src/vikroutingengine.h | 5 ++ src/vikroutingwebengine.c | 124 +++++++++++++++++++++++++++++++++++ src/viktrwlayer.c | 19 ++---- src/vikwindow.c | 10 +-- 17 files changed, 414 insertions(+), 157 deletions(-) diff --git a/help/C/viking.xml b/help/C/viking.xml index 569509a..b3d0642 100644 --- a/help/C/viking.xml +++ b/help/C/viking.xml @@ -547,6 +547,16 @@ This gets <emphasis>interesting</emphasis> points from Wikipedia for the specifi </para> </section> +<section> +<title>From Routing</title> +<para> +<menuchoice><guimenu>File</guimenu><guimenuitem>Acquire</guimenuitem><guimenuitem>From Directions</guimenuitem></menuchoice> +</para> +<para> +This gets a route from given directions. +</para> +</section> + </section> <!-- End Acquire --> <section><title>Print</title> @@ -2444,6 +2454,16 @@ Accept: */* <listitem><para>the part of the URL setting the end point location, parametrized in the spirit of C printf format, with 2 "%s" for coordinates (eg. "&start=%s,%s")</para></listitem> </varlistentry> <varlistentry> + <term>url-start-dir</term> + <listitem><para>the part of the URL setting the starting point location for direction based routing, parametrized in the spirit of C printf format, with one "%s" for direction (eg. "&start=%s")</para> + <para>(Optional)</para></listitem> + </varlistentry> + <varlistentry> + <term>url-stop-dir</term> + <listitem><para>the part of the URL setting the end point location for direction based routing, parametrized in the spirit of C printf format, with one "%s" for direction (eg. "&start=%s")</para> + <para>(Optional)</para></listitem> + </varlistentry> + <varlistentry> <term>referer</term> <listitem><para>an URL to serve as referer for the HTTP request (eg. "http://hostname/")</para></listitem> </varlistentry> diff --git a/po/POTFILES.in b/po/POTFILES.in index 968dbe2..bc53f26 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -13,10 +13,10 @@ src/googlesearch.c src/datasource_file.c src/datasource_gc.c src/datasource_geotag.c -src/datasource_google.c src/datasource_gps.c src/datasource_osm.c src/datasource_osm_my_traces.c +src/datasource_routing.c src/datasource_wikipedia.c src/dem.c src/download.c diff --git a/src/Makefile.am b/src/Makefile.am index 01e221d..25a3fd3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -108,7 +108,7 @@ libviking_a_SOURCES = \ babel.c babel.h \ datasource_file.c \ datasource_gps.c datasource_gps.h \ - datasource_google.c \ + datasource_routing.c \ datasource_gc.c \ datasource_bfilter.c \ datasource_wikipedia.c \ diff --git a/src/babel.c b/src/babel.c index c5f8c61..5d30af9 100644 --- a/src/babel.c +++ b/src/babel.c @@ -3,6 +3,7 @@ * * Copyright (C) 2003-2005, Evan Battaglia <gtoe...@gmx.net> * Copyright (C) 2006, Quy Tonthat <qtont...@gmail.com> + * Copyright (C) 2013, Guilhem Bonnefille <guilhem.bonnefi...@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,6 +49,11 @@ #define BASH_LOCATION "/bin/bash" /** + * List of supported protocols. + */ +const gchar *PROTOS[] = { "http://", "https://", "ftp://", NULL }; + +/** * Path to gpsbabel */ static gchar *gpsbabel_loc = NULL; @@ -366,6 +372,43 @@ gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char return ret; } +/** + * a_babel_convert_from_url_or_shell: + * @vt: The #VikTrwLayer where to insert the collected data + * @url: the URL to fetch + * @cb: Optional callback function. Same usage as in a_babel_convert(). + * @user_data: passed along to cb + * @options: download options. Maybe NULL. + * + * Download the file pointed by the URL and optionally uses GPSBabel to convert from input_file_type. + * If input_file_type is %NULL, doesn't use GPSBabel. Input must be GPX. + * + * Returns: %TRUE on successful invocation of GPSBabel or read of the GPX + * + */ +gboolean a_babel_convert_from_url_or_shell ( VikTrwLayer *vt, const char *input, const char *input_type, BabelStatusFunc cb, gpointer user_data, DownloadMapOptions *options ) +{ + + /* Check nature of input */ + gboolean isUrl = FALSE; + int i = 0; + for (i = 0 ; PROTOS[i] != NULL ; i++) + { + const gchar *proto = PROTOS[i]; + if (strncmp (input, proto, strlen(proto)) == 0) + { + /* Procotol matches: save result */ + isUrl = TRUE; + } + } + + /* Do the job */ + if (isUrl) + return a_babel_convert_from_url (vt, input, input_type, cb, user_data, options); + else + return a_babel_convert_from_shellcommand (vt, input, input_type, cb, user_data, options); +} + static gboolean babel_general_convert_to( VikTrwLayer *vt, VikTrack *trk, BabelStatusFunc cb, gchar **args, const gchar *name_src, gpointer user_data ) { // Now strips out invisible tracks and waypoints diff --git a/src/babel.h b/src/babel.h index a627d05..6fe4a07 100644 --- a/src/babel.h +++ b/src/babel.h @@ -99,6 +99,7 @@ gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFun gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, const char *file, BabelStatusFunc cb, gpointer user_data, gpointer options ); gboolean a_babel_convert_from_shellcommand ( VikTrwLayer *vt, const char *input_cmd, const char *input_file_type, BabelStatusFunc cb, gpointer user_data, gpointer options ); gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char *input_type, BabelStatusFunc cb, gpointer user_data, DownloadMapOptions *options ); +gboolean a_babel_convert_from_url_or_shell ( VikTrwLayer *vt, const char *input, const char *input_type, BabelStatusFunc cb, gpointer user_data, DownloadMapOptions *options ); gboolean a_babel_convert_to( VikTrwLayer *vt, VikTrack *track, const char *babelargs, const char *file, BabelStatusFunc cb, gpointer user_data ); void a_babel_init (); diff --git a/src/datasource_google.c b/src/datasource_google.c deleted file mode 100644 index 8f557d3..0000000 --- a/src/datasource_google.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * viking -- GPS Data and Topo Analyzer, Explorer, and Manager - * - * Copyright (C) 2003-2005, Evan Battaglia <gtoe...@gmx.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <string.h> - -#include <glib/gprintf.h> -#include <glib/gi18n.h> - -#include "viking.h" -#include "babel.h" -#include "gpx.h" -#include "acquire.h" - -#define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s+to:%s&output=js" - -typedef struct { - GtkWidget *from_entry, *to_entry; -} datasource_google_widgets_t; - -static gchar *last_from_str = NULL; -static gchar *last_to_str = NULL; - -static gpointer datasource_google_init ( acq_vik_t *avt ); -static void datasource_google_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ); -static void datasource_google_get_cmd_string ( datasource_google_widgets_t *widgets, gchar **cmd, gchar **input_file_type, DownloadMapOptions *options ); -static void datasource_google_cleanup ( gpointer data ); - -VikDataSourceInterface vik_datasource_google_interface = { - N_("Google Directions"), - N_("Google Directions"), - VIK_DATASOURCE_ADDTOLAYER, - VIK_DATASOURCE_INPUTTYPE_NONE, - TRUE, - TRUE, - TRUE, - (VikDataSourceInitFunc) datasource_google_init, - (VikDataSourceCheckExistenceFunc) NULL, - (VikDataSourceAddSetupWidgetsFunc) datasource_google_add_setup_widgets, - (VikDataSourceGetCmdStringFunc) datasource_google_get_cmd_string, - (VikDataSourceProcessFunc) a_babel_convert_from_url, - (VikDataSourceProgressFunc) NULL, - (VikDataSourceAddProgressWidgetsFunc) NULL, - (VikDataSourceCleanupFunc) datasource_google_cleanup, - (VikDataSourceOffFunc) NULL, -}; - -static gpointer datasource_google_init ( acq_vik_t *avt ) -{ - datasource_google_widgets_t *widgets = g_malloc(sizeof(*widgets)); - return widgets; -} - -static void datasource_google_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ) -{ - datasource_google_widgets_t *widgets = (datasource_google_widgets_t *)user_data; - GtkWidget *from_label, *to_label; - from_label = gtk_label_new (_("From:")); - widgets->from_entry = gtk_entry_new(); - to_label = gtk_label_new (_("To:")); - widgets->to_entry = gtk_entry_new(); - if (last_from_str) - gtk_entry_set_text(GTK_ENTRY(widgets->from_entry), last_from_str); - if (last_to_str) - gtk_entry_set_text(GTK_ENTRY(widgets->to_entry), last_to_str); - - /* Packing all these widgets */ - GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); - gtk_box_pack_start ( box, from_label, FALSE, FALSE, 5 ); - gtk_box_pack_start ( box, widgets->from_entry, FALSE, FALSE, 5 ); - gtk_box_pack_start ( box, to_label, FALSE, FALSE, 5 ); - gtk_box_pack_start ( box, widgets->to_entry, FALSE, FALSE, 5 ); - gtk_widget_show_all(dialog); -} - -static void datasource_google_get_cmd_string ( datasource_google_widgets_t *widgets, gchar **cmd, gchar **input_file_type, DownloadMapOptions *options ) -{ - /* TODO: special characters handling!!! */ - gchar *from_quoted, *to_quoted; - gchar **from_split, **to_split; - from_quoted = g_shell_quote ( gtk_entry_get_text ( GTK_ENTRY(widgets->from_entry) ) ); - to_quoted = g_shell_quote ( gtk_entry_get_text ( GTK_ENTRY(widgets->to_entry) ) ); - - from_split = g_strsplit( from_quoted, " ", 0); - to_split = g_strsplit( to_quoted, " ", 0); - from_quoted = g_strjoinv( "%20", from_split); - to_quoted = g_strjoinv( "%20", to_split); - - *cmd = g_strdup_printf( GOOGLE_DIRECTIONS_STRING, from_quoted, to_quoted ); - *input_file_type = g_strdup("google"); - options = NULL; - - g_free(last_from_str); - g_free(last_to_str); - - last_from_str = g_strdup( gtk_entry_get_text ( GTK_ENTRY(widgets->from_entry) )); - last_to_str = g_strdup( gtk_entry_get_text ( GTK_ENTRY(widgets->to_entry) )); - - g_free(from_quoted); - g_free(to_quoted); - g_strfreev(from_split); - g_strfreev(to_split); - -} - -static void datasource_google_cleanup ( gpointer data ) -{ - g_free ( data ); -} diff --git a/src/datasource_routing.c b/src/datasource_routing.c new file mode 100644 index 0000000..4a8a1bc --- /dev/null +++ b/src/datasource_routing.c @@ -0,0 +1,159 @@ +/* + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager + * + * Copyright (C) 2003-2005, Evan Battaglia <gtoe...@gmx.net> + * Copyright (C) 2013, Guilhem Bonnefille <guilhem.bonnefi...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include <glib/gprintf.h> +#include <glib/gi18n.h> + +#include "viking.h" +#include "babel.h" +#include "gpx.h" +#include "acquire.h" +#include "vikrouting.h" + +typedef struct { + GList *engines; + GtkWidget *engines_combo; + GtkWidget *from_entry, *to_entry; +} datasource_routing_widgets_t; + +/* Memory of previous selection */ +static gint last_engine = 0; +static gchar *last_from_str = NULL; +static gchar *last_to_str = NULL; + +static gpointer datasource_routing_init ( acq_vik_t *avt ); +static void datasource_routing_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ); +static void datasource_routing_get_cmd_string ( datasource_routing_widgets_t *widgets, gchar **cmd, gchar **input_file_type, DownloadMapOptions *options ); +static void datasource_routing_cleanup ( gpointer data ); + +VikDataSourceInterface vik_datasource_routing_interface = { + N_("Directions"), + N_("Directions"), + VIK_DATASOURCE_ADDTOLAYER, + VIK_DATASOURCE_INPUTTYPE_NONE, + TRUE, + TRUE, + TRUE, + (VikDataSourceInitFunc) datasource_routing_init, + (VikDataSourceCheckExistenceFunc) NULL, + (VikDataSourceAddSetupWidgetsFunc) datasource_routing_add_setup_widgets, + (VikDataSourceGetCmdStringFunc) datasource_routing_get_cmd_string, + (VikDataSourceProcessFunc) a_babel_convert_from_url_or_shell, + (VikDataSourceProgressFunc) NULL, + (VikDataSourceAddProgressWidgetsFunc) NULL, + (VikDataSourceCleanupFunc) datasource_routing_cleanup, + (VikDataSourceOffFunc) NULL, +}; + +static gpointer datasource_routing_init ( acq_vik_t *avt ) +{ + datasource_routing_widgets_t *widgets = g_malloc(sizeof(*widgets)); + /* Ensure NULL as GList functions adapt their behavior */ + widgets->engines = NULL; + return widgets; +} + +/* + * @see g_list_foreach() + */ +static void fill_engine_box (gpointer data, gpointer user_data) +{ + VikRoutingEngine *engine = (VikRoutingEngine*) data; + /* Only register engine supporting direction request */ + gboolean ok = vik_routing_engine_supports_direction (engine); + if (ok) + { + datasource_routing_widgets_t *widgets = (datasource_routing_widgets_t*) user_data; + /* Add item in widget */ + const gchar *label = vik_routing_engine_get_label (engine); + vik_combo_box_text_append (widgets->engines_combo, label); + /* Save engine in internal list */ + widgets->engines = g_list_append ( widgets->engines, engine ); + } +} + +static void datasource_routing_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ) +{ + datasource_routing_widgets_t *widgets = (datasource_routing_widgets_t *)user_data; + GtkWidget *engine_label, *from_label, *to_label; + + /* Engine selector */ + engine_label = gtk_label_new (_("Engine:")); + widgets->engines_combo = vik_combo_box_text_new (); + vik_routing_foreach_engine (fill_engine_box, widgets); + gtk_combo_box_set_active (GTK_COMBO_BOX (widgets->engines_combo), last_engine); + + /* From and To entries */ + from_label = gtk_label_new (_("From:")); + widgets->from_entry = gtk_entry_new(); + to_label = gtk_label_new (_("To:")); + widgets->to_entry = gtk_entry_new(); + if (last_from_str) + gtk_entry_set_text(GTK_ENTRY(widgets->from_entry), last_from_str); + if (last_to_str) + gtk_entry_set_text(GTK_ENTRY(widgets->to_entry), last_to_str); + + /* Packing all these widgets */ + GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); + gtk_box_pack_start ( box, engine_label, FALSE, FALSE, 5 ); + gtk_box_pack_start ( box, widgets->engines_combo, FALSE, FALSE, 5 ); + gtk_box_pack_start ( box, from_label, FALSE, FALSE, 5 ); + gtk_box_pack_start ( box, widgets->from_entry, FALSE, FALSE, 5 ); + gtk_box_pack_start ( box, to_label, FALSE, FALSE, 5 ); + gtk_box_pack_start ( box, widgets->to_entry, FALSE, FALSE, 5 ); + gtk_widget_show_all(dialog); +} + +static void datasource_routing_get_cmd_string ( datasource_routing_widgets_t *widgets, gchar **cmd, gchar **input_file_type, DownloadMapOptions *options ) +{ + const gchar *from, *to; + + /* Retrieve directions */ + from = gtk_entry_get_text ( GTK_ENTRY(widgets->from_entry) ); + to = gtk_entry_get_text ( GTK_ENTRY(widgets->to_entry) ); + + /* Retrieve engine */ + int active = gtk_combo_box_get_active ( GTK_COMBO_BOX(widgets->engines_combo) ); + VikRoutingEngine *engine = g_list_nth_data ( widgets->engines, active ); + + *cmd = vik_routing_engine_get_cmd_from_directions ( engine, from, to ); + *input_file_type = g_strdup ( vik_routing_engine_get_format (engine) ); + options = NULL; + + /* Save last selection */ + g_free ( last_from_str ); + g_free ( last_to_str ); + + last_from_str = g_strdup( from ); + last_to_str = g_strdup( to ); +} + +static void datasource_routing_cleanup ( gpointer data ) +{ + g_list_free (((datasource_routing_widgets_t *)data)->engines ); + g_free ( data ); +} diff --git a/src/datasources.h b/src/datasources.h index 445abce..10df1a6 100644 --- a/src/datasources.h +++ b/src/datasources.h @@ -27,9 +27,7 @@ G_BEGIN_DECLS extern VikDataSourceInterface vik_datasource_gps_interface; extern VikDataSourceInterface vik_datasource_file_interface; -#ifdef VIK_CONFIG_GOOGLE -extern VikDataSourceInterface vik_datasource_google_interface; -#endif +extern VikDataSourceInterface vik_datasource_routing_interface; #ifdef VIK_CONFIG_OPENSTREETMAP extern VikDataSourceInterface vik_datasource_osm_interface; extern VikDataSourceInterface vik_datasource_osm_my_traces_interface; diff --git a/src/google.c b/src/google.c index 32f5efb..2e1aa61 100644 --- a/src/google.c +++ b/src/google.c @@ -59,6 +59,8 @@ void google_init () { "url-base", "http://maps.google.com/maps?output=js&q=", "url-start-ll", "from:%s,%s", "url-stop-ll", "+to:%s,%s", + "url-start-dir", "from:%s", + "url-stop-dir", "+to:%s", "referer", "http://maps.google.com/", NULL); vik_routing_register ( VIK_ROUTING_ENGINE ( routing ) ); diff --git a/src/menu.xml.h b/src/menu.xml.h index 56405c9..b2b169b 100644 --- a/src/menu.xml.h +++ b/src/menu.xml.h @@ -18,9 +18,7 @@ static const char *menu_xml = " <menu action='Acquire'>" " <menuitem action='AcquireGPS'/>" " <menuitem action='AcquireGPSBabel'/>" -#ifdef VIK_CONFIG_GOOGLE - " <menuitem action='AcquireGoogle'/>" -#endif + " <menuitem action='AcquireRouting'/>" #ifdef VIK_CONFIG_OPENSTREETMAP " <menuitem action='AcquireOSM'/>" " <menuitem action='AcquireMyOSM'/>" diff --git a/src/vikrouting.c b/src/vikrouting.c index dc43a02..165a16a 100644 --- a/src/vikrouting.c +++ b/src/vikrouting.c @@ -72,6 +72,7 @@ vik_routing_prefs_init() a_preferences_register(prefs, tmp, VIKING_ROUTING_PARAMS_GROUP_KEY); } +/* @see g_list_find_custom */ static gint search_by_id (gconstpointer a, gconstpointer b) @@ -208,3 +209,16 @@ vik_routing_unregister_all () g_strfreev ( routing_engine_labels ); g_strfreev ( routing_engine_ids ); } + +/** + * vik_routing_foreach_engine: + * @func: the function to run on each element + * @user_data: user's data to give to each call of @func + * + * Loop over all registered routing engines. + */ +void +vik_routing_foreach_engine (GFunc func, gpointer user_data) +{ + g_list_foreach ( routing_engine_list, func, user_data ); +} diff --git a/src/vikrouting.h b/src/vikrouting.h index 1a98636..acb1e88 100644 --- a/src/vikrouting.h +++ b/src/vikrouting.h @@ -27,7 +27,6 @@ G_BEGIN_DECLS - /* Default */ void vik_routing_default_find ( VikTrwLayer *vt, struct LatLon start, struct LatLon end ); @@ -35,6 +34,7 @@ void vik_routing_default_find ( VikTrwLayer *vt, struct LatLon start, struct Lat void vik_routing_prefs_init(); void vik_routing_register( VikRoutingEngine *engine ); void vik_routing_unregister_all (); +void vik_routing_foreach_engine (GFunc func, gpointer user_data); G_END_DECLS diff --git a/src/vikroutingengine.c b/src/vikroutingengine.c index e0eb168..c06f264 100644 --- a/src/vikroutingengine.c +++ b/src/vikroutingengine.c @@ -141,7 +141,8 @@ vik_routing_engine_class_init ( VikRoutingEngineClass *klass ) routing_class = VIK_ROUTING_ENGINE_CLASS ( klass ); routing_class->find = NULL; - + routing_class->supports_direction = NULL; + routing_class->get_cmd_from_directions = NULL; pspec = g_param_spec_string ("id", "Identifier", @@ -244,3 +245,32 @@ vik_routing_engine_get_format ( VikRoutingEngine *self ) return priv->format; } + +/** + * vik_routing_engine_support_direction: + * + * Returns: %TRUE if this engine supports the route finding based on directions + */ +gboolean +vik_routing_engine_supports_direction ( VikRoutingEngine *self ) +{ + VikRoutingEngineClass *klass; + + g_return_val_if_fail ( VIK_IS_ROUTING_ENGINE (self), FALSE ); + klass = VIK_ROUTING_ENGINE_GET_CLASS( self ); + g_return_val_if_fail ( klass->supports_direction != NULL, FALSE ); + + return klass->supports_direction( self ); +} + +gchar * +vik_routing_engine_get_cmd_from_directions ( VikRoutingEngine *self, const gchar *start, const gchar *end ) +{ + VikRoutingEngineClass *klass; + + g_return_val_if_fail ( VIK_IS_ROUTING_ENGINE (self), NULL ); + klass = VIK_ROUTING_ENGINE_GET_CLASS( self ); + g_return_val_if_fail ( klass->get_cmd_from_directions != NULL, NULL ); + + return klass->get_cmd_from_directions( self, start, end ); +} diff --git a/src/vikroutingengine.h b/src/vikroutingengine.h index ab707f6..a5da970 100644 --- a/src/vikroutingengine.h +++ b/src/vikroutingengine.h @@ -46,6 +46,8 @@ struct _VikRoutingEngineClass { GObjectClass object_class; int (*find)(VikRoutingEngine *self, VikTrwLayer *vt, struct LatLon start, struct LatLon end); + gchar *(*get_cmd_from_directions)(VikRoutingEngine *self, const gchar *start, const gchar *end); + gboolean (*supports_direction)(VikRoutingEngine *self); }; GType vik_routing_engine_get_type (); @@ -55,12 +57,15 @@ struct _VikRoutingEngine { }; int vik_routing_engine_find ( VikRoutingEngine *self, VikTrwLayer *vt, struct LatLon start, struct LatLon end ); +gchar *vik_routing_engine_get_cmd_from_directions ( VikRoutingEngine *self, const gchar *start, const gchar *end ); /* Acessors */ gchar *vik_routing_engine_get_id ( VikRoutingEngine *self ); gchar *vik_routing_engine_get_label ( VikRoutingEngine *self ); gchar *vik_routing_engine_get_format ( VikRoutingEngine *self ); +gboolean vik_routing_engine_supports_direction ( VikRoutingEngine *self ); + G_END_DECLS #endif diff --git a/src/vikroutingwebengine.c b/src/vikroutingwebengine.c index bb809fe..b4cd635 100644 --- a/src/vikroutingwebengine.c +++ b/src/vikroutingwebengine.c @@ -43,15 +43,23 @@ static void vik_routing_web_engine_finalize ( GObject *gob ); static int vik_routing_web_engine_find ( VikRoutingEngine *self, VikTrwLayer *vtl, struct LatLon start, struct LatLon end ); +static gchar *vik_routing_web_engine_get_cmd_from_directions(VikRoutingEngine *self, const gchar *start, const gchar *end); +static gboolean vik_routing_web_engine_supports_direction(VikRoutingEngine *self); typedef struct _VikRoutingWebEnginePrivate VikRoutingWebEnginePrivate; struct _VikRoutingWebEnginePrivate { gchar *url_base; + + /* LatLon */ gchar *url_start_ll_fmt; gchar *url_stop_ll_fmt; gchar *url_via_ll_fmt; + /* Directions */ + gchar *url_start_dir_fmt; + gchar *url_stop_dir_fmt; + DownloadMapOptions options; }; @@ -63,10 +71,16 @@ enum PROP_0, PROP_URL_BASE, + + /* LatLon */ PROP_URL_START_LL, PROP_URL_STOP_LL, PROP_URL_VIA_LL, + /* Direction */ + PROP_URL_START_DIR, + PROP_URL_STOP_DIR, + PROP_REFERER, PROP_FOLLOW_LOCATION, }; @@ -103,6 +117,16 @@ vik_routing_web_engine_set_property (GObject *object, priv->url_via_ll_fmt = g_strdup(g_value_get_string (value)); break; + case PROP_URL_START_DIR: + g_free (priv->url_start_dir_fmt); + priv->url_start_dir_fmt = g_strdup(g_value_get_string (value)); + break; + + case PROP_URL_STOP_DIR: + g_free (priv->url_stop_dir_fmt); + priv->url_stop_dir_fmt = g_strdup(g_value_get_string (value)); + break; + case PROP_REFERER: g_free (priv->options.referer); priv->options.referer = g_value_dup_string (value); @@ -145,6 +169,14 @@ vik_routing_web_engine_get_property (GObject *object, g_value_set_string (value, priv->url_via_ll_fmt); break; + case PROP_URL_START_DIR: + g_value_set_string (value, priv->url_start_dir_fmt); + break; + + case PROP_URL_STOP_DIR: + g_value_set_string (value, priv->url_stop_dir_fmt); + break; + case PROP_REFERER: g_value_set_string (value, priv->options.referer); break; @@ -175,6 +207,8 @@ static void vik_routing_web_engine_class_init ( VikRoutingWebEngineClass *klass parent_class = VIK_ROUTING_ENGINE_CLASS (klass); parent_class->find = vik_routing_web_engine_find; + parent_class->supports_direction = vik_routing_web_engine_supports_direction; + parent_class->get_cmd_from_directions = vik_routing_web_engine_get_cmd_from_directions; /** * VikRoutingWebEngine:url-base: @@ -229,6 +263,32 @@ static void vik_routing_web_engine_class_init ( VikRoutingWebEngineClass *klass /** + * VikRoutingWebEngine:url-start-dir: + * + * The part of the request hosting the end point. + */ + pspec = g_param_spec_string ("url-start-dir", + "Start part of the URL", + "The part of the request hosting the start point", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_URL_START_DIR, pspec); + + + /** + * VikRoutingWebEngine:url-stop-dir: + * + * The part of the request hosting the end point. + */ + pspec = g_param_spec_string ("url-stop-dir", + "Stop part of the URL", + "The part of the request hosting the end point", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_URL_STOP_DIR, pspec); + + + /** * VikRoutingWebEngine:referer: * * The REFERER string to use in HTTP request. @@ -263,10 +323,16 @@ static void vik_routing_web_engine_init ( VikRoutingWebEngine *self ) VikRoutingWebEnginePrivate *priv = VIK_ROUTING_WEB_ENGINE_PRIVATE ( self ); priv->url_base = NULL; + + /* LatLon */ priv->url_start_ll_fmt = NULL; priv->url_stop_ll_fmt = NULL; priv->url_via_ll_fmt = NULL; + /* Directions */ + priv->url_start_dir_fmt = NULL; + priv->url_stop_dir_fmt = NULL; + priv->options.referer = NULL; priv->options.follow_location = 0; priv->options.check_file = NULL; @@ -280,6 +346,8 @@ static void vik_routing_web_engine_finalize ( GObject *gob ) g_free (priv->url_base); priv->url_base = NULL; + + /* LatLon */ g_free (priv->url_start_ll_fmt); priv->url_start_ll_fmt = NULL; g_free (priv->url_stop_ll_fmt); @@ -287,6 +355,12 @@ static void vik_routing_web_engine_finalize ( GObject *gob ) g_free (priv->url_via_ll_fmt); priv->url_via_ll_fmt = NULL; + /* Directions */ + g_free (priv->url_start_dir_fmt); + priv->url_start_dir_fmt = NULL; + g_free (priv->url_stop_dir_fmt); + priv->url_stop_dir_fmt = NULL; + g_free (priv->options.referer); priv->options.referer = NULL; @@ -319,6 +393,8 @@ vik_routing_web_engine_get_url_for_coords ( VikRoutingEngine *self, struct LatLo gchar *startURL; gchar *endURL; gchar *url; + + g_return_val_if_fail ( VIK_IS_ROUTING_WEB_ENGINE (self), NULL); VikRoutingWebEnginePrivate *priv = VIK_ROUTING_WEB_ENGINE_PRIVATE ( self ); @@ -329,6 +405,8 @@ vik_routing_web_engine_get_url_for_coords ( VikRoutingEngine *self, struct LatLo startURL = substitute_latlon ( priv->url_start_ll_fmt, start ); endURL = substitute_latlon ( priv->url_stop_ll_fmt, end ); url = g_strconcat ( priv->url_base, startURL, endURL, NULL ); + + /* Free memory */ g_free ( startURL ); g_free ( endURL ); @@ -349,5 +427,51 @@ vik_routing_web_engine_find ( VikRoutingEngine *self, VikTrwLayer *vtl, struct L a_babel_convert_from_url ( vtl, uri, format, NULL, NULL, options ); g_free(uri); + return ret; } + +static gchar * +vik_routing_web_engine_get_cmd_from_directions ( VikRoutingEngine *self, const gchar *start, const gchar *end ) +{ + g_return_val_if_fail ( VIK_IS_ROUTING_WEB_ENGINE (self), NULL); + + VikRoutingWebEnginePrivate *priv = VIK_ROUTING_WEB_ENGINE_PRIVATE ( self ); + + g_return_val_if_fail ( priv->url_base != NULL, NULL); + g_return_val_if_fail ( priv->url_start_dir_fmt != NULL, NULL); + g_return_val_if_fail ( priv->url_stop_dir_fmt != NULL, NULL); + + gchar *from_quoted, *to_quoted; + gchar **from_split, **to_split; + from_quoted = g_shell_quote ( start ); + to_quoted = g_shell_quote ( end ); + + from_split = g_strsplit( from_quoted, " ", 0); + to_split = g_strsplit( to_quoted, " ", 0); + + from_quoted = g_strjoinv( "%20", from_split); + to_quoted = g_strjoinv( "%20", to_split); + + gchar *url_fmt = g_strconcat ( priv->url_base, priv->url_start_dir_fmt, priv->url_stop_dir_fmt, NULL ); + gchar *url = g_strdup_printf ( url_fmt, from_quoted, to_quoted ); + + g_free ( url_fmt ); + + g_free(from_quoted); + g_free(to_quoted); + g_strfreev(from_split); + g_strfreev(to_split); + + return url; +} + +static gboolean +vik_routing_web_engine_supports_direction ( VikRoutingEngine *self ) +{ + g_return_val_if_fail ( VIK_IS_ROUTING_WEB_ENGINE (self), FALSE); + + VikRoutingWebEnginePrivate *priv = VIK_ROUTING_WEB_ENGINE_PRIVATE ( self ); + + return (priv->url_start_dir_fmt) != NULL; +} diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c index 78b2ff9..27629d7 100644 --- a/src/viktrwlayer.c +++ b/src/viktrwlayer.c @@ -298,9 +298,7 @@ static void trw_layer_geotagging_track ( gpointer pass_along[6] ); static void trw_layer_geotagging ( gpointer lav[2] ); #endif static void trw_layer_acquire_gps_cb ( gpointer lav[2] ); -#ifdef VIK_CONFIG_GOOGLE -static void trw_layer_acquire_google_cb ( gpointer lav[2] ); -#endif +static void trw_layer_acquire_routing_cb ( gpointer lav[2] ); #ifdef VIK_CONFIG_OPENSTREETMAP static void trw_layer_acquire_osm_cb ( gpointer lav[2] ); static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ); @@ -3036,20 +3034,18 @@ static void trw_layer_acquire_gps_cb ( gpointer lav[2] ) a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface, NULL, NULL ); } -#ifdef VIK_CONFIG_GOOGLE /* - * Acquire into this TRW Layer from Google Directions + * Acquire into this TRW Layer from Directions */ -static void trw_layer_acquire_google_cb ( gpointer lav[2] ) +static void trw_layer_acquire_routing_cb ( gpointer lav[2] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); VikViewport *vvp = vik_window_viewport(vw); - a_acquire ( vw, vlp, vvp, &vik_datasource_google_interface, NULL, NULL ); + a_acquire ( vw, vlp, vvp, &vik_datasource_routing_interface, NULL, NULL ); } -#endif #ifdef VIK_CONFIG_OPENSTREETMAP /* @@ -3511,12 +3507,11 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item); gtk_widget_show ( item ); -#ifdef VIK_CONFIG_GOOGLE - item = gtk_menu_item_new_with_mnemonic ( _("From Google _Directions...") ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_google_cb), pass_along ); + /* FIXME: only add menu when at least a routing engine has support for Directions */ + item = gtk_menu_item_new_with_mnemonic ( _("From _Directions...") ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_routing_cb), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item); gtk_widget_show ( item ); -#endif #ifdef VIK_CONFIG_OPENSTREETMAP item = gtk_menu_item_new_with_mnemonic ( _("From _OSM Traces...") ); diff --git a/src/vikwindow.c b/src/vikwindow.c index e7d7a95..3ecebfe 100644 --- a/src/vikwindow.c +++ b/src/vikwindow.c @@ -2695,12 +2695,10 @@ static void acquire_from_file ( GtkAction *a, VikWindow *vw ) a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_file_interface, NULL, NULL ); } -#ifdef VIK_CONFIG_GOOGLE -static void acquire_from_google ( GtkAction *a, VikWindow *vw ) +static void acquire_from_routing ( GtkAction *a, VikWindow *vw ) { - a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_google_interface, NULL, NULL ); + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_routing_interface, NULL, NULL ); } -#endif #ifdef VIK_CONFIG_OPENSTREETMAP static void acquire_from_osm ( GtkAction *a, VikWindow *vw ) @@ -3435,9 +3433,7 @@ static GtkActionEntry entries[] = { { "Acquire", GTK_STOCK_GO_DOWN, N_("A_cquire"), NULL, NULL, (GCallback)NULL }, { "AcquireGPS", NULL, N_("From _GPS..."), NULL, N_("Transfer data from a GPS device"), (GCallback)acquire_from_gps }, { "AcquireGPSBabel", NULL, N_("Import File With GPS_Babel..."), NULL, N_("Import file via GPSBabel converter"), (GCallback)acquire_from_file }, -#ifdef VIK_CONFIG_GOOGLE - { "AcquireGoogle", NULL, N_("Google _Directions..."), NULL, N_("Get driving directions from Google"), (GCallback)acquire_from_google }, -#endif + { "AcquireRouting", NULL, N_("_Directions..."), NULL, N_("Get driving directions"), (GCallback)acquire_from_routing }, #ifdef VIK_CONFIG_OPENSTREETMAP { "AcquireOSM", NULL, N_("_OSM Traces..."), NULL, N_("Get traces from OpenStreetMap"), (GCallback)acquire_from_osm }, { "AcquireMyOSM", NULL, N_("_My OSM Traces..."), NULL, N_("Get Your Own Traces from OpenStreetMap"), (GCallback)acquire_from_my_osm }, -- tg: (2190abb..) t/routing/datasource (depends on: master) ------------------------------------------------------------------------------ How ServiceNow helps IT people transform IT departments: 1. A cloud service to automate IT design, transition and operations 2. Dashboards that offer high-level views of enterprise services 3. A single system of record for all IT processes http://p.sf.net/sfu/servicenow-d2d-j _______________________________________________ Viking-devel mailing list Viking-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/viking-devel Viking home page: http://viking.sf.net/