8 #include "mapper-types.h"
16 struct sql_select_stmt {
17 sqlite3_stmt *select_track;
18 sqlite3_stmt *select_track_nodes;
19 sqlite3_stmt *insert_track;
20 sqlite3_stmt *insert_track_node;
21 sqlite3_stmt *delete_track_nodes;
22 sqlite3_stmt *delete_track;
24 static struct sql_select_stmt sql;
29 memset(&_track, 0, sizeof(_track));
30 MACRO_PATH_INIT(_track);
36 MACRO_PATH_FREE(_track);
44 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Clear the track?"));
46 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
47 _track.tail = _track.head;
50 gtk_widget_destroy(confirm);
54 track_calculate_distance_from(Point * point)
56 gfloat lat1, lon1, lat2, lon2;
59 unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
61 /* Skip _track.tail because that should be _pos. */
62 for (curr = _track.tail; curr > point; --curr) {
64 unit2latlon(curr->unitx, curr->unity, lat2, lon2);
65 sum += calculate_distance(lat1, lon1, lat2, lon2);
74 track_show_distance_from(Point * point)
79 sum = track_calculate_distance_from(point);
81 snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
82 sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
83 MACRO_BANNER_SHOW_INFO(_window, buffer);
87 track_show_distance_from_last()
89 /* Find last zero point. */
90 if (_track.head != _track.tail) {
92 /* Find last zero point. */
93 for (point = _track.tail; point->unity; point--) {
95 track_show_distance_from(point);
97 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
102 track_show_distance_from_first()
104 if (_track.head != _track.tail) {
105 track_show_distance_from(_track.head);
107 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
112 * Add a point to the _track list. This function is slightly overloaded,
113 * since it is what houses the check for "have we moved
114 * significantly": it also initiates the re-calculation of the _near_point
115 * data, as well as calling osso_display_state_on() when we have the focus.
117 * If a non-zero time is given, then the current position (as taken from the
118 * _pos variable) is appended to _track with the given time. If time is zero,
119 * then _point_null is appended to _track with time zero (this produces a "break"
123 track_add(time_t time, gboolean newly_fixed)
125 gboolean show_directions = TRUE;
126 gint announce_thres_unsquared;
128 if (abs((gint)_pos.unitx-_track.tail->unitx) > _draw_width || abs((gint)_pos.unity-_track.tail->unity) > _draw_width) {
129 /* If time != 0, update the nearest-waypoint data. */
130 if (time && _route.head != _route.tail &&
131 (newly_fixed ? (route_find_nearest_point(), TRUE) : route_update_nears(TRUE))) {
132 /* Nearest waypoint has changed - re-render paths. */
134 MACRO_QUEUE_DRAW_AREA();
137 if (_show_tracks & TRACKS_MASK) {
138 gint tx1, ty1, tx2, ty2;
140 /* Instead of calling map_render_paths(), we'll draw the new line
141 * ourselves and call gtk_widget_queue_draw_area(). */
142 map_render_segment(_gc[COLORABLE_TRACK],
143 _gc[COLORABLE_TRACK_BREAK],
145 _track.tail->unity, _pos.unitx,
148 if (time && _track.tail->unity) {
149 tx1 = unit2x(_track.tail->unitx);
150 ty1 = unit2y(_track.tail->unity);
151 tx2 = unit2x(_pos.unitx);
152 ty2 = unit2y(_pos.unity);
153 gtk_widget_queue_draw_area(_map_widget,
154 MIN(tx1, tx2) - _draw_width,
155 MIN(ty1, ty2) - _draw_width,
156 abs(tx1 - tx2) + (2 * _draw_width),
157 abs(ty1 - ty2) + (2 * _draw_width));
161 MACRO_PATH_INCREMENT_TAIL(_track);
166 *_track.tail = _point_null;
168 if (_autoroute_data.enabled && !_autoroute_data.in_progress && _near_point_dist_squared > 400) {
169 MACRO_BANNER_SHOW_INFO(_window, _("Recalculating directions..."));
170 _autoroute_data.in_progress = TRUE;
171 show_directions = FALSE;
172 g_idle_add((GSourceFunc) auto_route_dl_idle, NULL);
175 /* Keep the display on. */
179 announce_thres_unsquared=(20+(guint)_gps.speed)*_announce_notice_ratio*3;
181 /* Check if we should announce upcoming waypoints. */
182 if (show_directions && time && _next_way_dist_squared < (announce_thres_unsquared * announce_thres_unsquared)) {
183 if (_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase)) {
184 g_free(_last_spoken_phrase);
185 _last_spoken_phrase=g_strdup(_next_way->desc);
186 speak_text(_last_spoken_phrase);
188 MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
193 track_insert_break(void)
195 if (_track.tail->unity) {
198 /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
199 * another instance of the most recent track point. */
200 MACRO_PATH_INCREMENT_TAIL(_track);
201 *_track.tail=_point_null;
202 MACRO_PATH_INCREMENT_TAIL(_track);
203 *_track.tail=_track.tail[-2];
205 /* Instead of calling map_render_paths(), we'll just add the waypoint ourselves. */
206 x1 = unit2bufx(_track.tail->unitx);
207 y1 = unit2bufy(_track.tail->unity);
208 /* Make sure this circle will be visible. */
209 if ((x1 < BUF_WIDTH_PIXELS) && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
210 gdk_draw_arc(_map_pixmap, _gc[COLORABLE_TRACK_BREAK], FALSE,
211 x1 - _draw_width, y1 - _draw_width,
212 2 * _draw_width, 2 * _draw_width, 0,
215 MACRO_BANNER_SHOW_INFO(_window, _("Break already inserted."));
226 if (open_file(&buffer, NULL, &size, NULL, &_track_file_uri, GTK_FILE_CHOOSER_ACTION_OPEN)) {
227 if (parse_gpx(&_track, buffer, size, -1)) {
229 MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
232 popup_error(_window, _("Error parsing GPX file."));
242 GnomeVFSHandle *handle;
245 if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
246 if (write_gpx(&_track, handle)) {
247 MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
251 popup_error(_window, _("Error writing GPX file."));
253 gnome_vfs_close(handle);
259 * Add a text description at current point
263 track_insert_mark_text(gchar *text)
265 MACRO_PATH_INCREMENT_WTAIL(_track);
266 _track.wtail->point = _track.tail;
267 _track.wtail->desc = text;
271 * Ask for a text description for the current point
275 track_insert_mark(void)
278 gchar tmp1[16], tmp2[16], *p_latlon;
282 GtkWidget *txt_scroll;
285 dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
287 GTK_DIALOG_MODAL, GTK_STOCK_OK,
290 GTK_RESPONSE_REJECT, NULL);
292 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
293 table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
295 gtk_table_attach(GTK_TABLE(table),
296 label = gtk_label_new(_("Lat, Lon")),
297 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
298 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
300 unit2latlon(_pos.unitx, _pos.unity, lat, lon);
301 lat_format(lat, tmp1);
302 lon_format(lon, tmp2);
303 p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
304 gtk_table_attach(GTK_TABLE(table),
305 label = gtk_label_new(p_latlon),
306 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
307 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
310 gtk_table_attach(GTK_TABLE(table),
311 label = gtk_label_new(_("Description")),
312 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
313 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
315 txt_scroll = gtk_scrolled_window_new(NULL, NULL);
316 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
318 gtk_table_attach(GTK_TABLE(table),
320 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
322 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
323 GTK_POLICY_AUTOMATIC,
324 GTK_POLICY_AUTOMATIC);
326 txt_desc = gtk_text_view_new();
327 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
329 gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
330 gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 450, 80);
332 gtk_widget_show_all(dialog);
334 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
336 GtkTextIter ti1, ti2;
338 tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
339 gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
340 gtk_text_buffer_get_end_iter(tbuf, &ti2);
342 if (gtk_text_buffer_get_char_count(tbuf)>0) {
343 track_insert_mark_text(gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE));
345 popup_error(dialog, _("Please provide a description for the mark."));
350 MACRO_QUEUE_DRAW_AREA();
353 gtk_widget_destroy(dialog);