diff options
author | mvglasow <michael@vonglasow.com> | 2021-04-26 23:29:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-26 23:29:57 +0200 |
commit | 488d07fc4989326f6c8c915de0beb07bca2b546a (patch) | |
tree | 9ed2b1949f6f42e2623297ce0a6cf7c7328d2eec | |
parent | 8de0102febe6a378256fe2b0def51d0da8c7916a (diff) | |
parent | 80fdb18d36861a19b8d4a015906197d92058f3b8 (diff) | |
download | navit-488d07fc4989326f6c8c915de0beb07bca2b546a.tar.gz |
Merge pull request #1115 from navit-gps/issue-1113
Fix issues resulting in ignored traffic messages
-rw-r--r-- | navit/item.c | 7 | ||||
-rw-r--r-- | navit/route.c | 16 | ||||
-rw-r--r-- | navit/traffic.c | 21 |
3 files changed, 35 insertions, 9 deletions
diff --git a/navit/item.c b/navit/item.c index ab590cb4e..120675339 100644 --- a/navit/item.c +++ b/navit/item.c @@ -394,6 +394,13 @@ void item_attr_rewind(struct item *it) { * This function returns the next attribute matching `attr_type` from an item and advances the * "attribute pointer" accordingly, so that at the next call the next attribute will be returned. * + * IMPORTANT: Unless you are iterating over attributes, or operating on a “fresh” item (from which no + * other code has had a chance to retrieve an attribute), be sure to call + * {@link item_attr_rewind(struct item *)} before each call to this method. Not doing so may result in + * unpredictable behavior, i.e. attributes not being found if the attribute pointer is already past the + * requested attribute (which depends on the physical ordering of attributes and on the last attribute + * retrieved from the item). + * * This function is not safe to call after destroying the item's map rect, and doing so may cause errors * with some map implementations. * diff --git a/navit/route.c b/navit/route.c index b9fa9667f..9d9ecf23d 100644 --- a/navit/route.c +++ b/navit/route.c @@ -1609,11 +1609,7 @@ int route_graph_segment_is_duplicate(struct route_graph_point *start, struct rou * @param this The route graph to insert the segment into * @param start The graph point which should be connected to the start of this segment * @param end The graph point which should be connected to the end of this segment - * @param len The length of this segment - * @param item The item that is represented by this segment - * @param flags Flags for this segment - * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item - * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known. + * @param data The segment data */ void route_graph_add_segment(struct route_graph *this, struct route_graph_point *start, struct route_graph_point *end, struct route_graph_segment_data *data) { @@ -2335,10 +2331,12 @@ static void route_graph_add_traffic_distortion(struct route_graph *this, struct e_pnt=route_graph_add_point(this,&l); s_pnt->flags |= RP_TRAFFIC_DISTORTION; e_pnt->flags |= RP_TRAFFIC_DISTORTION; + item_attr_rewind(item); if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) { data.flags |= AF_SPEED_LIMIT; data.maxspeed=maxspeed_attr.u.num; } + item_attr_rewind(item); if (item_attr_get(item, attr_delay, &delay_attr)) data.len=delay_attr.u.num; route_graph_add_segment(this, s_pnt, e_pnt, &data); @@ -2552,37 +2550,45 @@ static void route_graph_add_street(struct route_graph *this, struct item *item, if (item_coord_get(item, &l, 1)) { if (!(default_flags = item_get_default_flags(item->type))) default_flags = &default_flags_value; + item_attr_rewind(item); if (item_attr_get(item, attr_flags, &attr)) { data.flags = attr.u.num; segmented = (data.flags & AF_SEGMENTED); } else data.flags = *default_flags; + item_attr_rewind(item); if ((data.flags & AF_SPEED_LIMIT) && (item_attr_get(item, attr_maxspeed, &attr))) data.maxspeed = attr.u.num; if (data.flags & AF_DANGEROUS_GOODS) { + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr)) data.dangerous_goods = attr.u.num; else data.flags &= ~AF_DANGEROUS_GOODS; } if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT) { + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_width, &attr)) data.size_weight.width=attr.u.num; else data.size_weight.width=-1; + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_height, &attr)) data.size_weight.height=attr.u.num; else data.size_weight.height=-1; + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_length, &attr)) data.size_weight.length=attr.u.num; else data.size_weight.length=-1; + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_weight, &attr)) data.size_weight.weight=attr.u.num; else data.size_weight.weight=-1; + item_attr_rewind(item); if (item_attr_get(item, attr_vehicle_axle_weight, &attr)) data.size_weight.axle_weight=attr.u.num; else diff --git a/navit/traffic.c b/navit/traffic.c index 8dc3a1645..a9cc5a1a7 100644 --- a/navit/traffic.c +++ b/navit/traffic.c @@ -731,6 +731,7 @@ static struct item * tm_find_item(struct map_rect *mr, enum item_type type, stru if (attr_generic_get_attr(attrs, NULL, attr_flags, &wanted_flags_attr, NULL)) { if (!item_attr_get(curr, attr_flags, &curr_flags_attr)) continue; + item_attr_rewind(curr); if ((wanted_flags_attr.u.num & AF_ALL) != (curr_flags_attr.u.num & AF_ALL)) continue; continue; @@ -954,10 +955,6 @@ static struct map_rect_priv * tm_rect_new(struct map_priv *priv, struct map_sele int dirty = 0; dbg(lvl_debug,"enter"); - mr=g_new0(struct map_rect_priv, 1); - mr->mpriv = priv; - mr->next_item = priv->items; - /* all other pointers are initially NULL */ /* lazy location matching */ if (sel != NULL) @@ -990,6 +987,12 @@ static struct map_rect_priv * tm_rect_new(struct map_priv *priv, struct map_sele map_selection_destroy(msg_sel); } } + + mr=g_new0(struct map_rect_priv, 1); + mr->mpriv = priv; + mr->next_item = priv->items; + /* all other pointers are initially NULL */ + if (dirty) /* dump message store if new messages have been received */ traffic_dump_messages_to_xml(priv->shared); @@ -1379,6 +1382,7 @@ static int traffic_location_match_attributes(struct traffic_location * this_, st /* road_ref */ if (this_->road_ref) { maxscore += 400; + item_attr_rewind(item); if (item_attr_get(item, attr_street_name_systematic, &attr)) score += (400 * (MAX_MISMATCH - compare_name_systematic(this_->road_ref, attr.u.str))) / MAX_MISMATCH; } @@ -1386,6 +1390,7 @@ static int traffic_location_match_attributes(struct traffic_location * this_, st /* road_name */ if (this_->road_name) { maxscore += 200; + item_attr_rewind(item); if (item_attr_get(item, attr_street_name, &attr)) { // TODO crude comparison in need of refinement if (!strcmp(this_->road_name, attr.u.str)) @@ -1430,12 +1435,14 @@ static int traffic_point_match_attributes(struct traffic_point * this_, struct i /* junction_ref */ if (this_->junction_ref) { maxscore += 400; + item_attr_rewind(item); if (item_attr_get(item, attr_ref, &attr)) score += (400 * (MAX_MISMATCH - compare_name_systematic(this_->junction_ref, attr.u.str))) / MAX_MISMATCH; } /* junction_name */ if (this_->junction_name) { + item_attr_rewind(item); if (item_attr_get(item, attr_label, &attr)) { maxscore += 400; // TODO crude comparison in need of refinement @@ -1560,6 +1567,7 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_, if (!strcmp(this_->junction_name, attr.u.str)) has_start_match = 1; } + item_attr_rewind(item); if (item_attr_get(item, attr_street_name_systematic, &attr)) start_ref = g_strdup(attr.u.str); } @@ -1576,6 +1584,7 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_, if (!strcmp(this_->junction_name, attr.u.str)) has_end_match = 1; } + item_attr_rewind(item); if (item_attr_get(item, attr_street_name_systematic, &attr)) end_ref = g_strdup(attr.u.str); } @@ -1620,6 +1629,7 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_, if (end_name) route_leaves_road |= !strcmp(end_name, attr.u.str); } + item_attr_rewind(item); if (!route_leaves_road && item_attr_get(item, attr_street_name_systematic, &attr)) { if (start_ref) route_leaves_road |= !compare_name_systematic(start_ref, attr.u.str); @@ -1645,6 +1655,7 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_, if (end_name) route_leaves_road |= !strcmp(end_name, attr.u.str); } + item_attr_rewind(item); if (!route_leaves_road && item_attr_get(item, attr_street_name_systematic, &attr)) { if (start_ref) route_leaves_road |= !compare_name_systematic(start_ref, attr.u.str); @@ -1981,6 +1992,7 @@ static void traffic_location_populate_route_graph(struct traffic_location * this } else data.flags = *default_flags; + item_attr_rewind(item); if ((data.flags & AF_SPEED_LIMIT) && (item_attr_get(item, attr_maxspeed, &attr))) data.maxspeed = attr.u.num; @@ -3614,6 +3626,7 @@ static int traffic_message_restore_segments(struct traffic_message * this_, stru segmented = 0; } /* Get maxspeed, if any */ + item_attr_rewind(map_item); if ((item_flags & AF_SPEED_LIMIT) && (item_attr_get(map_item, attr_maxspeed, &attr))) maxspeed = attr.u.num; else |