summaryrefslogtreecommitdiff
path: root/navit/route.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-05-12 08:26:22 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-05-12 08:26:22 +0000
commit6c4f3ff463df27373e0c9349dd8490bf642fe734 (patch)
tree3ef68e59d32547d623f7faf5f033370bfb1d26d5 /navit/route.c
parent98a69f0c5284ec29c8442ac986589c1527273a11 (diff)
downloadnavit-6c4f3ff463df27373e0c9349dd8490bf642fe734.tar.gz
Add:Core:Support for length and weight restrictions
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@3236 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/route.c')
-rw-r--r--navit/route.c197
1 files changed, 147 insertions, 50 deletions
diff --git a/navit/route.c b/navit/route.c
index 19b7ec0fd..d0d736c0b 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -119,10 +119,30 @@ struct route_segment_data {
*/
};
+
+struct size_weight_limit {
+ int width;
+ int length;
+ int height;
+ int weight;
+ int axle_weight;
+};
+
#define RSD_OFFSET(x) *((int *)route_segment_data_field_pos((x), attr_offset))
#define RSD_MAXSPEED(x) *((int *)route_segment_data_field_pos((x), attr_maxspeed))
+#define RSD_SIZE_WEIGHT(x) *((struct size_weight_limit *)route_segment_data_field_pos((x), attr_vehicle_width))
+#define RSD_DANGEROUS_GOODS(x) *((int *)route_segment_data_field_pos((x), attr_vehicle_dangerous_goods))
+struct route_graph_segment_data {
+ struct item *item;
+ int offset;
+ int flags;
+ int len;
+ int maxspeed;
+ struct size_weight_limit size_weight;
+ int dangerous_goods;
+};
/**
* @brief A segment in the route graph
@@ -1074,6 +1094,16 @@ route_segment_data_field_pos(struct route_segment_data *seg, enum attr_type type
return (void*)ptr;
ptr += sizeof(int);
}
+ if (seg->flags & AF_SIZE_OR_WEIGHT_LIMIT) {
+ if (type == attr_vehicle_width)
+ return (void*)ptr;
+ ptr += sizeof(struct size_weight_limit);
+ }
+ if (seg->flags & AF_DANGEROUS_GOODS) {
+ if (type == attr_vehicle_dangerous_goods)
+ return (void*)ptr;
+ ptr += sizeof(int);
+ }
return NULL;
}
@@ -1091,19 +1121,23 @@ route_segment_data_size(int flags)
ret+=sizeof(int);
if (flags & AF_SEGMENTED)
ret+=sizeof(int);
+ if (flags & AF_SIZE_OR_WEIGHT_LIMIT)
+ ret+=sizeof(struct size_weight_limit);
+ if (flags & AF_DANGEROUS_GOODS)
+ ret+=sizeof(int);
return ret;
}
static int
-route_graph_segment_is_duplicate(struct route_graph_point *start, struct item *item, int flags, int offset)
+route_graph_segment_is_duplicate(struct route_graph_point *start, struct route_graph_segment_data *data)
{
struct route_graph_segment *s;
s=start->start;
while (s) {
- if (item_is_equal(*item, s->data.item)) {
- if (flags & AF_SEGMENTED) {
- if (RSD_OFFSET(&s->data) == offset) {
+ if (item_is_equal(*data->item, s->data.item)) {
+ if (data->flags & AF_SEGMENTED) {
+ if (RSD_OFFSET(&s->data) == data->offset) {
return 1;
}
} else
@@ -1131,13 +1165,12 @@ route_graph_segment_is_duplicate(struct route_graph_point *start, struct item *i
*/
static void
route_graph_add_segment(struct route_graph *this, struct route_graph_point *start,
- struct route_graph_point *end, int len, struct item *item,
- int flags, int offset, int maxspeed)
+ struct route_graph_point *end, struct route_graph_segment_data *data)
{
struct route_graph_segment *s;
int size;
- size = sizeof(struct route_graph_segment)-sizeof(struct route_segment_data)+route_segment_data_size(flags);
+ size = sizeof(struct route_graph_segment)-sizeof(struct route_segment_data)+route_segment_data_size(data->flags);
s = g_malloc0(size);
if (!s) {
printf("%s:Out of memory\n", __FUNCTION__);
@@ -1149,15 +1182,19 @@ route_graph_add_segment(struct route_graph *this, struct route_graph_point *star
s->end=end;
s->end_next=end->end;
end->end=s;
- dbg_assert(len >= 0);
- s->data.len=len;
- s->data.item=*item;
- s->data.flags=flags;
-
- if (flags & AF_SPEED_LIMIT)
- RSD_MAXSPEED(&s->data)=maxspeed;
- if (flags & AF_SEGMENTED)
- RSD_OFFSET(&s->data)=offset;
+ dbg_assert(data->len >= 0);
+ s->data.len=data->len;
+ s->data.item=*data->item;
+ s->data.flags=data->flags;
+
+ if (data->flags & AF_SPEED_LIMIT)
+ RSD_MAXSPEED(&s->data)=data->maxspeed;
+ if (data->flags & AF_SEGMENTED)
+ RSD_OFFSET(&s->data)=data->offset;
+ if (data->flags & AF_SIZE_OR_WEIGHT_LIMIT)
+ RSD_SIZE_WEIGHT(&s->data)=data->size_weight;
+ if (data->flags & AF_DANGEROUS_GOODS)
+ RSD_DANGEROUS_GOODS(&s->data)=data->dangerous_goods;
s->next=this->route_segments;
this->route_segments=s;
@@ -1493,6 +1530,23 @@ route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over,
if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed < speed))
speed=maxspeed;
}
+ if (over->flags & AF_DANGEROUS_GOODS) {
+ if (profile->dangerous_goods & RSD_DANGEROUS_GOODS(over))
+ return INT_MAX;
+ }
+ if (over->flags & AF_SIZE_OR_WEIGHT_LIMIT) {
+ struct size_weight_limit *size_weight=&RSD_SIZE_WEIGHT(over);
+ if (size_weight->width != -1 && profile->width != -1 && profile->width > size_weight->width)
+ return INT_MAX;
+ if (size_weight->height != -1 && profile->height != -1 && profile->height > size_weight->height)
+ return INT_MAX;
+ if (size_weight->length != -1 && profile->length != -1 && profile->length > size_weight->length)
+ return INT_MAX;
+ if (size_weight->weight != -1 && profile->weight != -1 && profile->weight > size_weight->weight)
+ return INT_MAX;
+ if (size_weight->axle_weight != -1 && profile->axle_weight != -1 && profile->axle_weight > size_weight->axle_weight)
+ return INT_MAX;
+ }
if (!speed)
return INT_MAX;
return over->len*36/speed+(dist ? dist->delay : 0);
@@ -1571,10 +1625,13 @@ 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;
- int len=0;
- int flags = 0;
- int offset = 1;
- int maxspeed = INT_MAX;
+ struct route_graph_segment_data data;
+
+ data.item=item;
+ data.len=0;
+ data.flags=0;
+ data.offset=1;
+ data.maxspeed = INT_MAX;
if (item_coord_get(item, &l, 1)) {
s_pnt=route_graph_add_point(this,&l);
@@ -1585,12 +1642,12 @@ route_process_traffic_distortion(struct route_graph *this, struct item *item)
s_pnt->flags |= RP_TRAFFIC_DISTORTION;
e_pnt->flags |= RP_TRAFFIC_DISTORTION;
if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) {
- flags |= AF_SPEED_LIMIT;
- maxspeed=maxspeed_attr.u.num;
+ data.flags |= AF_SPEED_LIMIT;
+ data.maxspeed=maxspeed_attr.u.num;
}
if (item_attr_get(item, attr_delay, &delay_attr))
- len=delay_attr.u.num;
- route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset, maxspeed);
+ data.len=delay_attr.u.num;
+ route_graph_add_segment(this, s_pnt, e_pnt, &data);
}
}
@@ -1606,6 +1663,7 @@ route_process_turn_restriction(struct route_graph *this, struct item *item)
struct route_graph_point *pnt[4];
struct coord c[5];
int i,count;
+ struct route_graph_segment_data data;
count=item_coord_get(item, c, 5);
if (count != 3 && count != 4) {
@@ -1617,8 +1675,11 @@ route_process_turn_restriction(struct route_graph *this, struct item *item)
for (i = 0 ; i < count ; i++)
pnt[i]=route_graph_add_point(this,&c[i]);
dbg(1,"%s: (0x%x,0x%x)-(0x%x,0x%x)-(0x%x,0x%x) %p-%p-%p\n",item_to_name(item->type),c[0].x,c[0].y,c[1].x,c[1].y,c[2].x,c[2].y,pnt[0],pnt[1],pnt[2]);
- route_graph_add_segment(this, pnt[0], pnt[1], 0, item, 0, 0, 0);
- route_graph_add_segment(this, pnt[1], pnt[2], 0, item, 0, 0, 0);
+ data.item=item;
+ data.flags=0;
+ data.len=0;
+ route_graph_add_segment(this, pnt[0], pnt[1], &data);
+ route_graph_add_segment(this, pnt[1], pnt[2], &data);
#if 0
if (count == 4) {
pnt[1]->flags |= RP_TURN_RESTRICTION;
@@ -1648,28 +1709,57 @@ route_process_street_graph(struct route_graph *this, struct item *item)
#endif
struct route_graph_point *s_pnt,*e_pnt;
struct coord c,l;
- struct attr flags_attr, maxspeed_attr;
- int flags = 0;
+ struct attr attr;
+ struct route_graph_segment_data data;
+ data.flags=0;
+ data.offset=1;
+ data.maxspeed=-1;
+ data.item=item;
int segmented = 0;
- int offset = 1;
- 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)
+ if (item_attr_get(item, attr_flags, &attr)) {
+ data.flags = attr.u.num;
+ if (data.flags & AF_SEGMENTED)
segmented = 1;
} else
- flags = *default_flags;
+ data.flags = *default_flags;
- if (flags & AF_SPEED_LIMIT) {
- if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) {
- maxspeed = maxspeed_attr.u.num;
- }
+ if (data.flags & AF_SPEED_LIMIT) {
+ if (item_attr_get(item, attr_maxspeed, &attr))
+ data.maxspeed = attr.u.num;
+ }
+ if (data.flags & AF_DANGEROUS_GOODS) {
+ 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) {
+ if (item_attr_get(item, attr_vehicle_width, &attr))
+ data.size_weight.width=attr.u.num;
+ else
+ data.size_weight.width=-1;
+ if (item_attr_get(item, attr_vehicle_height, &attr))
+ data.size_weight.height=attr.u.num;
+ else
+ data.size_weight.height=-1;
+ if (item_attr_get(item, attr_vehicle_length, &attr))
+ data.size_weight.length=attr.u.num;
+ else
+ data.size_weight.length=-1;
+ if (item_attr_get(item, attr_vehicle_weight, &attr))
+ data.size_weight.weight=attr.u.num;
+ else
+ data.size_weight.weight=-1;
+ if (item_attr_get(item, attr_vehicle_axle_weight, &attr))
+ data.size_weight.axle_weight=attr.u.num;
+ else
+ data.size_weight.axle_weight=-1;
}
s_pnt=route_graph_add_point(this,&l);
@@ -1680,8 +1770,9 @@ route_process_street_graph(struct route_graph *this, struct item *item)
}
e_pnt=route_graph_add_point(this,&l);
dbg_assert(len >= 0);
- if (!route_graph_segment_is_duplicate(s_pnt, item, flags, offset))
- route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset, maxspeed);
+ data.len=len;
+ if (!route_graph_segment_is_duplicate(s_pnt, &data))
+ route_graph_add_segment(this, s_pnt, e_pnt, &data);
} else {
int isseg,rc;
int sc = 0;
@@ -1693,9 +1784,10 @@ route_process_street_graph(struct route_graph *this, struct item *item)
l=c;
if (isseg) {
e_pnt=route_graph_add_point(this,&l);
- if (!route_graph_segment_is_duplicate(s_pnt, item, flags, offset))
- route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset, maxspeed);
- offset++;
+ data.len=len;
+ if (!route_graph_segment_is_duplicate(s_pnt, &data))
+ route_graph_add_segment(this, s_pnt, e_pnt, &data);
+ data.offset++;
s_pnt=route_graph_add_point(this,&l);
len = 0;
}
@@ -1704,8 +1796,9 @@ route_process_street_graph(struct route_graph *this, struct item *item)
e_pnt=route_graph_add_point(this,&l);
dbg_assert(len >= 0);
sc++;
- if (!route_graph_segment_is_duplicate(s_pnt, item, flags, offset))
- route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset, maxspeed);
+ data.len=len;
+ if (!route_graph_segment_is_duplicate(s_pnt, &data))
+ route_graph_add_segment(this, s_pnt, e_pnt, &data);
}
}
}
@@ -2078,14 +2171,18 @@ is_turn_allowed(struct route_graph_point *p, struct route_graph_segment *from, s
static void
route_graph_clone_segment(struct route_graph *this, struct route_graph_segment *s, struct route_graph_point *start, struct route_graph_point *end, int flags)
{
- int offset=0;
- int maxspeed=0;
+ struct route_graph_segment_data data;
+ data.flags=s->data.flags|flags;
+ data.offset=1;
+ data.maxspeed=-1;
+ data.item=&s->data.item;
+ data.len=s->data.len+1;
if (s->data.flags & AF_SPEED_LIMIT)
- maxspeed=RSD_MAXSPEED(&s->data);
+ data.maxspeed=RSD_MAXSPEED(&s->data);
if (s->data.flags & AF_SEGMENTED)
- offset=RSD_OFFSET(&s->data);
+ data.offset=RSD_OFFSET(&s->data);
dbg(1,"cloning segment from %p (0x%x,0x%x) to %p (0x%x,0x%x)\n",start,start->c.x,start->c.y, end, end->c.x, end->c.y);
- route_graph_add_segment(this, start, end, s->data.len+1, &s->data.item, s->data.flags | flags, offset, maxspeed);
+ route_graph_add_segment(this, start, end, &data);
}
static void