summaryrefslogtreecommitdiff
path: root/navit
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-06-03 09:37:43 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-06-03 09:37:43 +0000
commitb13dd0c7ed3f264531095d52c36f594c1d58de3d (patch)
treec19009380db918d1436d42eded80fca6ba946af9 /navit
parent1baaf10c5f50494446d955e65e3ba31691755710 (diff)
downloadnavit-b13dd0c7ed3f264531095d52c36f594c1d58de3d.tar.gz
Add:Core:Experimental support for traffic distortions
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@2302 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit')
-rw-r--r--navit/attr_def.h1
-rw-r--r--navit/item_def.h1
-rw-r--r--navit/navit.xml39
-rw-r--r--navit/popup.c74
-rw-r--r--navit/route.c149
5 files changed, 220 insertions, 44 deletions
diff --git a/navit/attr_def.h b/navit/attr_def.h
index 5262bab89..8c253d070 100644
--- a/navit/attr_def.h
+++ b/navit/attr_def.h
@@ -118,6 +118,7 @@ ATTR(flags_reverse_mask)
ATTR(house_number_interpolation)
ATTR(house_number_left_interpolation)
ATTR(house_number_right_interpolation)
+ATTR(delay)
ATTR2(0x00027500,type_rel_abs_begin)
/* These attributes are int that can either hold relative *
diff --git a/navit/item_def.h b/navit/item_def.h
index 4579ab77c..dec5d24f0 100644
--- a/navit/item_def.h
+++ b/navit/item_def.h
@@ -423,6 +423,7 @@ ITEM(street_turn_restriction_only)
ITEM(border_city)
ITEM(border_county)
ITEM(selected_line)
+ITEM(traffic_distortion)
/* Area */
ITEM2(0xc0000000,area)
ITEM2(0xc0000001,area_unspecified)
diff --git a/navit/navit.xml b/navit/navit.xml
index 00e0ef4e9..4b22c2662 100644
--- a/navit/navit.xml
+++ b/navit/navit.xml
@@ -1194,6 +1194,45 @@
<itemgra item_types="street_nopass,street_0,street_1_city,street_1_land" order="12-18">
<text text_size="9"/>
</itemgra>
+ <itemgra item_types="traffic_distortion" order="2">
+ <polyline color="#ff9000" width="2"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="3-5">
+ <polyline color="#ff9000" width="4"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="6">
+ <polyline color="#ff9000" width="5"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="7-8">
+ <polyline color="#ff9000" width="8"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="9-10">
+ <polyline color="#ff9000" width="10"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="11">
+ <polyline color="#ff9000" width="14"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="12">
+ <polyline color="#ff9000" width="16"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="13">
+ <polyline color="#ff9000" width="26"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="14">
+ <polyline color="#ff9000" width="32"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="15">
+ <polyline color="#ff9000" width="34"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="16">
+ <polyline color="#ff9000" width="66"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="17">
+ <polyline color="#ff9000" width="134"/>
+ </itemgra>
+ <itemgra item_types="traffic_distortion" order="18">
+ <polyline color="#ff9000" width="265"/>
+ </itemgra>
</layer>
<layer name="polylines">
<itemgra item_types="aeroway_taxiway" order="10">
diff --git a/navit/popup.c b/navit/popup.c
index 1f347c186..d5c09f129 100644
--- a/navit/popup.c
+++ b/navit/popup.c
@@ -61,6 +61,44 @@ popup_set_no_passing(struct popup_item *item, void *param)
#endif
static void
+popup_traffic_distortion(struct item *item, char *attr)
+{
+ FILE *map=fopen("distortion.txt","a");
+ struct coord c;
+ struct map_rect *mr;
+ fprintf(map,"type=traffic_distortion %s\n",attr);
+ mr=map_rect_new(item->map,NULL);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ while (item_coord_get(item, &c, 1)) {
+ fprintf(map,"0x%x 0x%x\n",c.x,c.y);
+ }
+ fclose(map);
+}
+
+static void
+popup_traffic_distortion_blocked(struct item *item)
+{
+ dbg(0,"item=%p\n",item);
+ popup_traffic_distortion(item, "maxspeed=0");
+}
+
+static void
+popup_traffic_distortion_speed(struct item *item, int maxspeed)
+{
+ char buffer[256];
+ sprintf(buffer,"maxspeed=%d",maxspeed);
+ popup_traffic_distortion(item,buffer);
+}
+
+static void
+popup_traffic_distortion_delay(struct item *item, int delay)
+{
+ char buffer[256];
+ sprintf(buffer,"delay=%d",delay*600);
+ popup_traffic_distortion(item,buffer);
+}
+
+static void
popup_set_destination(struct navit *nav, struct pcoord *pc)
{
struct coord c;
@@ -207,23 +245,23 @@ static void
popup_show_item(struct navit *nav, void *popup, struct displayitem *di)
{
struct map_rect *mr;
- void *menu, *menu_map, *menu_item;
+ void *menu, *menu_map, *menu_item, *menu_dist;
char *label;
- struct item *item;
+ struct item *item,*diitem;
label=graphics_displayitem_get_label(di);
- item=graphics_displayitem_get_item(di);
+ diitem=graphics_displayitem_get_item(di);
if (label)
- menu=popup_printf(popup, menu_type_submenu, "%s '%s'", item_to_name(item->type), label);
+ menu=popup_printf(popup, menu_type_submenu, "%s '%s'", item_to_name(diitem->type), label);
else
- menu=popup_printf(popup, menu_type_submenu, "%s", item_to_name(item->type));
+ menu=popup_printf(popup, menu_type_submenu, "%s", item_to_name(diitem->type));
menu_item=popup_printf(menu, menu_type_submenu, "Item");
- popup_printf(menu_item, menu_type_menu, "type: 0x%x", item->type);
- popup_printf(menu_item, menu_type_menu, "id: 0x%x 0x%x", item->id_hi, item->id_lo);
- if (item->map) {
- mr=map_rect_new(item->map,NULL);
- item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ popup_printf(menu_item, menu_type_menu, "type: 0x%x", diitem->type);
+ popup_printf(menu_item, menu_type_menu, "id: 0x%x 0x%x", diitem->id_hi, diitem->id_lo);
+ if (diitem->map) {
+ mr=map_rect_new(diitem->map,NULL);
+ item=map_rect_get_item_byid(mr, diitem->id_hi, diitem->id_lo);
dbg(1,"item=%p\n", item);
if (item) {
popup_show_attrs(item->map, menu_item, item);
@@ -246,6 +284,22 @@ popup_show_item(struct navit *nav, void *popup, struct displayitem *di)
} else {
popup_printf(menu, menu_type_menu, "(No map)");
}
+ if (diitem && item_get_default_flags(diitem->type)) {
+ int speeds[]={5,10,20,30,40,50,60,70,80,90,100};
+ int delays[]={1,2,3,5,10,15,20,30,45,60,75,90,120,150,180,240,300};
+ int i;
+ menu_dist=popup_printf(menu, menu_type_submenu, "Traffic distortion");
+ popup_printf_cb(menu_dist, menu_type_menu, callback_new_1(callback_cast(popup_traffic_distortion_blocked), diitem), "Blocked");
+ menu_item=popup_printf(menu_dist, menu_type_submenu,"Max speed");
+ for (i = 0 ; i < sizeof(speeds)/sizeof(int); i++) {
+ popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_traffic_distortion_speed), diitem, speeds[i]), "%d km/h",speeds[i]);
+ }
+ menu_item=popup_printf(menu_dist, menu_type_submenu,"Delay");
+ for (i = 0 ; i < sizeof(delays)/sizeof(int); i++) {
+ popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_traffic_distortion_delay), diitem, delays[i]*600), "%d min",delays[i]);
+ }
+ }
+
}
static void
diff --git a/navit/route.c b/navit/route.c
index dcc2a70ba..1fed6aad5 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -94,8 +94,10 @@ struct route_graph_point {
* to this point's heap-element */
int value; /**< The cost at which one can reach the destination from this point on */
struct coord c; /**< Coordinates of this point */
+ int flags; /**< Flags for this point (eg traffic distortion) */
};
+#define RP_TRAFFIC_DISTORTION 1
/**
* @brief A segment in the route graph or path
@@ -136,6 +138,16 @@ struct route_graph_segment {
};
/**
+ * @brief A traffic distortion
+ *
+ * This is distortion in the traffic where you can't drive as fast as usual or have to wait for some time
+ */
+struct route_traffic_distortion {
+ int maxspeed; /**< Maximum speed possible in km/h */
+ int delay; /**< Delay in tenths of seconds */
+};
+
+/**
* @brief A segment in the route path
*
* This is a segment in the route path.
@@ -183,12 +195,6 @@ struct route_path {
struct item_hash *path_hash; /**< A hashtable of all the items represented by this route's segements */
};
-#define RF_FASTEST (1<<0)
-#define RF_SHORTEST (1<<1)
-#define RF_AVOIDHW (1<<2)
-#define RF_AVOIDPAID (1<<3)
-#define RF_LOCKONROAD (1<<4)
-
/**
* @brief A complete route
*
@@ -939,17 +945,13 @@ route_graph_add_point(struct route_graph *this, struct coord *f)
hashval=HASHCOORD(f);
if (debug_route)
printf("p (0x%x,0x%x)\n", f->x, f->y);
- p=g_new(struct route_graph_point,1);
+ p=g_new0(struct route_graph_point,1);
if (!p) {
printf("%s:Out of memory\n", __FUNCTION__);
return p;
}
p->hash_next=this->hash[hashval];
this->hash[hashval]=p;
- p->el=NULL;
- p->start=NULL;
- p->end=NULL;
- p->seg=NULL;
p->value=INT_MAX;
p->c=*f;
}
@@ -1395,22 +1397,58 @@ route_graph_destroy(struct route_graph *this)
*/
static int
-route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over)
+route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist)
{
struct roadprofile *roadprofile=vehicleprofile_get_roadprofile(profile, over->item.type);
- int speed;
+ int speed,maxspeed;
if (!roadprofile || !roadprofile->route_weight)
return INT_MAX;
/* maxspeed_handling: 0=always, 1 only if maxspeed restricts the speed, 2 never */
- if (profile->maxspeed_handling != 2 && (over->flags & AF_SPEED_LIMIT)) {
- speed=RSD_MAXSPEED(over);
- if (profile->maxspeed_handling == 1 && speed > roadprofile->route_weight)
- speed=roadprofile->route_weight;
- } else
- speed=roadprofile->route_weight;
+ speed=roadprofile->route_weight;
+ if (profile->maxspeed_handling != 2) {
+ if (over->flags & AF_SPEED_LIMIT) {
+ maxspeed=RSD_MAXSPEED(over);
+ if (!profile->maxspeed_handling)
+ speed=maxspeed;
+ } else
+ maxspeed=INT_MAX;
+ if (dist && maxspeed > dist->maxspeed)
+ maxspeed=dist->maxspeed;
+ if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed < speed))
+ speed=maxspeed;
+ }
if (!speed)
- return INT_MAX;
- return over->len*36/speed;
+ return INT_MAX;
+ return over->len*36/speed+(dist ? dist->delay : 0);
+}
+
+static int
+route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traffic_distortion *ret)
+{
+ struct route_graph_point *start=seg->start;
+ struct route_graph_point *end=seg->end;
+ struct route_graph_segment *tmp,*found=NULL;
+ tmp=start->start;
+ while (tmp && !found) {
+ if (tmp->data.item.type == type_traffic_distortion && tmp->start == start && tmp->end == end)
+ found=tmp;
+ tmp=tmp->start_next;
+ }
+ tmp=start->end;
+ while (tmp && !found) {
+ if (tmp->data.item.type == type_traffic_distortion && tmp->end == start && tmp->start == end)
+ found=tmp;
+ tmp=tmp->end_next;
+ }
+ if (found) {
+ ret->delay=found->data.len;
+ if (found->data.flags & AF_SPEED_LIMIT)
+ ret->maxspeed=RSD_MAXSPEED(&found->data);
+ else
+ ret->maxspeed=INT_MAX;
+ return 1;
+ }
+ return 0;
}
/**
@@ -1424,14 +1462,54 @@ route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over)
*/
static int
-route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_segment_data *over, int dir)
+route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir)
{
#if 0
dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask, profile->flags);
#endif
- if ((over->flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags)
+ if ((over->data.flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags)
return INT_MAX;
- return route_time_seg(profile, over);
+ if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION)) {
+ struct route_traffic_distortion dist;
+ if (route_get_traffic_distortion(over, &dist))
+ return route_time_seg(profile, &over->data, &dist);
+ }
+ return route_time_seg(profile, &over->data, NULL);
+}
+
+/**
+ * @brief Adds a route distortion item to the route graph
+ *
+ * @param this The route graph to add to
+ * @param item The item to add
+ */
+static void
+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;
+
+ if (item_coord_get(item, &l, 1)) {
+ s_pnt=route_graph_add_point(this,&l);
+ while (item_coord_get(item, &c, 1)) {
+ l=c;
+ }
+ e_pnt=route_graph_add_point(this,&l);
+ 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;
+ }
+ 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);
+ }
}
/**
@@ -1458,7 +1536,7 @@ route_process_street_graph(struct route_graph *this, struct 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)
@@ -1557,14 +1635,14 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehic
dbg(0,"no segment for destination found\n");
return;
}
- val=route_value_seg(profile, NULL, &s->data, -1);
+ val=route_value_seg(profile, NULL, s, -1);
if (val != INT_MAX) {
val=val*(100-dst->percent)/100;
s->end->seg=s;
s->end->value=val;
s->end->el=fh_insertkey(heap, s->end->value, s->end);
}
- val=route_value_seg(profile, NULL, &s->data, 1);
+ val=route_value_seg(profile, NULL, s, 1);
if (val != INT_MAX) {
val=val*dst->percent/100;
s->start->seg=s;
@@ -1581,7 +1659,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehic
p_min->el=NULL; /* This point is permanently calculated now, we've taken it out of the heap */
s=p_min->start;
while (s) { /* Iterating all the segments leading away from our point to update the points at their ends */
- val=route_value_seg(profile, p_min, &s->data, -1);
+ val=route_value_seg(profile, p_min, s, -1);
if (val != INT_MAX) {
new=min+val;
if (debug_route)
@@ -1609,7 +1687,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehic
}
s=p_min->end;
while (s) { /* Doing the same as above with the segments leading towards our point */
- val=route_value_seg(profile, p_min, &s->data, 1);
+ val=route_value_seg(profile, p_min, s, 1);
if (val != INT_MAX) {
new=min+val;
if (debug_route)
@@ -1758,12 +1836,12 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout
dbg(0,"no segment for position found\n");
return NULL;
}
- val=route_value_seg(profile, NULL, &s->data, 1);
+ val=route_value_seg(profile, NULL, s, 1);
if (val != INT_MAX) {
val=val*(100-pos->percent)/100;
val1=s->end->value+val;
}
- val=route_value_seg(profile, NULL, &s->data, -1);
+ val=route_value_seg(profile, NULL, s, -1);
if (val != INT_MAX) {
val=val*pos->percent/100;
val2=s->start->value+val;
@@ -1866,7 +1944,10 @@ route_graph_build_idle(struct route_graph *rg)
return;
}
}
- route_process_street_graph(rg, item);
+ if (item->type == type_traffic_distortion)
+ route_process_traffic_distortion(rg, item);
+ else
+ route_process_street_graph(rg, item);
count--;
}
}
@@ -2245,7 +2326,7 @@ rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
case attr_time:
mr->attr_next=attr_none;
if (seg)
- attr->u.num=route_time_seg(route->vehicleprofile, seg->data);
+ attr->u.num=route_time_seg(route->vehicleprofile, seg->data, NULL);
else
return 0;
return 1;
@@ -2399,7 +2480,7 @@ rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
case type_rg_segment:
if (! seg)
return 0;
- mr->str=g_strdup_printf("len %d time %d",seg->data.len, route_time_seg(route->vehicleprofile, &seg->data));
+ mr->str=g_strdup_printf("len %d time %d",seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL));
attr->u.str = mr->str;
return 1;
default: