]> git.street.me.uk Git - andy/viking.git/commitdiff
Generalize route finder
authorGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Thu, 16 May 2013 21:36:09 +0000 (23:36 +0200)
committerGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Thu, 16 May 2013 21:36:09 +0000 (23:36 +0200)
This patch generalize the route finder feature. The goal is to allow
the use of different services to compute a route from two clics.

To achieve this I introduced:
- vik_routing_engine as base class for engines
- vik_routing module for registering engines and providing "default"
  features
And I rewrote the Google related feature.

The new design seems quite overkill, but many more feature will be add in
the future. One of them is to rewrite the Acquire -> Google Direction.
An other is to add a "filter" on a route/track in order to allow a finer
route computation, based on more than 2 points.

Signed-off-by: Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
help/C/viking.xml
src/Makefile.am
src/google.c
src/googlerouting.c [new file with mode: 0644]
src/googlerouting.h [new file with mode: 0644]
src/main.c
src/vikrouting.c [new file with mode: 0644]
src/vikrouting.h [new file with mode: 0644]
src/vikroutingengine.c [new file with mode: 0644]
src/vikroutingengine.h [new file with mode: 0644]
src/viktrwlayer.c

index 2aa1d871560d8bd86f82988609a8e30f5d206786..61db5191ca297928780d9659cdf4497290bc96e7 100644 (file)
@@ -669,7 +669,7 @@ By default routes are coloured red. Tracks are automatically assigned a spread o
 </para>
 
 <para>
-Most operations are available on tracks are available on routes, except for functionality that relies on having timestamps - since routes by definition have no timing information. Thus for example, uploading a route to OpenStreetMap Traces is not available nor is Geotagging on a route.
+Most operations available on tracks are available on routes, except for functionality that relies on having timestamps - since routes by definition have no timing information. Thus for example, uploading a route to OpenStreetMap Traces is not available nor is Geotagging on a route.
 It is possible to convert between Tracks and Routes, although converting from a Track to a Route may involve a loss of information (hence you are required to confirm this operation before it happens).
 </para>
 
@@ -1053,7 +1053,7 @@ Changes the current tool to add trackpoints to the end of the track.
 
 <section><title>Extend Using Route Finder</title>
 <para>
-Enables the Route Finder tool. Thus on a subsequent left click in the viewport, a route is calculated from the end of track to that point using Google's route service and applied to the track.
+Enables the Route Finder tool. Thus on a subsequent left click in the viewport, a route is calculated from the end of track to that point using the default route service and applied to the track.
 </para>
 </section>
 
@@ -1539,11 +1539,11 @@ For Linux you can override this with the setting in the <xref linkend="prefs_ext
 </para>
 </section>
 
-<section><title>Route Finder</title>
+<section id="route_finder" xreflabel="Route Finder"><title>Route Finder</title>
 <para>
 Enable this tool by clicking on the toolbar icon: <guiicon><inlinegraphic fileref="figures/route_finder_18.png"/></guiicon>
 </para>
-<para>Creates a track using Google maps routing between two points.
+<para>Creates a track using default routing engine between two points.
 Requires an internet connection. Click one point, then click another to
 create a track.
 </para>
@@ -1735,6 +1735,12 @@ Your OSM password will be stored in plain text.
 </section>
 </section>
 
+<section id="prefs_routing" xreflabel="Routing Preferences"><title>Routing</title>
+<section><title>Routing engine</title>
+<para>You can select the routing engine used by default, ie by features that do not propose a live selection, like <xref linkend="route_finder"/>.</para>
+</section>
+</section>
+
 </section>
 
 <!-- HOWTOS-->
index 5ed5ea6e7354cce84f0b1c0f8eaf0ccdc15ff0df..e8397d5dd97869f0cda921dd8adf65e780d5c129 100644 (file)
@@ -85,6 +85,8 @@ libviking_a_SOURCES = \
        vikgoto.c vikgoto.h \
        viktrwlayer_tpwin.c viktrwlayer_tpwin.h \
        viktrwlayer_propwin.c viktrwlayer_propwin.h \
+       vikrouting.c vikrouting.h \
+       vikroutingengine.c vikroutingengine.h \
        thumbnails.c thumbnails.h \
        background.c background.h \
        vikradiogroup.c vikradiogroup.h \
@@ -137,6 +139,7 @@ endif
 
 if GOOGLE
 libviking_a_SOURCES += \
+       googlerouting.c googlerouting.h \
        google.c google.h
 endif
 
index de20d08e9d9bc2a9a12338a68594e3447871fadf..eea0c4e22d2c2af5bd27d54919f2199b16a64fe9 100644 (file)
@@ -30,6 +30,8 @@
 #include "vikwebtoolcenter.h"
 #include "vikgoto.h"
 #include "googlesearch.h"
+#include "vikrouting.h"
+#include "googlerouting.h"
 
 void google_init () {
   // Webtools
@@ -41,4 +43,9 @@ void google_init () {
   GoogleGotoTool *gototool = google_goto_tool_new (  );
   vik_goto_register ( VIK_GOTO_TOOL ( gototool ) );
   g_object_unref ( gototool );
+
+  // Routing
+  GoogleRouting *routing = google_routing_new ( );
+  vik_routing_register ( VIK_ROUTING_ENGINE ( routing ) );
+  g_object_unref ( routing );
 }
diff --git a/src/googlerouting.c b/src/googlerouting.c
new file mode 100644 (file)
index 0000000..97df909
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2005-2008, Alex Foobarian <foobarian@gmail.com>
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ *
+ */
+
+/**
+ * SECTION:googlerouting
+ * @short_description: the class for Google Directions
+ * 
+ * The #GoogleRouting class handles Google Directions 
+ * service as routing engine.
+ * 
+ * Technical details are available here:
+ * https://developers.google.com/maps/documentation/directions/#DirectionsResponses
+ *
+ * gpsbabel supports this format.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "googlerouting.h"
+
+#define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js"
+
+static DownloadMapOptions googles_routing_options = { FALSE, FALSE, "http://maps.google.com/", 0, NULL };
+
+static void google_routing_finalize ( GObject *gob );
+
+static gchar *google_routing_get_url_for_coords ( VikRoutingEngine *self, struct LatLon start, struct LatLon end );
+static DownloadMapOptions *google_routing_get_download_options ( VikRoutingEngine *self );
+
+G_DEFINE_TYPE (GoogleRouting, google_routing, VIK_ROUTING_ENGINE_TYPE)
+
+static void google_routing_class_init ( GoogleRoutingClass *klass )
+{
+  GObjectClass *object_class;
+  VikRoutingEngineClass *parent_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = google_routing_finalize;
+
+  parent_class = VIK_ROUTING_ENGINE_CLASS (klass);
+
+  parent_class->get_url_for_coords = google_routing_get_url_for_coords;
+  parent_class->get_download_options = google_routing_get_download_options;
+}
+
+/**
+ * google_routing_new:
+ * 
+ * Create a new instance of GoogleRouting routing engine.
+ */
+GoogleRouting *google_routing_new ()
+{
+  return GOOGLE_ROUTING ( g_object_new ( GOOGLE_ROUTING_TYPE,
+                                         "id", "google",
+                                         "label", "Google",
+                                         "format", "google",
+                                         NULL ) );
+}
+
+static void google_routing_init ( GoogleRouting *vlp )
+{
+}
+
+static void google_routing_finalize ( GObject *gob )
+{
+  G_OBJECT_GET_CLASS(gob)->finalize(gob);
+}
+
+static DownloadMapOptions *
+google_routing_get_download_options ( VikRoutingEngine *self )
+{
+       return &googles_routing_options;
+}
+
+/*
+ * Override VikRoutingEngine:get_download_options()
+ */
+gchar *
+google_routing_get_url_for_coords ( VikRoutingEngine *self, struct LatLon start, struct LatLon end )
+{
+    gchar startlat[G_ASCII_DTOSTR_BUF_SIZE], startlon[G_ASCII_DTOSTR_BUF_SIZE];
+    gchar endlat[G_ASCII_DTOSTR_BUF_SIZE], endlon[G_ASCII_DTOSTR_BUF_SIZE];
+    gchar *url;
+    url = g_strdup_printf(GOOGLE_DIRECTIONS_STRING,
+                          g_ascii_dtostr (startlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lat),
+                          g_ascii_dtostr (startlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lon),
+                          g_ascii_dtostr (endlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lat),
+                          g_ascii_dtostr (endlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lon));
+
+    return url;
+}
diff --git a/src/googlerouting.h b/src/googlerouting.h
new file mode 100644 (file)
index 0000000..a67ba7b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ *
+ */
+#ifndef _GOOGLE_ROUTING_H
+#define _GOOGLE_ROUTING_H
+
+#include <glib.h>
+
+#include "vikroutingengine.h"
+
+G_BEGIN_DECLS
+
+#define GOOGLE_ROUTING_TYPE            (google_routing_get_type ())
+#define GOOGLE_ROUTING(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOOGLE_ROUTING_TYPE, GoogleRouting))
+#define GOOGLE_ROUTING_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOOGLE_ROUTING_TYPE, GoogleRoutingClass))
+#define GOOGLE_IS_ROUTING(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOOGLE_ROUTING_TYPE))
+#define GOOGLE_IS_ROUTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOOGLE_ROUTING_TYPE))
+#define GOOGLE_ROUTING_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOOGLE_ROUTING_TYPE, GoogleRoutingClass))
+
+
+typedef struct _GoogleRouting GoogleRouting;
+typedef struct _GoogleRoutingClass GoogleRoutingClass;
+
+struct _GoogleRoutingClass
+{
+  VikRoutingEngineClass object_class;
+};
+
+GType google_routing_get_type ();
+
+struct _GoogleRouting {
+  VikRoutingEngine obj;
+};
+
+GoogleRouting *google_routing_new ();
+
+G_END_DECLS
+
+#endif
index ab353b57adf720bbfdbd824573f95f06f8889f90..31861a624598eb82dbf07cccb5a10baaa014d623 100644 (file)
@@ -34,6 +34,7 @@
 #include "viklayer_defaults.h"
 #include "globals.h"
 #include "vikmapslayer.h"
+#include "vikrouting.h"
 
 #ifdef VIK_CONFIG_GEOCACHES
 void a_datasource_gc_init();
@@ -182,6 +183,8 @@ int main( int argc, char *argv[] )
   a_datasource_gc_init();
 #endif
 
+  vik_routing_prefs_init();
+
   /* Set the icon */
   main_icon = gdk_pixbuf_from_pixdata(&viking_pixbuf, FALSE, NULL);
   gtk_window_set_default_icon(main_icon);
diff --git a/src/vikrouting.c b/src/vikrouting.c
new file mode 100644 (file)
index 0000000..6a4fd47
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ */
+
+/**
+ * SECTION:vikrouting
+ * @short_description: the routing framework
+ * 
+ * This module handles the list of #VikRoutingEngine.
+ * It also handles the "default" functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+
+#include "curl_download.h"
+#include "babel.h"
+
+#include "preferences.h"
+
+#include "vikrouting.h"
+#include "vikroutingengine.h"
+
+/* params will be routing.default */
+/* we have to make sure these don't collide. */
+#define VIKING_ROUTING_PARAMS_GROUP_KEY "routing"
+#define VIKING_ROUTING_PARAMS_NAMESPACE "routing."
+
+/* List to register all routing engines */
+static GList *routing_engine_list = NULL;
+
+static VikLayerParam prefs[] = {
+  { 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 },
+};
+
+gchar **routing_engine_labels = NULL;
+gchar **routing_engine_ids = NULL;
+
+/**
+ * vik_routing_prefs_init:
+ * 
+ * Initialize the preferences of the routing feature.
+ */
+void
+vik_routing_prefs_init()
+{
+  a_preferences_register_group ( VIKING_ROUTING_PARAMS_GROUP_KEY, "Routing" );
+
+  VikLayerParamData tmp;
+  tmp.s = NULL;
+  a_preferences_register(prefs, tmp, VIKING_ROUTING_PARAMS_GROUP_KEY);
+}
+
+static gint
+search_by_id (gconstpointer a,
+              gconstpointer b)
+{
+       const gchar *id = b;
+       VikRoutingEngine *engine = a;
+       gchar *engineId = vik_routing_engine_get_id (engine);
+       if (id && engine)
+               return strcmp(id, engineId);
+       else
+               return -1;
+}
+
+/**
+ * vik_routing_find_engine:
+ * @id: the id of the engine we are looking for
+ * 
+ * Returns: the found engine or %NULL
+ */
+VikRoutingEngine *
+vik_routing_find_engine ( const gchar *id )
+{
+       VikRoutingEngine *engine = NULL;
+       GList *elem = g_list_find_custom (routing_engine_list, id, search_by_id);
+       if (elem)
+               engine = elem->data;
+       return engine;
+}
+
+/**
+ * vik_routing_default:
+ * 
+ * Retrieve the default engine, based on user's preferences.
+ * 
+ * Returns: the default engine
+ */
+static VikRoutingEngine *
+vik_routing_default( void )
+{
+  gchar *id = a_preferences_get ( VIKING_ROUTING_PARAMS_NAMESPACE "default")->s;
+  VikRoutingEngine *engine = vik_routing_find_engine(id);
+  if (engine == NULL && routing_engine_list != NULL && g_list_first (routing_engine_list) != NULL)
+    /* Fallback to first element */
+    engine = g_list_first (routing_engine_list)->data;
+
+  return engine;
+}
+
+/**
+ * vik_routing_default_find:
+ * 
+ * Route computation with default engine.
+ */
+void
+vik_routing_default_find(VikTrwLayer *vt, struct LatLon start, struct LatLon end)
+{
+  /* The engine */
+  VikRoutingEngine *engine = vik_routing_default ( );
+  /* The route computation */
+  vik_routing_engine_find ( engine, vt, start, end );
+}
+
+/**
+ * vik_routing_register:
+ * @engine: new routing engine to register
+ * 
+ * Register a new routing engine.
+ */
+void
+vik_routing_register( VikRoutingEngine *engine )
+{
+  if ( VIK_IS_ROUTING_ENGINE ( engine ) )
+    routing_engine_list = g_list_append ( routing_engine_list, g_object_ref ( engine ) );
+
+  gsize len = 0;
+  if (routing_engine_labels)
+    len = g_strv_length (routing_engine_labels);
+
+  gchar *label = vik_routing_engine_get_label ( engine );
+  gchar *id = vik_routing_engine_get_id ( engine );
+
+  /* Add the label */
+  routing_engine_labels = g_realloc (routing_engine_labels, (len+2)*sizeof(gchar*));
+  routing_engine_labels[len] = g_strdup (label);
+  routing_engine_labels[len+1] = NULL;
+
+  /* Add the id */
+  routing_engine_ids = g_realloc (routing_engine_ids, (len+2)*sizeof(gchar*));
+  routing_engine_ids[len] = g_strdup (id);
+  routing_engine_ids[len+1] = NULL;
+  
+  /* Hack
+     We have to ensure the mode LayerParam references the up-to-date
+     GLists.
+  */
+  /*
+  memcpy(&maps_layer_params[0].widget_data, &params_maptypes, sizeof(gpointer));
+  memcpy(&maps_layer_params[0].extra_widget_data, &params_maptypes_ids, sizeof(gpointer));
+  */
+  prefs[0].widget_data = routing_engine_labels;
+  prefs[0].extra_widget_data = routing_engine_ids;
+}
+
+/**
+ * vik_routing_unregister_all:
+ * 
+ * Unregister all registered routing engines.
+ */
+void
+vik_routing_unregister_all ()
+{
+  g_list_foreach ( routing_engine_list, (GFunc) g_object_unref, NULL );
+  g_strfreev ( routing_engine_labels );
+  g_strfreev ( routing_engine_ids );
+}
diff --git a/src/vikrouting.h b/src/vikrouting.h
new file mode 100644 (file)
index 0000000..1a98636
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ *
+ */
+#ifndef _VIKING_ROUTING_H
+#define _VIKING_ROUTING_H
+
+#include <glib.h>
+
+#include "vikroutingengine.h"
+
+G_BEGIN_DECLS
+
+
+/* Default */
+void vik_routing_default_find ( VikTrwLayer *vt, struct LatLon start, struct LatLon end );
+
+/* Routing engines management */
+void vik_routing_prefs_init();
+void vik_routing_register( VikRoutingEngine *engine );
+void vik_routing_unregister_all ();
+
+G_END_DECLS
+
+#endif
diff --git a/src/vikroutingengine.c b/src/vikroutingengine.c
new file mode 100644 (file)
index 0000000..34fa34a
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ */
+
+/**
+ * SECTION:vikroutingengine
+ * @short_description: the base class to describe routing engine
+ * 
+ * The #VikRoutingEngine class is both the interface and the base class
+ * for the hierarchie of routing engines.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+
+#include "curl_download.h"
+#include "babel.h"
+
+#include "vikroutingengine.h"
+
+static void vik_routing_engine_finalize ( GObject *gob );
+static DownloadMapOptions *vik_routing_engine_get_download_options_default ( VikRoutingEngine *self );
+static GObjectClass *parent_class;
+
+typedef struct _VikRoutingPrivate VikRoutingPrivate;
+struct _VikRoutingPrivate
+{
+       gchar *id;
+       gchar *label;
+       gchar *format;
+};
+
+#define VIK_ROUTING_ENGINE_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIK_ROUTING_ENGINE_TYPE, VikRoutingPrivate))
+
+/* properties */
+enum
+{
+  PROP_0,
+
+  PROP_ID,
+  PROP_LABEL,
+  PROP_FORMAT,
+};
+
+G_DEFINE_ABSTRACT_TYPE (VikRoutingEngine, vik_routing_engine, G_TYPE_OBJECT)
+
+static void
+vik_routing_engine_set_property (GObject      *object,
+                          guint         property_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE ( object );
+
+  switch (property_id)
+    {
+    case PROP_ID:
+      g_free (priv->id);
+      priv->id = g_strdup(g_value_get_string (value));
+      break;
+
+    case PROP_LABEL:
+      g_free (priv->label);
+      priv->label = g_strdup(g_value_get_string (value));
+      break;
+
+    case PROP_FORMAT:
+      g_free (priv->format);
+      priv->format = g_strdup(g_value_get_string (value));
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+vik_routing_engine_get_property (GObject    *object,
+                          guint       property_id,
+                          GValue     *value,
+                          GParamSpec *pspec)
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE ( object );
+
+  switch (property_id)
+    {
+    case PROP_ID:
+      g_value_set_string (value, priv->id);
+      break;
+
+    case PROP_LABEL:
+      g_value_set_string (value, priv->label);
+      break;
+
+    case PROP_FORMAT:
+      g_value_set_string (value, priv->format);
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+vik_routing_engine_class_init ( VikRoutingEngineClass *klass )
+{
+  GObjectClass *object_class;
+  VikRoutingEngineClass *routing_class;
+  GParamSpec *pspec = NULL;
+
+  object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = vik_routing_engine_set_property;
+  object_class->get_property = vik_routing_engine_get_property;
+  object_class->finalize = vik_routing_engine_finalize;
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  routing_class = VIK_ROUTING_ENGINE_CLASS ( klass );
+  routing_class->find = NULL;
+  routing_class->get_download_options = vik_routing_engine_get_download_options_default;
+  routing_class->get_url_for_coords = NULL;
+
+
+  pspec = g_param_spec_string ("id",
+                               "Identifier",
+                               "The identifier of the routing engine",
+                               "<no-set>" /* default value */,
+                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_ID, pspec);
+  
+  pspec = g_param_spec_string ("label",
+                               "Label",
+                               "The label of the routing engine",
+                               "<no-set>" /* default value */,
+                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_LABEL, pspec);
+    
+  pspec = g_param_spec_string ("format",
+                               "Format",
+                               "The format of the output (see gpsbabel)",
+                               "<no-set>" /* default value */,
+                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_FORMAT, pspec);
+
+  g_type_class_add_private (klass, sizeof (VikRoutingPrivate));
+}
+
+static void
+vik_routing_engine_init ( VikRoutingEngine *self )
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE (self);
+
+  priv->id = NULL;
+  priv->label = NULL;
+  priv->format = NULL;
+}
+
+static void
+vik_routing_engine_finalize ( GObject *self )
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE (self);
+
+  g_free (priv->id);
+  priv->id = NULL;
+
+  g_free (priv->label);
+  priv->label = NULL;
+
+  g_free (priv->format);
+  priv->format = NULL;
+
+  G_OBJECT_CLASS(parent_class)->finalize(self);
+}
+
+static DownloadMapOptions *
+vik_routing_engine_get_download_options_default ( VikRoutingEngine *self )
+{
+       // Default: return NULL
+       return NULL;
+}
+
+static gchar *
+vik_routing_engine_get_url_for_coords ( VikRoutingEngine *self, struct LatLon start, struct LatLon 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_url_for_coords != NULL, NULL );
+       
+       return klass->get_url_for_coords( self, start, end );
+}
+
+static DownloadMapOptions *
+vik_routing_engine_get_download_options ( VikRoutingEngine *self )
+{
+       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_download_options != NULL, NULL );
+
+       return klass->get_download_options( self );
+}
+
+int
+vik_routing_engine_find ( VikRoutingEngine *self, VikTrwLayer *vtl, struct LatLon start, struct LatLon end )
+{
+  gchar *uri;
+  int ret = 0;  /* OK */
+
+  uri = vik_routing_engine_get_url_for_coords(self, start, end);
+
+  DownloadMapOptions *options = vik_routing_engine_get_download_options(self);
+  
+  gchar *format = vik_routing_engine_get_format ( self );
+  a_babel_convert_from_url ( vtl, uri, format, NULL, NULL, options );
+
+  g_free(uri);
+  return ret;
+}
+
+/**
+ * vik_routing_engine_get_id:
+ * 
+ * Returns: the id of self
+ */
+gchar *
+vik_routing_engine_get_id ( VikRoutingEngine *self )
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE (self);
+
+  return priv->id;
+}
+
+/**
+ * vik_routing_engine_get_label:
+ * 
+ * Returns: the label of self
+ */
+gchar *
+vik_routing_engine_get_label ( VikRoutingEngine *self )
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE (self);
+
+  return priv->label;
+}
+
+/**
+ * vik_routing_engine_get_format:
+ * 
+ * Returns: the format of self
+ */
+gchar *
+vik_routing_engine_get_format ( VikRoutingEngine *self )
+{
+  VikRoutingPrivate *priv = VIK_ROUTING_ENGINE_PRIVATE (self);
+
+  return priv->format;
+}
diff --git a/src/vikroutingengine.h b/src/vikroutingengine.h
new file mode 100644 (file)
index 0000000..c90d4e6
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
+ *
+ */
+#ifndef _VIKING_ROUTING_ENGINE_H
+#define _VIKING_ROUTING_ENGINE_H
+
+#include <glib.h>
+
+#include "viktrwlayer.h"
+#include "coords.h"
+#include "download.h"
+
+#include "vikwindow.h"
+
+G_BEGIN_DECLS
+
+#define VIK_ROUTING_ENGINE_TYPE            (vik_routing_engine_get_type ())
+#define VIK_ROUTING_ENGINE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIK_ROUTING_ENGINE_TYPE, VikRoutingEngine))
+#define VIK_ROUTING_ENGINE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), VIK_ROUTING_ENGINE_TYPE, VikRoutingEngineClass))
+#define VIK_IS_ROUTING_ENGINE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIK_ROUTING_ENGINE_TYPE))
+#define VIK_IS_ROUTING_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIK_ROUTING_ENGINE_TYPE))
+#define VIK_ROUTING_ENGINE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), VIK_ROUTING_ENGINE_TYPE, VikRoutingEngineClass))
+
+
+typedef struct _VikRoutingEngine VikRoutingEngine;
+typedef struct _VikRoutingEngineClass VikRoutingEngineClass;
+
+struct _VikRoutingEngineClass
+{
+  GObjectClass object_class;
+  void (*find)(VikTrwLayer *vt, struct LatLon start, struct LatLon end);
+  gchar *(*get_url_for_coords)(VikRoutingEngine *self, struct LatLon start, struct LatLon end);
+  DownloadMapOptions *(*get_download_options) ( VikRoutingEngine *self );
+};
+
+GType vik_routing_engine_get_type ();
+
+struct _VikRoutingEngine {
+  GObject obj;
+};
+
+int vik_routing_engine_find ( VikRoutingEngine *self, VikTrwLayer *vt, struct LatLon start, struct LatLon 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 );
+
+G_END_DECLS
+
+#endif
index 8c4455b9195e660604a5d138d01c687cd38c1035..bf09976f99a41d445269c538afb627a329452f82 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2007, Quy Tonthat <qtonthat@gmail.com>
  * Copyright (C) 2009, Hein Ragas <viking@ragas.nl>
  * Copyright (c) 2012, Rob Norris <rw_norris@hotmail.com>
+ * Copyright (c) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@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
@@ -55,6 +56,8 @@
 #include "vikexttool_datasources.h"
 #include "util.h"
 
+#include "vikrouting.h"
+
 #include "icons/icons.h"
 
 #ifdef HAVE_MATH_H
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 
-#ifdef VIK_CONFIG_GOOGLE
-#define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js"
-#endif
-
 #define VIK_TRW_LAYER_TRACK_GC 6
 #define VIK_TRW_LAYER_TRACK_GCS 10
 #define VIK_TRW_LAYER_TRACK_GC_BLACK 0
@@ -356,10 +355,8 @@ static void tool_new_track_release ( VikTrwLayer *vtl, GdkEventButton *event, Vi
 static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp ); 
 static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-#ifdef VIK_CONFIG_GOOGLE
 static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp);
 static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-#endif
 
 static void cached_pixbuf_free ( CachedPixbuf *cp );
 static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
@@ -428,13 +425,11 @@ static VikToolInterface trw_layer_tools[] = {
     FALSE,
     GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
 
-#ifdef VIK_CONFIG_GOOGLE
   { { "RouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
     (VikToolConstructorFunc) tool_route_finder_create,  NULL, NULL, NULL,
     (VikToolMouseFunc) tool_route_finder_click, NULL, NULL, (VikToolKeyFunc) NULL,
     FALSE,
     GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf },
-#endif
 };
 
 enum {
@@ -444,9 +439,7 @@ enum {
   TOOL_EDIT_WAYPOINT,
   TOOL_EDIT_TRACKPOINT,
   TOOL_SHOW_PICTURE,
-#ifdef VIK_CONFIG_GOOGLE
   TOOL_ROUTE_FINDER,
-#endif
   NUM_TOOLS
 };
 
@@ -4552,7 +4545,6 @@ static void trw_layer_extend_track_end ( gpointer pass_along[6] )
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
 }
 
-#ifdef VIK_CONFIG_GOOGLE
 /**
  * extend a track using route finder
  */
@@ -4573,7 +4565,6 @@ static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] )
     goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
 
 }
-#endif
 
 static void trw_layer_apply_dem_data ( gpointer pass_along[6] )
 {
@@ -6668,7 +6659,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
-#ifdef VIK_CONFIG_GOOGLE
     if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
       item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
       gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
@@ -6676,7 +6666,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men
       gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
       gtk_widget_show ( item );
     }
-#endif
 
     // ATM can't upload a single waypoint but can do waypoints to a GPS
     if ( subtype != VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
@@ -8275,7 +8264,6 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton
 }
 
 
-#ifdef VIK_CONFIG_GOOGLE
 /*** Route Finder ***/
 static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
 {
@@ -8307,9 +8295,6 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
   }
   else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
     struct LatLon start, end;
-    gchar startlat[G_ASCII_DTOSTR_BUF_SIZE], startlon[G_ASCII_DTOSTR_BUF_SIZE];
-    gchar endlat[G_ASCII_DTOSTR_BUF_SIZE], endlon[G_ASCII_DTOSTR_BUF_SIZE];
-    gchar *url;
 
     vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
     vik_coord_to_latlon ( &(tmp), &end );
@@ -8323,14 +8308,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
       vtl->route_finder_started = FALSE;
     }
 
-    url = g_strdup_printf(GOOGLE_DIRECTIONS_STRING,
-                          g_ascii_dtostr (startlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lat),
-                          g_ascii_dtostr (startlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lon),
-                          g_ascii_dtostr (endlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lat),
-                          g_ascii_dtostr (endlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lon));
-    // NB normally this returns a GPX Route - so subsequent usage of it must lookup via the routes hash
-    a_babel_convert_from_url ( vtl, url, "google", NULL, NULL, NULL );
-    g_free ( url );
+    vik_routing_default_find ( vtl, start, end);
 
     /* see if anything was done -- a track was added or appended to */
     if ( vtl->route_finder_check_added_track && vtl->route_finder_added_track ) {
@@ -8356,7 +8334,6 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even
   }
   return TRUE;
 }
-#endif
 
 /*** Show picture ****/