From 5be419a75a73b04740e2aa46e489700adf351208 Mon Sep 17 00:00:00 2001 From: martin-s Date: Sun, 12 Apr 2009 06:37:36 +0000 Subject: [PATCH] Fix:Core:Made routing more flexible git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@2203 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/navit/attr.h | 2 + navit/navit/attr_def.h | 5 ++ navit/navit/item.c | 56 ++++++++++++------ navit/navit/item_def.h | 1 + navit/navit/navit.c | 5 ++ navit/navit/navit.xml | 48 ++++++++++------ navit/navit/osm2navit.c | 131 ++++++++++++++++++++++++++++++------------- navit/navit/roadprofile.c | 22 ++++++-- navit/navit/roadprofile.h | 6 ++ navit/navit/route.c | 129 +++++++++++++++++------------------------- navit/navit/vehicleprofile.c | 52 +++++++++++++++-- navit/navit/vehicleprofile.h | 10 ++++ navit/navit/xmlconfig.c | 30 ---------- 13 files changed, 306 insertions(+), 191 deletions(-) diff --git a/navit/navit/attr.h b/navit/navit/attr.h index 25a9c26..f82c627 100644 --- a/navit/navit/attr.h +++ b/navit/navit/attr.h @@ -114,6 +114,8 @@ struct attr { struct cursor *cursor; struct displaylist *displaylist; struct transformation *transformation; + struct vehicleprofile *vehicleprofile; + struct roadprofile *roadprofile; struct range { short min, max; } range; diff --git a/navit/navit/attr_def.h b/navit/navit/attr_def.h index 9abc5fd..0421f1b 100644 --- a/navit/navit/attr_def.h +++ b/navit/navit/attr_def.h @@ -113,6 +113,8 @@ ATTR(route_weight) ATTR(distance_metric) ATTR(route_mode) ATTR(maxspeed_handling) +ATTR(flags_forward_mask) +ATTR(flags_reverse_mask) ATTR2(0x00027500,type_rel_abs_begin) /* These attributes are int that can either hold relative * @@ -224,6 +226,9 @@ ATTR(state_name) ATTR(message) ATTR(callbacks) ATTR(enable_expression) +ATTR(fax) +ATTR(email) +ATTR(url) ATTR2(0x0003ffff,type_string_end) ATTR2(0x00040000,type_special_begin) ATTR(order) diff --git a/navit/navit/item.c b/navit/navit/item.c index 623aa3e..9d1d8d5 100644 --- a/navit/navit/item.c +++ b/navit/navit/item.c @@ -37,26 +37,33 @@ struct item_range item_range_all = { type_none, type_last }; #define AF_ALL (AF_PBH|AF_MOPED|AF_MOTORIZED_FAST) -int default_flags[]={ - /* AF_PBH, street_nopass */ - AF_ALL, /* street_0 */ - AF_ALL, /* street_1_city */ - AF_ALL, /* street_2_city */ - AF_ALL, /* street_3_city */ - AF_ALL, /* street_4_city */ - AF_MOTORIZED_FAST, /* highway_city */ - AF_ALL, /* street_1_land */ - AF_ALL, /* street_2_land */ - AF_ALL, /* street_3_land */ - AF_ALL, /* street_4_land */ - AF_MOTORIZED_FAST, /* street_n_lanes */ - AF_MOTORIZED_FAST, /* highway_land */ - AF_MOTORIZED_FAST, /* ramp */ - AF_ALL, /* roundabout */ - AF_ALL, /* ferry */ +struct default_flags { + enum item_type type; + int flags; +}; + +struct default_flags default_flags2[]={ + {type_street_nopass, AF_PBH}, + {type_street_0, AF_ALL}, + {type_street_1_city, AF_ALL}, + {type_street_2_city, AF_ALL}, + {type_street_3_city, AF_ALL}, + {type_street_4_city, AF_ALL}, + {type_highway_city, AF_MOTORIZED_FAST}, + {type_street_1_land, AF_ALL}, + {type_street_2_land, AF_ALL}, + {type_street_3_land, AF_ALL}, + {type_street_4_land, AF_ALL}, + {type_street_n_lanes, AF_MOTORIZED_FAST}, + {type_highway_land, AF_MOTORIZED_FAST}, + {type_ramp, AF_MOTORIZED_FAST}, + {type_roundabout, AF_ALL}, + {type_ferry, AF_ALL}, + {type_cycleway, AF_ALL}, }; + struct item_name item_names[]={ #define ITEM2(x,y) ITEM(y) #define ITEM(x) { type_##x, #x }, @@ -65,6 +72,21 @@ struct item_name item_names[]={ #undef ITEM }; +static GHashTable *default_flags_hash; + +int * +item_get_default_flags(enum item_type type) +{ + if (!default_flags_hash) { + int i; + default_flags_hash=g_hash_table_new(NULL, NULL); + for (i = 0 ; i < sizeof(default_flags2)/sizeof(struct default_flags); i++) { + g_hash_table_insert(default_flags_hash, (void *)(long)default_flags2[i].type, &default_flags2[i].flags); + } + } + return g_hash_table_lookup(default_flags_hash, (void *)(long)type); +} + void item_coord_rewind(struct item *it) { diff --git a/navit/navit/item_def.h b/navit/navit/item_def.h index 05d17fb..4579ab7 100644 --- a/navit/navit/item_def.h +++ b/navit/navit/item_def.h @@ -303,6 +303,7 @@ ITEM(house_number) ITEM(route_start) ITEM(route_end) ITEM(selected_point) +ITEM(power_tower) /* Line */ ITEM2(0x80000000,line) ITEM2(0x80000001,line_unspecified) diff --git a/navit/navit/navit.c b/navit/navit/navit.c index 2886501..c8bbc44 100644 --- a/navit/navit/navit.c +++ b/navit/navit/navit.c @@ -134,6 +134,7 @@ struct navit { int use_mousewheel; struct messagelist *messages; struct callback *resize_callback,*button_callback,*motion_callback; + struct vehicleprofile *vehicleprofile; int pitch; }; @@ -1281,6 +1282,7 @@ navit_init(struct navit *this_) } route_set_mapset(this_->route, ms); route_set_projection(this_->route, transform_get_projection(this_->trans)); + route_set_profile(this_->route, this_->vehicleprofile); } if (this_->tracking) { tracking_set_mapset(this_->tracking, ms); @@ -1867,6 +1869,9 @@ navit_add_attr(struct navit *this_, struct attr *attr) case attr_vehicle: ret=navit_add_vehicle(this_, attr->u.vehicle); break; + case attr_vehicleprofile: + this_->vehicleprofile=attr->u.vehicleprofile; + break; case attr_autozoom_min: this_->autozoom_min = attr->u.num; break; diff --git a/navit/navit/navit.xml b/navit/navit/navit.xml index d01ab8d..656dbcc 100644 --- a/navit/navit/navit.xml +++ b/navit/navit/navit.xml @@ -107,7 +107,7 @@ - + @@ -171,23 +171,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + diff --git a/navit/navit/osm2navit.c b/navit/navit/osm2navit.c index 9eafcd2..edc93c0 100644 --- a/navit/navit/osm2navit.c +++ b/navit/navit/osm2navit.c @@ -141,6 +141,7 @@ static char *attrmap={ "n place=suburb district_label\n" "n place=town town_label_2e4\n" "n place=village town_label_2e3\n" + "n power=tower power_tower\n" "n railway=halt poi_rail_halt\n" "n railway=level_crossing poi_level_crossing\n" "n railway=station poi_rail_station\n" @@ -555,12 +556,6 @@ struct attr_bin maxspeed_attr = { }; int maxspeed_attr_value; -struct attr_bin house_number_attr = { - 0, attr_house_number -}; -char house_number_attr_buffer[BUFFER_SIZE]; - - struct attr_bin town_name_attr = { 0, attr_town_name }; @@ -593,7 +588,36 @@ long int osmid_attr_value; char is_in_buffer[BUFFER_SIZE]; +char attr_strings_buffer[BUFFER_SIZE*16]; +int attr_strings_buffer_len; + +enum attr_strings { + attr_string_phone, + attr_string_fax, + attr_string_email, + attr_string_url, + attr_string_street_name, + attr_string_house_number, + attr_string_label, + attr_string_last, +}; +char *attr_strings[attr_string_last]; + +static void +attr_strings_clear(void) +{ + attr_strings_buffer_len=0; + memset(attr_strings, 0, sizeof(attr_strings)); +} + +static void +attr_strings_save(enum attr_strings id, char *str) +{ + attr_strings[id]=attr_strings_buffer+attr_strings_buffer_len; + strcpy(attr_strings[id], str); + attr_strings_buffer_len+=strlen(str)+1; +} static void item_bin_init(struct item_bin *ib, enum item_type type) @@ -643,6 +667,26 @@ item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val) } static void +item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val) +{ + struct attr attr; + attr.type=type; + attr.u.num64=&val; + item_bin_add_attr(ib, &attr); +} + +static void +item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str) +{ + struct attr attr; + if (! str) + return; + attr.type=type; + attr.u.str=str; + item_bin_add_attr(ib, &attr); +} + +static void item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max) { struct attr attr; @@ -723,6 +767,7 @@ access_value(char *v) return 2; return 3; } + static void add_tag(char *k, char *v) { @@ -837,15 +882,30 @@ add_tag(char *k, char *v) if (! strcmp(k,"name")) { strcpy(label_attr_buffer, v); pad_text_attr(&label_attr, label_attr_buffer); + attr_strings_save(attr_string_label, v); + level=5; + } + if (! strcmp(k,"addr:email")) { + attr_strings_save(attr_string_email, v); level=5; } if (! strcmp(k,"addr:housenumber")) { - strcpy(house_number_attr_buffer, v); - pad_text_attr(&house_number_attr, house_number_attr_buffer); + attr_strings_save(attr_string_house_number, v); + level=5; } if (! strcmp(k,"addr:street")) { + attr_strings_save(attr_string_street_name, v); strcpy(street_name_attr_buffer, v); pad_text_attr(&street_name_attr, street_name_attr_buffer); + level=5; + } + if (! strcmp(k,"phone")) { + attr_strings_save(attr_string_phone, v); + level=5; + } + if (! strcmp(k,"fax")) { + attr_strings_save(attr_string_fax, v); + level=5; } if (! strcmp(k,"ref")) { if (in_way) { @@ -1024,11 +1084,11 @@ add_node(int id, double lat, double lon) { if (node_buffer.size + sizeof(struct node_item) > node_buffer.malloced) extend_buffer(&node_buffer); + attr_strings_clear(); node_is_tagged=0; nodeid=id; item.type=type_point_unkn; label_attr.len=0; - house_number_attr.len=0; street_name_attr.len=0; town_name_attr.len=0; debug_attr.len=0; @@ -1145,9 +1205,9 @@ add_way(int id) { wayid=id; coord_count=0; + attr_strings_clear(); item.type=type_street_unkn; label_attr.len=0; - house_number_attr.len=0; street_name_attr.len=0; street_name_systematic_attr.len=0; debug_attr.len=0; @@ -1285,6 +1345,7 @@ static void end_way(FILE *out) { int alen=0,count; + int *def_flags; enum item_type types[5]; if (! out) @@ -1312,9 +1373,9 @@ end_way(FILE *out) item.type=type_street_unkn; if (coverage && item_is_street(item)) item.type=type_coverage; - if (item.type >= route_item_first && item.type <= route_item_last) { - int def_flags=default_flags[item.type-route_item_first]; - flags_attr_value=(def_flags | flags[0] | flags[1]) & ~flags[2]; + def_flags=item_get_default_flags(item.type); + if (def_flags) { + flags_attr_value=(*def_flags | flags[0] | flags[1]) & ~flags[2]; if (flags_attr_value != def_flags) { flags_attr.len=2; alen+=flags_attr.len+1; @@ -1339,40 +1400,30 @@ end_way(FILE *out) static void end_node(FILE *out) { - int alen=0,conflict=0,count; + int conflict=0,count; enum item_type types[5]; struct country_table *result=NULL, *lookup; if (!out || ! node_is_tagged || ! nodeid) return; count=attr_longest_match(attr_mapping_node, attr_mapping_node_count, types, sizeof(types)/sizeof(enum item_type)); - pad_text_attr(&debug_attr, debug_attr_buffer); - if (label_attr.len) - alen+=label_attr.len+1; - if (debug_attr.len) - alen+=debug_attr.len+1; - if (house_number_attr.len) - alen+=house_number_attr.len+1; - if (street_name_attr.len) - alen+=street_name_attr.len+1; - if (osmid_attr.len) - alen+=osmid_attr.len+1; if (count) - item.type=types[0]; + item_bin_init(item_bin, types[0]); else - item.type=type_point_unkn; - item.clen=2; - item.len=item.clen+2+alen; - fwrite(&item, sizeof(item), 1, out); - fwrite(&ni->c, 1*sizeof(struct coord), 1, out); - if (item_is_town(item)) { - town_name_attr.len=label_attr.len; - write_attr(out, &town_name_attr, label_attr_buffer); - } else - write_attr(out, &label_attr, label_attr_buffer); - write_attr(out, &house_number_attr, house_number_attr_buffer); - write_attr(out, &street_name_attr, street_name_attr_buffer); - write_attr(out, &osmid_attr, &osmid_attr_value); - write_attr(out, &debug_attr, debug_attr_buffer); + item_bin_init(item_bin, type_point_unkn); + item_bin_add_coord(item_bin, &ni->c, 1); + if (osmid_attr_value == 368279467) { + fprintf(stderr,"%s\n", attr_strings[attr_string_label]); + } + item_bin_add_attr_string(item_bin, item_is_town(item) ? attr_town_name : attr_label, attr_strings[attr_string_label]); + item_bin_add_attr_string(item_bin, attr_house_number, attr_strings[attr_string_house_number]); + item_bin_add_attr_string(item_bin, attr_street_name, attr_strings[attr_string_street_name]); + item_bin_add_attr_string(item_bin, attr_phone, attr_strings[attr_string_phone]); + item_bin_add_attr_string(item_bin, attr_fax, attr_strings[attr_string_fax]); + item_bin_add_attr_string(item_bin, attr_email, attr_strings[attr_string_email]); + item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]); + item_bin_add_attr_longlong(item_bin, attr_osm_nodeid, osmid_attr_value); + item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer); + item_bin_write(item_bin,out); if (item_is_town(item) && town_name_attr.len) { char *tok,*buf=is_in_buffer; while ((tok=strtok(buf, ","))) { diff --git a/navit/navit/roadprofile.c b/navit/navit/roadprofile.c index a3ce77c..07c2929 100644 --- a/navit/navit/roadprofile.c +++ b/navit/navit/roadprofile.c @@ -22,17 +22,30 @@ #include "item.h" #include "roadprofile.h" -struct roadprofile { - struct attr **attrs; -}; +static void +roadprofile_set_attr_do(struct roadprofile *this, struct attr *attr) +{ + switch (attr->type) { + case attr_speed: + this->speed=attr->u.num; + break; + case attr_route_weight: + this->route_weight=attr->u.num; + break; + default: + break; + } +} struct roadprofile * roadprofile_new(struct attr *parent, struct attr **attrs) { struct roadprofile *this_; - struct attr *type_attr; + struct attr **attr; this_=g_new0(struct roadprofile, 1); this_->attrs=attr_list_dup(attrs); + for (attr=attrs;*attr; attr++) + roadprofile_set_attr_do(this_, *attr); return this_; } @@ -45,6 +58,7 @@ roadprofile_get_attr(struct roadprofile *this_, enum attr_type type, struct attr int roadprofile_set_attr(struct roadprofile *this_, struct attr *attr) { + roadprofile_set_attr_do(this_, attr); this_->attrs=attr_generic_set_attr(this_->attrs, attr); return 1; } diff --git a/navit/navit/roadprofile.h b/navit/navit/roadprofile.h index 3154820..04d7263 100644 --- a/navit/navit/roadprofile.h +++ b/navit/navit/roadprofile.h @@ -17,6 +17,12 @@ * Boston, MA 02110-1301, USA. */ +struct roadprofile { + struct attr **attrs; + int speed; + int route_weight; +}; + struct roadprofile * roadprofile_new(struct attr *parent, struct attr **attrs); int roadprofile_get_attr(struct roadprofile *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter); int roadprofile_set_attr(struct roadprofile *this_, struct attr *attr); diff --git a/navit/navit/route.c b/navit/navit/route.c index 3cce31a..81c492a 100644 --- a/navit/navit/route.c +++ b/navit/navit/route.c @@ -66,6 +66,8 @@ #include "fib.h" #include "event.h" #include "callback.h" +#include "vehicleprofile.h" +#include "roadprofile.h" struct map_priv { @@ -190,21 +192,6 @@ struct route_path { #define RF_SHOWGRAPH (1<<5) /** - * @brief Routing preferences - * - * This struct holds all information about route preferences (fastest, shortest, etc) - */ - -struct route_preferences { - int mode; /**< 0 = Auto, 1 = On-Road, 2 = Off-Road */ - int flags_forward_mask; /**< Flags mask for moving in positive direction */ - int flags_reverse_mask; /**< Flags mask for moving in reverse direction */ - int flags; /**< Required flags to move through a segment */ - int maxspeed_handling; /**< 0 = Always, 1 = Only if lower, 2 = Never */ - int speedlist[route_item_last-route_item_first+1]; /**< The speedlist for this route */ -}; - -/** * @brief A complete route * * This struct holds all information about a route. @@ -223,7 +210,7 @@ struct route { struct callback * route_graph_flood_done_cb ; /**< Callback when route graph flooding is done */ struct callback_list *cbl2; /**< Callback list to call when route changes */ int destination_distance; /**< Distance to the destination at which the destination is considered "reached" */ - struct route_preferences preferences; /**< Routing preferences */ + struct vehicleprofile *vehicleprofile; /**< Routing preferences */ int route_status; /**< Route Status */ }; @@ -237,7 +224,8 @@ struct route_graph { struct map_selection *sel; /**< The rectangle selection for the graph */ struct mapset_handle *h; /**< Handle to the mapset */ struct map *m; /**< Pointer to the currently active map */ - struct map_rect *mr; /**< Pointer to the currently active map rectangle */ + struct map_rect *mr; /**< Pointer to the currently active map rectangle */ + struct vehicleprofile *vehicleprofile; /**< The vehicle profile */ struct callback *idle_cb; /**< Idle callback to process the graph */ struct callback *done_cb; /**< Callback when graph is done */ struct event_idle *idle_ev; /**< The pointer to the idle event */ @@ -265,7 +253,7 @@ static struct route_info * route_find_nearest_street(struct mapset *ms, struct p static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c); static void route_graph_update(struct route *this, struct callback *cb); static void route_graph_build_done(struct route_graph *rg, int cancel); -static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct route_preferences *pref); +static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile); static void route_process_street_graph(struct route_graph *this, struct item *item); static void route_graph_destroy(struct route_graph *this); static void route_path_update(struct route *this, int cancel); @@ -400,9 +388,6 @@ route_new(struct attr *parent, struct attr **attrs) this->destination_distance = 50; // Default value } this->cbl2=callback_list_new(); - this->preferences.flags_forward_mask=AF_ONEWAYREV|AF_CAR; - this->preferences.flags_reverse_mask=AF_ONEWAY|AF_CAR; - this->preferences.flags=AF_CAR; return this; } @@ -493,6 +478,19 @@ route_set_mapset(struct route *this, struct mapset *ms) } /** + * @brief Sets the vehicle profile of a route + * + * @param this The route to set the profile for + * @param prof The vehicle profile + */ + +void +route_set_profile(struct route *this, struct vehicleprofile *prof) +{ + this->vehicleprofile=prof; +} + +/** * @brief Returns the mapset of the route passed * * @param this The route to get the mapset of @@ -529,18 +527,6 @@ route_get_dst(struct route *this) } /** - * @brief Returns the speedlist of the route passed - * - * @param this The route to get the speedlist for - * @return The speedlist of the route passed - */ -int * -route_get_speedlist(struct route *this) -{ - return this->preferences.speedlist; -} - -/** * @brief Checks if the path is calculated for the route passed * * @param this The route to check @@ -553,25 +539,6 @@ route_get_path_set(struct route *this) } /** - * @brief Sets the driving speed for a certain itemtype - * - * @param this The route to set the speed for - * @param type The itemtype to set the speed for - * @param value The speed that should be set - * @return True on success, false if the itemtype does not exist - */ -int -route_set_speed(struct route *this, enum item_type type, int value) -{ - if (type < route_item_first || type > route_item_last) { - dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last); - return 0; - } - this->preferences.speedlist[type-route_item_first]=value; - return 1; -} - -/** * @brief Checks if the route passed contains a certain item within the route path * * This function checks if a certain items exists in the path that navit will guide @@ -660,7 +627,7 @@ route_path_update_done(struct route *this, int new_graph) route_status.u.num=route_status_building_path; route_set_attr(this, &route_status); - this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, &this->preferences); + this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->vehicleprofile); route_path_destroy(oldpath); if (this->path2) { if (!new_graph && this->path2->updated) @@ -1419,22 +1386,24 @@ route_graph_destroy(struct route_graph *this) * This function returns the time needed to drive len meters on * the item passed in item in tenth of seconds. * - * @param preferences The routing preferences + * @param profile The routing preferences * @param over The segment which is passed * @return The time needed to drive len on item in thenth of senconds */ static int -route_time_seg(struct route_preferences *preferences, struct route_segment_data *over) +route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over) { - int pspeed=preferences->speedlist[over->item.type-route_item_first]; - int speed=pspeed; - if (preferences->maxspeed_handling != 2 && (over->flags & AF_SPEED_LIMIT)) { + struct roadprofile *roadprofile=vehicleprofile_get_roadprofile(profile, over->item.type); + int speed; + if (!roadprofile || !roadprofile->route_weight) + return INT_MAX; + if (profile->maxspeed_handling != 2 && (over->flags & AF_SPEED_LIMIT)) { speed=RSD_MAXSPEED(over); - if (preferences->maxspeed_handling == 1 && speed > pspeed) - speed=pspeed; + if (profile->maxspeed_handling == 1 && speed > roadprofile->route_weight) + speed=roadprofile->route_weight; } else - speed=preferences->speedlist[over->item.type-route_item_first]; + speed=roadprofile->route_weight; if (!speed) return INT_MAX; return over->len*36/speed; @@ -1443,7 +1412,7 @@ route_time_seg(struct route_preferences *preferences, struct route_segment_data /** * @brief Returns the "costs" of driving from point from over segment over in direction dir * - * @param preferences The routing preferences + * @param profile The routing preferences * @param from The point where we are starting * @param over The segment we are using * @param dir The direction of segment which we are driving @@ -1451,14 +1420,14 @@ route_time_seg(struct route_preferences *preferences, struct route_segment_data */ static int -route_value_seg(struct route_preferences *preferences, struct route_graph_point *from, struct route_segment_data *over, int dir) +route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_segment_data *over, int dir) { #if 0 dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? preferences->flags_forward_mask : preferences->flags_reverse_mask, preferences->flags); #endif - if ((over->flags & (dir >= 0 ? preferences->flags_forward_mask : preferences->flags_reverse_mask)) != preferences->flags) + if ((over->flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags) return INT_MAX; - return route_time_seg(preferences, over); + return route_time_seg(profile, over); } /** @@ -1487,12 +1456,15 @@ route_process_street_graph(struct route_graph *this, struct item *item) int maxspeed = -1; if (item_coord_get(item, &l, 1)) { + int *default_flags=item_get_default_flags(item->type); + if (! default_flags) + return; if (item_attr_get(item, attr_flags, &flags_attr)) { flags = flags_attr.u.num; if (flags & AF_SEGMENTED) segmented = 1; } else - flags = default_flags[item->type-route_item_first]; + flags = *default_flags; if (flags & AF_SPEED_LIMIT) { @@ -1567,7 +1539,7 @@ route_graph_get_segment(struct route_graph *graph, struct street_data *sd) * at this algorithm. */ static void -route_graph_flood(struct route_graph *this, struct route_info *dst, struct route_preferences *preferences, struct callback *cb) +route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb) { struct route_graph_point *p_min; struct route_graph_segment *s; @@ -1581,14 +1553,14 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route dbg(0,"no segment for destination found\n"); return; } - val=route_value_seg(preferences, NULL, &s->data, 1); + val=route_value_seg(profile, NULL, &s->data, 1); if (val != INT_MAX) { val=val*(100-dst->percent)/100; s->end->seg=s; s->end->value=val; s->end->el=fh_insertkey(heap, s->end->value, s->end); } - val=route_value_seg(preferences, NULL, &s->data, -1); + val=route_value_seg(profile, NULL, &s->data, -1); if (val != INT_MAX) { val=val*dst->percent/100; s->start->seg=s; @@ -1605,7 +1577,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route p_min->el=NULL; /* This point is permanently calculated now, we've taken it out of the heap */ s=p_min->start; while (s) { /* Iterating all the segments leading away from our point to update the points at their ends */ - val=route_value_seg(preferences, p_min, &s->data, -1); + val=route_value_seg(profile, p_min, &s->data, -1); if (val != INT_MAX) { new=min+val; if (debug_route) @@ -1633,7 +1605,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route } s=p_min->end; while (s) { /* Doing the same as above with the segments leading towards our point */ - val=route_value_seg(preferences, p_min, &s->data, 1); + val=route_value_seg(profile, p_min, &s->data, 1); if (val != INT_MAX) { new=min+val; if (debug_route) @@ -1761,7 +1733,7 @@ route_get_coord_dist(struct route *this_, int dist) * @return The new route path */ static struct route_path * -route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct route_preferences *preferences) +route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile) { struct route_graph_segment *first,*s=NULL; struct route_graph_point *start; @@ -1774,7 +1746,7 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout if (! pos->street || ! dst->street) return NULL; - if (preferences->mode == 2 || (preferences->mode == 0 && pos->lenextra + dst->lenextra + pos->lenpos-dst->lenpos > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) + if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra + pos->lenpos-dst->lenpos > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) return route_path_new_offroad(this, pos, dst); s=route_graph_get_segment(this, pos->street); @@ -1782,12 +1754,12 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout dbg(0,"no segment for position found\n"); return NULL; } - val=route_value_seg(preferences, NULL, &s->data, -1); + val=route_value_seg(profile, NULL, &s->data, -1); if (val != INT_MAX) { val=val*(100-pos->percent)/100; val1=s->end->value+val; } - val=route_value_seg(preferences, NULL, &s->data, 1); + val=route_value_seg(profile, NULL, &s->data, 1); if (val != INT_MAX) { val=val*pos->percent/100; val2=s->start->value+val; @@ -1888,8 +1860,7 @@ route_graph_build_idle(struct route_graph *rg) return; } } - if (item->type >= route_item_first && item->type <= route_item_last) - route_process_street_graph(rg, item); + route_process_street_graph(rg, item); count--; } } @@ -1933,7 +1904,7 @@ route_graph_build(struct mapset *ms, struct coord *c1, struct coord *c2, struct static void route_graph_update_done(struct route *this, struct callback *cb) { - route_graph_flood(this->graph, this->dst, &this->preferences, cb); + route_graph_flood(this->graph, this->dst, this->vehicleprofile, cb); } /** @@ -2255,7 +2226,7 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) case attr_time: mr->attr_next=attr_none; if (seg) { - attr->u.num=route_time_seg(&route->preferences, seg->data); + attr->u.num=route_time_seg(route->vehicleprofile, seg->data); } else return 0; return 1; diff --git a/navit/navit/vehicleprofile.c b/navit/navit/vehicleprofile.c index 7d3f781..31c9bc9 100644 --- a/navit/navit/vehicleprofile.c +++ b/navit/navit/vehicleprofile.c @@ -23,20 +23,43 @@ #include "item.h" #include "vehicleprofile.h" -struct vehicleprofile { - struct attr **attrs; -}; +void +vehicleprofile_set_attr_do(struct vehicleprofile *this_, struct attr *attr) +{ + switch (attr->type) { + case attr_flags: + this_->flags=attr->u.num; + break; + case attr_flags_forward_mask: + this_->flags_forward_mask=attr->u.num; + break; + case attr_flags_reverse_mask: + this_->flags_forward_mask=attr->u.num; + break; + case attr_maxspeed_handling: + this_->maxspeed_handling=attr->u.num; + break; + case attr_route_mode: + this_->mode=attr->u.num; + break; + default: + break; + } +} struct vehicleprofile * vehicleprofile_new(struct attr *parent, struct attr **attrs) { struct vehicleprofile *this_; - struct attr *type_attr; + struct attr **attr, *type_attr; if (! (type_attr=attr_search(attrs, NULL, attr_name))) { return NULL; } this_=g_new0(struct vehicleprofile, 1); this_->attrs=attr_list_dup(attrs); + this_->roadprofile_hash=g_hash_table_new(NULL, NULL); + for (attr=attrs;*attr; attr++) + vehicleprofile_set_attr_do(this_, *attr); return this_; } @@ -49,6 +72,7 @@ vehicleprofile_get_attr(struct vehicleprofile *this_, enum attr_type type, struc int vehicleprofile_set_attr(struct vehicleprofile *this_, struct attr *attr) { + vehicleprofile_set_attr_do(this_, attr); this_->attrs=attr_generic_set_attr(this_->attrs, attr); return 1; } @@ -57,6 +81,21 @@ int vehicleprofile_add_attr(struct vehicleprofile *this_, struct attr *attr) { this_->attrs=attr_generic_add_attr(this_->attrs, attr); + struct attr item_types_attr; + switch (attr->type) { + case attr_roadprofile: + if (roadprofile_get_attr(attr->u.roadprofile, attr_item_types, &item_types_attr)) { + enum item_type *types=item_types_attr.u.item_types; + while (*types != type_none) { + g_hash_table_insert(this_->roadprofile_hash, (void *)(long)(*types), attr->u.roadprofile); + types++; + } + dbg(0,"ok\n"); + } + break; + default: + break; + } return 1; } @@ -67,3 +106,8 @@ vehicleprofile_remove_attr(struct vehicleprofile *this_, struct attr *attr) return 1; } +struct roadprofile_data * +vehicleprofile_get_roadprofile(struct vehicleprofile *this_, enum item_type type) +{ + return g_hash_table_lookup(this_->roadprofile_hash, (void *)(long)type); +} diff --git a/navit/navit/vehicleprofile.h b/navit/navit/vehicleprofile.h index bb09f5d..cbb7271 100644 --- a/navit/navit/vehicleprofile.h +++ b/navit/navit/vehicleprofile.h @@ -17,6 +17,16 @@ * Boston, MA 02110-1301, USA. */ +struct vehicleprofile { + int mode; /**< 0 = Auto, 1 = On-Road, 2 = Off-Road */ + int flags_forward_mask; /**< Flags mask for moving in positive direction */ + int flags_reverse_mask; /**< Flags mask for moving in reverse direction */ + int flags; /**< Required flags to move through a segment */ + int maxspeed_handling; /**< 0 = Always, 1 = Only if lower, 2 = Never */ + struct attr **attrs; + GHashTable *roadprofile_hash; +}; + struct vehicleprofile * vehicleprofile_new(struct attr *parent, struct attr **attrs); int vehicleprofile_get_attr(struct vehicleprofile *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter); int vehicleprofile_set_attr(struct vehicleprofile *this_, struct attr *attr); diff --git a/navit/navit/xmlconfig.c b/navit/navit/xmlconfig.c index 061feda..7110c24 100644 --- a/navit/navit/xmlconfig.c +++ b/navit/navit/xmlconfig.c @@ -194,35 +194,6 @@ xmlconfig_config(struct xmlstate *state) } static int -xmlconfig_speed(struct xmlstate *state) -{ - const char *type; - const char *value; - int v; - enum item_type itype; - char *tok, *type_str, *str; - - type=find_attribute(state, "type", 1); - if (! type) - return 0; - value=find_attribute(state, "value", 1); - if (! value) - return 0; - v=convert_number(value); - type_str=g_strdup(type); - str=type_str; - while ((tok=strtok(str, ","))) { - itype=item_from_name(tok); - route_set_speed(state->parent->element_attr.u.data, itype, v); - str=NULL; - } - g_free(type_str); - - return 1; -} - - -static int xmlconfig_announce(struct xmlstate *state) { const char *type,*value; @@ -323,7 +294,6 @@ struct element_func { { "speech", "navit", NULL, attr_speech}, { "tracking", "navit", NULL, attr_tracking}, { "route", "navit", NULL, attr_route}, - { "speed", "route", xmlconfig_speed}, { "mapset", "navit", NULL, attr_mapset}, { "map", "mapset", NULL, attr_map}, { "debug", "config", NULL, attr_debug}, -- 2.7.4