diff options
author | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-08-27 17:24:28 +0000 |
---|---|---|
committer | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-08-27 17:24:28 +0000 |
commit | 1fcd71da862004d3d241332a25463090d981a9fa (patch) | |
tree | c0c27c5a54d7e8df3b490bc7775e4b4fb9210340 | |
parent | 35817fcbb4049bcbb61458a53e54c1eaf4800b7a (diff) | |
download | navit-1fcd71da862004d3d241332a25463090d981a9fa.tar.gz |
Add:Core:Add configurable penalty to turn around
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5613 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r-- | navit/attr_def.h | 1 | ||||
-rw-r--r-- | navit/route.c | 72 | ||||
-rw-r--r-- | navit/vehicleprofile.c | 3 | ||||
-rw-r--r-- | navit/vehicleprofile.h | 1 |
4 files changed, 73 insertions, 4 deletions
diff --git a/navit/attr_def.h b/navit/attr_def.h index 0a9a8e00b..5d6d37a3b 100644 --- a/navit/attr_def.h +++ b/navit/attr_def.h @@ -183,6 +183,7 @@ ATTR(battery_charge) /* mAh */ ATTR(battery_resistance) /* mOhm */ ATTR(battery_temperature) /* mK */ ATTR(turn_around_count) +ATTR(turn_around_penalty) ATTR2(0x00027500,type_rel_abs_begin) /* These attributes are int that can either hold relative * * or absolute values. A relative value is indicated by * diff --git a/navit/route.c b/navit/route.c index 434a4cf16..94306454e 100644 --- a/navit/route.c +++ b/navit/route.c @@ -268,6 +268,7 @@ struct route_graph { struct callback *done_cb; /**< Callback when graph is done */ struct event_idle *idle_ev; /**< The pointer to the idle event */ struct route_graph_segment *route_segments; /**< Pointer to the first route_graph_segment in the linked list of all segments */ + struct route_graph_segment *avoid_seg; #define HASH_SIZE 8192 struct route_graph_point *hash[HASH_SIZE]; /**< A hashtable containing all route_graph_points in this graph */ }; @@ -1987,7 +1988,7 @@ route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, if (from && from->seg == over) return INT_MAX; if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && - route_get_traffic_distortion(over, &dist)) { + route_get_traffic_distortion(over, &dist) && dir != 2 && dir != -2) { distp=&dist; } ret=route_time_seg(profile, &over->data, distp); @@ -1998,6 +1999,45 @@ route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, return ret; } +static int +route_graph_segment_match(struct route_graph_segment *s1, struct route_graph_segment *s2) +{ + if (!s1 || !s2) + return 0; + return (s1->start->c.x == s2->start->c.x && s1->start->c.y == s2->start->c.y && + s1->end->c.x == s2->end->c.x && s1->end->c.y == s2->end->c.y); +} + +static void +route_graph_set_traffic_distortion(struct route_graph *this, struct route_graph_segment *seg, int delay) +{ + struct route_graph_point *start=NULL; + struct route_graph_segment *s; + + while ((start=route_graph_get_point_next(this, &seg->start->c, start))) { + s=start->start; + while (s) { + if (route_graph_segment_match(s, seg)) { + if (s->data.item.type != type_none && s->data.item.type != type_traffic_distortion && delay) { + struct route_graph_segment_data data; + struct item item; + memset(&data, 0, sizeof(data)); + memset(&item, 0, sizeof(item)); + item.type=type_traffic_distortion; + data.item=&item; + data.len=delay; + s->start->flags |= RP_TRAFFIC_DISTORTION; + s->end->flags |= RP_TRAFFIC_DISTORTION; + route_graph_add_segment(this, s->start, s->end, &data); + } else if (s->data.item.type == type_traffic_distortion && !delay) { + s->data.item.type = type_none; + } + } + s=s->start_next; + } + } +} + /** * @brief Adds a route distortion item to the route graph * @@ -2428,7 +2468,7 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout struct route_graph_segment *s=NULL,*s1=NULL,*s2=NULL; struct route_graph_point *start; struct route_info *posinfo, *dstinfo; - int segs=0; + int segs=0,dir; int val1=INT_MAX,val2=INT_MAX; int val,val1_new,val2_new; struct route_path *ret; @@ -2441,19 +2481,29 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) return route_path_new_offroad(this, pos, dst); while ((s=route_graph_get_segment(this, pos->street, s))) { - val=route_value_seg(profile, NULL, s, 1); + val=route_value_seg(profile, NULL, s, 2); if (val != INT_MAX && s->end->value != INT_MAX) { val=val*(100-pos->percent)/100; + dbg(1,"val1 %d\n",val); + if (route_graph_segment_match(s,this->avoid_seg) && pos->street_direction < 0) + val+=profile->turn_around_penalty; + dbg(1,"val1 %d\n",val); val1_new=s->end->value+val; + dbg(1,"val1 +%d=%d\n",s->end->value,val1_new); if (val1_new < val1) { val1=val1_new; s1=s; } } - val=route_value_seg(profile, NULL, s, -1); + val=route_value_seg(profile, NULL, s, -2); if (val != INT_MAX && s->start->value != INT_MAX) { val=val*pos->percent/100; + dbg(1,"val2 %d\n",val); + if (route_graph_segment_match(s,this->avoid_seg) && pos->street_direction > 0) + val+=profile->turn_around_penalty; + dbg(1,"val2 %d\n",val); val2_new=s->start->value+val; + dbg(1,"val2 +%d=%d\n",s->start->value,val2_new); if (val2_new < val2) { val2=val2_new; s2=s; @@ -2471,9 +2521,23 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout if (val1 < val2) { start=s1->start; s=s1; + dir=1; } else { start=s2->end; s=s2; + dir=-1; + } + if (pos->street_direction && dir != pos->street_direction && profile->turn_around_penalty) { + if (!route_graph_segment_match(this->avoid_seg,s)) { + dbg(0,"avoid current segment\n"); + if (this->avoid_seg) + route_graph_set_traffic_distortion(this, this->avoid_seg, 0); + this->avoid_seg=s; + route_graph_set_traffic_distortion(this, this->avoid_seg, profile->turn_around_penalty); + route_graph_reset(this); + route_graph_flood(this, dst, profile, NULL); + return route_path_new(this, oldpath, pos, dst, profile); + } } ret=g_new0(struct route_path, 1); ret->in_use=1; diff --git a/navit/vehicleprofile.c b/navit/vehicleprofile.c index 2ce3ad1fa..905044fca 100644 --- a/navit/vehicleprofile.c +++ b/navit/vehicleprofile.c @@ -85,6 +85,9 @@ vehicleprofile_set_attr_do(struct vehicleprofile *this_, struct attr *attr) case attr_through_traffic_penalty: this_->through_traffic_penalty=attr->u.num; break; + case attr_turn_around_penalty: + this_->turn_around_penalty=attr->u.num; + break; default: break; } diff --git a/navit/vehicleprofile.h b/navit/vehicleprofile.h index 2733d722d..88edad41f 100644 --- a/navit/vehicleprofile.h +++ b/navit/vehicleprofile.h @@ -41,6 +41,7 @@ struct vehicleprofile { int through_traffic_penalty; /**< Penalty when driving on a through traffic limited road */ GHashTable *roadprofile_hash; struct attr active_callback; + int turn_around_penalty; /**< Penalty when turning around */ }; struct vehicleprofile * vehicleprofile_new(struct attr *parent, struct attr **attrs); |