summaryrefslogtreecommitdiff
path: root/navit
diff options
context:
space:
mode:
authormvglasow <michael -at- vonglasow.com>2018-04-13 17:35:01 +0200
committermvglasow <michael -at- vonglasow.com>2018-04-13 17:35:01 +0200
commita35f6e2a4b3594cb28c75fc1e36c671e68e000bd (patch)
treee47082f3e4f932e05a5302c3bdceaa043b1d624d /navit
parente79d572086f079dfe12be54eae6ad93061607375 (diff)
downloadnavit-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.h1
-rw-r--r--navit/route.c25
-rw-r--r--navit/traffic.c69
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;