+/*
+ * This file is part of mapper
+ *
+ * Copyright (C) 2007-2008 Kaj-Michael Lang
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include <config.h>
#include <libgnomevfs/gnome-vfs.h>
#include "utils.h"
#include "gps.h"
#include "settings.h"
+#include "help.h"
#include "mapper-types.h"
#include "ui-common.h"
#include "dialogs.h"
#include "file.h"
#include "latlon.h"
#include "path.h"
+#include "map-download.h"
typedef struct _OriginToggleInfo OriginToggleInfo;
struct _OriginToggleInfo {
return res;
}
+/**
+ *
+ */
void
-track_show_distance_from(Path *path, Point *point)
+path_show_distance_from(Path *path, Point *point)
{
gchar buffer[80];
+gdouble dist;
+
+if (path && path_has_points(path)) {
+ dist=path_calculate_distance_from(path, point);
+ g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"), sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
+ MACRO_BANNER_SHOW_INFO(_window, buffer);
+} else {
+ MACRO_BANNER_SHOW_INFO(_window, _("The current path is empty."));
+}
+}
+
+/**
+ * path_show_distance_from_last:
+ *
+ */
+void
+path_show_distance_from_last(Path *path)
+{
+path_show_distance_from(path, path_find_last_point(path));
+}
+
+/**
+ * path_show_distance_from_first:
+ *
+ */
+void
+path_show_distance_from_first(Path *path)
+{
+path_show_distance_from(path, path->head);
+}
+
+/**
+ * Show the distance from the current GPS location to the given point,
+ * following the route. If point is NULL, then the distance is shown to the
+ * next waypoint.
+ */
+gboolean
+route_show_distance_to(Path *route, Point *point)
+{
+gchar buffer[80];
+gdouble lat, lon;
gdouble sum;
-sum=path_calculate_distance_from(path, point);
+g_return_val_if_fail(route, FALSE);
+
+unit2latlon(point->unitx, point->unity, &lat, &lon);
+sum=path_get_distance_to(route, point, lat, lon);
g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"), sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
MACRO_BANNER_SHOW_INFO(_window, buffer);
+
+return TRUE;
}
void
-track_show_distance_from_last(Path *track)
+route_show_distance_to_next_waypoint(Path *route)
{
-/* Find last zero point. */
-if (track->head != track->tail) {
- Point *point;
- /* Find last zero point. */
- for (point = _track->tail; point->unity; point--) {
- }
- track_show_distance_from(point);
-} else {
- MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
-}
+g_return_if_fail(route);
+
+if (!route_show_distance_to(route, NULL))
+ MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
}
void
-track_show_distance_from_first(Path *track)
+route_show_distance_to_last(Path *route)
{
-if (track->head != track->tail) {
- track_show_distance_from(track->head);
+g_return_if_fail(route);
+
+if (route->head != route->tail) {
+ route_show_distance_to(route, path_find_last_point(route));
} else {
- MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
+ MACRO_BANNER_SHOW_INFO(_window, _("The current route is empty."));
}
}
/**
+ * route_autoroute_check:
+ *
* Check if we should re-calculate route
*/
void
-route_autoroute_check(Path *route)
+route_autoroute_check(Path *path)
{
-g_return_if_fail(route);
+g_return_if_fail(path);
-if (_autoroute_data.enabled && !_autoroute_data.in_progress && route->near_point_dist_squared > 400) {
- MACRO_BANNER_SHOW_INFO(_window, _("Recalculating directions..."));
+if (_autoroute_data.enabled && !_autoroute_data.in_progress && path->near_point_dist_squared > 400) {
_autoroute_data.in_progress = TRUE;
- show_directions = FALSE;
+ show_directions=FALSE;
g_idle_add((GSourceFunc)route_auto_route_dl_idle_cb, NULL);
+ MACRO_BANNER_SHOW_INFO(_window, _("Recalculating directions..."));
+}
+
+}
+
+gboolean
+path_open(Path *track)
+{
+gchar *buffer;
+gint size;
+gboolean r = FALSE;
+
+if (file_open_get_contents(&_track_file_uri, &buffer, &size)) {
+ if (path_gpx_parse(track, buffer, size, GPX_PATH_NEW)) {
+ MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
+ r = TRUE;
+ } else {
+ popup_error(_window, _("Error parsing track GPX file."));
+ }
+ g_free(buffer);
}
+return r;
}
+gboolean
+path_save(Path *track)
+{
+GnomeVFSHandle *handle;
+gboolean r = FALSE;
+
+if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
+ if (path_gpx_write(track, handle)) {
+ MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
+ r = TRUE;
+ path_clear_ask(track);
+ } else {
+ popup_error(_window, _("Error writing track GPX file."));
+ }
+ gnome_vfs_close(handle);
+}
+return r;
+}
+
+/**
+ * route_open_file:
+ * @route
+ *
+ * Open a route GPX file
+ *
+ */
gboolean
route_open_file(Path *route)
{
route_set_destination_from_last(route, &_dest);
return TRUE;
} else {
- popup_error(_window, _("Error parsing GPX file."));
+ popup_error(_window, _("Error parsing route GPX file."));
g_free(buffer);
return FALSE;
}
}
/**
- * Ask user to save route
+ * route_save:
+ *
+ * Ask user to save route to GPX file.
+ *
*/
gboolean
route_save(Path *route)
if (path_gpx_write(route, handle)) {
MACRO_BANNER_SHOW_INFO(_window, _("Route Saved"));
} else {
- popup_error(_window, _("Error writing GPX file."));
+ popup_error(_window, _("Error writing route GPX file."));
}
gnome_vfs_close(handle);
return TRUE;
return FALSE;
}
-/**
- *
- */
static gboolean
route_origin_type_selected_cb(GtkWidget *toggle, OriginToggleInfo *oti)
{
+gchar buffer[80];
+gchar strlat[32];
+gchar strlon[32];
+
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) {
if (toggle == oti->rad_use_gps) {
- gchar buffer[80];
- gchar strlat[32];
- gchar strlon[32];
g_ascii_formatd(strlat, 32, "%.06f", _gps->data.lat);
g_ascii_formatd(strlon, 32, "%.06f", _gps->data.lon);
g_snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
gtk_entry_set_text(GTK_ENTRY(oti->txt_from), buffer);
} else if (toggle == oti->rad_use_route) {
- gchar buffer[80];
- gchar strlat[32];
- gchar strlon[32];
gdouble lat, lon;
Point *p;
}
/**
+ * route_cancel_autoroute:
+ *
* Cancel the current auto-route.
*/
void
}
if (_autoroute_data.curl_easy) {
- if (_curl_multi)
- curl_multi_remove_handle(_curl_multi, _autoroute_data.curl_easy);
+ if (_autoroute_data.curl_multi)
+ curl_multi_remove_handle(_autoroute_data.curl_multi, _autoroute_data.curl_easy);
curl_easy_cleanup(_autoroute_data.curl_easy);
+ curl_multi_cleanup(_autoroute_data.curl_multi);
_autoroute_data.curl_easy = NULL;
+ _autoroute_data.curl_multi = NULL;
}
g_free(_autoroute_data.rdl_data.bytes);
_autoroute_data.rdl_data.bytes = NULL;
_autoroute_data.rdl_data.bytes_read = 0;
-
_autoroute_data.in_progress = FALSE;
}
}
+static gboolean
+route_auto_download_timeout()
+{
+CURLMsg *msg;
+gint num_msgs = 0;
+
+if (!_autoroute.curl_multi) {
+ route_cancel_autoroute(_route, TRUE);
+ return FALSE;
+}
+
+while (_autoroute.curl_multi && (msg = curl_multi_info_read(_autoroute.curl_multi, &num_msgs))) {
+ if (msg->msg == CURLMSG_DONE) {
+ /* Now, parse the autoroute and update the display. */
+ if (_autoroute_data.enabled && path_gpx_parse(_route, _autoroute_data.rdl_data.bytes, _autoroute_data.rdl_data.bytes_read, 0)) {
+ /* Find the nearest route point, if we're connected. */
+ path_find_nearest_point(_route, _gps->data.lat, _gps->data.lon);
+ }
+ route_cancel_autoroute(_route, TRUE); /* We're done. Clean up. */
+ }
+}
+
/**
* Read the data provided by the given handle as GPX data, updating the
* auto-route with that data.
*/
-size_t
-route_dl_cb_read(void *ptr, size_t size, size_t nmemb, RouteDownloadData * rdl_data)
+static size_t
+route_auto_dl_read_cb(void *ptr, size_t size, size_t nmemb, RouteDownloadData * rdl_data)
{
size_t old_size = rdl_data->bytes_read;
return (size * nmemb);
}
-gboolean
-route_auto_route_dl_idle_cb()
+static gboolean
+route_auto_dl_idle_cb()
{
gchar latstr[32], lonstr[32], *latlonstr;
MACRO_CURL_EASY_INIT(_autoroute_data.curl_easy);
curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_URL, _autoroute_data.src_str);
-curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_WRITEFUNCTION, route_dl_cb_read);
+curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_WRITEFUNCTION, route_auto_dl_read_cb);
curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_WRITEDATA, &_autoroute_data.rdl_data);
-curl_multi_add_handle(_curl_multi, _autoroute_data.curl_easy);
+_autoroute_data.curl_multi=curl_multi_init();
+curl_multi_add_handle(_autoroute_data.curl_multi, _autoroute_data.curl_easy);
-if (iap_is_connected() && !_curl_sid)
- _curl_sid = g_timeout_add(100, (GSourceFunc)map_download_timeout, NULL);
+if (iap_is_connected() && !_autoroute_data.curl_sid)
+ _autoroute_data.curl_sid=g_timeout_add(250, (GSourceFunc)route_auto_download_timeout, NULL);
-_autoroute_data.in_progress = TRUE;
+_autoroute_data.in_progress=TRUE;
return FALSE;
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
-if (route->head != route->tail) {
+if (path_has_points(route)) {
/* Use "End of Route" by default if they have a route. */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
gtk_widget_grab_focus(oti.rad_use_route);
/* Let them try again. */
}
/* Else, if GPS is enabled, replace the route, otherwise append it. */
- else if (gpx_parse(route, rdl_data.bytes, rdl_data.bytes_read,
+ else if (path_gpx_parse(route, rdl_data.bytes, rdl_data.bytes_read,
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)) ? GPX_PATH_NEW : GPX_PATH_APPEND))) {
GtkTreeIter iter;
gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX, 0, to, -1);
}
- MACRO_BANNER_SHOW_INFO(_window, _("Route Downloaded"));
g_free(rdl_data.bytes);
route_set_destination_from_last(route, &_dest);
+ MACRO_BANNER_SHOW_INFO(_window, _("Route Downloaded"));
+
/* Success! Get out of the while loop. */
r=TRUE;
break;
return r;
}
-/**
- * Show the distance from the current GPS location to the given point,
- * following the route. If point is NULL, then the distance is shown to the
- * next waypoint.
- */
-gboolean
-route_show_distance_to(Path *route, Point *point)
-{
-gchar buffer[80];
-gdouble lat, lon;
-gdouble sum;
-
-g_return_val_if_fail(route, FALSE);
-g_return_val_if_fail(point, FALSE);
-
-unit2latlon(point->unitx, point->unity, &lat, &lon);
-sum=path_get_distance_to(route, point, lat, lon);
-g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"), sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
-MACRO_BANNER_SHOW_INFO(_window, buffer);
-
-return TRUE;
-}
-
-void
-route_show_distance_to_next_waypoint(Path *route)
-{
-g_return_if_fail(route);
-
-if (!route_show_distance_to(route, NULL))
- MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
-}
-
-void
-route_show_distance_to_last(Path *route)
-{
-g_return_if_fail(route);
-
-if (route->head != route->tail) {
- route_show_distance_to(route, path_find_last_point(route));
-} else {
- MACRO_BANNER_SHOW_INFO(_window, _("The current route is empty."));
-}
-}
-
-gboolean
-track_open(Path *track)
-{
-gchar *buffer;
-gint size;
-gboolean r = FALSE;
-
-if (file_open_get_contents(&_track_file_uri, &buffer, &size)) {
- if (path_gpx_parse(track, buffer, size, GPX_PATH_NEW)) {
- MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
- r = TRUE;
- } else {
- popup_error(_window, _("Error parsing GPX file."));
- }
- g_free(buffer);
-}
-return r;
-}
-
-gboolean
-track_save(Path *track)
-{
-GnomeVFSHandle *handle;
-gboolean r = FALSE;
-
-if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
- if (path_gpx_write(track, handle)) {
- MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
- r = TRUE;
- path_clear_ask(track);
- } else {
- popup_error(_window, _("Error writing GPX file."));
- }
- gnome_vfs_close(handle);
-}
-return r;
-}
-
/**
* Ask for a text description for the current point
*