- Convert more track/route specific functions to generic path functions.
- Prepare for multiple tracks/routes, don't use global track/route variables in track/route functions.
- Adjust common code for above changes
- Still much todo...
if (!store)
return FALSE;
-gtk_tree_view_set_model(tree_view, store);
+gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), store);
g_object_unref(G_OBJECT(store));
return TRUE;
}
gboolean
menu_cb_route_download(GtkAction * action)
{
-route_download(NULL);
+route_download(_route, NULL);
route_menu_set_sensitive(path_tree_view_update_store(route_tree_view, _route));
return TRUE;
}
gboolean
menu_cb_route_open(GtkAction *action)
{
-route_open_file();
+route_open_file(_route);
route_menu_set_sensitive(path_tree_view_update_store(route_tree_view, _route));
return TRUE;
}
gboolean
menu_cb_route_save(GtkAction * action)
{
-route_save();
+route_save(_route);
return TRUE;
}
gboolean
menu_cb_route_distnext(GtkAction * action)
{
-route_show_distance_to_next();
+route_show_distance_to_next(_route);
return TRUE;
}
gboolean
menu_cb_route_distlast(GtkAction * action)
{
-route_show_distance_to_last();
+route_show_distance_to_last(_route);
return TRUE;
}
gboolean
menu_cb_route_reset(GtkAction * action)
{
-route_find_nearest_point();
+route_find_nearest_point(_route);
map_render_data();
MACRO_QUEUE_DRAW_AREA();
return TRUE;
gboolean
menu_cb_route_clear(GtkAction * action)
{
-route_clear();
-gtk_tree_view_set_model(route_tree_view, NULL);
-route_menu_set_sensitive(FALSE);
+if (route_clear(_route)) {
+ gtk_tree_view_set_model(route_tree_view, NULL);
+ route_menu_set_sensitive(FALSE);
+}
return TRUE;
}
gboolean
menu_cb_track_open(GtkAction * action)
{
-track_open();
+track_open(_track);
path_tree_view_update_store(track_tree_view, _track);
return TRUE;
}
gboolean
menu_cb_track_save(GtkAction * action)
{
-track_save();
+track_save(_track);
path_tree_view_update_store(track_tree_view, _track);
return TRUE;
}
gboolean
menu_cb_track_insert_break(GtkAction * action)
{
-track_insert_break();
+path_insert_break(_track);
path_tree_view_update_store(track_tree_view, _track);
return TRUE;
}
gboolean
menu_cb_track_insert_mark(GtkAction * action)
{
-if (track_insert_mark()) {
+if (track_insert_mark(_track)) {
map_render_paths();
MACRO_QUEUE_DRAW_AREA();
path_tree_view_update_store(track_tree_view, _track);
gboolean
menu_cb_track_distlast(GtkAction * action)
{
-track_show_distance_from_last();
+track_show_distance_from_last(_track);
return TRUE;
}
gboolean
menu_cb_track_distfirst(GtkAction * action)
{
-track_show_distance_from_first();
+track_show_distance_from_first(_track);
return TRUE;
}
gboolean
menu_cb_track_clear(GtkAction * action)
{
-track_clear();
+track_clear(_track);
path_tree_view_update_store(track_tree_view, _track);
return TRUE;
}
if (_gps->io.conn > RCVR_OFF)
gps_conn_set_state(_gps, RCVR_OFF);
gps_disconnect(_gps);
- track_add(NULL);
+ track_add(_track, NULL);
_speed_excess=FALSE;
}
if (_enable_gps==FALSE)
}
break;
case CUSTOM_ACTION_ROUTE_DISTNEXT:
- route_show_distance_to_next();
+ route_show_distance_to_next(_route);
break;
case CUSTOM_ACTION_ROUTE_DISTLAST:
- route_show_distance_to_last();
+ route_show_distance_to_last(_route);
break;
case CUSTOM_ACTION_TRACK_BREAK:
- track_insert_break();
+ path_insert_break(_track);
break;
case CUSTOM_ACTION_TRACK_DISTLAST:
- track_show_distance_from_last();
+ track_show_distance_from_last(_track);
break;
case CUSTOM_ACTION_TRACK_DISTFIRST:
- track_show_distance_from_first();
+ track_show_distance_from_first(_track);
break;
case CUSTOM_ACTION_TOGGLE_GPS:
set_action_activate("gps_enable", !_enable_gps);
g_ascii_formatd(strlon, 32, "%.06f", lon);
g_snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
-route_download(buffer);
+route_download(_route, buffer);
}
void
MACRO_PATH_INCREMENT_TAIL(*_route);
_route->tail->unitx = x2unit(_cmenu_position_x);
_route->tail->unity = y2unit(_cmenu_position_y);
-route_find_nearest_point();
+route_find_nearest_point(_route);
map_force_redraw();
}
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(unitx, 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), 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) {
- /* There's a description. Add a waypoint. */
- MACRO_PATH_INCREMENT_TAIL(*_route);
- _route->tail->unitx = unitx;
- _route->tail->unity = unity;
- _route->tail->time = 0;
- _route->tail->altitude = NAN;
+gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
- MACRO_PATH_INCREMENT_WTAIL(*_route);
- _route->wtail->point = _route->tail;
- _route->wtail->desc
- = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
- } else {
- GtkWidget *confirm;
+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);
- g_free(desc);
+unit2latlon(unitx, 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);
- confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog),
- _("Creating a \"waypoint\" with no description actually "
- "adds a break point. Is that what you want?"));
+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);
- if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
- /* There's no description. Add a break by adding a (0, 0)
- * point (if necessary), and then the ordinary route point. */
- if (_route->tail->unity) {
- MACRO_PATH_INCREMENT_TAIL(*_route);
- *_route->tail = _point_null;
- }
+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);
- MACRO_PATH_INCREMENT_TAIL(*_route);
- _route->tail->unitx = unitx;
- _route->tail->unity = unity;
- _route->tail->time = 0;
- _route->tail->altitude = NAN;
+gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_widget_destroy(confirm);
- } else {
- gtk_widget_destroy(confirm);
- continue;
+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) {
+ /* There's a description. Add a waypoint. */
+ MACRO_PATH_INCREMENT_TAIL(*_route);
+ _route->tail->unitx = unitx;
+ _route->tail->unity = unity;
+ _route->tail->time = 0;
+ _route->tail->altitude = NAN;
+
+ MACRO_PATH_INCREMENT_WTAIL(*_route);
+ _route->wtail->point = _route->tail;
+ _route->wtail->desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
+ } else {
+ GtkWidget *confirm;
+
+ g_free(desc);
+
+ confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog),
+ _("Creating a \"waypoint\" with no description actually "
+ "adds a break point. Is that what you want?"));
+
+ if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
+ /* There's no description. Add a break by adding a (0, 0)
+ * point (if necessary), and then the ordinary route point. */
+ if (_route->tail->unity) {
+ MACRO_PATH_INCREMENT_TAIL(*_route);
+ *_route->tail = _point_null;
}
- }
- route_find_nearest_point();
- map_render_paths();
- MACRO_QUEUE_DRAW_AREA();
- break;
+ MACRO_PATH_INCREMENT_TAIL(*_route);
+ _route->tail->unitx = unitx;
+ _route->tail->unity = unity;
+ _route->tail->time = 0;
+ _route->tail->altitude = NAN;
+
+ gtk_widget_destroy(confirm);
+ } else {
+ gtk_widget_destroy(confirm);
+ continue;
+ }
}
+
+ route_find_nearest_point(_route);
+ map_render_paths();
+ MACRO_QUEUE_DRAW_AREA();
+ break;
+}
gtk_widget_destroy(dialog);
}
/* Move mark to new location. */
_gps->data.time=time(NULL);
-track_add(&_gps->data);
+track_add(_track, &_gps->data);
map_refresh_mark();
return TRUE;
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
cmenu_show_latlon(way->point->unitx, way->point->unity);
return TRUE;
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
MACRO_BANNER_SHOW_INFO(_window, way->desc);
}
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
cmenu_clip_latlon(way->point->unitx, way->point->unity);
return TRUE;
}
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), way->desc, -1);
return TRUE;
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
cmenu_route_to(way->point->unitx, way->point->unity);
return TRUE;
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
- route_show_distance_to(way->point);
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
+ route_show_distance_to(_route, way->point);
return TRUE;
}
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
gchar buffer[BUFFER_SIZE];
GtkWidget *confirm;
}
_route->wtail--;
- route_find_nearest_point();
+ route_find_nearest_point(_route);
map_force_redraw();
}
gtk_widget_destroy(confirm);
{
WayPoint *way;
-if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
+if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) {
poi_info *p;
p=poi_new();
unit2latlon(way->point->unitx, way->point->unity, p->lat, p->lon);
poi_edit_dialog(ACTION_ADD_POI, p);
+ /* XXX: free it ? */
}
return TRUE;
}
/* Now, parse the autoroute and update the display. */
if (_autoroute_data.enabled && gpx_parse(&_route, _autoroute_data.rdl_data.bytes, _autoroute_data.rdl_data.bytes_read, 0)) {
/* Find the nearest route point, if we're connected. */
- route_find_nearest_point();
+ route_find_nearest_point(_route);
map_force_redraw();
}
- route_cancel_autoroute(TRUE); /* We're done. Clean up. */
+ route_cancel_autoroute(_route, TRUE); /* We're done. Clean up. */
} else {
ProgressUpdateInfo *pui = g_hash_table_lookup(pui_by_easy, msg->easy_handle);
g_queue_push_head(curl_easy_queue, msg->easy_handle);
_gps->data.speed=20.f;
gps_data_integerize(&_gps->data);
_gps->data.time=time(NULL);
-track_add(&_gps->data);
+track_add(_track, &_gps->data);
map_refresh_mark();
}
#include "map.h"
#include "track.h"
#include "route.h"
+#include "gps.h"
#include "settings.h"
#include "latlon.h"
#include "gpx.h"
+struct sql_select_stmt {
+ sqlite3_stmt *select_path;
+ sqlite3_stmt *select_path_nodes;
+ sqlite3_stmt *insert_path;
+ sqlite3_stmt *insert_path_node;
+ sqlite3_stmt *delete_path_nodes;
+ sqlite3_stmt *delete_path;
+};
+static struct sql_select_stmt sql;
+
+
+/* Path point add sensitivity */
+static gint sensitivity=3;
+
Path *
path_new(void)
{
g_slice_free(Path, p);
}
-void
+void
+path_clear(Path *p)
+{
+g_return_if_fail(p);
+MACRO_PATH_FREE(*p);
+p->length=p->avgspeed=0.0;
+p->points=0;
+}
+
+gboolean
path_resize(Path *path, guint size)
{
if (path->head + size != path->cap) {
for (curr = path->whead - 1; curr++ != path->wtail;)
curr->point = path->head + (curr->point - old_head);
}
+ return TRUE;
}
+return FALSE;
}
-void
+gboolean
path_wresize(Path *path, guint wsize)
{
if (path->whead + wsize != path->wcap) {
path->whead = g_renew(WayPoint, old_whead, wsize);
path->wtail = path->whead + (path->wtail - old_whead);
path->wcap = path->whead + wsize;
+ return TRUE;
+}
+return FALSE;
+}
+
+gboolean
+path_add_point(Path *path, GpsData *gps)
+{
+if (!gps) {
+ MACRO_PATH_INCREMENT_TAIL(*path);
+ *path->tail=_point_null;
+ return FALSE;
+}
+
+if (abs((gint)gps->unitx-path->tail->unitx) > sensitivity || abs((gint)gps->unity-path->tail->unity) > sensitivity) {
+ if (path->tail->unity && path->tail->unitx) {
+ gdouble lat, lon;
+
+ unit2latlon(path->tail->unitx, path->tail->unity, lat, lon);
+ path->length+=calculate_distance(lat, lon, gps->lat, gps->lon);
+ }
+ MACRO_PATH_INCREMENT_TAIL(*path);
+ path->tail->unitx=gps->unitx;
+ path->tail->unity=gps->unity;
+ path->tail->time=gps->time;
+ path->tail->altitude=gps->altitude;
+ path->maxspeed=gps->maxspeed;
+ path->tspeed+=gps->speed;
+ path->avgspeed=(path->points>0) ? path->tspeed/path->points : 0.0;
+ path->points++;
+ g_debug("TRACK: %f %f (%d)", path->length, path->avgspeed, path->points);
}
+
+return TRUE;
}
gboolean
y1 = unit2bufy(path->tail->unity);
map_render_waypoint(x1, y1, _gc[COLORABLE_TRACK_BREAK]);
#endif
+ return TRUE;
}
return FALSE;
}
+Point *
+path_find_last_point(Path *path)
+{
+Point *p=NULL;
+
+if (path->head == path->tail)
+ return p;
+
+for (p=path->tail; !p->unity; p--) {
+}
+return p;
+}
+
+gdouble
+path_get_distance_to(Path *path, Point *point, gdouble lat, gdouble lon)
+{
+gdouble lat1, lon1, lat2, lon2;
+gdouble sum=0.0;
+
+/* If point is NULL, use the next waypoint. */
+if (point == NULL && path->next_way)
+ point = path->next_way->point;
+
+/* If point is still NULL, return an error. */
+if (point==NULL)
+ return FALSE;
+
+lat1=lat;
+lon1=lon;
+
+if (point > path->near_point) {
+ Point *curr;
+ /* Skip _near_point in case we have already passed it. */
+ for (curr = path->near_point + 1; curr <= point; ++curr) {
+ if (curr->unity) {
+ unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+ sum += calculate_distance(lat1, lon1, lat2, lon2);
+ lat1 = lat2;
+ lon1 = lon2;
+ }
+ }
+} else if (point < path->near_point) {
+ Point *curr;
+ /* Skip near_point in case we have already passed it. */
+ for (curr = path->near_point - 1; curr >= point; --curr) {
+ if (curr->unity) {
+ unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+ sum += calculate_distance(lat1, lon1, lat2, lon2);
+ lat1 = lat2;
+ lon1 = lon2;
+ }
+ }
+} else {
+ /* Waypoint _is_ the nearest point. */
+ unit2latlon(path->near_point->unitx, path->near_point->unity, lat2, lon2);
+ sum += calculate_distance(lat1, lon1, lat2, lon2);
+}
+return sum;
+}
+
gboolean
path_load(Path *path, const gchar *config_dir, const gchar *file)
{
{
g_assert(path);
MACRO_PATH_INCREMENT_WTAIL(*path);
-path->wtail->point = path->tail;
-path->wtail->desc = text;
+path->wtail->point=path->tail;
+if (text) {
+ path->wtail->desc=text;
+} else {
+ path->wpcnt++;
+ path->wtail->desc=g_strdup_printf("WP: %u", path->wpcnt);
+}
}
GtkListStore *
position_set(Position *pos, gboolean valid, gdouble lat, gdouble lon)
{
pos->valid=valid;
-if (valid) {
- pos->lat=lat;
- pos->lon=lon;
-} else {
- pos->lat=NAN;
- pos->lon=NAN;
-}
+pos->lat=valid ? lat : NAN;
+pos->lon=valid ? lon : NAN;
}
void
position_update(Position *pos, GpsData *data)
{
-
+if (!pos->valid)
+ return;
}
#include <glib.h>
#include <gtk/gtk.h>
-#define MACRO_PATH_INIT(path) { \
- (path).head = (path).tail = g_new0(Point, ARRAY_CHUNK_SIZE); \
- *((path).tail) = _point_null; \
- (path).cap = (path).head + ARRAY_CHUNK_SIZE; \
- (path).whead = g_new0(WayPoint, ARRAY_CHUNK_SIZE); \
- (path).wtail = (path).whead - 1; \
- (path).wcap = (path).whead + ARRAY_CHUNK_SIZE; \
-}
-
-#define MACRO_PATH_FREE(path) if((path).head) { \
- WayPoint *curr; \
- g_free((path).head); \
- (path).head = (path).tail = (path).cap = NULL; \
- for(curr = (path).whead - 1; curr++ != (path).wtail; ) \
- g_free(curr->desc); \
- g_free((path).whead); \
- (path).whead = (path).wtail = (path).wcap = NULL; \
-}
-
-#define MACRO_PATH_INCREMENT_TAIL(route) { \
- if(++(route).tail == (route).cap) \
- path_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE);\
-}
-
-#define MACRO_PATH_INCREMENT_WTAIL(route) { \
- if(++(route).wtail == (route).wcap) \
- path_wresize(&(route), (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
-}
-
/** A lat/lon/alt position */
typedef struct _Position Position;
struct _Position {
- gchar *desc;
+ gchar *name;
gboolean valid;
gdouble lat;
gdouble lon;
gfloat altitude;
gfloat angle; /* Course from current position to this one */
time_t time;
- guint type; /* Type of position */
+ guint type; /* Type of position (Home, Destination, Waypoint, etc) */
};
/** A general definition of a point in the Mapper unit system. */
WayPoint *wtail; /* points to last element in array. */
WayPoint *wcap; /* points after last slot in array. */
+ /* Internal waypoint data */
+ Point *near_point;
+ guint64 near_point_dist_squared;
+
+ /* next_way is what we currently interpret to be the next waypoint. */
+ WayPoint *next_way;
+ guint64 next_way_dist_squared;
+
+ /* next_wpt is the route point immediately following next_way. */
+ Point *next_wpt;
+ guint64 next_wpt_dist_squared;
+
/* Path statistics */
- guint32 points;
+ guint32 points;
+ guint32 wpcnt; /* Auto waypoint number counter */
gdouble length;
gdouble tspeed;
gdouble avgspeed;
gchar *desc;
gchar *author;
gchar *keywords;
- time_t time;
gchar *copyright;
gchar *src;
+ time_t time;
};
/* Null point */
Path *path_new(void);
void path_free(Path *p);
+void path_clear(Path *p);
-void path_insert_mark_text(Path *path, gchar *text);
+Point *path_find_last_point(Path *path);
+
+gboolean path_resize(Path *path, guint size);
+gboolean path_wresize(Path *path, guint wsize);
-void path_resize(Path *path, guint size);
-void path_wresize(Path *path, guint wsize);
+gdouble path_get_distance_to(Path *path, Point *point, gdouble lat, gdouble lon);
+
+gboolean path_insert_break(Path *path);
+void path_insert_mark_text(Path *path, gchar *text);
+void path_insert_mark_autonumber(Path *path);
+void path_insert_mark_audio(Path *path, gchar *audio);
GtkListStore *path_generate_store(Path *path);
+#define MACRO_PATH_INIT(path) { \
+ (path).head = (path).tail = g_new0(Point, ARRAY_CHUNK_SIZE); \
+ *((path).tail) = _point_null; \
+ (path).cap = (path).head + ARRAY_CHUNK_SIZE; \
+ (path).whead = g_new0(WayPoint, ARRAY_CHUNK_SIZE); \
+ (path).wtail = (path).whead - 1; \
+ (path).wcap = (path).whead + ARRAY_CHUNK_SIZE; \
+}
+
+#define MACRO_PATH_FREE(path) if((path).head) { \
+ WayPoint *curr; \
+ g_free((path).head); \
+ (path).head = (path).tail = (path).cap = NULL; \
+ for(curr = (path).whead - 1; curr++ != (path).wtail; ) \
+ g_free(curr->desc); \
+ g_free((path).whead); \
+ (path).whead = (path).wtail = (path).wcap = NULL; \
+}
+
+#define MACRO_PATH_INCREMENT_TAIL(route) { \
+ if(++(route).tail == (route).cap) \
+ path_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE);\
+}
+
+#define MACRO_PATH_INCREMENT_WTAIL(route) { \
+ if(++(route).wtail == (route).wcap) \
+ path_wresize(&(route), (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
+}
+
#endif
GtkWidget *chk_auto;
GtkWidget *txt_from;
GtkWidget *txt_to;
+ Path *path;
};
-void route_find_nearest_point(void);
-void route_cancel_autoroute(gboolean temporary);
-void route_show_distance_to_last(void);
-void route_set_destination_from_last(void);
-
-void
-route_clear(void)
+gboolean
+route_clear(Path *route)
{
GtkWidget *confirm;
+gboolean r=FALSE;
-confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Really clear the route?"));
+confirm=hildon_note_new_confirmation(GTK_WINDOW(_window), _("Really clear the route?"));
if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
- route_cancel_autoroute(FALSE);
+ route_cancel_autoroute(route, FALSE);
announced_waypoint=NULL;
- path_free(_route);
- _route=path_new();
- route_find_nearest_point();
- map_force_redraw();
+ path_clear(route);
+ route_find_nearest_point(route);
+ r=TRUE;
}
gtk_widget_destroy(confirm);
+return r;
}
/**
* Check if we should announce upcoming waypoints.
*/
void
-route_check_waypoint_announce(GpsData *gps)
+route_check_waypoint_announce(Path *route, GpsData *gps)
{
guint announce_thres_unsquared;
* Check if we should re-calculate route
*/
void
-route_autoroute_check(void)
+route_autoroute_check(Path *route)
{
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);
+ g_idle_add((GSourceFunc)route_auto_route_dl_idle_cb, NULL);
}
}
gboolean
-route_open_file(void)
+route_open_file(Path *route)
{
gchar *buffer;
gint size;
if (file_open_get_contents(&_route_dir_uri, &buffer, &size)) {
/* If auto is enabled, append the route, otherwise replace it. */
- if (gpx_parse(_route, buffer, size, _autoroute_data.enabled ? GPX_PATH_APPEND : GPX_PATH_NEW)) {
- route_cancel_autoroute(FALSE);
+ if (gpx_parse(route, buffer, size, _autoroute_data.enabled ? GPX_PATH_APPEND : GPX_PATH_NEW)) {
+ route_cancel_autoroute(route, FALSE);
MACRO_BANNER_SHOW_INFO(_window, _("Route Opened"));
/* Find the nearest route point, if we're connected. */
- route_find_nearest_point();
- map_force_redraw();
- route_set_destination_from_last();
+ route_find_nearest_point(route);
+ route_set_destination_from_last(route);
return TRUE;
} else {
popup_error(_window, _("Error parsing GPX file."));
* Ask user to save route
*/
gboolean
-route_save(void)
+route_save(Path *route)
{
GnomeVFSHandle *handle;
-if (_route->head==_route->tail) {
+if (route->head==route->tail) {
MACRO_BANNER_SHOW_INFO(_window, _("No route exist."));
return FALSE;
}
if (file_save(&_route_dir_uri, &_route_dir_uri, &handle)) {
- if (gpx_write(_route, handle)) {
+ if (gpx_write(route, handle)) {
MACRO_BANNER_SHOW_INFO(_window, _("Route Saved"));
} else {
popup_error(_window, _("Error writing GPX file."));
*
*/
static gboolean
-origin_type_selected_cb(GtkWidget * toggle, OriginToggleInfo * oti)
+route_origin_type_selected_cb(GtkWidget *toggle, OriginToggleInfo *oti)
{
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];
- Point *p;
gdouble lat, lon;
+ Point *p;
- /* Use last non-zero route point. */
- for (p = _route->tail; !p->unity; p--) {
+ p=path_find_last_point(oti->path);
+ if (p) {
+ unit2latlon(p->unitx, p->unity, lat, lon);
+ g_ascii_formatd(strlat, 32, "%.06f", lat);
+ g_ascii_formatd(strlon, 32, "%.06f", lon);
+ g_snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+ gtk_entry_set_text(GTK_ENTRY(oti->txt_from), buffer);
}
-
- unit2latlon(p->unitx, p->unity, lat, lon);
- g_ascii_formatd(strlat, 32, "%.06f", lat);
- g_ascii_formatd(strlon, 32, "%.06f", lon);
- g_snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
- gtk_entry_set_text(GTK_ENTRY(oti->txt_from), buffer);
}
gtk_widget_set_sensitive(oti->txt_from, toggle == oti->rad_use_text);
gtk_widget_set_sensitive(oti->chk_auto, toggle == oti->rad_use_gps);
* Cancel the current auto-route.
*/
void
-route_cancel_autoroute(gboolean temporary)
+route_cancel_autoroute(Path *route, gboolean temporary)
{
if (_autoroute_data.enabled) {
if (!temporary) {
}
gboolean
-auto_route_dl_idle()
+route_auto_route_dl_idle_cb()
{
gchar latstr[32], lonstr[32], *latlonstr;
curl_multi_add_handle(_curl_multi, _autoroute_data.curl_easy);
if (iap_is_connected() && !_curl_sid)
- _curl_sid = g_timeout_add(100, (GSourceFunc) map_download_timeout, NULL);
+ _curl_sid = g_timeout_add(100, (GSourceFunc)map_download_timeout, NULL);
_autoroute_data.in_progress = TRUE;
* safe to free either string as soon as this function returns.
*/
gboolean
-route_download(gchar * to)
+route_download(Path *route, gchar *to)
{
GtkWidget *dialog;
GtkWidget *table;
OriginToggleInfo oti;
GtkEntryCompletion *from_comp;
GtkEntryCompletion *to_comp;
+gboolean r=FALSE;
-iap_connect();
+oti.path=route;
dialog = gtk_dialog_new_with_buttons(_("Download Route"),
GTK_WINDOW(_window),
GTK_RESPONSE_REJECT, NULL);
help_dialog_help_enable(GTK_DIALOG(dialog), HELP_ID_DOWNROUTE);
-
-gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- table = gtk_table_new(2, 5, FALSE), TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 5, FALSE), TRUE, TRUE, 0);
from_comp = gtk_entry_completion_new();
gtk_entry_completion_set_model(from_comp, GTK_TREE_MODEL(_loc_model));
gtk_entry_set_width_chars(GTK_ENTRY(txt_source_url), 25);
/* Auto. */
-gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 6),
- 0, 2, 1, 2, GTK_FILL, 0, 2, 4);
-gtk_box_pack_start(GTK_BOX(hbox),
- oti.rad_use_gps = gtk_radio_button_new_with_label(NULL, _("Use GPS Location")),
- TRUE, TRUE, 0);
-gtk_box_pack_start(GTK_BOX(hbox), oti.chk_auto =
- gtk_check_button_new_with_label(_("Auto-Update")),
- TRUE, TRUE, 0);
+gtk_table_attach(GTK_TABLE(table), hbox = gtk_hbox_new(FALSE, 6), 0, 2, 1, 2, GTK_FILL, 0, 2, 4);
+gtk_box_pack_start(GTK_BOX(hbox), oti.rad_use_gps = gtk_radio_button_new_with_label(NULL, _("Use GPS Location")), TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(hbox), oti.chk_auto = gtk_check_button_new_with_label(_("Auto-Update")), TRUE, TRUE, 0);
gtk_widget_set_sensitive(oti.chk_auto, FALSE);
/* Use End of Route. */
-gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 6),
- 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
-gtk_box_pack_start(GTK_BOX(hbox),
- oti.rad_use_route =
- gtk_radio_button_new_with_label_from_widget
- (GTK_RADIO_BUTTON(oti.rad_use_gps),
- _("Use End of Route")), TRUE, TRUE, 0);
-gtk_widget_set_sensitive(oti.rad_use_route, _route->head != _route->tail);
+gtk_table_attach(GTK_TABLE(table), hbox = gtk_hbox_new(FALSE, 6), 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
+gtk_box_pack_start(GTK_BOX(hbox), oti.rad_use_route = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")), TRUE, TRUE, 0);
+gtk_widget_set_sensitive(oti.rad_use_route, route->head != route->tail);
/* Origin. */
-gtk_table_attach(GTK_TABLE(table),
- oti.rad_use_text =
- gtk_radio_button_new_with_label_from_widget
- (GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")), 0, 1,
- 3, 4, GTK_FILL, 0, 2, 4);
-gtk_table_attach(GTK_TABLE(table), oti.txt_from =
- gtk_entry_new(), 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0,
- 2, 4);
+gtk_table_attach(GTK_TABLE(table), oti.rad_use_text = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")), 0, 1, 3, 4, GTK_FILL, 0, 2, 4);
+gtk_table_attach(GTK_TABLE(table), oti.txt_from = gtk_entry_new(), 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_completion(GTK_ENTRY(oti.txt_from), from_comp);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_from), 25);
/* Destination. */
-gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Destination")),
- 0, 1, 4, 5, GTK_FILL, 0, 2, 4);
+gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Destination")), 0, 1, 4, 5, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-gtk_table_attach(GTK_TABLE(table),
- oti.txt_to = gtk_entry_new(), 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+gtk_table_attach(GTK_TABLE(table), oti.txt_to = gtk_entry_new(), 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_completion(GTK_ENTRY(oti.txt_to), to_comp);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_to), 25);
-g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled", G_CALLBACK(origin_type_selected_cb), &oti);
-g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled", G_CALLBACK(origin_type_selected_cb), &oti);
-g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled", G_CALLBACK(origin_type_selected_cb), &oti);
+g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled", G_CALLBACK(route_origin_type_selected_cb), &oti);
+g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled", G_CALLBACK(route_origin_type_selected_cb), &oti);
+g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled", G_CALLBACK(route_origin_type_selected_cb), &oti);
#if defined (WITH_HILDON) && defined (HILDON_AUTOCAP)
g_object_set(G_OBJECT(oti.txt_from), HILDON_AUTOCAP, FALSE, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
-/* Use "End of Route" by default if they have a route. */
-if (_route->head != _route->tail) {
+if (route->head != route->tail) {
+ /* 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);
-}
-/* Else use "GPS Location" if they have GPS enabled. */
-else if (_enable_gps) {
+} else if (_enable_gps) {
+ /* Else use "GPS Location" if they have GPS enabled. */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
gtk_widget_grab_focus(oti.rad_use_gps);
-}
-/* Else use text. */
-else {
+} else {
+ /* Else use text. */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
gtk_widget_grab_focus(oti.txt_from);
}
g_free(from_escaped);
g_free(to_escaped);
+ iap_connect();
+
/* Attempt to download the route from the server. */
MACRO_CURL_EASY_INIT(curl_easy);
curl_easy_setopt(curl_easy, CURLOPT_URL, buffer);
/* 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 (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;
/* Find the nearest route point, if we're connected. */
- route_find_nearest_point();
+ route_find_nearest_point(route);
/* Cancel any autoroute that might be occurring. */
- route_cancel_autoroute(FALSE);
-
- map_force_redraw();
+ route_cancel_autoroute(route, FALSE);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.chk_auto))) {
/* Kick off a timeout to start the first update. */
}
/* Save Origin in Route Locations list if not from GPS. */
- if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps))
- && !g_slist_find_custom(_loc_list, from, (GCompareFunc) strcmp)) {
+ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)) && !g_slist_find_custom(_loc_list, from, (GCompareFunc) strcmp)) {
_loc_list = g_slist_prepend(_loc_list, g_strdup(from));
gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX, 0, from, -1);
}
gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX, 0, to, -1);
}
+ map_force_redraw();
+
MACRO_BANNER_SHOW_INFO(_window, _("Route Downloaded"));
g_free(rdl_data.bytes);
- route_set_destination_from_last();
+ route_set_destination_from_last(route);
/* Success! Get out of the while loop. */
+ r=TRUE;
break;
} else {
- popup_error(dialog, _("Error parsing GPX file."));
+ popup_error(dialog, _("Error parsing route GPX data."));
g_free(rdl_data.bytes);
/* Let them try again. */
}
gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */
-return TRUE;
+return r;
}
WayPoint *
-find_nearest_waypoint(guint unitx, guint unity)
+route_find_nearest_waypoint(Path *route, guint unitx, guint unity)
{
WayPoint *wcurr;
WayPoint *wnear;
guint64 nearest_squared;
Point pos = { unitx, unity, 0, NAN };
-wcurr = wnear = _route->whead;
-if (wcurr && wcurr->point && wcurr != _route->wtail) {
+wcurr = wnear = route->whead;
+if (wcurr && wcurr->point && wcurr != route->wtail) {
nearest_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
- while (wcurr++ != _route->wtail) {
+ while (wcurr++ != route->wtail) {
guint64 test_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
if (test_squared < nearest_squared) {
wnear = wcurr;
if (wnear && wnear->point) {
/* Only use the waypoint if it is within a 6*_draw_width square drawn
* around the position. This is consistent with select_poi(). */
- if (abs(unitx - wnear->point->unitx) < pixel2unit(3 * _draw_width) &&
- abs(unity - wnear->point->unity) < pixel2unit(3 * _draw_width))
+ if (abs(unitx - wnear->point->unitx) < pixel2unit(3 * _draw_width) && abs(unity - wnear->point->unity) < pixel2unit(3 * _draw_width))
return wnear;
}
* stop searching when we find a point that is farther away.
*/
gboolean
-route_update_nears(gboolean quick)
+route_update_nears(Path *route, gboolean quick)
{
gboolean ret = FALSE;
Point *curr, *near;
near = _near_point;
near_dist_squared = DISTANCE_SQUARED(_gps->data, *near);
- /* Now, search _route for a closer point. If quick is TRUE, then we'll
+ /* Now, search route for a closer point. If quick is TRUE, then we'll
* only search forward, only as long as we keep finding closer points.
*/
- for (curr = _near_point; curr++ != _route->tail;) {
+ for (curr = _near_point; curr++ != route->tail;) {
if (curr->unity) {
guint dist_squared = DISTANCE_SQUARED(_gps->data, *curr);
if (dist_squared <= near_dist_squared) {
_near_point = near;
_near_point_dist_squared = near_dist_squared;
- for (wnext = wcurr = _next_way; wcurr != _route->wtail; wcurr++) {
+ for (wnext = wcurr = _next_way; wcurr != route->wtail; wcurr++) {
if (wcurr->point < near || (wcurr->point == near && quick
&& (_next_wpt && (DISTANCE_SQUARED(_gps->data, *near) > _next_way_dist_squared
&& DISTANCE_SQUARED(_gps->data, *_next_wpt) < _next_wpt_dist_squared))))
break;
}
- if (wnext == _route->wtail && (wnext->point < near || (wnext->point == near && quick
+ if (wnext == route->wtail && (wnext->point < near || (wnext->point == near && quick
&& (_next_wpt && (DISTANCE_SQUARED (_gps->data, *near) > _next_way_dist_squared
&& DISTANCE_SQUARED(_gps->data, *_next_wpt) < _next_wpt_dist_squared)))))
{
if (!quick || _next_way != wnext) {
_next_way = wnext;
_next_wpt = wnext->point;
- if (_next_wpt == _route->tail)
+ if (_next_wpt == route->tail)
_next_wpt = NULL;
else {
while (!(++_next_wpt)->unity) {
- if (_next_wpt == _route->tail) {
+ if (_next_wpt == route->tail) {
_next_wpt = NULL;
break;
}
* route point and waypoint.
*/
void
-route_find_nearest_point()
+route_find_nearest_point(Path *route)
{
/* Initialize _near_point to first non-zero point. */
-_near_point = _route->head;
-while (!_near_point->unity && _near_point != _route->tail)
+_near_point = route->head;
+while (!_near_point->unity && _near_point != route->tail)
_near_point++;
/* Initialize _next_way. */
-if (_route->wtail == _route->whead - 1 || (_autoroute_data.enabled && _route->wtail == _route->whead))
+if (route->wtail == route->whead - 1 || (_autoroute_data.enabled && route->wtail == route->whead))
_next_way = NULL;
else
/* We have at least one waypoint. */
- _next_way = (_autoroute_data.enabled ? _route->whead + 1 : _route->whead);
+ _next_way = (_autoroute_data.enabled ? route->whead + 1 : route->whead);
_next_way_dist_squared = -1;
_next_wpt = NULL;
_next_wpt_dist_squared = -1;
-route_update_nears(FALSE);
+route_update_nears(route, FALSE);
}
/**
* 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
+ * following the route. If point is NULL, then the distance is shown to the
* next waypoint.
*/
gboolean
-route_show_distance_to(Point *point)
+route_show_distance_to(Path *route, Point *point)
{
gchar buffer[80];
-gdouble lat1, lon1, lat2, lon2;
-gdouble sum = 0.0;
-
-/* If point is NULL, use the next waypoint. */
-if (point == NULL && _next_way)
- point = _next_way->point;
-
-/* If point is still NULL, return an error. */
-if (point == NULL)
- return FALSE;
-
-unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
-if (point > _near_point) {
- Point *curr;
- /* Skip _near_point in case we have already passed it. */
- for (curr = _near_point + 1; curr <= point; ++curr) {
- if (curr->unity) {
- unit2latlon(curr->unitx, curr->unity, lat2, lon2);
- sum += calculate_distance(lat1, lon1, lat2, lon2);
- lat1 = lat2;
- lon1 = lon2;
- }
- }
-} else if (point < _near_point) {
- Point *curr;
- /* Skip _near_point in case we have already passed it. */
- for (curr = _near_point - 1; curr >= point; --curr) {
- if (curr->unity) {
- unit2latlon(curr->unitx, curr->unity, lat2, lon2);
- sum += calculate_distance(lat1, lon1, lat2, lon2);
- lat1 = lat2;
- lon1 = lon2;
- }
- }
-} else {
- /* Waypoint _is_ the nearest point. */
- unit2latlon(_near_point->unitx, _near_point->unity, lat2, lon2);
- sum += calculate_distance(lat1, lon1, lat2, lon2);
-}
+gdouble lat, lon;
+gdouble sum;
+unit2latlon(_gps->data.unitx, _gps->data.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);
}
void
-route_show_distance_to_next()
+route_show_distance_to_next(Path *route)
{
-if (!route_show_distance_to(NULL)) {
+if (!route_show_distance_to(route, NULL))
MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
}
-}
-void
-route_set_destination_from_last(void)
+gboolean
+route_set_destination_from_last(Path *route, Position *pos)
{
Point *p;
gdouble lat,lon;
-if (_route->head == _route->tail)
- return;
-/* Find last non-zero point. */
-for (p = _route->tail; !p->unity; p--) {
+if (route->head==route->tail) {
+ position_set(pos, FALSE, NAN, NAN);
+ return FALSE;
+}
+
+p=path_find_last_point(route);
+if (p) {
+ unit2latlon(p->unitx, p->unity, lat, lon);
+ position_set(pos, TRUE, lat, lon);
}
-unit2latlon(p->unitx, p->unity, lat, lon);
-_dest.valid=TRUE;
-_dest.lat=lat;
-_dest.lon=lon;
+return TRUE;
}
void
-route_show_distance_to_last(void)
+route_show_distance_to_last(Path *route)
{
-Point *p;
-
-if (_route->head != _route->tail) {
- /* Find last non-zero point. */
- for (p = _route->tail; !p->unity; p--) {
- }
- route_show_distance_to(p);
+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."));
- }
}
-
-/***/
-
+}
/** The singleton auto-route-download data. */
AutoRouteDownloadData _autoroute_data;
-void route_init(void);
-void route_deinit(void);
+gboolean route_open_file(Path *route);
+gboolean route_save(Path *route);
+gboolean route_download(Path *route, gchar *to);
+gboolean route_clear(Path *route);
-gboolean route_open_file(void);
-gboolean route_save(void);
-gboolean route_download(gchar * to);
-void route_clear(void);
+void route_check_waypoint_announce(Path *route, GpsData *gps);
+void route_autoroute_check(Path *route);
-void route_check_waypoint_announce(GpsData *gps);
-void route_autoroute_check(void);
+gboolean route_auto_route_dl_idle_cb();
+void route_cancel_autoroute(Path *route, gboolean temporary);
-gboolean auto_route_dl_idle();
+void route_find_nearest_point(Path *route);
+WayPoint *route_find_nearest_waypoint(Path *route, guint unitx, guint unity);
-WayPoint *find_nearest_waypoint(guint unitx, guint unity);
+gboolean route_update_nears(Path *route, gboolean quick);
-gboolean route_update_nears(gboolean quick);
-
-gboolean route_show_distance_to(Point * point);
-void route_show_distance_to_last();
-void route_show_distance_to_next();
+gboolean route_show_distance_to(Path *route, Point *point);
+void route_show_distance_to_last(Path *route);
+void route_show_distance_to_next(Path *route);
#endif
#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"
-struct sql_select_stmt {
- sqlite3_stmt *select_track;
- sqlite3_stmt *select_track_nodes;
- sqlite3_stmt *insert_track;
- sqlite3_stmt *insert_track_node;
- sqlite3_stmt *delete_track_nodes;
- sqlite3_stmt *delete_track;
-};
-static struct sql_select_stmt sql;
-
/* Add sensitivity */
static gint sensitivity=3;
void
-track_clear(void)
+track_clear(Path *track)
{
GtkWidget *confirm;
confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Clear the track?"));
if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
- _track->tail = _track->head;
- _track->length=_track->avgspeed=0.0;
- _track->points=0;
+ path_clear(track);
map_force_redraw();
}
gtk_widget_destroy(confirm);
gdouble
track_calculate_distance_from(Point *point)
{
+Point *curr;
gdouble lat1, lon1, lat2, lon2;
gdouble sum = 0.0;
-Point *curr;
+
unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
/* Skip _track->tail because that should be _gps. */
}
void
-track_show_distance_from(Point * point)
+track_show_distance_from(Point *point)
{
gchar buffer[80];
gdouble sum;
sum = track_calculate_distance_from(point);
-
-g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
- sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
+g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"), sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
MACRO_BANNER_SHOW_INFO(_window, buffer);
}
* appended to _track with time zero (this produces a "break" in the track).
*/
gboolean
-track_add(GpsData *gps)
+track_add(Path *track, GpsData *gps)
{
if (!gps) {
- MACRO_PATH_INCREMENT_TAIL(*_track);
- *_track->tail=_point_null;
+ MACRO_PATH_INCREMENT_TAIL(*track);
+ *track->tail=_point_null;
return FALSE;
}
-if (abs((gint)gps->unitx-_track->tail->unitx) > sensitivity || abs((gint)gps->unity-_track->tail->unity) > sensitivity) {
+if (abs((gint)gps->unitx-track->tail->unitx) > sensitivity || abs((gint)gps->unity-track->tail->unity) > sensitivity) {
/* If gps is available, update the nearest-waypoint data. */
- if (gps && _route->head != _route->tail && (gps->newly_fixed ? (route_find_nearest_point(), TRUE) : route_update_nears(TRUE))) {
+ /* 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();
/* 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);
+ 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);
+ 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);
}
}
- if (_track->tail->unity && _track->tail->unitx) {
+ if (track->tail->unity && track->tail->unitx) {
gdouble lat, lon;
- 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;
+ 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);
+ track->avgspeed=0.0;
+ g_debug("TRACK: %f %f (%d)", track->length, track->avgspeed, track->points);
}
- 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++;
+ 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++;
}
-/* Keep the display on if we are moving. */
-KEEP_DISPLAY_ON();
return TRUE;
}
-gboolean
-track_insert_break(void)
-{
-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 draw the waypoint ourselves. */
- x1 = unit2bufx(_track->tail->unitx);
- y1 = unit2bufy(_track->tail->unity);
- map_render_waypoint(x1, y1, _gc[COLORABLE_TRACK_BREAK]);
-}
-return FALSE;
-}
-
gboolean
-track_open(void)
+track_open(Path *track)
{
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)) {
+ if (gpx_parse(track, buffer, size, GPX_PATH_NEW)) {
map_force_redraw();
MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
r = TRUE;
}
gboolean
-track_save(void)
+track_save(Path *track)
{
GnomeVFSHandle *handle;
gboolean r = FALSE;
if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
- if (gpx_write(_track, handle)) {
+ if (gpx_write(track, handle)) {
MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
r = TRUE;
- track_clear();
+ track_clear(track);
} else {
popup_error(_window, _("Error writing GPX file."));
}
*
*/
gboolean
-track_insert_mark(void)
+track_insert_mark(Path *track)
{
gdouble lat, lon;
gchar tmp1[16], tmp2[16], *p_latlon;
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_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_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));
+ 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;
void track_init(void);
void track_deinit(void);
-gboolean track_add(GpsData *gps);
-gboolean track_insert_break(void);
-gboolean track_insert_mark(void);
-gboolean track_save(void);
-gboolean track_open(void);
-void track_clear(void);
+gboolean track_add(Path *track, GpsData *gps);
+gboolean track_insert_mark(Path *track);
+gboolean track_save(Path *track);
+gboolean track_open(Path *track);
+void track_clear(Path *track);
void track_show_distance_from_first();
void track_show_distance_from_last();
-void track_show_distance_from(Point * point);
+void track_show_distance_from(Point *point);
#endif
gtk_idle_add((GSourceFunc)window_present, NULL);
}
+/******* XXX: Move these !! *******/
+
gboolean
gps_info_update(Gps *gps)
{
g_assert(gps);
if (filter_check(&filter, &gps->data, &map_loc)==TRUE) {
if (track_add(&_gps->data)) {
- route_check_waypoint_announce(&_gps->data);
- route_autoroute_check();
+ KEEP_DISPLAY_ON();
+ route_check_waypoint_announce(_route, &_gps->data);
+ route_autoroute_check(_route);
}
map_refresh_mark();
}