8 #include "mapper-types.h"
18 struct sql_select_stmt {
19 sqlite3_stmt *select_track;
20 sqlite3_stmt *select_track_nodes;
21 sqlite3_stmt *insert_track;
22 sqlite3_stmt *insert_track_node;
23 sqlite3_stmt *delete_track_nodes;
24 sqlite3_stmt *delete_track;
26 static struct sql_select_stmt sql;
31 memset(&_track, 0, sizeof(_track));
32 MACRO_PATH_INIT(_track);
38 MACRO_PATH_FREE(_track);
46 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Clear the track?"));
48 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
49 _track.tail = _track.head;
52 gtk_widget_destroy(confirm);
56 track_calculate_distance_from(Point *point)
58 gdouble lat1, lon1, lat2, lon2;
61 unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
63 /* Skip _track.tail because that should be _gps. */
64 for (curr = _track.tail; curr > point; --curr) {
66 unit2latlon(curr->unitx, curr->unity, lat2, lon2);
67 sum += calculate_distance(lat1, lon1, lat2, lon2);
76 track_show_distance_from(Point * point)
81 sum = track_calculate_distance_from(point);
83 g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
84 sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
85 MACRO_BANNER_SHOW_INFO(_window, buffer);
89 track_show_distance_from_last()
91 /* Find last zero point. */
92 if (_track.head != _track.tail) {
94 /* Find last zero point. */
95 for (point = _track.tail; point->unity; point--) {
97 track_show_distance_from(point);
99 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
104 track_show_distance_from_first()
106 if (_track.head != _track.tail) {
107 track_show_distance_from(_track.head);
109 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
114 * Add a point to the _track list. This function is slightly overloaded,
115 * since it is what houses the check for "have we moved
116 * significantly": it also initiates the re-calculation of the _near_point
117 * data, as well as calling osso_display_state_on() when we have the focus.
119 * If a non-zero time is given, then the current position (as taken from the
120 * _gps variable) is appended to _track with the given time. If time is zero,
121 * then _point_null is appended to _track with time zero (this produces a "break"
125 track_add(GpsData *gps, gboolean newly_fixed)
127 gboolean show_directions = TRUE;
128 gint announce_thres_unsquared;
131 MACRO_PATH_INCREMENT_TAIL(_track);
132 *_track.tail=_point_null;
136 if (abs((gint)gps->unitx-_track.tail->unitx) > _draw_width || abs((gint)gps->unity-_track.tail->unity) > _draw_width) {
138 /* If gps is available, update the nearest-waypoint data. */
139 if (gps && _route.head != _route.tail && (newly_fixed ? (route_find_nearest_point(), TRUE) : route_update_nears(TRUE))) {
140 /* Nearest waypoint has changed - re-render paths. */
142 MACRO_QUEUE_DRAW_AREA();
145 if (_show_tracks & TRACKS_MASK) {
146 gint tx1, ty1, tx2, ty2;
148 /* Instead of calling map_render_paths(), we'll draw the new line
149 * ourselves and call gtk_widget_queue_draw_area(). */
150 map_render_segment(_gc[COLORABLE_TRACK], _gc[COLORABLE_TRACK_BREAK],
151 _track.tail->unitx, _track.tail->unity, gps->unitx, gps->unity);
153 if (_track.tail->unity && _track.tail->unitx) {
154 tx1 = unit2x(_track.tail->unitx);
155 ty1 = unit2y(_track.tail->unity);
156 tx2 = unit2x(gps->unitx);
157 ty2 = unit2y(gps->unity);
158 gtk_widget_queue_draw_area(_map_widget,
159 MIN(tx1, tx2) - _draw_width,
160 MIN(ty1, ty2) - _draw_width,
161 abs(tx1 - tx2) + (2 * _draw_width),
162 abs(ty1 - ty2) + (2 * _draw_width));
166 MACRO_PATH_INCREMENT_TAIL(_track);
167 _track.tail->unitx=gps->unitx;
168 _track.tail->unity=gps->unity;
169 _track.tail->time=gps->time;
170 _track.tail->altitude=gps->altitude;
173 if (_autoroute_data.enabled && !_autoroute_data.in_progress && _near_point_dist_squared > 400) {
174 MACRO_BANNER_SHOW_INFO(_window, _("Recalculating directions..."));
175 _autoroute_data.in_progress = TRUE;
176 show_directions = FALSE;
177 g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
180 announce_thres_unsquared=(20+(guint)gps->speed)*_announce_notice_ratio*3;
182 /* Check if we should announce upcoming waypoints. */
183 if (gps && show_directions && _next_way_dist_squared < (announce_thres_unsquared * announce_thres_unsquared)) {
184 if (_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase)) {
185 g_free(_last_spoken_phrase);
186 _last_spoken_phrase=g_strdup(_next_way->desc);
187 speak_text(_last_spoken_phrase);
189 MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
192 /* Keep the display on if we are moving. */
197 track_insert_break(void)
199 if (_track.tail->unity) {
202 /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
203 * another instance of the most recent track point. */
204 MACRO_PATH_INCREMENT_TAIL(_track);
205 *_track.tail=_point_null;
206 MACRO_PATH_INCREMENT_TAIL(_track);
207 *_track.tail=_track.tail[-2];
209 /* Instead of calling map_render_paths(), we'll just add the waypoint ourselves. */
210 x1 = unit2bufx(_track.tail->unitx);
211 y1 = unit2bufy(_track.tail->unity);
212 /* Make sure this circle will be visible. */
213 if ((x1 < BUF_WIDTH_PIXELS) && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
214 gdk_draw_arc(_map_pixmap, _gc[COLORABLE_TRACK_BREAK], FALSE,
215 x1 - _draw_width, y1 - _draw_width,
216 2 * _draw_width, 2 * _draw_width, 0,
219 MACRO_BANNER_SHOW_INFO(_window, _("Break already inserted."));
230 if (file_open_get_contents(&_track_file_uri, &buffer, &size)) {
231 if (parse_gpx(&_track, buffer, size, -1)) {
233 MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
236 popup_error(_window, _("Error parsing GPX file."));
246 GnomeVFSHandle *handle;
249 if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
250 if (write_gpx(&_track, handle)) {
251 MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
255 popup_error(_window, _("Error writing GPX file."));
257 gnome_vfs_close(handle);
263 * Add a text description at current point
267 track_insert_mark_text(gchar *text)
269 MACRO_PATH_INCREMENT_WTAIL(_track);
270 _track.wtail->point = _track.tail;
271 _track.wtail->desc = text;
275 * Ask for a text description for the current point
279 track_insert_mark(void)
282 gchar tmp1[16], tmp2[16], *p_latlon;
286 GtkWidget *txt_scroll;
289 dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
291 GTK_DIALOG_MODAL, GTK_STOCK_OK,
294 GTK_RESPONSE_REJECT, NULL);
296 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
298 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Lat, Lon")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
299 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
301 unit2latlon(_gps->data.unitx, _gps->data.unity, lat, lon);
302 lat_format(_degformat, lat, tmp1);
303 lon_format(_degformat, lon, tmp2);
304 p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
305 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(p_latlon), 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
306 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
309 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Description")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
310 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
312 txt_scroll = gtk_scrolled_window_new(NULL, NULL);
313 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll), GTK_SHADOW_IN);
314 gtk_table_attach(GTK_TABLE(table), txt_scroll, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
316 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
318 txt_desc = gtk_text_view_new();
319 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
321 gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
322 gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 450, 80);
324 gtk_widget_show_all(dialog);
326 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
328 GtkTextIter ti1, ti2;
330 tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
331 gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
332 gtk_text_buffer_get_end_iter(tbuf, &ti2);
334 if (gtk_text_buffer_get_char_count(tbuf)>0) {
335 track_insert_mark_text(gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE));
337 popup_error(dialog, _("Please provide a description for the mark."));
342 MACRO_QUEUE_DRAW_AREA();
345 gtk_widget_destroy(dialog);