#include <config.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <sqlite3.h>
+
#include "utils.h"
#include "gps.h"
#include "map.h"
#include "settings.h"
#include "mapper-types.h"
#include "ui-common.h"
+#include "dialogs.h"
#include "file.h"
-
#include "track.h"
+#include "latlon.h"
+#include "path.h"
+#include "gpx.h"
-void path_resize(Path * path, guint size)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- if (path->head + size != path->cap) {
- Point *old_head = path->head;
- WayPoint *curr;
- path->head = g_renew(Point, old_head, size);
- path->cap = path->head + size;
- if (path->head != old_head) {
- path->tail = path->head + (path->tail - old_head);
-
- /* Adjust all of the waypoints. */
- for (curr = path->whead - 1; curr++ != path->wtail;)
- curr->point =
- path->head + (curr->point - old_head);
- }
- }
-
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+/* Add sensitivity */
+static gint sensitivity=3;
-void path_wresize(Path * path, guint wsize)
+void
+track_clear(Path *track)
{
- printf("%s()\n", __PRETTY_FUNCTION__);
+GtkWidget *confirm;
- if (path->whead + wsize != path->wcap) {
- WayPoint *old_whead = path->whead;
- path->whead = g_renew(WayPoint, old_whead, wsize);
- path->wtail = path->whead + (path->wtail - old_whead);
- path->wcap = path->whead + wsize;
- }
+confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Clear the track?"));
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
+ path_clear(track);
+ map_force_redraw();
}
-
-void track_clear()
-{
- GtkWidget *confirm;
-
- confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
- _("Really clear the track?"));
-
- if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
- _track.tail = _track.head;
- map_force_redraw();
- }
-
- gtk_widget_destroy(confirm);
+gtk_widget_destroy(confirm);
}
-gfloat track_calculate_distance_from(Point * point)
+gdouble
+track_calculate_distance_from(Point *point)
{
- gfloat lat1, lon1, lat2, lon2;
- gfloat sum = 0.0;
- Point *curr;
- unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
-
- /* Skip _track.tail because that should be _pos. */
- for (curr = _track.tail; curr > point; --curr) {
- if (curr->unity) {
- unit2latlon(curr->unitx, curr->unity, lat2, lon2);
- g_printf("B:[%f %f %f %f (%f)]\n", lat1, lon1, lat2,
- lon2, sum);
- sum += calculate_distance(lat1, lon1, lat2, lon2);
- lat1 = lat2;
- lon1 = lon2;
- }
+Point *curr;
+gdouble lat1, lon1, lat2, lon2;
+gdouble sum = 0.0;
+
+unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
+
+/* Skip _track->tail because that should be _gps. */
+for (curr = _track->tail; curr > point; --curr) {
+ if (curr->unity) {
+ unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+ sum += calculate_distance(lat1, lon1, lat2, lon2);
+ lat1 = lat2;
+ lon1 = lon2;
}
- return sum;
+}
+return sum;
}
-void track_show_distance_from(Point * point)
+void
+track_show_distance_from(Point *point)
{
- gchar buffer[80];
- gfloat sum;
-
- sum = track_calculate_distance_from(point);
+gchar buffer[80];
+gdouble sum;
- snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
- sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
- MACRO_BANNER_SHOW_INFO(_window, buffer);
+sum = track_calculate_distance_from(point);
+g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"), sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
+MACRO_BANNER_SHOW_INFO(_window, buffer);
}
-void track_show_distance_from_last()
+void
+track_show_distance_from_last()
{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
+/* Find last zero point. */
+if (_track->head != _track->tail) {
+ Point *point;
/* 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."));
+ for (point = _track->tail; point->unity; point--) {
}
- printf("%s(): return\n", __PRETTY_FUNCTION__);
+ track_show_distance_from(point);
+} else {
+ MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
+}
}
-void track_show_distance_from_first()
+void
+track_show_distance_from_first()
{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- /* Find last zero point. */
- if (_track.head != _track.tail) {
- track_show_distance_from(_track.head);
- } else {
- MACRO_BANNER_SHOW_INFO(_window,
- _("The current track is empty."));
- }
- printf("%s(): return\n", __PRETTY_FUNCTION__);
+if (_track->head != _track->tail) {
+ track_show_distance_from(_track->head);
+} else {
+ MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
+}
}
/**
- * Add a point to the _track list. This function is slightly overloaded,
- * since it is what houses the check for "have we moved
- * significantly": it also initiates the re-calculation of the _near_point
- * data, as well as calling osso_display_state_on() when we have the focus.
+ * Add a point to the _track list.
*
- * If a non-zero time is given, then the current position (as taken from the
- * _pos variable) is appended to _track with the given time. If time is zero,
- * then _point_null is appended to _track with time zero (this produces a "break"
- * in the track).
+ * If a non-null gps is given, then the current position is appended
+ * to _track with the given time. If gps is null, then _point_null is
+ * appended to _track with time zero (this produces a "break" in the track).
*/
-void track_add(time_t time, gboolean newly_fixed)
+gboolean
+track_add(Path *track, GpsData *gps)
{
- gboolean show_directions = TRUE;
- gint announce_thres_unsquared;
- printf("%s(%u, %u)\n", __PRETTY_FUNCTION__, _pos.unitx, _pos.unity);
-
- if (abs((gint) _pos.unitx - _track.tail->unitx) > _draw_width
- || abs((gint) _pos.unity - _track.tail->unity) > _draw_width) {
- /* If time != 0, update the nearest-waypoint data. */
- if (time && _route.head != _route.tail
- && (newly_fixed ? (route_find_nearest_point(), TRUE)
- : route_update_nears(TRUE))) {
- /* Nearest waypoint has changed - re-render paths. */
- map_render_paths();
- MACRO_QUEUE_DRAW_AREA();
- }
- if (_show_tracks & TRACKS_MASK) {
- /* Instead of calling map_render_paths(), we'll draw the new line
- * ourselves and call gtk_widget_queue_draw_area(). */
- gint tx1, ty1, tx2, ty2;
- map_render_segment(_gc[COLORABLE_TRACK],
- _gc[COLORABLE_TRACK_BREAK],
- _track.tail->unitx,
- _track.tail->unity, _pos.unitx,
- _pos.unity);
- if (time && _track.tail->unity) {
- tx1 = unit2x(_track.tail->unitx);
- ty1 = unit2y(_track.tail->unity);
- tx2 = unit2x(_pos.unitx);
- ty2 = unit2y(_pos.unity);
- gtk_widget_queue_draw_area(_map_widget,
- MIN(tx1,
- tx2) -
- _draw_width, MIN(ty1,
- ty2)
- - _draw_width,
- abs(tx1 - tx2) +
- (2 * _draw_width),
- abs(ty1 - ty2) +
- (2 * _draw_width));
- }
- }
- MACRO_PATH_INCREMENT_TAIL(_track);
+if (!gps) {
+ MACRO_PATH_INCREMENT_TAIL(*track);
+ *track->tail=_point_null;
+ return FALSE;
+}
- if (time)
- *_track.tail = _pos;
- else
- *_track.tail = _point_null;
-
- if (_autoroute_data.enabled && !_autoroute_data.in_progress
- && _near_point_dist_squared > 400) {
- MACRO_BANNER_SHOW_INFO(_window,
- _
- ("Recalculating directions..."));
- _autoroute_data.in_progress = TRUE;
- show_directions = FALSE;
- g_idle_add((GSourceFunc) auto_route_dl_idle, NULL);
- }
+if (abs((gint)gps->unitx-track->tail->unitx) > sensitivity || abs((gint)gps->unity-track->tail->unity) > sensitivity) {
- /* Keep the display on. */
- KEEP_DISPLAY_ON();
+ /* If gps is available, update the nearest-waypoint data. */
+ /* XXX: MOVE THIS */
+ if (gps && _route->head != _route->tail && (gps->newly_fixed ? (route_find_nearest_point(_route), TRUE) : route_update_nears(_route, TRUE))) {
+ /* Nearest waypoint has changed - re-render paths. */
+ map_render_paths();
+ MACRO_QUEUE_DRAW_AREA();
}
- announce_thres_unsquared = (20 + (guint) _gps.speed)
- * _announce_notice_ratio * 3;
- /* Check if we should announce upcoming waypoints. */
- if (show_directions && time && _next_way_dist_squared
- < (announce_thres_unsquared * announce_thres_unsquared)) {
- if (_enable_voice
- && strcmp(_next_way->desc, _last_spoken_phrase)) {
- g_free(_last_spoken_phrase);
- _last_spoken_phrase = g_strdup(_next_way->desc);
- sound_speak(_last_spoken_phrase);
+ if (_show_tracks & TRACKS_MASK) {
+ gint tx1, ty1, tx2, ty2;
+
+ /* Instead of calling map_render_paths(), we'll draw the new line
+ * ourselves and call gtk_widget_queue_draw_area(). */
+ map_render_segment(_gc[COLORABLE_TRACK], _gc[COLORABLE_TRACK_BREAK],
+ track->tail->unitx, track->tail->unity, gps->unitx, gps->unity);
+
+ if (track->tail->unity && track->tail->unitx) {
+ tx1 = unit2x(track->tail->unitx);
+ ty1 = unit2y(track->tail->unity);
+ tx2 = unit2x(gps->unitx);
+ ty2 = unit2y(gps->unity);
+
+ /* XXX: This should not be here... */
+ gtk_widget_queue_draw_area(_map_widget,
+ MIN(tx1, tx2) - _draw_width,
+ MIN(ty1, ty2) - _draw_width,
+ abs(tx1 - tx2) + (2 * _draw_width),
+ abs(ty1 - ty2) + (2 * _draw_width));
}
- MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
}
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ if (track->tail->unity && track->tail->unitx) {
+ gdouble lat, lon;
-void track_insert_break(void)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- if (_track.tail->unity) {
- guint x1, y1;
-
- /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
- * another instance of the most recent track point. */
- MACRO_PATH_INCREMENT_TAIL(_track);
- *_track.tail = _point_null;
- MACRO_PATH_INCREMENT_TAIL(_track);
- *_track.tail = _track.tail[-2];
-
- /** Instead of calling map_render_paths(), we'll just add the waypoint
- * ourselves. */
- x1 = unit2bufx(_track.tail->unitx);
- y1 = unit2bufy(_track.tail->unity);
- /* Make sure this circle will be visible. */
- if ((x1 < BUF_WIDTH_PIXELS)
- && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
- gdk_draw_arc(_map_pixmap, _gc[COLORABLE_TRACK_BREAK], FALSE, /* FALSE: not filled. */
- x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
- 360 * 64);
- } else {
- MACRO_BANNER_SHOW_INFO(_window, _("Break already inserted."));
+ unit2latlon(track->tail->unitx, track->tail->unity, lat, lon);
+ track->length += calculate_distance(lat, lon, gps->lat, gps->lon);
+ track->tspeed+=gps->speed;
+ if (track->points>0)
+ track->avgspeed=track->tspeed/track->points;
+ else
+ track->avgspeed=0.0;
+ g_debug("TRACK: %f %f (%d)", track->length, track->avgspeed, track->points);
}
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ MACRO_PATH_INCREMENT_TAIL(*track);
+ track->tail->unitx=gps->unitx;
+ track->tail->unity=gps->unity;
+ track->tail->time=gps->time;
+ track->tail->altitude=gps->altitude;
+ track->maxspeed=gps->maxspeed;
+ track->points++;
}
-gboolean track_open(void)
+return TRUE;
+}
+
+gboolean
+track_open(Path *track)
{
- gchar *buffer;
- gint size;
- gboolean r = FALSE;
-
- if (open_file(&buffer, NULL, &size, NULL, &_track_file_uri, GTK_FILE_CHOOSER_ACTION_OPEN)) {
- if (parse_gpx(&_track, buffer, size, -1)) {
- map_force_redraw();
- MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
- r = TRUE;
- } else
- popup_error(_window, _("Error parsing GPX file."));
-
- g_free(buffer);
+gchar *buffer;
+gint size;
+gboolean r = FALSE;
+
+if (file_open_get_contents(&_track_file_uri, &buffer, &size)) {
+ if (gpx_parse(track, buffer, size, GPX_PATH_NEW)) {
+ map_force_redraw();
+ MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
+ r = TRUE;
+ } else {
+ popup_error(_window, _("Error parsing GPX file."));
}
- return r;
+ g_free(buffer);
+}
+return r;
}
-gboolean track_save(void)
+gboolean
+track_save(Path *track)
{
- GnomeVFSHandle *handle;
- gboolean r = FALSE;
-
-/* if (open_file(NULL, &handle, NULL, NULL, &_track_file_uri, GTK_FILE_CHOOSER_ACTION_SAVE)) { */
-
- if (file_save(_track_file_uri, _track_file_uri, &handle)) {
- if (write_gpx(&_track, handle)) {
- MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
- r = TRUE;
- } else
- popup_error(_window, _("Error writing GPX file."));
- gnome_vfs_close(handle);
+GnomeVFSHandle *handle;
+gboolean r = FALSE;
+
+if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
+ if (gpx_write(track, handle)) {
+ MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
+ r = TRUE;
+ track_clear(track);
+ } else {
+ popup_error(_window, _("Error writing GPX file."));
}
- return r;
+ gnome_vfs_close(handle);
+}
+return r;
}
-gboolean track_insert_mark(void)
+/**
+ * Ask for a text description for the current point
+ *
+ */
+gboolean
+track_insert_mark(Path *track)
{
- gfloat lat, lon;
- gchar tmp1[16], tmp2[16], *p_latlon;
- GtkWidget *dialog;
- GtkWidget *table;
- GtkWidget *label;
- GtkWidget *txt_scroll;
- GtkWidget *txt_desc;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
- GTK_WINDOW(_window),
- GTK_DIALOG_MODAL, GTK_STOCK_OK,
- GTK_RESPONSE_ACCEPT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_REJECT, NULL);
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
-
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Lat, Lon")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
- unit2latlon(_pos.unitx, _pos.unity, lat, lon);
- lat_format(lat, tmp1);
- lon_format(lon, tmp2);
- p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(p_latlon),
- 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- g_free(p_latlon);
-
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Description")),
- 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
- txt_scroll = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
- GTK_SHADOW_IN);
- gtk_table_attach(GTK_TABLE(table),
- txt_scroll,
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- txt_desc = gtk_text_view_new();
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
-
- gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
- gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
-
- gtk_widget_show_all(dialog);
-
- while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
- GtkTextBuffer *tbuf;
- GtkTextIter ti1, ti2;
- gchar *desc;
-
- tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
- gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
- gtk_text_buffer_get_end_iter(tbuf, &ti2);
- desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
-
- if (*desc) {
- MACRO_PATH_INCREMENT_WTAIL(_track);
- _track.wtail->point = _track.tail;
- _track.wtail->desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
- } else {
- popup_error(dialog, _("Please provide a description for the mark."));
- g_free(desc);
- continue;
- }
-
- map_render_paths();
- MACRO_QUEUE_DRAW_AREA();
- break;
+gdouble lat, lon;
+gchar tmp1[16], tmp2[16], *p_latlon;
+GtkWidget *dialog;
+GtkWidget *table;
+GtkWidget *label;
+GtkWidget *txt_scroll;
+GtkWidget *txt_desc;
+gboolean ret;
+
+dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
+ GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+
+gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
+
+gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Lat, Lon")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+unit2latlon(_gps->data.unitx, _gps->data.unity, lat, lon);
+lat_format(_degformat, lat, tmp1);
+lon_format(_degformat, lon, tmp2);
+p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
+gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(p_latlon), 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+g_free(p_latlon);
+
+gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Description")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+txt_scroll = gtk_scrolled_window_new(NULL, NULL);
+gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll), GTK_SHADOW_IN);
+gtk_table_attach(GTK_TABLE(table), txt_scroll, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+txt_desc = gtk_text_view_new();
+gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
+
+gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
+gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 450, 100);
+
+gtk_widget_show_all(dialog);
+
+ret=FALSE;
+while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
+ GtkTextBuffer *tbuf;
+ GtkTextIter ti1, ti2;
+
+ tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
+ gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
+ gtk_text_buffer_get_end_iter(tbuf, &ti2);
+
+ if (gtk_text_buffer_get_char_count(tbuf)>0) {
+ path_insert_mark_text(track, gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE));
+ } else {
+ popup_error(dialog, _("Please provide a description for the mark."));
+ continue;
}
- gtk_widget_destroy(dialog);
+
+ ret=TRUE;
+ break;
+}
+gtk_widget_destroy(dialog);
+return ret;
}