diff options
author | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2012-11-09 22:09:37 +0000 |
---|---|---|
committer | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2012-11-09 22:09:37 +0000 |
commit | 6f03504eeda8799fa1098c2f50a7570e1ed90e2a (patch) | |
tree | 0f8c91fbd5628d0a7791dfd8cb7713c084278364 | |
parent | 8f2a5742605d56049aa8ca371877b30f19bae44b (diff) | |
download | navit-6f03504eeda8799fa1098c2f50a7570e1ed90e2a.tar.gz |
Add:core:Better waypoints handling, see #1040 |Based on ideas & patches from pini and antiram
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5264 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r-- | navit/bookmarks.c | 117 | ||||
-rw-r--r-- | navit/bookmarks.h | 2 | ||||
-rw-r--r-- | navit/gui/internal/gui_internal.c | 195 | ||||
-rw-r--r-- | navit/item.c | 22 | ||||
-rw-r--r-- | navit/item.h | 1 | ||||
-rw-r--r-- | navit/map/textfile/textfile.c | 8 | ||||
-rw-r--r-- | navit/navit.c | 79 | ||||
-rw-r--r-- | navit/navit.h | 1 | ||||
-rw-r--r-- | navit/navit_shipped.xml | 212 | ||||
-rw-r--r-- | navit/route.c | 108 | ||||
-rw-r--r-- | navit/vehicle/demo/vehicle_demo.c | 2 |
11 files changed, 653 insertions, 94 deletions
diff --git a/navit/bookmarks.c b/navit/bookmarks.c index bcad314e8..6c1c79665 100644 --- a/navit/bookmarks.c +++ b/navit/bookmarks.c @@ -645,29 +645,40 @@ bookmarks_rename_bookmark(struct bookmarks *this_, const char *oldName, const ch struct former_destination{ enum item_type type; char* description; - struct coord c; + GList* c; }; static void free_former_destination(struct former_destination* former_destination){ g_free(former_destination->description); + g_list_foreach(former_destination->c, (GFunc)g_free, NULL); + g_list_free(former_destination->c); g_free(former_destination); } - +/* + * Doesn't read any items besides former_destination. So active waypoints items of type former_itinerary and former_itinerary_part are skipped. + */ static GList* read_former_destination_map_as_list(struct map *map){ struct map_rect *mr; struct item *item; struct attr attr; struct former_destination *dest; + struct coord c; + int more; GList* list = NULL; if (map && (mr=map_rect_new(map, NULL))) { while ((item=map_rect_get_item(mr))) { if (item->type != type_former_destination) continue; - dest = g_new(struct former_destination, 1); + dest = g_new0(struct former_destination, 1); dest->type=item->type; item_attr_get(item, attr_label, &attr); dest->description = g_strdup(attr.u.str); - item_coord_get(item, &(dest->c), 1); + more = item_coord_get(item, &c, 1); + while (more) { + dest->c = g_list_append(dest->c, g_new(struct coord, 1)); + *(struct coord *)g_list_last(dest->c)->data = c; + more = item_coord_get(item, &c, 1); + } list = g_list_prepend(list, dest); } map_rect_destroy(mr); @@ -676,41 +687,57 @@ static GList* read_former_destination_map_as_list(struct map *map){ } static int -destination_equal(struct former_destination* dest1, struct former_destination* dest2) +destination_equal(struct former_destination* dest1, struct former_destination* dest2, int ignore_descriptions) { if ((dest1->type == dest2->type) && - (!strcmp(dest1->description, dest2->description)) && - (coord_equal(&(dest1->c), &(dest2->c)))){ + (ignore_descriptions || !strcmp(dest1->description, dest2->description)) && + (coord_equal((struct coord *)g_list_last(dest1->c)->data, (struct coord *)g_list_last(dest2->c)->data))){ return TRUE; } return FALSE; } +/* + * Find destination in given GList. If remove_found is non-zero, any matching items are removed and new beginning of the list is returned. + * If remove_found is zero, last matching item is returned. In the latter case, description is ignored and can be NULL. + */ static GList* -remove_destination_from_list(struct former_destination* dest_to_remove, GList* former_destinations) +find_destination_in_list(struct former_destination* dest_to_remove, GList* former_destinations, int remove_found) { GList* curr_el = former_destinations; GList* prev_el = NULL; + GList* found_el = NULL; struct former_destination* curr_dest; - while(curr_el){ curr_dest = curr_el->data; - if (destination_equal(dest_to_remove, curr_dest)){ - free_former_destination(curr_dest); - curr_el = g_list_remove(curr_el, curr_dest); - }else{ - prev_el = curr_el; - curr_el = g_list_next(curr_el); + if (destination_equal(dest_to_remove, curr_dest, remove_found?0:1)) { + if(remove_found) { + free_former_destination(curr_dest); + curr_el = g_list_remove(curr_el, curr_dest); + continue; + } else { + found_el=curr_el; + } } + prev_el = curr_el; + curr_el = g_list_next(curr_el); + } - return g_list_first(prev_el); + if(remove_found) + return g_list_first(prev_el); + else + return found_el; + } + static void write_former_destinations(GList* former_destinations, char *former_destination_file, enum projection proj) { FILE *f; GList* currdest = NULL; + GList* c_list = NULL; + struct coord *c; struct former_destination *dest; const char* prostr = projection_to_name(proj); f=fopen(former_destination_file, "w"); @@ -721,40 +748,66 @@ write_former_destinations(GList* former_destinations, char *former_destination_f fprintf(f,"type=%s label=\"%s\"\n", item_to_name(dest->type), dest->description); else fprintf(f,"type=%s\n", item_to_name(dest->type)); - fprintf(f,"%s%s%s0x%x %s0x%x\n", - prostr, *prostr ? ":" : "", - dest->c.x >= 0 ? "":"-", dest->c.x >= 0 ? dest->c.x : -dest->c.x, - dest->c.y >= 0 ? "":"-", dest->c.y >= 0 ? dest->c.y : -dest->c.y); - + c_list = dest->c; + do { + c = (struct coord *)c_list->data; + fprintf(f,"%s%s%s0x%x %s0x%x\n", + prostr, *prostr ? ":" : "", + c->x >= 0 ? "":"-", c->x >= 0 ? c->x : -c->x, + c->y >= 0 ? "":"-", c->y >= 0 ? c->y : -c->y); + c_list = g_list_next(c_list); + } while (c_list); } fclose(f); } else { dbg(0, "Error updating destinations file %s: %s\n", former_destination_file, strerror(errno)); } } - /** + * Append recent destination(s) item to the former destionations map. + * @param former_destination_map + * @param former_destination_file + * @param c coordinates of item point(s). Can be set to NULL when navigation is stopped to remove type_former_itinerary and + * type_former_itinerary_part items from the file. + * @param count number of points in this item. Set to 0 when navigation is stopped. + * @param type type_former_destination, type_former_itinerary and type_former_itinerary_part are meaningful here + * @param description character string used to identify this destination. If NULL, most recent waypoint at these coordinates will be used + * to get description. * @param limit Limits the number of entries in the "backlog". Set to 0 for "infinite" */ void -bookmarks_append_coord(struct map *former_destination_map, char *former_destination_file, - struct pcoord *c, enum item_type type, const char *description, int limit) +bookmarks_append_destinations(struct map *former_destination_map, char *former_destination_file, + struct pcoord *c, int count, enum item_type type, const char *description, int limit) { - struct former_destination *new_dest; + struct former_destination *new_dest=NULL; GList* former_destinations = NULL; GList* former_destinations_shortened = NULL; + struct coord* c_dup; int no_of_former_destinations; + int i; former_destinations = read_former_destination_map_as_list(former_destination_map); - new_dest = g_new(struct former_destination, 1); - new_dest->type = type; - new_dest->description = g_strdup(description?description:_("Map Point")); - new_dest->c.x = c->x; - new_dest->c.y = c->y; - former_destinations = remove_destination_from_list(new_dest, former_destinations); - former_destinations = g_list_append(former_destinations, new_dest); + if(c && count>0) { + GList *older; + struct coord ctmp; + new_dest = g_new0(struct former_destination, 1); + new_dest->type = type; + for (i=0; i<count; i++) { + ctmp.x=c[i].x; + ctmp.y=c[i].y; + c_dup = g_new(struct coord, 1); + transform_from_to(&ctmp,c[i].pro, c_dup, map_projection(former_destination_map)); + new_dest->c = g_list_append(new_dest->c, c_dup); + } + older=find_destination_in_list(new_dest, former_destinations,0); + if(!description && older) + description=((struct former_destination *)older->data)->description; + new_dest->description = g_strdup(description?description:_("Map point")); + former_destinations = find_destination_in_list(new_dest, former_destinations, 1); + former_destinations = g_list_append(former_destinations, new_dest); + } no_of_former_destinations = g_list_length(former_destinations); if (limit > 0 && no_of_former_destinations > limit) former_destinations_shortened = g_list_nth(former_destinations, no_of_former_destinations - limit); diff --git a/navit/bookmarks.h b/navit/bookmarks.h index d8291289b..58ed47fc1 100644 --- a/navit/bookmarks.h +++ b/navit/bookmarks.h @@ -54,7 +54,7 @@ char* bookmarks_get_destination_file(gboolean create); void bookmarks_set_center_from_file(struct bookmarks *this_, char *file); char* bookmarks_get_center_file(gboolean create); void bookmarks_write_center_to_file(struct bookmarks *this_, char *file); -void bookmarks_append_coord(struct map *former_destination_map, char *file, struct pcoord *c, enum item_type type, const char *description, int limit); +void bookmarks_append_destinations(struct map *former_destination_map, char *file, struct pcoord *c, int count, enum item_type type, const char *description, int limit); /* end of prototypes */ #ifdef __cplusplus diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c index ed33958db..21a0e6f69 100644 --- a/navit/gui/internal/gui_internal.c +++ b/navit/gui/internal/gui_internal.c @@ -493,6 +493,8 @@ static void gui_internal_enter_setup(struct gui_priv *this); static void gui_internal_html_main_menu(struct gui_priv *this); static void gui_internal_menu_vehicle_settings(struct gui_priv *this, struct vehicle *v, char *name); +static void gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data); + /* * * Display image scaled to specific size @@ -2166,6 +2168,112 @@ gui_internal_cmd_set_destination(struct gui_priv *this, struct widget *wm, void } static void +gui_internal_cmd_insert_destination_do(struct gui_priv *this, struct widget *wm, void *data) { + char *name=data; + int dstcount=navit_get_destination_count(this->nav)+1; + int pos,i; + struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); + dstcount=navit_get_destinations(this->nav,dst,dstcount); + + pos=dstcount-wm->datai; + if(pos<0) + pos=0; + + for(i=dstcount;i>pos;i--) + dst[i]=dst[i-1]; + + dst[pos]=wm->c; + navit_add_destination_description(this->nav,&wm->c,(char*)data); + navit_set_destinations(this->nav,dst,dstcount+1,name,1); + gui_internal_prune_menu(this, NULL); +} + +/* + * @brief Display waypoint list to the user and let she choose one for the action specified as cmd parameter. + * Widget passed as wm parameter of the called cmd function will have item set to user choosen waypoint item. Its datai will be set + * to zero-based choosen waypoint number, counting from the route end. Coordinates to wm->c will be copied from wm_->c if wm_ is not null. Otherwise, + * waypoint coordinates will be copied to wm->c. + * @param in this gui context + * @param title Menu title + * @param hint Text to dispaly above the waypoint list describing the action to be performed, can be NULL + * @param wm The called widget pointer. Can be NULL. + * @param cmd Function to call on item selection + * @param data data argument to be passed to the cmd function + * @returns nothing + */ +static void +gui_internal_select_waypoint(struct gui_priv *this, char *title, char *hint, struct widget *wm_, void(*cmd)(struct gui_priv *priv, struct widget *widget, void *data),void *data) +{ + struct widget *wb,*w,*wtable,*row,*wc; + struct map *map; + struct map_rect *mr; + struct item *item; + char *label,*text; + int i; + int dstcount=navit_get_destination_count(this->nav)+1; + + map=route_get_map(navit_get_route(this->nav)); + if(!map) + return; + mr = map_rect_new(map, NULL); + if(!mr) + return; + + wb=gui_internal_menu(this, title); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + if(hint) + gui_internal_widget_append(w, gui_internal_label_new(this, hint)); + wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); + gui_internal_widget_append(w,wtable); + + i=0; + while((item = map_rect_get_item(mr))!=NULL) { + struct attr attr; + if(item->type!=type_waypoint) + continue; + if (item_attr_get(item, attr_label, &attr)) { + label=map_convert_string(item->map, attr.u.str); + text=g_strdup_printf(_("Waypoint %s"), label); + map_convert_free(label); + } else + continue; + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, wc=gui_internal_button_new_with_callback(this, text, + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + cmd, data)); + wc->item=*item; + if(wm_) + wc->c=wm_->c; + else { + struct coord c; + item_coord_get(item,&c,1); + wc->c.x=c.x; + wc->c.y=c.y; + wc->c.pro=map_projection(item->map); + } + i++; + wc->datai=dstcount-i; + g_free(text); + } + map_rect_destroy(mr); + gui_internal_menu_render(this); +} + +static void +gui_internal_cmd_insert_destination(struct gui_priv *this, struct widget *wm, void *data) +{ + gui_internal_select_waypoint(this, data, _("Select waypoint to insert the new one before"), wm, gui_internal_cmd_insert_destination_do, data); +} + +static void +gui_internal_cmd2_waypoints(struct gui_priv *this, char *function, struct attr **in, struct attr ***out, int *valid) +{ + gui_internal_select_waypoint(this, _("Waypoints"), NULL, NULL, gui_internal_cmd_position, (void*)2); +} + + +static void gui_internal_cmd_set_position(struct gui_priv *this, struct widget *wm, void *data) { struct attr v; @@ -2425,6 +2533,7 @@ gui_internal_cmd_load_bookmarks_as_waypoints(struct gui_priv *this, struct widge pc[i].x=c.x; pc[i].y=c.y; pc[i].pro=pro; + navit_add_destination_description(this->nav,&pc[i],attr.u.str); i++; } } @@ -2480,7 +2589,9 @@ gui_internal_cmd_replace_bookmarks_from_waypoints(struct gui_priv *this, struct navit_get_destinations(this->nav, pc, bm_count); for (i=0; i<bm_count; i++){ - desc=g_strdup_printf("%s WP%d", navit_get_destination_description(this->nav, i), i+1); + char *tmp=navit_get_destination_description(this->nav, i); + desc=g_strdup_printf("%s WP%d", tmp, i+1); + g_free(tmp); navit_get_attr(this->nav, attr_bookmarks, &attr, NULL); bookmarks_add_bookmark(attr.u.bookmarks, &pc[i], desc); bookmarks_move_down(mattr.u.bookmarks,wm->prefix); @@ -2519,8 +2630,6 @@ get_direction(char *buffer, int angle, int mode) } } -static void gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data); - struct selector { char *icon; char *name; @@ -3555,6 +3664,34 @@ gui_internal_cmd_results_map_clean(struct gui_priv *this, struct widget *wm, voi navit_draw(this->nav); } +static void +gui_internal_cmd_delete_waypoint(struct gui_priv *this, struct widget *wm, void *data) +{ + int dstcount=navit_get_destination_count(this->nav); + int i; + struct map_rect *mr; + struct item *item; + struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); + dstcount=navit_get_destinations(this->nav,dst,dstcount); + mr=map_rect_new(wm->item.map, NULL); + i=0; + while((item=map_rect_get_item(mr))!=NULL) { + struct coord c; + if(item->type!=type_waypoint) + continue; + if(item_is_equal_id(*item,wm->item)) + continue; + item_coord_get_pro(item,&c,1,projection_mg); + dst[i].x=c.x; + dst[i].y=c.y; + dst[i].pro=projection_mg; + i++; + } + map_rect_destroy(mr); + navit_set_destinations(this->nav,dst,i,NULL,1); + gui_internal_prune_menu(this, NULL); +} + /* meaning of the bits in "flags": * 1: "Streets" @@ -3659,6 +3796,15 @@ gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct gui_internal_cmd_set_destination, g_strdup(name))); wbc->data_free=g_free_func; wbc->c=pc; + if(navit_get_destination_count(this->nav)>=1) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Visit before..."), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_insert_destination, g_strdup(name))); + wbc->data_free=g_free_func; + wbc->c=pc; + } } if (flags & 16) { const char *text; @@ -3762,13 +3908,16 @@ gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct mr=map_rect_new(item->map, sel); itemo=map_rect_get_item_byid(mr, item->id_hi, item->id_lo); - + if(!itemo) { + map_rect_destroy(mr); + continue; + } if (item_attr_get(itemo, attr_label, &attr)) { label=map_convert_string(itemo->map, attr.u.str); - text=g_strdup_printf("%s %s", item_to_name(item->type), label); + text=g_strdup(label); map_convert_free(label); } else - text=g_strdup_printf("%s", item_to_name(item->type)); + text=g_strdup(item_to_name(item->type)); gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); gui_internal_widget_append(row, wc=gui_internal_cmd_pois_item(this, NULL, itemo, NULL, -1, text)); wc->c=pc; @@ -3816,6 +3965,15 @@ gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct gui_internal_cmd_delete_bookmark, NULL)); wbc->text=g_strdup(wm->text); } + + if (wm && wm->item.type==type_waypoint) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Delete waypoint"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_delete_waypoint, NULL)); + wbc->item=wm->item; + } gui_internal_menu_render(this); @@ -4013,7 +4171,7 @@ gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm, void *data) // load bookmark folder as Waypoints, if any if (bookmarks_get_bookmark_count(mattr.u.bookmarks) > 0){ - wbm=gui_internal_button_new_with_callback(this, _("Bookmarks as Waypoints"), + wbm=gui_internal_button_new_with_callback(this, _("Bookmarks as waypoints"), image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_load_bookmarks_as_waypoints, NULL); wbm->prefix=g_strdup(prefix); @@ -4023,11 +4181,11 @@ gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm, void *data) // save Waypoints in bookmark folder, if route exists if (navit_get_destination_count(this->nav) > 0){ if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0){ - wbm=gui_internal_button_new_with_callback(this, _("Save Waypoints"), + wbm=gui_internal_button_new_with_callback(this, _("Save waypoints"), image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); }else{ - wbm=gui_internal_button_new_with_callback(this, _("Replace Waypoints"), + wbm=gui_internal_button_new_with_callback(this, _("Replace with waypoints"), image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); } @@ -4129,6 +4287,19 @@ gui_internal_cmd_formerdests(struct gui_priv *this, char *function, struct attr char *label_full; enum projection projection; + if(!navit_get_attr(this->nav, attr_former_destination_map, &attr, NULL)) + return; + + formerdests=attr.u.map; + if(!formerdests) + return; + + mr_formerdests=map_rect_new(formerdests, NULL); + if(!mr_formerdests) + return; + + projection = map_projection(formerdests); + gui_internal_prune_menu_count(this, 1, 0); wb=gui_internal_menu(this, _("Former Destinations")); wb->background=this->background; @@ -4137,13 +4308,10 @@ gui_internal_cmd_formerdests(struct gui_priv *this, char *function, struct attr gravity_top_center|orientation_vertical|flags_expand|flags_fill); w->spy=this->spacing*2; gui_internal_widget_append(wb, w); - - formerdests=read_former_destinations_from_file(); - mr_formerdests=map_rect_new(formerdests, NULL); - projection = map_projection(formerdests); while ((item=map_rect_get_item(mr_formerdests))) { struct coord c; struct widget *row; + if (item->type!=type_former_destination) continue; if (!item_attr_get(item, attr_label, &attr)) continue; if(!tbl) { tbl=gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand | orientation_vertical,1); @@ -8220,6 +8388,7 @@ static struct command_table commands[] = { {"town",command_cast(gui_internal_cmd2_town)}, {"enter_coord",command_cast(gui_internal_cmd_enter_coord)}, {"quit",command_cast(gui_internal_cmd2_quit)}, + {"waypoints",command_cast(gui_internal_cmd2_waypoints)}, {"write",command_cast(gui_internal_cmd_write)}, {"about",command_cast(gui_internal_cmd2_about)}, diff --git a/navit/item.c b/navit/item.c index 99cffecfc..58b33296b 100644 --- a/navit/item.c +++ b/navit/item.c @@ -304,6 +304,28 @@ item_id_equal(const void *a, const void *b) return (id_a->id_hi == id_b->id_hi && id_a->id_lo == id_b->id_lo); } +/** + * @brief Derive item id_lo and id_hi from pointer, considering pointer could be 32 or 64 bit wide but both ids are 32 bit. + * + * @param it reference to the item. + * @param id pointer to derive item id from. + * @return Nothing. + */ +void +item_id_from_ptr(struct item *item, void *id) +{ +#if !defined(__LP64__) && !defined(__LLP64__) && !defined(WIN64) + item->id_lo=(int) id; + item->id_hi=0; +#else +# ifndef _MSC_VER + item->id_lo=((long long)id)&0xFFFFFFFFll; +# else + item->id_lo=((long long)id)&0xFFFFFFFFi64; +# endif + item->id_hi=((long long)id)>>32; +#endif +} struct item_hash * diff --git a/navit/item.h b/navit/item.h index 6c9cf83e0..574ac5a5c 100644 --- a/navit/item.h +++ b/navit/item.h @@ -134,6 +134,7 @@ enum item_type item_from_name(const char *name); char *item_to_name(enum item_type item); unsigned int item_id_hash(const void *key); int item_id_equal(const void *a, const void *b); +void item_id_from_ptr(struct item *item, void *id); struct item_hash *item_hash_new(void); void item_hash_insert(struct item_hash *h, struct item *item, void *val); int item_hash_remove(struct item_hash *h, struct item *item); diff --git a/navit/map/textfile/textfile.c b/navit/map/textfile/textfile.c index c9713cd83..551a2ac19 100644 --- a/navit/map/textfile/textfile.c +++ b/navit/map/textfile/textfile.c @@ -97,9 +97,11 @@ textfile_coord_get(void *priv_data, struct coord *c, int count) dbg(1,"enter, count: %d\n",count); while (count--) { if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) { - *c=mr->c; - dbg(1,"c=0x%x,0x%x\n", c->x, c->y); - c++; + if (c){ + *c=mr->c; + dbg(1,"c=0x%x,0x%x\n", c->x, c->y); + c++; + } ret++; get_line(mr); if (mr->item.id_hi) diff --git a/navit/navit.c b/navit/navit.c index a2ec5703d..84eb16cf1 100644 --- a/navit/navit.c +++ b/navit/navit.c @@ -1529,6 +1529,7 @@ navit_mark_navigation_stopped(char *former_destination_file){ } } + /** * Start or add a given set of coordinates for route computing * @@ -1547,15 +1548,21 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip this_->destination_valid=1; dbg(1, "c=(%i,%i)\n", c->x,c->y); - bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_destination, description, this_->recentdest_count); + bookmarks_append_destinations(this_->former_destination, destination_file, c, 1, type_former_destination, description, this_->recentdest_count); } else { this_->destination_valid=0; + bookmarks_append_destinations(this_->former_destination, destination_file, NULL, 0, type_former_destination, NULL, this_->recentdest_count); navit_mark_navigation_stopped(destination_file); } g_free(destination_file); + callback_list_call_attr_0(this_->attr_cbl, attr_destination); + if (this_->route) { struct attr attr; + int dstcount; + struct pcoord *pc; + navit_get_attr(this_, attr_waypoints_flag, &attr, NULL); if (this_->waypoints_flag==0 || route_get_destination_count(this_->route)==0){ route_set_destination(this_->route, c, async); @@ -1563,13 +1570,23 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip route_append_destination(this_->route, c, async); } + dstcount=route_get_destination_count(this_->route); + if(dstcount>0) { + destination_file = bookmarks_get_destination_file(TRUE); + pc=g_new(struct pcoord,dstcount); + route_get_destinations(this_->route,pc,dstcount); + bookmarks_append_destinations(this_->former_destination, destination_file, pc, dstcount, type_former_itinerary, description, this_->recentdest_count); + g_free(pc); + g_free(destination_file); + } + if (this_->ready == 3) navit_draw(this_); } } /** - * Start the route computing to a given set of coordinates including waypoints + * Add destination description to the recent dest file. Doesn't start routing. * * @param navit The navit instance * @param c The coordinate to start routing to @@ -1577,6 +1594,27 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip * @returns nothing */ void +navit_add_destination_description(struct navit *this_, struct pcoord *c, const char *description) +{ + char *destination_file; + if (c) { + destination_file = bookmarks_get_destination_file(TRUE); + bookmarks_append_destinations(this_->former_destination, destination_file, c, 1, type_former_destination, description, this_->recentdest_count); + g_free(destination_file); + } +} + + +/** + * Start the route computing to a given set of coordinates including waypoints + * + * @param this_ The navit instance + * @param c The coordinate to start routing to + * @param description A label which allows the user to later identify this destination in the former destinations selection + * @param async If routing should be done asynchronously + * @returns nothing + */ +void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async) { char *destination_file; @@ -1585,7 +1623,7 @@ navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const c this_->destination_valid=1; destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_itinerary, description, this_->recentdest_count); + bookmarks_append_destinations(this_->former_destination, destination_file, c, count, type_former_itinerary, description, this_->recentdest_count); g_free(destination_file); } else this_->destination_valid=0; @@ -1684,6 +1722,7 @@ navit_former_destinations_active(struct navit *this_) return active; } + struct map* read_former_destinations_from_file(){ struct attr type, data, no_warn, flags, *attrs[5]; char *destination_file = bookmarks_get_destination_file(FALSE); @@ -1713,9 +1752,9 @@ static void navit_add_former_destinations_from_file(struct navit *this_) { struct item *item; - int i,valid=0,count=0; - struct coord c[16]; - struct pcoord pc[16]; + int i,valid=0,count=0,maxcount=1; + struct coord *c=g_new(struct coord, maxcount); + struct pcoord *pc; struct map_rect *mr; this_->former_destination=read_former_destinations_from_file(); @@ -1723,11 +1762,20 @@ navit_add_former_destinations_from_file(struct navit *this_) return; mr=map_rect_new(this_->former_destination, NULL); while ((item=map_rect_get_item(mr))) { - if ((item->type == type_former_destination || item->type == type_former_itinerary || item->type == type_former_itinerary_part) && (count=item_coord_get(item, c, 16))) + if (item->type == type_former_itinerary || item->type == type_former_itinerary_part) { + count=item_coord_get(item, c, maxcount); + while(count==maxcount) { + maxcount*=2; + c=g_realloc(c, sizeof(struct coord)*maxcount); + count+=item_coord_get(item, &c[count], maxcount-count); + } + if(count) valid=1; + } } map_rect_destroy(mr); if (valid && count > 0) { + pc=g_new(struct pcoord, count); for (i = 0 ; i < count ; i++) { pc[i].pro=map_projection(this_->former_destination); pc[i].x=c[i].x; @@ -1739,7 +1787,9 @@ navit_add_former_destinations_from_file(struct navit *this_) route_set_destinations(this_->route, pc, count, 1); this_->destination=pc[count-1]; this_->destination_valid=1; + g_free(pc); } + g_free(c); } @@ -2930,7 +2980,7 @@ navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv) struct pcoord cursor_pc; struct point cursor_pnt, *pnt=&cursor_pnt; struct tracking *tracking=NULL; - struct pcoord pc[16]; + struct pcoord *pc; enum projection pro=transform_get_projection(this_->trans_cursor); int count; int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *); @@ -3004,18 +3054,19 @@ navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv) case 1: description=route_get_destination_description(this_->route, 0); route_remove_waypoint(this_->route); - count=route_get_destinations(this_->route, pc, 16); + count=route_get_destination_count(this_->route); + pc=g_alloca(sizeof(*pc)*count); + route_get_destinations(this_->route, pc, count); destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, description, this_->recentdest_count); + bookmarks_append_destinations(this_->former_destination, destination_file, pc, count, type_former_itinerary_part, description, this_->recentdest_count); + g_free(destination_file); g_free(description); break; case 2: - description=route_get_destination_description(this_->route, 0); - count=route_get_destinations(this_->route, pc, 1); destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, description, this_->recentdest_count); - g_free(description); + bookmarks_append_destinations(this_->former_destination, destination_file, NULL, 0, type_former_itinerary_part, NULL, this_->recentdest_count); navit_set_destination(this_, NULL, NULL, 0); + g_free(destination_file); break; } } diff --git a/navit/navit.h b/navit/navit.h index 8ac7a0ff8..325287582 100644 --- a/navit/navit.h +++ b/navit/navit.h @@ -79,6 +79,7 @@ struct vehicleprofile *navit_get_vehicleprofile(struct navit *this_); GList *navit_get_vehicleprofiles(struct navit *this_); void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async); void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async); +void navit_add_destination_description(struct navit *this_, struct pcoord *c, const char *description); int navit_get_destinations(struct navit *this_, struct pcoord *pc, int count); int navit_get_destination_count(struct navit *this_); char* navit_get_destination_description(struct navit *this_, int n); diff --git a/navit/navit_shipped.xml b/navit/navit_shipped.xml index 46ad71d15..13f907fa6 100644 --- a/navit/navit_shipped.xml +++ b/navit/navit_shipped.xml @@ -87,9 +87,10 @@ Navigation</text></img> <a name='Route'><text>Route</text> <img src='gui_actions' onclick='route_description()'><text>Description</text></img> <img src='gui_actions' onclick='route_height_profile()'><text>Height Profile</text></img> - <img cond='navit.route.route_status&1' src='gui_stop' onclick='navit.route_remove_last_waypoint()'><text>Drop last + <img cond='navit.waypoints_flag && (navit.route.route_status&1)' src='cursor_still' onclick='waypoints()'><text>Waypoints</text></img> + <img cond='navit.waypoints_flag && (navit.route.route_status&1)' src='gui_stop' onclick='navit.route_remove_last_waypoint()'><text>Drop last Waypoint</text></img> - <img cond='navit.route.route_status&1' src='gui_stop' onclick='navit.route_remove_next_waypoint()'><text>Drop next + <img cond='navit.waypoints_flag && (navit.route.route_status&1)' src='gui_stop' onclick='navit.route_remove_next_waypoint()'><text>Drop next Waypoint</text></img> </a> <a name='Map Point'><text>Map Point</text> @@ -1848,6 +1849,46 @@ Waypoint</text></img> <icon src="gui_sound_32_32.png"/> <circle color="#FF089C" radius="10" text_size="7"/> </itemgra> + + <itemgra item_types="waypoint" order="2"> + <circle color="#008080" radius="4" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="3-5"> + <circle color="#008080" radius="8" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="6"> + <circle color="#008080" radius="10" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="7-8"> + <circle color="#008080" radius="16" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="9-10"> + <circle color="#008080" radius="20" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="11"> + <circle color="#008080" radius="28" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="12"> + <circle color="#008080" radius="32" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="13"> + <circle color="#008080" radius="52" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="14"> + <circle color="#008080" radius="64" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="15"> + <circle color="#008080" radius="68" width="6" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="16"> + <circle color="#008080" radius="132" width="8" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="17"> + <circle color="#008080" radius="268" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="waypoint" order="18"> + <circle color="#008080" radius="530" width="8" text_size="48"/> + </itemgra> </layer> <layer name="Unknown" enabled="no"> <!-- This entry shows all unknow point elements as blue circles --> @@ -3266,6 +3307,46 @@ Waypoint</text></img> <icon src="gui_sound_32_32.png"/> <circle color="#FF089C" radius="10" text_size="7"/> </itemgra> + + <itemgra item_types="waypoint" order="2"> + <circle color="#00a0a0" radius="4" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="3-5"> + <circle color="#00a0a0" radius="8" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="6"> + <circle color="#00a0a0" radius="10" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="7-8"> + <circle color="#00a0a0" radius="16" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="9-10"> + <circle color="#00a0a0" radius="20" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="11"> + <circle color="#00a0a0" radius="28" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="12"> + <circle color="#00a0a0" radius="32" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="13"> + <circle color="#00a0a0" radius="52" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="14"> + <circle color="#00a0a0" radius="64" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="15"> + <circle color="#00a0a0" radius="68" width="6" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="16"> + <circle color="#00a0a0" radius="132" width="8" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="17"> + <circle color="#00a0a0" radius="268" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="waypoint" order="18"> + <circle color="#00a0a0" radius="530" width="8" text_size="48"/> + </itemgra> </layer> <layer name="points"> <itemgra item_types="mini_roundabout" order="12-"> @@ -4542,6 +4623,47 @@ Waypoint</text></img> <itemgra item_types="route_end" order="0-"> <icon src="nav_destination_bk.png" w="32" h="32" /> </itemgra> + + <itemgra item_types="waypoint" order="2"> + <circle color="#000000" radius="4" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="3-5"> + <circle color="#000000" radius="8" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="6"> + <circle color="#000000" radius="10" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="7-8"> + <circle color="#000000" radius="16" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="9-10"> + <circle color="#000000" radius="20" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="11"> + <circle color="#000000" radius="28" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="12"> + <circle color="#000000" radius="32" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="13"> + <circle color="#000000" radius="52" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="14"> + <circle color="#000000" radius="64" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="15"> + <circle color="#000000" radius="68" width="6" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="16"> + <circle color="#000000" radius="132" width="8" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="17"> + <circle color="#000000" radius="268" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="waypoint" order="18"> + <circle color="#000000" radius="530" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="nav_none" order="0-"> <icon src="unknown.png" /> </itemgra> @@ -5207,6 +5329,10 @@ Waypoint</text></img> <itemgra item_types="street_route" > <polyline width="9" color="#ffffff" /> </itemgra> + + <itemgra item_types="waypoint" > + <circle color="#000000" radius="8" width="2" text_size="24"/> + </itemgra> </layer> <layer name="labels"> <itemgra item_types="water_line" order="11-"> @@ -6145,6 +6271,47 @@ Waypoint</text></img> <itemgra item_types="route_end" order="0-"> <icon src="nav_destination_bk.svg" w="32" h="32"/> </itemgra> + + <itemgra item_types="waypoint" order="2"> + <circle color="#000000" radius="4" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="3-5"> + <circle color="#000000" radius="8" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="6"> + <circle color="#000000" radius="10" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="7-8"> + <circle color="#000000" radius="16" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="9-10"> + <circle color="#000000" radius="20" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="11"> + <circle color="#000000" radius="28" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="12"> + <circle color="#000000" radius="32" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="13"> + <circle color="#000000" radius="52" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="14"> + <circle color="#000000" radius="64" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="15"> + <circle color="#000000" radius="68" width="6" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="16"> + <circle color="#000000" radius="132" width="8" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="17"> + <circle color="#000000" radius="268" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="waypoint" order="18"> + <circle color="#000000" radius="530" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="nav_none" order="0-"> <icon src="unknown.svg"/> </itemgra> @@ -6701,6 +6868,47 @@ Waypoint</text></img> <itemgra item_types="rg_point" order="0-"> <circle color="#FF089C" radius="10"/> </itemgra> + + <itemgra item_types="waypoint" order="2"> + <circle color="#008080" radius="4" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="3-5"> + <circle color="#008080" radius="8" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="6"> + <circle color="#008080" radius="10" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="7-8"> + <circle color="#008080" radius="16" width="2" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="9-10"> + <circle color="#008080" radius="20" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="11"> + <circle color="#008080" radius="28" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="12"> + <circle color="#008080" radius="32" width="4" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="13"> + <circle color="#008080" radius="52" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="14"> + <circle color="#008080" radius="64" width="4" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="15"> + <circle color="#008080" radius="68" width="6" text_size="24"/> + </itemgra> + <itemgra item_types="waypoint" order="16"> + <circle color="#008080" radius="132" width="8" text_size="32"/> + </itemgra> + <itemgra item_types="waypoint" order="17"> + <circle color="#008080" radius="268" width="8" text_size="48"/> + </itemgra> + <itemgra item_types="waypoint" order="18"> + <circle color="#008080" radius="530" width="8" text_size="48"/> + </itemgra> + <!-- !!!!...POIs...!!!! --> <!-- amenity=bank --> <itemgra item_types="poi_bank" order="14-"> diff --git a/navit/route.c b/navit/route.c index ce598dce3..d2165995f 100644 --- a/navit/route.c +++ b/navit/route.c @@ -233,6 +233,7 @@ struct route { unsigned flags; struct route_info *pos; /**< Current position within this route */ GList *destinations; /**< Destinations of the route */ + int reached_destinations_count; /**< Used as base to calculate waypoint numbers */ struct route_info *current_dst; /**< Current destination */ struct route_graph *graph; /**< Pointer to the route graph */ @@ -1057,8 +1058,10 @@ route_set_destinations(struct route *this, struct pcoord *dst, int count, int as } } route_status.u.num=route_status_destination_set; - } else + } else { + this->reached_destinations_count=0; route_status.u.num=route_status_no_destination; + } callback_list_call_attr_1(this->cbl2, attr_destination, this); route_set_attr(this, &route_status); profile(1,"find_nearest_street"); @@ -1118,6 +1121,9 @@ route_get_destination_description(struct route *this, int n) char *label=NULL; char *desc=NULL; + if(!this->destinations) + return NULL; + dst=g_list_nth_data(this->destinations,n); mr=map_rect_new(dst->street->item.map, NULL); item = map_rect_get_item_byid(mr, dst->street->item.id_hi, dst->street->item.id_lo); @@ -1134,6 +1140,7 @@ route_get_destination_description(struct route *this, int n) } else if (attr.type==attr_osm_wayid && !label){ char *tmp=attr_to_text(&attr, item->map, 1); label=g_strdup_printf("WayID %s", tmp); + g_free(tmp); } } @@ -1169,12 +1176,14 @@ route_set_destination(struct route *this, struct pcoord *dst, int async) } /** - * @brief Append a given set of coordinates for route computing + * @brief Append a waypoint to the route. * - * @param this The route instance - * @param c The coordinate to start routing to - * @param async 1 for async - * @return nothing + * This appends a waypoint to the current route, targetting the street + * nearest to the coordinates passed, and updates the route. + * + * @param this The route to set the destination for + * @param dst Coordinates of the new waypoint + * @param async: If set, do routing asynchronously */ void route_append_destination(struct route *this, struct pcoord *dst, int async) @@ -1219,18 +1228,23 @@ route_remove_nth_waypoint(struct route *this, int n) void route_remove_waypoint(struct route *this) { - struct route_path *path=this->path2; - struct route_info *ri=this->destinations->data; - this->destinations=g_list_remove(this->destinations,ri); - route_info_free(ri); - this->path2=this->path2->next; - route_path_destroy(path,0); - if (!this->destinations) - return; - route_graph_reset(this->graph); - this->current_dst=this->destinations->data; - route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb); - + if (this->path2) { + struct route_path *path = this->path2; + struct route_info *ri = this->destinations->data; + this->destinations = g_list_remove(this->destinations, ri); + route_info_free(ri); + this->path2 = this->path2->next; + route_path_destroy(path, 0); + if (!this->destinations) { + this->route_status=route_status_no_destination; + this->reached_destinations_count=0; + return; + } + this->reached_destinations_count++; + route_graph_reset(this->graph); + this->current_dst = this->destinations->data; + route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb); + } } /** @@ -3003,6 +3017,8 @@ struct map_rect_priv { int hash_bucket; struct coord *coord_sel; /**< Set this to a coordinate if you want to filter for just a single route graph point */ struct route_graph_point_iterator it; + /* Pointer to current waypoint element of route->destinations */ + GList *dest; }; static void @@ -3025,7 +3041,7 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) struct map_rect_priv *mr = priv_data; struct route_path_segment *seg=mr->seg; struct route *route=mr->mpriv->route; - if (mr->item.type != type_street_route) + if (mr->item.type != type_street_route && mr->item.type != type_waypoint) return 0; attr->type=attr_type; switch (attr_type) { @@ -3077,7 +3093,7 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) return 0; return 1; case attr_speed: - mr->attr_next=attr_none; + mr->attr_next=attr_label; if (seg) attr->u.num=route_seg_speed(route->vehicleprofile, seg->data, NULL); else @@ -3085,6 +3101,13 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) return 1; case attr_label: mr->attr_next=attr_none; + if(mr->item.type==type_waypoint) { + if(mr->str) + g_free(mr->str); + mr->str=g_strdup_printf("%d",route->reached_destinations_count+g_list_position(route->destinations,mr->dest)+1); + attr->u.str=mr->str; + return 1; + } return 0; default: mr->attr_next=attr_none; @@ -3105,15 +3128,17 @@ rm_coord_get(void *priv_data, struct coord *c, int count) if (pro == projection_none) return 0; - if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse || mr->item.type == type_route_end) { + if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse || mr->item.type == type_route_end || mr->item.type == type_waypoint ) { if (! count || mr->last_coord) return 0; mr->last_coord=1; if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse) c[0]=r->pos->c; - else { + else if (mr->item.type == type_waypoint) { + c[0]=((struct route_info *)mr->dest->data)->c; + } else { /*type_route_end*/ c[0]=route_get_dst(r)->c; - } + } return 1; } if (! seg) @@ -3226,6 +3251,7 @@ rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) mr->attr_next=attr_none; if (mr->str) g_free(mr->str); + mr->str=NULL; switch (mr->item.type) { case type_rg_point: { @@ -3461,12 +3487,13 @@ rp_get_item(struct map_rect_priv *mr) rm_coord_rewind(mr); rp_attr_rewind(mr); return &mr->item; - } else + } else mr->item.type = type_rg_segment; } - + + if (mr->coord_sel) { - if (!mr->point) { // This means that no point has been found + if (!mr->point) { /* This means that no point has been found */ return NULL; } seg = rp_iterator_next(&(mr->it)); @@ -3502,6 +3529,8 @@ static struct item * rm_get_item(struct map_rect_priv *mr) { struct route *route=mr->mpriv->route; + void *id=0; + dbg(1,"enter\n", mr->pos); switch (mr->item.type) { @@ -3510,8 +3539,26 @@ rm_get_item(struct map_rect_priv *mr) mr->item.type=type_route_start_reverse; else mr->item.type=type_route_start; - if (route->pos) + if (route->pos) { + id=route->pos; + break; + } + + case type_route_start: + case type_route_start_reverse: + case type_waypoint: + mr->item.type=type_waypoint; + mr->seg=NULL; + if(!mr->dest) + mr->dest=mr->mpriv->route->destinations; + else + mr->dest=g_list_next(mr->dest); + + if(mr->dest) { + id=mr->dest; break; + } + default: mr->item.type=type_street_route; mr->seg=mr->seg_next; @@ -3528,16 +3575,18 @@ rm_get_item(struct map_rect_priv *mr) } if (mr->seg) { mr->seg_next=mr->seg->next; + id=mr->seg; break; } mr->item.type=type_route_end; + id=&(mr->mpriv->route->destinations); if (mr->mpriv->route->destinations) break; case type_route_end: return NULL; } mr->last_coord = 0; - mr->item.id_lo++; + item_id_from_ptr(&mr->item,id); rm_attr_rewind(mr); return &mr->item; } @@ -3546,8 +3595,9 @@ static struct item * rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) { struct item *ret=NULL; - while (id_lo-- > 0) + do { ret=rm_get_item(mr); + } while (ret && (ret->id_lo!=id_lo || ret->id_hi!=id_hi)); return ret; } diff --git a/navit/vehicle/demo/vehicle_demo.c b/navit/vehicle/demo/vehicle_demo.c index e37a04933..5390390c2 100644 --- a/navit/vehicle/demo/vehicle_demo.c +++ b/navit/vehicle/demo/vehicle_demo.c @@ -159,6 +159,8 @@ vehicle_demo_timer(struct vehicle_priv *priv) item=map_rect_get_item(mr); if (item && item->type == type_route_start) item=map_rect_get_item(mr); + while(item && item->type!=type_street_route) + item=map_rect_get_item(mr); if (item && item_coord_get(item, &pos, 1)) { priv->position_set=0; dbg(1, "current pos=0x%x,0x%x\n", pos.x, pos.y); |