Ticket #46: patch4.txt

File patch4.txt, 22.5 KB (added by heiko wegeler, 8 years ago)

fixes and changes

Line 
1Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/attr_def.h
2===================================================================
3--- /home/navit/_navit_develop/work/navit_repo/navit/navit/attr_def.h   (revision 4997)
4+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/attr_def.h   (working copy)
5@@ -234,6 +234,7 @@
6 ATTR(cache)
7 ATTR(create)
8 ATTR(persistent)
9+ATTR(waypoints_flag) /* toggle for "set as destination" to switch between start a new route or add */
10 ATTR2(0x0002ffff,type_int_end)
11 ATTR2(0x00030000,type_string_begin)
12 ATTR(type)
13Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.c
14===================================================================
15--- /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.c  (revision 4997)
16+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.c  (working copy)
17@@ -130,6 +130,19 @@
18        return ret;
19 }
20 
21+int bookmarks_get_bookmark_count(struct bookmarks* this_) {
22+       int ret=0;
23+       bookmarks_item_rewind(this_);
24+       while (this_->current->iter!=NULL) {
25+               struct bookmark_item_priv* data=(struct bookmark_item_priv*)this_->current->iter->data;
26+               if (data->type == type_bookmark) {
27+                       ret++;
28+               }
29+               this_->current->iter=g_list_next(this_->current->iter);
30+       }
31+       return ret;
32+}
33+
34 const char* bookmarks_item_cwd(struct bookmarks* this_) {
35        return this_->current->label;
36 }
37Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.h
38===================================================================
39--- /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.h  (revision 4997)
40+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/bookmarks.h  (working copy)
41@@ -45,6 +45,7 @@
42 int bookmarks_move_down(struct bookmarks *this_,const char* name);
43 
44 struct item* bookmarks_get_item(struct bookmarks* this_);
45+int bookmarks_get_bookmark_count(struct bookmarks* this_);
46 void bookmarks_item_rewind(struct bookmarks* this_);
47 const char* bookmarks_item_cwd(struct bookmarks* this_);
48 
49Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/gui/internal/gui_internal.c
50===================================================================
51--- /home/navit/_navit_develop/work/navit_repo/navit/navit/gui/internal/gui_internal.c  (revision 4997)
52+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/gui/internal/gui_internal.c  (working copy)
53@@ -2412,6 +2412,164 @@
54 }
55 
56 static void
57+gui_internal_cmd_delete_bookmark_folder(struct gui_priv *this, struct widget *wm, void *data)
58+{
59+       struct attr mattr;
60+       GList *l;
61+       navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL);
62+       bookmarks_move_up(mattr.u.bookmarks);
63+       bookmarks_delete_bookmark(mattr.u.bookmarks,wm->prefix);
64+       l=g_list_first(this->root.children);
65+       gui_internal_prune_menu(this, l->data);
66+}
67+
68+static void
69+gui_internal_cmd_load_bookmarks_as_waypoints(struct gui_priv *this, struct widget *wm, void *data)
70+{
71+       struct attr mattr;
72+       char *prefix=0;
73+       int plen=0;
74+
75+       if (data)
76+               prefix=g_strdup(data);
77+       else {
78+               if (wm && wm->prefix)
79+                       prefix=g_strdup(wm->prefix);
80+       }
81+       if ( prefix )
82+               plen=strlen(prefix);
83+
84+       if(navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL) ) {
85+               struct attr attr;
86+               struct item *item;
87+               struct coord c;
88+               struct pcoord *pc;
89+               int i, bm_count;
90+               if (!plen) {
91+                       bookmarks_move_root(mattr.u.bookmarks);
92+               } else {
93+                       if (!strcmp(prefix,"..")) {
94+                               bookmarks_move_up(mattr.u.bookmarks);
95+                               g_free(prefix);
96+                               prefix=g_strdup(bookmarks_item_cwd(mattr.u.bookmarks));
97+                               if (prefix) {
98+                                       plen=strlen(prefix);
99+                               } else {
100+                                       plen=0;
101+                               }
102+                       } else {
103+                               bookmarks_move_down(mattr.u.bookmarks,prefix);
104+                       }
105+               }
106+
107+               navit_set_destination(this->nav, NULL, NULL, 0);
108+
109+               bm_count=bookmarks_get_bookmark_count(mattr.u.bookmarks);
110+               pc=g_alloca(bm_count*sizeof(struct pcoord));
111+               bookmarks_item_rewind(mattr.u.bookmarks);
112+               i=0;
113+               while ((item=bookmarks_get_item(mattr.u.bookmarks))) {
114+                       if (!item_attr_get(item, attr_label, &attr)) continue;
115+                       if (item->type == type_bookmark) {
116+                               if (item_coord_get(item, &c, 1)) {
117+                                       pc[i].x=c.x;
118+                                       pc[i].y=c.y;
119+                                       pc[i].pro=projection_mg; /* FIXME */
120+                                       i++;
121+                               }
122+                       }
123+               }
124+
125+               if (bm_count>0){
126+                       navit_set_destinations(this->nav, pc, bm_count, prefix, 1);
127+                       if (this->flags & 512) {
128+                               struct attr follow;
129+                               follow.type=attr_follow;
130+                               follow.u.num=180;
131+                               navit_set_attr(this->nav, &this->osd_configuration);
132+                               navit_set_attr(this->nav, &follow);
133+                               navit_zoom_to_route(this->nav, 0);
134+                       }
135+               }
136+       }
137+
138+       if (plen) {
139+               g_free(prefix);
140+       }
141+       gui_internal_prune_menu(this, NULL);
142+}
143+
144+static void
145+gui_internal_cmd_replace_bookmarks_from_waypoints(struct gui_priv *this, struct widget *wm, void *data)
146+{
147+       struct attr mattr;
148+       char *prefix=0;
149+       int plen=0;
150+
151+       if (data)
152+               prefix=g_strdup(data);
153+       else {
154+               if (wm && wm->prefix)
155+                       prefix=g_strdup(wm->prefix);
156+       }
157+       if ( prefix )
158+               plen=strlen(prefix);
159+
160+       if(navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL) ) {
161+               struct attr attr;
162+               char *desc=NULL;
163+               struct pcoord *pc;
164+               int i, bm_count;
165+               if (!plen) {
166+                       bookmarks_move_root(mattr.u.bookmarks);
167+               } else {
168+                       if (!strcmp(prefix,"..")) {
169+                               bookmarks_move_up(mattr.u.bookmarks);
170+                               g_free(prefix);
171+                               prefix=g_strdup(bookmarks_item_cwd(mattr.u.bookmarks));
172+                               if (prefix) {
173+                                       plen=strlen(prefix);
174+                               } else {
175+                                       plen=0;
176+                               }
177+                       } else {
178+                               bookmarks_move_down(mattr.u.bookmarks,prefix);
179+                       }
180+               }
181+
182+               if (bookmarks_get_bookmark_count(mattr.u.bookmarks)>0){
183+                       struct item *item;
184+                       bookmarks_item_rewind(mattr.u.bookmarks);
185+                       while ((item=bookmarks_get_item(mattr.u.bookmarks))) {
186+                               if (!item_attr_get(item, attr_label, &attr)) continue;
187+                               if (item->type == type_bookmark) {
188+                                       bookmarks_delete_bookmark(mattr.u.bookmarks,  attr.u.str);
189+                               }
190+                               bookmarks_move_down(mattr.u.bookmarks,prefix);
191+                       }
192+               }
193+               bookmarks_item_rewind(mattr.u.bookmarks);
194+
195+               bm_count=navit_get_destination_count(this->nav);
196+               pc=g_alloca(bm_count*sizeof(struct pcoord));
197+               navit_get_destinations(this->nav, pc, bm_count);
198+
199+               for (i=0; i<bm_count; i++){
200+                       desc=g_strdup_printf("%s WP%d", navit_get_destination_description(this->nav, i), i+1);
201+                       navit_get_attr(this->nav, attr_bookmarks, &attr, NULL);
202+                       bookmarks_add_bookmark(attr.u.bookmarks, &pc[i], desc);
203+                       bookmarks_move_down(mattr.u.bookmarks,prefix);
204+                       g_free(desc);
205+               }
206+       }
207+
208+       if (plen) {
209+               g_free(prefix);
210+       }
211+       gui_internal_prune_menu(this, NULL);
212+}
213+
214+static void
215 get_direction(char *buffer, int angle, int mode)
216 {
217        angle=angle%360;
218@@ -3787,6 +3945,40 @@
219                                                gui_internal_cmd_bookmarks, NULL);
220                                                wbm->prefix=g_strdup("..");
221                                gui_internal_widget_append(w, wbm);
222+
223+                               // load bookmark folder as Waypoints, if any
224+                               if (bookmarks_get_bookmark_count(mattr.u.bookmarks) > 0){
225+                                       wbm=gui_internal_button_new_with_callback(this, _("Bookmarks as Waypoints"),
226+                                                       image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill,
227+                                                       gui_internal_cmd_load_bookmarks_as_waypoints, NULL);
228+                                       wbm->prefix=g_strdup(prefix);
229+                                       gui_internal_widget_append(w, wbm);
230+                               }
231+
232+                               // save Waypoints in bookmark folder, if route exists
233+                               if (navit_get_destination_count(this->nav) > 0){
234+                                       if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0){
235+                                               wbm=gui_internal_button_new_with_callback(this, _("Save Waypoints"),
236+                                                                       image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill,
237+                                                                       gui_internal_cmd_replace_bookmarks_from_waypoints, NULL);
238+                                       }else{
239+                                               wbm=gui_internal_button_new_with_callback(this, _("Replace Waypoints"),
240+                                                                       image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill,
241+                                                                       gui_internal_cmd_replace_bookmarks_from_waypoints, NULL);
242+                                       }
243+                                       wbm->prefix=g_strdup(prefix);
244+                                       gui_internal_widget_append(w, wbm);
245+                               }
246+
247+                               // delete empty folder
248+                               if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0){
249+                                       gui_internal_widget_append(w,
250+                                                       wbm=gui_internal_button_new_with_callback(this, _("Delete Folder"),
251+                                                       image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill,
252+                                                       gui_internal_cmd_delete_bookmark_folder, NULL));
253+                                       wbm->prefix=g_strdup(prefix);
254+                               }
255+
256                        }
257                }
258               
259@@ -5422,6 +5614,12 @@
260        gui_internal_widget_append(w,
261                gui_internal_button_navit_attr_new(this, _("Map follows Vehicle"), gravity_left_center|orientation_horizontal|flags_fill,
262                        &on, &off));
263+       on.u.num=1;
264+       off.u.num=0;
265+       on.type=off.type=attr_waypoints_flag;
266+       gui_internal_widget_append(w,
267+                       gui_internal_button_navit_attr_new(this, _("Plan with Waypoints"), gravity_left_center|orientation_horizontal|flags_fill,
268+                                       &on, &off));
269        gui_internal_menu_render(this);
270 }
271 
272@@ -7423,6 +7621,18 @@
273 }
274 
275 static void
276+gui_internal_cmd2_route_remove_last_waypoint(struct gui_priv *this, char *function, struct attr **in, struct attr ***out, int *valid)
277+{
278+       navit_remove_nth_waypoint(this->nav, navit_get_destination_count(this->nav)-1);
279+}
280+
281+static void
282+gui_internal_cmd2_route_remove_next_waypoint(struct gui_priv *this, char *function, struct attr **in, struct attr ***out, int *valid)
283+{
284+       navit_remove_waypoint(this->nav);
285+}
286+
287+static void
288 gui_internal_cmd2_locale(struct gui_priv *this, char *function, struct attr **in, struct attr ***out, int *valid)
289 {
290        struct widget *menu,*wb,*w;
291@@ -7734,6 +7944,8 @@
292        {"pois",command_cast(gui_internal_cmd2_pois)},
293        {"route_description",command_cast(gui_internal_cmd2_route_description)},
294        {"route_height_profile",command_cast(gui_internal_cmd2_route_height_profile)},
295+       {"route_remove_last_waypoint",command_cast(gui_internal_cmd2_route_remove_last_waypoint)},
296+       {"route_remove_next_waypoint",command_cast(gui_internal_cmd2_route_remove_next_waypoint)},
297        {"set",command_cast(gui_internal_cmd2_set)},
298        {"setting_layout",command_cast(gui_internal_cmd2_setting_layout)},
299        {"setting_maps",command_cast(gui_internal_cmd2_setting_maps)},
300Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.c
301===================================================================
302--- /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.c      (revision 4997)
303+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.c      (working copy)
304@@ -163,6 +163,7 @@
305                 /* 2=No gui ok */
306        int border;
307        int imperial;
308+       int waypoints_flag;
309        struct attr **attr_list;
310 };
311 
312@@ -1198,6 +1199,20 @@
313 
314 
315 static void
316+navit_cmd_route_remove_next_waypoint(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
317+{
318+       navit_remove_waypoint(this);
319+}
320+
321+
322+static void
323+navit_cmd_route_remove_last_waypoint(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
324+{
325+       navit_remove_nth_waypoint(this, navit_get_destination_count(this)-1);
326+}
327+
328+
329+static void
330 navit_cmd_set_center(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
331 {
332        struct pcoord pc;
333@@ -1336,6 +1351,8 @@
334        {"set_center",command_cast(navit_cmd_set_center)},
335        {"set_center_cursor",command_cast(navit_cmd_set_center_cursor)},
336        {"set_destination",command_cast(navit_cmd_set_destination)},
337+       {"route_remove_next_waypoint",command_cast(navit_cmd_route_remove_next_waypoint)},
338+       {"route_remove_last_waypoint",command_cast(navit_cmd_route_remove_last_waypoint)},
339        {"set_position",command_cast(navit_cmd_set_position)},
340        {"announcer_toggle",command_cast(navit_cmd_announcer_toggle)},
341        {"fmt_coordinates",command_cast(navit_cmd_fmt_coordinates)},
342@@ -1511,7 +1528,7 @@
343 }
344 
345 /**
346- * Start the route computing to a given set of coordinates
347+ * Start or add a given set of coordinates for route computing
348  *
349  * @param navit The navit instance
350  * @param c The coordinate to start routing to
351@@ -1536,7 +1553,13 @@
352        g_free(destination_file);
353        callback_list_call_attr_0(this_->attr_cbl, attr_destination);
354        if (this_->route) {
355-               route_set_destination(this_->route, c, async);
356+               struct attr attr;
357+               navit_get_attr(this_, attr_waypoints_flag, &attr, NULL);
358+               if (this_->waypoints_flag==0 || route_get_destination_count(this_->route)==0){
359+                       route_set_destination(this_->route, c, async);
360+               }else{
361+                       route_append_destination(this_->route, c, async);
362+               }
363 
364                if (this_->ready == 3)
365                        navit_draw(this_);
366@@ -1573,6 +1596,44 @@
367        }
368 }
369 
370+int
371+navit_get_destinations(struct navit *this_, struct pcoord *pc, int count)
372+{
373+       return route_get_destinations(this_->route, pc, count);
374+}
375+
376+int
377+navit_get_destination_count(struct navit *this_)
378+{
379+       return route_get_destination_count(this_->route);
380+}
381+
382+char*
383+navit_get_destination_description(struct navit *this_, int n)
384+{
385+       return route_get_destination_description(this_->route, n);
386+}
387+
388+void
389+navit_remove_nth_waypoint(struct navit *this_, int n)
390+{
391+       if (route_get_destination_count(this_->route)>1){
392+               route_remove_nth_waypoint(this_->route, n);
393+       }else{
394+               navit_set_destination(this_, NULL, NULL, 0);
395+       }
396+}
397+
398+void
399+navit_remove_waypoint(struct navit *this_)
400+{
401+       if (route_get_destination_count(this_->route)>1){
402+               route_remove_waypoint(this_->route);
403+       }else{
404+               navit_set_destination(this_, NULL, NULL, 0);
405+       }
406+}
407+
408 /**
409  * @brief Checks if a route is calculated
410  *
411@@ -2447,10 +2508,14 @@
412                attr_updated=(this_->follow_cursor != !!attr->u.num);
413                this_->follow_cursor=!!attr->u.num;
414                break;
415-        case attr_imperial:
416-                attr_updated=(this_->imperial != attr->u.num);
417-                this_->imperial=attr->u.num;
418-                break;
419+       case attr_imperial:
420+               attr_updated=(this_->imperial != attr->u.num);
421+               this_->imperial=attr->u.num;
422+               break;
423+       case attr_waypoints_flag:
424+               attr_updated=(this_->waypoints_flag != !!attr->u.num);
425+               this_->waypoints_flag=!!attr->u.num;
426+               break;
427        default:
428                return 0;
429        }
430@@ -2638,6 +2703,9 @@
431        case attr_follow_cursor:
432                attr->u.num=this_->follow_cursor;
433                break;
434+       case attr_waypoints_flag:
435+               attr->u.num=this_->waypoints_flag;
436+               break;
437        default:
438                return 0;
439        }
440@@ -2827,6 +2895,7 @@
441        int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *);
442        void *attr_object;
443        char *destination_file;
444+       char *description;
445 
446        profile(0,NULL);
447        if (this_->ready != 3) {
448@@ -2892,12 +2961,19 @@
449        if (this_->route) {
450                switch(route_destination_reached(this_->route)) {
451                case 1:
452+                       description=route_get_destination_description(this_->route, 0);
453                        route_remove_waypoint(this_->route);
454                        count=route_get_destinations(this_->route, pc, 16);
455                        destination_file = bookmarks_get_destination_file(TRUE);
456-                       bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, NULL, this_->recentdest_count);
457+                       bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, description, this_->recentdest_count);
458+                       g_free(description);
459                        break; 
460                case 2:
461+                       description=route_get_destination_description(this_->route, 0);
462+                       count=route_get_destinations(this_->route, pc, 1);
463+                       destination_file = bookmarks_get_destination_file(TRUE);
464+                       bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, description, this_->recentdest_count);
465+                       g_free(description);
466                        navit_set_destination(this_, NULL, NULL, 0);
467                        break;
468                }
469Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.h
470===================================================================
471--- /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.h      (revision 4997)
472+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/navit.h      (working copy)
473@@ -50,6 +50,7 @@
474 struct transformation;
475 struct vehicleprofile;
476 struct command_table;
477+struct item;
478 void navit_add_mapset(struct navit *this_, struct mapset *ms);
479 struct mapset *navit_get_mapset(struct navit *this_);
480 struct tracking *navit_get_tracking(struct navit *this_);
481@@ -78,6 +79,12 @@
482 GList *navit_get_vehicleprofiles(struct navit *this_);
483 void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async);
484 void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async);
485+int navit_get_destinations(struct navit *this_, struct pcoord *pc, int count);
486+int navit_get_destination_count(struct navit *this_);
487+char* navit_get_destination_description(struct navit *this_, int n);
488+void navit_remove_nth_waypoint(struct navit *this_, int n);
489+void navit_remove_waypoint(struct navit *this_);
490+char* navit_get_coord_description(struct navit *this_, struct pcoord *c);
491 int navit_check_route(struct navit *this_);
492 struct map* read_former_destinations_from_file(void);
493 void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...);
494Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/navit_shipped.xml
495===================================================================
496--- /home/navit/_navit_develop/work/navit_repo/navit/navit/navit_shipped.xml    (revision 4997)
497+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/navit_shipped.xml    (working copy)
498@@ -86,6 +86,10 @@
499                        <a name='Route'><text>Route</text>
500                                <img src='gui_actions' onclick='route_description()'><text>Description</text></img>
501                                <img src='gui_actions' onclick='route_height_profile()'><text>Height Profile</text></img>
502+                               <img cond='navit.route.route_status&amp;52' src='gui_stop' onclick='route_remove_last_waypoint()'><text>Drop last
503+Waypoint</text></img>
504+                               <img cond='navit.route.route_status&amp;52' src='gui_stop' onclick='route_remove_next_waypoint()'><text>Drop next
505+Waypoint</text></img>
506                        </a>
507                        </html>
508                ]]></gui>
509Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/route.c
510===================================================================
511--- /home/navit/_navit_develop/work/navit_repo/navit/navit/route.c      (revision 4997)
512+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/route.c      (working copy)
513@@ -542,8 +542,12 @@
514 route_set_profile(struct route *this, struct vehicleprofile *prof)
515 {
516        if (this->vehicleprofile != prof) {
517-               this->vehicleprofile=prof;
518-               route_path_update(this, 1, 1);
519+               this->vehicleprofile = prof;
520+               int dest_count = g_list_length(this->destinations);
521+               struct pcoord *pc;
522+               pc = g_alloca(dest_count*sizeof(struct pcoord));
523+               route_get_destinations(this, pc, dest_count);
524+               route_set_destinations(this, pc, dest_count, 1);
525        }
526 }
527 
528@@ -1054,7 +1058,79 @@
529        }
530        return ret;
531 }
532-
533+
534+/**
535+ * @brief Get the destinations count for the route
536+ *
537+ * @param this The route instance
538+ * @return destination count for the route
539+ */
540+int
541+route_get_destination_count(struct route *this)
542+{
543+       return g_list_length(this->destinations);
544+}
545+
546+/**
547+ * @brief Returns a description for a waypoint as (type or street_name_systematic) + (label or WayID[osm_wayid])
548+ *
549+ * @param this The route instance
550+ * @param n The nth waypoint
551+ * @return The description
552+ */
553+char*
554+route_get_destination_description(struct route *this, int n)
555+{
556+       struct route_info *dst;
557+       struct map_rect *mr=NULL;
558+       struct item *item;
559+       struct attr attr;
560+       char *type=NULL;
561+       char *label=NULL;
562+       char *desc=NULL;
563+
564+       dst=g_list_nth_data(this->destinations,n);
565+       mr=map_rect_new(dst->street->item.map, NULL);
566+       item = map_rect_get_item_byid(mr, dst->street->item.id_hi, dst->street->item.id_lo);
567+       type=item_to_name(dst->street->item.type);
568+
569+       while(item_attr_get(item, attr_any, &attr)) {
570+               if (attr.type==attr_street_name_systematic){
571+                       type=attr_to_text(&attr, item->map, 1);
572+               }
573+               if (attr.type==attr_label){
574+                       g_free(label);
575+                       label=g_strdup_printf("%s", attr_to_text(&attr, item->map, 1));
576+               }else if (attr.type==attr_osm_wayid && label==NULL){
577+                       label=g_strdup_printf("WayID %s", attr_to_text(&attr, item->map, 1));
578+               }
579+       }
580+
581+       if (type!=NULL && label!=NULL){
582+               if (strcmp(type, label)==0){
583+                       desc=g_strdup_printf("%s", type);
584+               }else{
585+                       desc=g_strdup_printf("%s %s", type, label);
586+               }
587+       }else{
588+               desc="unknown way";
589+       }
590+
591+       g_free(label);
592+       if (mr!=NULL){
593+               map_rect_destroy(mr);
594+       }
595+       return desc;
596+}
597+
598+/**
599+ * @brief Start a route given set of coordinates
600+ *
601+ * @param this The route instance
602+ * @param c The coordinate to start routing to
603+ * @param async 1 for async
604+ * @return nothing
605+ */
606 void
607 route_set_destination(struct route *this, struct pcoord *dst, int async)
608 {
609@@ -1061,6 +1137,52 @@
610        route_set_destinations(this, dst, dst?1:0, async);
611 }
612 
613+/**
614+ * @brief Append a given set of coordinates for route computing
615+ *
616+ * @param this The route instance
617+ * @param c The coordinate to start routing to
618+ * @param async 1 for async
619+ * @return nothing
620+ */
621+void
622+route_append_destination(struct route *this, struct pcoord *dst, int async)
623+{
624+       if (dst){
625+               struct route_info *dsti;
626+               dsti=route_find_nearest_street(this->vehicleprofile, this->ms, &dst[0]);
627+               if(dsti) {
628+                       route_info_distances(dsti, dst->pro);
629+                       this->destinations=g_list_append(this->destinations, dsti);
630+               }
631+               /* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */
632+               route_graph_destroy(this->graph);
633+               this->graph=NULL;
634+               this->current_dst=route_get_dst(this);
635+               route_path_update(this, 1, async);
636+       }else{
637+               route_set_destinations(this, NULL, 0, async);
638+       }
639+}
640+
641+/**
642+ * @brief Remove the nth waypoint of the route
643+ *
644+ * @param this The route instance
645+ * @param n The waypoint to remove
646+ * @return nothing
647+ */
648+void
649+route_remove_nth_waypoint(struct route *this, int n)
650+{
651+       this->destinations=g_list_remove(this->destinations,g_list_nth_data(this->destinations, n));
652+       /* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */
653+       route_graph_destroy(this->graph);
654+       this->graph=NULL;
655+       this->current_dst=route_get_dst(this);
656+       route_path_update(this, 1, 1);
657+}
658+
659 void
660 route_remove_waypoint(struct route *this)
661 {
662Index: /home/navit/_navit_develop/work/navit_repo/navit/navit/route.h
663===================================================================
664--- /home/navit/_navit_develop/work/navit_repo/navit/navit/route.h      (revision 4997)
665+++ /home/navit/_navit_develop/work/navit_repo/navit/navit/route.h      (working copy)
666@@ -95,8 +95,11 @@
667 struct map_selection *route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs);
668 void route_set_destinations(struct route *this_, struct pcoord *dst, int count, int async);
669 int route_get_destinations(struct route *this_, struct pcoord *pc, int count);
670+int route_get_destination_count(struct route *this_);
671 void route_set_destination(struct route *this_, struct pcoord *dst, int async);
672+void route_remove_nth_waypoint(struct route *this_, int n);
673 void route_remove_waypoint(struct route *this_);
674+char* route_get_destination_description(struct route *this_, int n);
675 struct coord route_get_coord_dist(struct route *this_, int dist);
676 struct street_data *street_get_data(struct item *item);
677 struct street_data *street_data_dup(struct street_data *orig);