diff options
author | mvglasow <michael -at- vonglasow.com> | 2018-04-13 17:35:01 +0200 |
---|---|---|
committer | mvglasow <michael -at- vonglasow.com> | 2018-04-13 17:35:01 +0200 |
commit | a35f6e2a4b3594cb28c75fc1e36c671e68e000bd (patch) | |
tree | e47082f3e4f932e05a5302c3bdceaa043b1d624d /navit | |
parent | e79d572086f079dfe12be54eae6ad93061607375 (diff) | |
download | navit-a35f6e2a4b3594cb28c75fc1e36c671e68e000bd.tar.gz |
Add:traffic:Initial support for oneway/access flags on traffic distortions
Signed-off-by: mvglasow <michael -at- vonglasow.com>
Diffstat (limited to 'navit')
-rw-r--r-- | navit/attr.h | 1 | ||||
-rw-r--r-- | navit/route.c | 25 | ||||
-rw-r--r-- | navit/traffic.c | 69 |
3 files changed, 76 insertions, 19 deletions
diff --git a/navit/attr.h b/navit/attr.h index 4884ea95b..9f6a20ec4 100644 --- a/navit/attr.h +++ b/navit/attr.h @@ -91,6 +91,7 @@ enum attr_format { #define AF_PBH (AF_PEDESTRIAN|AF_BIKE|AF_HORSE) #define AF_MOTORIZED_FAST (AF_MOTORCYCLE|AF_CAR|AF_HIGH_OCCUPANCY_CAR|AF_TAXI|AF_PUBLIC_BUS|AF_DELIVERY_TRUCK|AF_TRANSPORT_TRUCK|AF_EMERGENCY_VEHICLES) #define AF_ALL (AF_PBH|AF_MOPED|AF_MOTORIZED_FAST) +#define AF_DISTORTIONMASK (AF_ALL|AF_ONEWAYMASK) #define AF_DG_ANY (1<<0) diff --git a/navit/route.c b/navit/route.c index 25a0c6564..662c36bad 100644 --- a/navit/route.c +++ b/navit/route.c @@ -104,6 +104,9 @@ struct route_traffic_distortion { leave the speed unchanged, or 0 to mark the segment as impassable. */ int delay; /**< Delay in tenths of seconds (0 for no delay) */ + int flags; /**< Flags indicating the modes of transportation and direction to + * which the traffic distortion applies. Other flags are not + * defined for traffic distortions and should not be used. */ }; /** @@ -1935,6 +1938,7 @@ route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, * * @return true if a traffic distortion was found, 0 if not */ +/* TODO handle multiple distortions for same segment (with different access flags) */ static int route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traffic_distortion *ret) { @@ -1959,6 +1963,7 @@ route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traff ret->maxspeed=RSD_MAXSPEED(&found->data); else ret->maxspeed=INT_MAX; + ret->flags = found->data.flags & AF_DISTORTIONMASK; return 1; } return 0; @@ -2005,9 +2010,16 @@ route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, return INT_MAX; if (from && from->seg == over) return INT_MAX; + if (over->data.item.type == type_traffic_distortion) + return INT_MAX; if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist) && dir != 2 && dir != -2) { + /* we have a traffic distortion, check if access flags match */ + if ((dist.flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags) { + distp = 0; + } else { distp=&dist; + } } ret=route_time_seg(profile, &over->data, distp); if (ret == INT_MAX) @@ -2064,6 +2076,7 @@ route_graph_set_traffic_distortion(struct route_graph *this, struct route_graph_ item.type=type_traffic_distortion; data.item=&item; data.len=delay; + data.flags = seg->data.flags & AF_DISTORTIONMASK; s->start->flags |= RP_TRAFFIC_DISTORTION; s->end->flags |= RP_TRAFFIC_DISTORTION; route_graph_add_segment(this, s->start, s->end, &data); @@ -2087,15 +2100,19 @@ route_process_traffic_distortion(struct route_graph *this, struct item *item) { struct route_graph_point *s_pnt,*e_pnt; struct coord c,l; - struct attr delay_attr, maxspeed_attr; + struct attr flags_attr, delay_attr, maxspeed_attr; struct route_graph_segment_data data; data.item=item; data.len=0; - data.flags=0; data.offset=1; data.maxspeed = INT_MAX; + if (item_attr_get(item, attr_flags, &flags_attr)) + data.flags = flags_attr.u.num & AF_DISTORTIONMASK; + else + data.flags = 0; + if (item_coord_get(item, &l, 1)) { s_pnt=route_graph_add_point(this,&l); while (item_coord_get(item, &c, 1)) { @@ -3269,6 +3286,8 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) return 0; return 1; case attr_time: + /* FIXME This ignores access flags on traffic distortions, but the attribute does not seem + * to be used anywhere */ mr->attr_next=attr_speed; if (seg) attr->u.num=route_time_seg(route->vehicleprofile, seg->data, NULL); @@ -3276,6 +3295,8 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) return 0; return 1; case attr_speed: + /* FIXME This ignores access flags on traffic distortions, but the attribute does not seem + * to be used anywhere */ mr->attr_next=attr_label; if (seg) attr->u.num=route_seg_speed(route->vehicleprofile, seg->data, NULL); diff --git a/navit/traffic.c b/navit/traffic.c index 5393de988..61739aaef 100644 --- a/navit/traffic.c +++ b/navit/traffic.c @@ -177,6 +177,8 @@ struct seg_data { int speed_factor; /**< Expected speed expressed as a percentage of the posted limit (100 * for full speed) */ int delay; /**< Expected delay for all segments combined, in 1/10 s */ + enum location_dir dir; /**< Directionality */ + int flags; /**< Access flags (modes of transportation to which the message applies) */ struct attr ** attrs; /**< Additional attributes to add to the segments */ }; @@ -225,7 +227,7 @@ struct xml_element { static struct seg_data * seg_data_new(void); static struct item * tm_add_item(struct map *map, enum item_type type, int id_hi, int id_lo, - struct attr **attrs, struct coord *c, int count, char * id); + int flags, struct attr **attrs, struct coord *c, int count, char * id); static void tm_dump_item_to_textfile(struct item * item); static void tm_destroy(struct map_priv *priv); static void tm_coord_rewind(void *priv_data); @@ -338,6 +340,10 @@ static int seg_data_equals(struct seg_data * l, struct seg_data * r) { return 0; if (l->delay != r->delay) return 0; + if (l->dir != r->dir) + return 0; + if (l->flags != r->flags) + return 0; if (!l->attrs && !r->attrs) return 1; if (!l->attrs || !r->attrs) @@ -576,8 +582,12 @@ static void tm_item_update_attrs(struct item * item) { /** * @brief Returns an item from the map which matches the supplied data. * - * For now only the item type, start coordinates and end coordinates are compared; attributes are - * ignored. Inverted coordinates are not considered a match for now. + * Comparison criteria are as follows: + * + * \li The item type must match + * \li Start and end coordinates must match (inverted coordinates are not considered a match for now) + * \li If `attr_flags` is supplied, the item must have this attribute and values must match + * \li Other attributes are ignored for now * * @param mr A map rectangle in the traffic map * @param type Type of the item @@ -595,10 +605,16 @@ static struct item * tm_find_item(struct map_rect *mr, enum item_type type, stru struct item * ret = NULL; struct item * curr; struct item_priv * curr_priv; + struct attr wanted_flags_attr, curr_flags_attr; while ((curr = map_rect_get_item(mr)) && !ret) { if (curr->type != type) continue; + if (attr_generic_get_attr(attrs, NULL, attr_flags, &wanted_flags_attr, NULL)) { + if (!item_attr_get(curr, attr_flags, &curr_flags_attr) + || (wanted_flags_attr.u.num != curr_flags_attr.u.num)) + continue; + } curr_priv = curr->priv_data; if (curr_priv->coords[0].x == c[0].x && curr_priv->coords[0].y == c[0].y && curr_priv->coords[curr_priv->coord_count-1].x == c[count-1].x @@ -695,13 +711,19 @@ static void tm_dump_to_textfile(struct map * map) { * @return The map item */ static struct item * tm_add_item(struct map *map, enum item_type type, int id_hi, int id_lo, - struct attr **attrs, struct coord *c, int count, char * id) { + int flags, struct attr **attrs, struct coord *c, int count, char * id) { struct item * ret = NULL; struct item_priv * priv_data; struct map_rect * mr; + struct attr ** int_attrs = NULL; + struct attr flags_attr; + + flags_attr.type = attr_flags; + flags_attr.u.num = flags; + int_attrs = attr_generic_set_attr(attr_list_dup(attrs), &flags_attr); mr = map_rect_new(map, NULL); - ret = tm_find_item(mr, type, attrs, c, count); + ret = tm_find_item(mr, type, int_attrs, c, count); if (!ret) { ret = map_rect_create_item(mr, type); ret->id_hi = id_hi; @@ -709,11 +731,14 @@ static struct item * tm_add_item(struct map *map, enum item_type type, int id_hi ret->map = map; ret->meth = &methods_traffic_item; priv_data = (struct item_priv *) ret->priv_data; - priv_data->attrs = attr_list_dup(attrs); + priv_data->attrs = int_attrs; priv_data->coords = g_memdup(c, sizeof(struct coord) * count); priv_data->coord_count = count; - priv_data->next_attr = attrs; + priv_data->next_attr = int_attrs; priv_data->next_coord = 0; + } else if (int_attrs) { + /* free up our copy of the attribute list if we’re not attaching it to a new item */ + attr_list_free(int_attrs); } map_rect_destroy(mr); //tm_dump_item(ret); @@ -902,6 +927,8 @@ static int tm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *a return ret; } +/* TODO setter method? */ + /** * @brief Sets the type of a traffic item. * @@ -2072,6 +2099,7 @@ static int traffic_location_is_valid(struct traffic_location * this_) { * * @return `true` if the locations were matched successfully, `false` if there was a failure. */ +/* TODO process data->flags and data->dir */ static int traffic_message_add_segments(struct traffic_message * this_, struct mapset * ms, struct seg_data * data, struct map *map) { int i; @@ -2126,6 +2154,9 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m /* The next item in the message's list of items */ struct item ** next_item; + /* Flags for the next item to add */ + int flags; + /* The last item added */ struct item * item; @@ -2519,22 +2550,22 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m else delay = data->delay; + for (i = 0; i < ccnt; i++) { + *cd++ = *c++; + } + if (s->start == p_iter) { - /* forward direction, maintain order of coordinates */ - for (i = 0; i < ccnt; i++) { - *cd++ = *c++; - } + /* forward direction */ p_iter = s->end; + flags = data->flags | (data->dir == location_dir_one ? AF_ONEWAY : 0); } else { - /* backward direction, reverse order of coordinates */ - c += ccnt-1; - for (i = 0; i < ccnt; i++) { - *cd++ = *c--; - } + /* backward direction */ p_iter = s->start; + flags = data->flags | (data->dir == location_dir_one ? AF_ONEWAYREV : 0); } - item = tm_add_item(map, type_traffic_distortion, s->data.item.id_hi, s->data.item.id_lo, data->attrs, cs, ccnt, this_->id); + + item = tm_add_item(map, type_traffic_distortion, s->data.item.id_hi, s->data.item.id_lo, flags, data->attrs, cs, ccnt, this_->id); tm_item_add_message_data(item, this_->id, speed, delay, data->attrs); @@ -2704,6 +2735,7 @@ static struct seg_data * traffic_message_parse_events(struct traffic_message * t struct seg_data * ret = NULL; int i; + int flags = AF_ALL; /* Default assumptions, used only if no explicit values are given */ int speed = INT_MAX; @@ -2711,6 +2743,7 @@ static struct seg_data * traffic_message_parse_events(struct traffic_message * t int speed_factor = 100; int delay = 0; + /* TODO derive flags (modes of transportation) from message */ for (i = 0; i < this_->event_count; i++) { if (this_->events[i]->speed != INT_MAX) { if (!ret) @@ -2818,6 +2851,8 @@ static struct seg_data * traffic_message_parse_events(struct traffic_message * t } if (!ret->delay) ret->delay = delay; + ret->dir = this_->location->directionality; + ret->flags = flags; } return ret; |