summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-04-12 06:37:36 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-04-12 06:37:36 +0000
commite474f8b91608e8aa23c5e5d0297e9fc0f2bd0828 (patch)
treed374b97c40b326ee01496587ed46f99b2c4f4e58
parent9ecdf6aec3d0fea7b84dc1cb38b81414a7c617db (diff)
downloadnavit-e474f8b91608e8aa23c5e5d0297e9fc0f2bd0828.tar.gz
Fix:Core:Made routing more flexible
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@2203 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--navit/attr.h2
-rw-r--r--navit/attr_def.h5
-rw-r--r--navit/item.c56
-rw-r--r--navit/item_def.h1
-rw-r--r--navit/navit.c5
-rw-r--r--navit/navit.xml48
-rw-r--r--navit/osm2navit.c131
-rw-r--r--navit/roadprofile.c22
-rw-r--r--navit/roadprofile.h6
-rw-r--r--navit/route.c129
-rw-r--r--navit/vehicleprofile.c52
-rw-r--r--navit/vehicleprofile.h10
-rw-r--r--navit/xmlconfig.c30
13 files changed, 306 insertions, 191 deletions
diff --git a/navit/attr.h b/navit/attr.h
index 25a9c260a..f82c6271e 100644
--- a/navit/attr.h
+++ b/navit/attr.h
@@ -114,6 +114,8 @@ struct attr {
struct cursor *cursor;
struct displaylist *displaylist;
struct transformation *transformation;
+ struct vehicleprofile *vehicleprofile;
+ struct roadprofile *roadprofile;
struct range {
short min, max;
} range;
diff --git a/navit/attr_def.h b/navit/attr_def.h
index 9abc5fd53..0421f1b89 100644
--- a/navit/attr_def.h
+++ b/navit/attr_def.h
@@ -113,6 +113,8 @@ ATTR(route_weight)
ATTR(distance_metric)
ATTR(route_mode)
ATTR(maxspeed_handling)
+ATTR(flags_forward_mask)
+ATTR(flags_reverse_mask)
ATTR2(0x00027500,type_rel_abs_begin)
/* These attributes are int that can either hold relative *
@@ -224,6 +226,9 @@ ATTR(state_name)
ATTR(message)
ATTR(callbacks)
ATTR(enable_expression)
+ATTR(fax)
+ATTR(email)
+ATTR(url)
ATTR2(0x0003ffff,type_string_end)
ATTR2(0x00040000,type_special_begin)
ATTR(order)
diff --git a/navit/item.c b/navit/item.c
index 623aa3e7d..9d1d8d573 100644
--- a/navit/item.c
+++ b/navit/item.c
@@ -37,26 +37,33 @@ struct item_range item_range_all = { type_none, type_last };
#define AF_ALL (AF_PBH|AF_MOPED|AF_MOTORIZED_FAST)
-int default_flags[]={
- /* AF_PBH, street_nopass */
- AF_ALL, /* street_0 */
- AF_ALL, /* street_1_city */
- AF_ALL, /* street_2_city */
- AF_ALL, /* street_3_city */
- AF_ALL, /* street_4_city */
- AF_MOTORIZED_FAST, /* highway_city */
- AF_ALL, /* street_1_land */
- AF_ALL, /* street_2_land */
- AF_ALL, /* street_3_land */
- AF_ALL, /* street_4_land */
- AF_MOTORIZED_FAST, /* street_n_lanes */
- AF_MOTORIZED_FAST, /* highway_land */
- AF_MOTORIZED_FAST, /* ramp */
- AF_ALL, /* roundabout */
- AF_ALL, /* ferry */
+struct default_flags {
+ enum item_type type;
+ int flags;
+};
+
+struct default_flags default_flags2[]={
+ {type_street_nopass, AF_PBH},
+ {type_street_0, AF_ALL},
+ {type_street_1_city, AF_ALL},
+ {type_street_2_city, AF_ALL},
+ {type_street_3_city, AF_ALL},
+ {type_street_4_city, AF_ALL},
+ {type_highway_city, AF_MOTORIZED_FAST},
+ {type_street_1_land, AF_ALL},
+ {type_street_2_land, AF_ALL},
+ {type_street_3_land, AF_ALL},
+ {type_street_4_land, AF_ALL},
+ {type_street_n_lanes, AF_MOTORIZED_FAST},
+ {type_highway_land, AF_MOTORIZED_FAST},
+ {type_ramp, AF_MOTORIZED_FAST},
+ {type_roundabout, AF_ALL},
+ {type_ferry, AF_ALL},
+ {type_cycleway, AF_ALL},
};
+
struct item_name item_names[]={
#define ITEM2(x,y) ITEM(y)
#define ITEM(x) { type_##x, #x },
@@ -65,6 +72,21 @@ struct item_name item_names[]={
#undef ITEM
};
+static GHashTable *default_flags_hash;
+
+int *
+item_get_default_flags(enum item_type type)
+{
+ if (!default_flags_hash) {
+ int i;
+ default_flags_hash=g_hash_table_new(NULL, NULL);
+ for (i = 0 ; i < sizeof(default_flags2)/sizeof(struct default_flags); i++) {
+ g_hash_table_insert(default_flags_hash, (void *)(long)default_flags2[i].type, &default_flags2[i].flags);
+ }
+ }
+ return g_hash_table_lookup(default_flags_hash, (void *)(long)type);
+}
+
void
item_coord_rewind(struct item *it)
{
diff --git a/navit/item_def.h b/navit/item_def.h
index 05d17fb4d..4579ab77c 100644
--- a/navit/item_def.h
+++ b/navit/item_def.h
@@ -303,6 +303,7 @@ ITEM(house_number)
ITEM(route_start)
ITEM(route_end)
ITEM(selected_point)
+ITEM(power_tower)
/* Line */
ITEM2(0x80000000,line)
ITEM2(0x80000001,line_unspecified)
diff --git a/navit/navit.c b/navit/navit.c
index 2886501b3..c8bbc4460 100644
--- a/navit/navit.c
+++ b/navit/navit.c
@@ -134,6 +134,7 @@ struct navit {
int use_mousewheel;
struct messagelist *messages;
struct callback *resize_callback,*button_callback,*motion_callback;
+ struct vehicleprofile *vehicleprofile;
int pitch;
};
@@ -1281,6 +1282,7 @@ navit_init(struct navit *this_)
}
route_set_mapset(this_->route, ms);
route_set_projection(this_->route, transform_get_projection(this_->trans));
+ route_set_profile(this_->route, this_->vehicleprofile);
}
if (this_->tracking) {
tracking_set_mapset(this_->tracking, ms);
@@ -1867,6 +1869,9 @@ navit_add_attr(struct navit *this_, struct attr *attr)
case attr_vehicle:
ret=navit_add_vehicle(this_, attr->u.vehicle);
break;
+ case attr_vehicleprofile:
+ this_->vehicleprofile=attr->u.vehicleprofile;
+ break;
case attr_autozoom_min:
this_->autozoom_min = attr->u.num;
break;
diff --git a/navit/navit.xml b/navit/navit.xml
index d01ab8d4e..656dbcc4c 100644
--- a/navit/navit.xml
+++ b/navit/navit.xml
@@ -107,7 +107,7 @@
<!-- For the cumulative displacement filter to be enabled, set cdf_hist="x" here, with x being an integer somewhere around 4 -->
<tracking cdf_histsize="0"/>
- <vehicleprofile name="car" flags="0x40000000" flags="0x4000000" flags_forward_mask="0x4000002" flags_reverse_mask="0x4000001" maxspeed_handling="0" route_mode="0">
+ <vehicleprofile name="car" flags="0x4000000" flags_forward_mask="0x4000002" flags_reverse_mask="0x4000001" maxspeed_handling="0" route_mode="0">
<roadprofile item_types="street_0,street_1_city" speed="10" route_weight="10">
<announcement level="0" distance_metric="25"/>
<announcement level="1" distance_metric="100"/>
@@ -171,23 +171,37 @@
<roadprofile item_types="roundabout" speed="10" route_weight="10"/>
<roadprofile item_types="ferry" speed="40" route_weight="40"/>
</vehicleprofile>
+ <vehicleprofile enabled="no" name="bike" flags="0x40000000" flags_forward_mask="0x40000000" flags_reverse_mask="0x40000000" maxspeed_handling="0" route_mode="0">
+ <roadprofile item_types="cycleway" speed="20" route_weight="20">
+ <announcement level="0" distance_metric="25"/>
+ <announcement level="1" distance_metric="100"/>
+ <announcement level="2" distance_metric="200"/>
+ </roadprofile>
+ <roadprofile item_types="street_0,street_1_city,street_2_city" speed="20" route_weight="14">
+ <announcement level="0" distance_metric="25"/>
+ <announcement level="1" distance_metric="100"/>
+ <announcement level="2" distance_metric="200"/>
+ </roadprofile>
+ <roadprofile item_types="street_3_city,street_4_city" speed="20" route_weight="7">
+ <announcement level="0" distance_metric="25"/>
+ <announcement level="1" distance_metric="100"/>
+ <announcement level="2" distance_metric="200"/>
+ </roadprofile>
+ <roadprofile item_types="street_1_land,street_2_land" speed="20" route_weight="14">
+ <announcement level="0" distance_metric="100"/>
+ <announcement level="1" distance_metric="400"/>
+ <announcement level="2" distance_metric="1000"/>
+ </roadprofile>
+ <roadprofile item_types="street_3_land,street_4_land" speed="20" route_weight="7">
+ <announcement level="0" distance_metric="100"/>
+ <announcement level="1" distance_metric="400"/>
+ <announcement level="2" distance_metric="1000"/>
+ </roadprofile>
+ <roadprofile item_types="roundabout" speed="20" route_weight="10"/>
+ <roadprofile item_types="ferry" speed="40" route_weight="40"/>
+ </vehicleprofile>
- <route destination_distance="50">
- <speed type="street_0,street_1_city" value="10"/>
- <speed type="street_2_city" value="30"/>
- <speed type="street_3_city" value="40"/>
- <speed type="street_4_city" value="50"/>
- <speed type="highway_city" value="80"/>
- <speed type="street_1_land" value="60"/>
- <speed type="street_2_land" value="65"/>
- <speed type="street_3_land" value="70"/>
- <speed type="street_4_land" value="80"/>
- <speed type="street_n_lanes" value="120"/>
- <speed type="highway_land" value="120"/>
- <speed type="ramp" value="40"/>
- <speed type="roundabout" value="10"/>
- <speed type="ferry" value="40"/>
- </route>
+ <route destination_distance="50"/>
<navigation>
<announce type="street_0,street_1_city" level0="25" level1="100" level2="200" unit="m"/>
diff --git a/navit/osm2navit.c b/navit/osm2navit.c
index 9eafcd2d2..edc93c06d 100644
--- a/navit/osm2navit.c
+++ b/navit/osm2navit.c
@@ -141,6 +141,7 @@ static char *attrmap={
"n place=suburb district_label\n"
"n place=town town_label_2e4\n"
"n place=village town_label_2e3\n"
+ "n power=tower power_tower\n"
"n railway=halt poi_rail_halt\n"
"n railway=level_crossing poi_level_crossing\n"
"n railway=station poi_rail_station\n"
@@ -555,12 +556,6 @@ struct attr_bin maxspeed_attr = {
};
int maxspeed_attr_value;
-struct attr_bin house_number_attr = {
- 0, attr_house_number
-};
-char house_number_attr_buffer[BUFFER_SIZE];
-
-
struct attr_bin town_name_attr = {
0, attr_town_name
};
@@ -593,7 +588,36 @@ long int osmid_attr_value;
char is_in_buffer[BUFFER_SIZE];
+char attr_strings_buffer[BUFFER_SIZE*16];
+int attr_strings_buffer_len;
+
+enum attr_strings {
+ attr_string_phone,
+ attr_string_fax,
+ attr_string_email,
+ attr_string_url,
+ attr_string_street_name,
+ attr_string_house_number,
+ attr_string_label,
+ attr_string_last,
+};
+char *attr_strings[attr_string_last];
+
+static void
+attr_strings_clear(void)
+{
+ attr_strings_buffer_len=0;
+ memset(attr_strings, 0, sizeof(attr_strings));
+}
+
+static void
+attr_strings_save(enum attr_strings id, char *str)
+{
+ attr_strings[id]=attr_strings_buffer+attr_strings_buffer_len;
+ strcpy(attr_strings[id], str);
+ attr_strings_buffer_len+=strlen(str)+1;
+}
static void
item_bin_init(struct item_bin *ib, enum item_type type)
@@ -643,6 +667,26 @@ item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val)
}
static void
+item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val)
+{
+ struct attr attr;
+ attr.type=type;
+ attr.u.num64=&val;
+ item_bin_add_attr(ib, &attr);
+}
+
+static void
+item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str)
+{
+ struct attr attr;
+ if (! str)
+ return;
+ attr.type=type;
+ attr.u.str=str;
+ item_bin_add_attr(ib, &attr);
+}
+
+static void
item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max)
{
struct attr attr;
@@ -723,6 +767,7 @@ access_value(char *v)
return 2;
return 3;
}
+
static void
add_tag(char *k, char *v)
{
@@ -837,15 +882,30 @@ add_tag(char *k, char *v)
if (! strcmp(k,"name")) {
strcpy(label_attr_buffer, v);
pad_text_attr(&label_attr, label_attr_buffer);
+ attr_strings_save(attr_string_label, v);
+ level=5;
+ }
+ if (! strcmp(k,"addr:email")) {
+ attr_strings_save(attr_string_email, v);
level=5;
}
if (! strcmp(k,"addr:housenumber")) {
- strcpy(house_number_attr_buffer, v);
- pad_text_attr(&house_number_attr, house_number_attr_buffer);
+ attr_strings_save(attr_string_house_number, v);
+ level=5;
}
if (! strcmp(k,"addr:street")) {
+ attr_strings_save(attr_string_street_name, v);
strcpy(street_name_attr_buffer, v);
pad_text_attr(&street_name_attr, street_name_attr_buffer);
+ level=5;
+ }
+ if (! strcmp(k,"phone")) {
+ attr_strings_save(attr_string_phone, v);
+ level=5;
+ }
+ if (! strcmp(k,"fax")) {
+ attr_strings_save(attr_string_fax, v);
+ level=5;
}
if (! strcmp(k,"ref")) {
if (in_way) {
@@ -1024,11 +1084,11 @@ add_node(int id, double lat, double lon)
{
if (node_buffer.size + sizeof(struct node_item) > node_buffer.malloced)
extend_buffer(&node_buffer);
+ attr_strings_clear();
node_is_tagged=0;
nodeid=id;
item.type=type_point_unkn;
label_attr.len=0;
- house_number_attr.len=0;
street_name_attr.len=0;
town_name_attr.len=0;
debug_attr.len=0;
@@ -1145,9 +1205,9 @@ add_way(int id)
{
wayid=id;
coord_count=0;
+ attr_strings_clear();
item.type=type_street_unkn;
label_attr.len=0;
- house_number_attr.len=0;
street_name_attr.len=0;
street_name_systematic_attr.len=0;
debug_attr.len=0;
@@ -1285,6 +1345,7 @@ static void
end_way(FILE *out)
{
int alen=0,count;
+ int *def_flags;
enum item_type types[5];
if (! out)
@@ -1312,9 +1373,9 @@ end_way(FILE *out)
item.type=type_street_unkn;
if (coverage && item_is_street(item))
item.type=type_coverage;
- if (item.type >= route_item_first && item.type <= route_item_last) {
- int def_flags=default_flags[item.type-route_item_first];
- flags_attr_value=(def_flags | flags[0] | flags[1]) & ~flags[2];
+ def_flags=item_get_default_flags(item.type);
+ if (def_flags) {
+ flags_attr_value=(*def_flags | flags[0] | flags[1]) & ~flags[2];
if (flags_attr_value != def_flags) {
flags_attr.len=2;
alen+=flags_attr.len+1;
@@ -1339,40 +1400,30 @@ end_way(FILE *out)
static void
end_node(FILE *out)
{
- int alen=0,conflict=0,count;
+ int conflict=0,count;
enum item_type types[5];
struct country_table *result=NULL, *lookup;
if (!out || ! node_is_tagged || ! nodeid)
return;
count=attr_longest_match(attr_mapping_node, attr_mapping_node_count, types, sizeof(types)/sizeof(enum item_type));
- pad_text_attr(&debug_attr, debug_attr_buffer);
- if (label_attr.len)
- alen+=label_attr.len+1;
- if (debug_attr.len)
- alen+=debug_attr.len+1;
- if (house_number_attr.len)
- alen+=house_number_attr.len+1;
- if (street_name_attr.len)
- alen+=street_name_attr.len+1;
- if (osmid_attr.len)
- alen+=osmid_attr.len+1;
if (count)
- item.type=types[0];
+ item_bin_init(item_bin, types[0]);
else
- item.type=type_point_unkn;
- item.clen=2;
- item.len=item.clen+2+alen;
- fwrite(&item, sizeof(item), 1, out);
- fwrite(&ni->c, 1*sizeof(struct coord), 1, out);
- if (item_is_town(item)) {
- town_name_attr.len=label_attr.len;
- write_attr(out, &town_name_attr, label_attr_buffer);
- } else
- write_attr(out, &label_attr, label_attr_buffer);
- write_attr(out, &house_number_attr, house_number_attr_buffer);
- write_attr(out, &street_name_attr, street_name_attr_buffer);
- write_attr(out, &osmid_attr, &osmid_attr_value);
- write_attr(out, &debug_attr, debug_attr_buffer);
+ item_bin_init(item_bin, type_point_unkn);
+ item_bin_add_coord(item_bin, &ni->c, 1);
+ if (osmid_attr_value == 368279467) {
+ fprintf(stderr,"%s\n", attr_strings[attr_string_label]);
+ }
+ item_bin_add_attr_string(item_bin, item_is_town(item) ? attr_town_name : attr_label, attr_strings[attr_string_label]);
+ item_bin_add_attr_string(item_bin, attr_house_number, attr_strings[attr_string_house_number]);
+ item_bin_add_attr_string(item_bin, attr_street_name, attr_strings[attr_string_street_name]);
+ item_bin_add_attr_string(item_bin, attr_phone, attr_strings[attr_string_phone]);
+ item_bin_add_attr_string(item_bin, attr_fax, attr_strings[attr_string_fax]);
+ item_bin_add_attr_string(item_bin, attr_email, attr_strings[attr_string_email]);
+ item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]);
+ item_bin_add_attr_longlong(item_bin, attr_osm_nodeid, osmid_attr_value);
+ item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer);
+ item_bin_write(item_bin,out);
if (item_is_town(item) && town_name_attr.len) {
char *tok,*buf=is_in_buffer;
while ((tok=strtok(buf, ","))) {
diff --git a/navit/roadprofile.c b/navit/roadprofile.c
index a3ce77cb0..07c292995 100644
--- a/navit/roadprofile.c
+++ b/navit/roadprofile.c
@@ -22,17 +22,30 @@
#include "item.h"
#include "roadprofile.h"
-struct roadprofile {
- struct attr **attrs;
-};
+static void
+roadprofile_set_attr_do(struct roadprofile *this, struct attr *attr)
+{
+ switch (attr->type) {
+ case attr_speed:
+ this->speed=attr->u.num;
+ break;
+ case attr_route_weight:
+ this->route_weight=attr->u.num;
+ break;
+ default:
+ break;
+ }
+}
struct roadprofile *
roadprofile_new(struct attr *parent, struct attr **attrs)
{
struct roadprofile *this_;
- struct attr *type_attr;
+ struct attr **attr;
this_=g_new0(struct roadprofile, 1);
this_->attrs=attr_list_dup(attrs);
+ for (attr=attrs;*attr; attr++)
+ roadprofile_set_attr_do(this_, *attr);
return this_;
}
@@ -45,6 +58,7 @@ roadprofile_get_attr(struct roadprofile *this_, enum attr_type type, struct attr
int
roadprofile_set_attr(struct roadprofile *this_, struct attr *attr)
{
+ roadprofile_set_attr_do(this_, attr);
this_->attrs=attr_generic_set_attr(this_->attrs, attr);
return 1;
}
diff --git a/navit/roadprofile.h b/navit/roadprofile.h
index 3154820a7..04d7263e5 100644
--- a/navit/roadprofile.h
+++ b/navit/roadprofile.h
@@ -17,6 +17,12 @@
* Boston, MA 02110-1301, USA.
*/
+struct roadprofile {
+ struct attr **attrs;
+ int speed;
+ int route_weight;
+};
+
struct roadprofile * roadprofile_new(struct attr *parent, struct attr **attrs);
int roadprofile_get_attr(struct roadprofile *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
int roadprofile_set_attr(struct roadprofile *this_, struct attr *attr);
diff --git a/navit/route.c b/navit/route.c
index 3cce31a5f..81c492a9a 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -66,6 +66,8 @@
#include "fib.h"
#include "event.h"
#include "callback.h"
+#include "vehicleprofile.h"
+#include "roadprofile.h"
struct map_priv {
@@ -190,21 +192,6 @@ struct route_path {
#define RF_SHOWGRAPH (1<<5)
/**
- * @brief Routing preferences
- *
- * This struct holds all information about route preferences (fastest, shortest, etc)
- */
-
-struct route_preferences {
- int mode; /**< 0 = Auto, 1 = On-Road, 2 = Off-Road */
- int flags_forward_mask; /**< Flags mask for moving in positive direction */
- int flags_reverse_mask; /**< Flags mask for moving in reverse direction */
- int flags; /**< Required flags to move through a segment */
- int maxspeed_handling; /**< 0 = Always, 1 = Only if lower, 2 = Never */
- int speedlist[route_item_last-route_item_first+1]; /**< The speedlist for this route */
-};
-
-/**
* @brief A complete route
*
* This struct holds all information about a route.
@@ -223,7 +210,7 @@ struct route {
struct callback * route_graph_flood_done_cb ; /**< Callback when route graph flooding is done */
struct callback_list *cbl2; /**< Callback list to call when route changes */
int destination_distance; /**< Distance to the destination at which the destination is considered "reached" */
- struct route_preferences preferences; /**< Routing preferences */
+ struct vehicleprofile *vehicleprofile; /**< Routing preferences */
int route_status; /**< Route Status */
};
@@ -237,7 +224,8 @@ struct route_graph {
struct map_selection *sel; /**< The rectangle selection for the graph */
struct mapset_handle *h; /**< Handle to the mapset */
struct map *m; /**< Pointer to the currently active map */
- struct map_rect *mr; /**< Pointer to the currently active map rectangle */
+ struct map_rect *mr; /**< Pointer to the currently active map rectangle */
+ struct vehicleprofile *vehicleprofile; /**< The vehicle profile */
struct callback *idle_cb; /**< Idle callback to process the graph */
struct callback *done_cb; /**< Callback when graph is done */
struct event_idle *idle_ev; /**< The pointer to the idle event */
@@ -265,7 +253,7 @@ static struct route_info * route_find_nearest_street(struct mapset *ms, struct p
static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c);
static void route_graph_update(struct route *this, struct callback *cb);
static void route_graph_build_done(struct route_graph *rg, int cancel);
-static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct route_preferences *pref);
+static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile);
static void route_process_street_graph(struct route_graph *this, struct item *item);
static void route_graph_destroy(struct route_graph *this);
static void route_path_update(struct route *this, int cancel);
@@ -400,9 +388,6 @@ route_new(struct attr *parent, struct attr **attrs)
this->destination_distance = 50; // Default value
}
this->cbl2=callback_list_new();
- this->preferences.flags_forward_mask=AF_ONEWAYREV|AF_CAR;
- this->preferences.flags_reverse_mask=AF_ONEWAY|AF_CAR;
- this->preferences.flags=AF_CAR;
return this;
}
@@ -493,6 +478,19 @@ route_set_mapset(struct route *this, struct mapset *ms)
}
/**
+ * @brief Sets the vehicle profile of a route
+ *
+ * @param this The route to set the profile for
+ * @param prof The vehicle profile
+ */
+
+void
+route_set_profile(struct route *this, struct vehicleprofile *prof)
+{
+ this->vehicleprofile=prof;
+}
+
+/**
* @brief Returns the mapset of the route passed
*
* @param this The route to get the mapset of
@@ -529,18 +527,6 @@ route_get_dst(struct route *this)
}
/**
- * @brief Returns the speedlist of the route passed
- *
- * @param this The route to get the speedlist for
- * @return The speedlist of the route passed
- */
-int *
-route_get_speedlist(struct route *this)
-{
- return this->preferences.speedlist;
-}
-
-/**
* @brief Checks if the path is calculated for the route passed
*
* @param this The route to check
@@ -553,25 +539,6 @@ route_get_path_set(struct route *this)
}
/**
- * @brief Sets the driving speed for a certain itemtype
- *
- * @param this The route to set the speed for
- * @param type The itemtype to set the speed for
- * @param value The speed that should be set
- * @return True on success, false if the itemtype does not exist
- */
-int
-route_set_speed(struct route *this, enum item_type type, int value)
-{
- if (type < route_item_first || type > route_item_last) {
- dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
- return 0;
- }
- this->preferences.speedlist[type-route_item_first]=value;
- return 1;
-}
-
-/**
* @brief Checks if the route passed contains a certain item within the route path
*
* This function checks if a certain items exists in the path that navit will guide
@@ -660,7 +627,7 @@ route_path_update_done(struct route *this, int new_graph)
route_status.u.num=route_status_building_path;
route_set_attr(this, &route_status);
- this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, &this->preferences);
+ this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->vehicleprofile);
route_path_destroy(oldpath);
if (this->path2) {
if (!new_graph && this->path2->updated)
@@ -1419,22 +1386,24 @@ route_graph_destroy(struct route_graph *this)
* This function returns the time needed to drive len meters on
* the item passed in item in tenth of seconds.
*
- * @param preferences The routing preferences
+ * @param profile The routing preferences
* @param over The segment which is passed
* @return The time needed to drive len on item in thenth of senconds
*/
static int
-route_time_seg(struct route_preferences *preferences, struct route_segment_data *over)
+route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over)
{
- int pspeed=preferences->speedlist[over->item.type-route_item_first];
- int speed=pspeed;
- if (preferences->maxspeed_handling != 2 && (over->flags & AF_SPEED_LIMIT)) {
+ struct roadprofile *roadprofile=vehicleprofile_get_roadprofile(profile, over->item.type);
+ int speed;
+ if (!roadprofile || !roadprofile->route_weight)
+ return INT_MAX;
+ if (profile->maxspeed_handling != 2 && (over->flags & AF_SPEED_LIMIT)) {
speed=RSD_MAXSPEED(over);
- if (preferences->maxspeed_handling == 1 && speed > pspeed)
- speed=pspeed;
+ if (profile->maxspeed_handling == 1 && speed > roadprofile->route_weight)
+ speed=roadprofile->route_weight;
} else
- speed=preferences->speedlist[over->item.type-route_item_first];
+ speed=roadprofile->route_weight;
if (!speed)
return INT_MAX;
return over->len*36/speed;
@@ -1443,7 +1412,7 @@ route_time_seg(struct route_preferences *preferences, struct route_segment_data
/**
* @brief Returns the "costs" of driving from point from over segment over in direction dir
*
- * @param preferences The routing preferences
+ * @param profile The routing preferences
* @param from The point where we are starting
* @param over The segment we are using
* @param dir The direction of segment which we are driving
@@ -1451,14 +1420,14 @@ route_time_seg(struct route_preferences *preferences, struct route_segment_data
*/
static int
-route_value_seg(struct route_preferences *preferences, 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_segment_data *over, int dir)
{
#if 0
dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? preferences->flags_forward_mask : preferences->flags_reverse_mask, preferences->flags);
#endif
- if ((over->flags & (dir >= 0 ? preferences->flags_forward_mask : preferences->flags_reverse_mask)) != preferences->flags)
+ if ((over->flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags)
return INT_MAX;
- return route_time_seg(preferences, over);
+ return route_time_seg(profile, over);
}
/**
@@ -1487,12 +1456,15 @@ route_process_street_graph(struct route_graph *this, struct item *item)
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)
segmented = 1;
} else
- flags = default_flags[item->type-route_item_first];
+ flags = *default_flags;
if (flags & AF_SPEED_LIMIT) {
@@ -1567,7 +1539,7 @@ route_graph_get_segment(struct route_graph *graph, struct street_data *sd)
* at this algorithm.
*/
static void
-route_graph_flood(struct route_graph *this, struct route_info *dst, struct route_preferences *preferences, struct callback *cb)
+route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb)
{
struct route_graph_point *p_min;
struct route_graph_segment *s;
@@ -1581,14 +1553,14 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route
dbg(0,"no segment for destination found\n");
return;
}
- val=route_value_seg(preferences, NULL, &s->data, 1);
+ val=route_value_seg(profile, NULL, &s->data, 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(preferences, NULL, &s->data, -1);
+ val=route_value_seg(profile, NULL, &s->data, -1);
if (val != INT_MAX) {
val=val*dst->percent/100;
s->start->seg=s;
@@ -1605,7 +1577,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route
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(preferences, p_min, &s->data, -1);
+ val=route_value_seg(profile, p_min, &s->data, -1);
if (val != INT_MAX) {
new=min+val;
if (debug_route)
@@ -1633,7 +1605,7 @@ route_graph_flood(struct route_graph *this, struct route_info *dst, struct route
}
s=p_min->end;
while (s) { /* Doing the same as above with the segments leading towards our point */
- val=route_value_seg(preferences, p_min, &s->data, 1);
+ val=route_value_seg(profile, p_min, &s->data, 1);
if (val != INT_MAX) {
new=min+val;
if (debug_route)
@@ -1761,7 +1733,7 @@ route_get_coord_dist(struct route *this_, int dist)
* @return The new route path
*/
static struct route_path *
-route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct route_preferences *preferences)
+route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile)
{
struct route_graph_segment *first,*s=NULL;
struct route_graph_point *start;
@@ -1774,7 +1746,7 @@ route_path_new(struct route_graph *this, struct route_path *oldpath, struct rout
if (! pos->street || ! dst->street)
return NULL;
- if (preferences->mode == 2 || (preferences->mode == 0 && pos->lenextra + dst->lenextra + pos->lenpos-dst->lenpos > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c)))
+ if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra + pos->lenpos-dst->lenpos > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c)))
return route_path_new_offroad(this, pos, dst);
s=route_graph_get_segment(this, pos->street);
@@ -1782,12 +1754,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(preferences, NULL, &s->data, -1);
+ val=route_value_seg(profile, NULL, &s->data, -1);
if (val != INT_MAX) {
val=val*(100-pos->percent)/100;
val1=s->end->value+val;
}
- val=route_value_seg(preferences, NULL, &s->data, 1);
+ val=route_value_seg(profile, NULL, &s->data, 1);
if (val != INT_MAX) {
val=val*pos->percent/100;
val2=s->start->value+val;
@@ -1888,8 +1860,7 @@ route_graph_build_idle(struct route_graph *rg)
return;
}
}
- if (item->type >= route_item_first && item->type <= route_item_last)
- route_process_street_graph(rg, item);
+ route_process_street_graph(rg, item);
count--;
}
}
@@ -1933,7 +1904,7 @@ route_graph_build(struct mapset *ms, struct coord *c1, struct coord *c2, struct
static void
route_graph_update_done(struct route *this, struct callback *cb)
{
- route_graph_flood(this->graph, this->dst, &this->preferences, cb);
+ route_graph_flood(this->graph, this->dst, this->vehicleprofile, cb);
}
/**
@@ -2255,7 +2226,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->preferences, seg->data);
+ attr->u.num=route_time_seg(route->vehicleprofile, seg->data);
} else
return 0;
return 1;
diff --git a/navit/vehicleprofile.c b/navit/vehicleprofile.c
index 7d3f7812c..31c9bc9a5 100644
--- a/navit/vehicleprofile.c
+++ b/navit/vehicleprofile.c
@@ -23,20 +23,43 @@
#include "item.h"
#include "vehicleprofile.h"
-struct vehicleprofile {
- struct attr **attrs;
-};
+void
+vehicleprofile_set_attr_do(struct vehicleprofile *this_, struct attr *attr)
+{
+ switch (attr->type) {
+ case attr_flags:
+ this_->flags=attr->u.num;
+ break;
+ case attr_flags_forward_mask:
+ this_->flags_forward_mask=attr->u.num;
+ break;
+ case attr_flags_reverse_mask:
+ this_->flags_forward_mask=attr->u.num;
+ break;
+ case attr_maxspeed_handling:
+ this_->maxspeed_handling=attr->u.num;
+ break;
+ case attr_route_mode:
+ this_->mode=attr->u.num;
+ break;
+ default:
+ break;
+ }
+}
struct vehicleprofile *
vehicleprofile_new(struct attr *parent, struct attr **attrs)
{
struct vehicleprofile *this_;
- struct attr *type_attr;
+ struct attr **attr, *type_attr;
if (! (type_attr=attr_search(attrs, NULL, attr_name))) {
return NULL;
}
this_=g_new0(struct vehicleprofile, 1);
this_->attrs=attr_list_dup(attrs);
+ this_->roadprofile_hash=g_hash_table_new(NULL, NULL);
+ for (attr=attrs;*attr; attr++)
+ vehicleprofile_set_attr_do(this_, *attr);
return this_;
}
@@ -49,6 +72,7 @@ vehicleprofile_get_attr(struct vehicleprofile *this_, enum attr_type type, struc
int
vehicleprofile_set_attr(struct vehicleprofile *this_, struct attr *attr)
{
+ vehicleprofile_set_attr_do(this_, attr);
this_->attrs=attr_generic_set_attr(this_->attrs, attr);
return 1;
}
@@ -57,6 +81,21 @@ int
vehicleprofile_add_attr(struct vehicleprofile *this_, struct attr *attr)
{
this_->attrs=attr_generic_add_attr(this_->attrs, attr);
+ struct attr item_types_attr;
+ switch (attr->type) {
+ case attr_roadprofile:
+ if (roadprofile_get_attr(attr->u.roadprofile, attr_item_types, &item_types_attr)) {
+ enum item_type *types=item_types_attr.u.item_types;
+ while (*types != type_none) {
+ g_hash_table_insert(this_->roadprofile_hash, (void *)(long)(*types), attr->u.roadprofile);
+ types++;
+ }
+ dbg(0,"ok\n");
+ }
+ break;
+ default:
+ break;
+ }
return 1;
}
@@ -67,3 +106,8 @@ vehicleprofile_remove_attr(struct vehicleprofile *this_, struct attr *attr)
return 1;
}
+struct roadprofile_data *
+vehicleprofile_get_roadprofile(struct vehicleprofile *this_, enum item_type type)
+{
+ return g_hash_table_lookup(this_->roadprofile_hash, (void *)(long)type);
+}
diff --git a/navit/vehicleprofile.h b/navit/vehicleprofile.h
index bb09f5d2f..cbb727131 100644
--- a/navit/vehicleprofile.h
+++ b/navit/vehicleprofile.h
@@ -17,6 +17,16 @@
* Boston, MA 02110-1301, USA.
*/
+struct vehicleprofile {
+ int mode; /**< 0 = Auto, 1 = On-Road, 2 = Off-Road */
+ int flags_forward_mask; /**< Flags mask for moving in positive direction */
+ int flags_reverse_mask; /**< Flags mask for moving in reverse direction */
+ int flags; /**< Required flags to move through a segment */
+ int maxspeed_handling; /**< 0 = Always, 1 = Only if lower, 2 = Never */
+ struct attr **attrs;
+ GHashTable *roadprofile_hash;
+};
+
struct vehicleprofile * vehicleprofile_new(struct attr *parent, struct attr **attrs);
int vehicleprofile_get_attr(struct vehicleprofile *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
int vehicleprofile_set_attr(struct vehicleprofile *this_, struct attr *attr);
diff --git a/navit/xmlconfig.c b/navit/xmlconfig.c
index 061feda0e..7110c2478 100644
--- a/navit/xmlconfig.c
+++ b/navit/xmlconfig.c
@@ -194,35 +194,6 @@ xmlconfig_config(struct xmlstate *state)
}
static int
-xmlconfig_speed(struct xmlstate *state)
-{
- const char *type;
- const char *value;
- int v;
- enum item_type itype;
- char *tok, *type_str, *str;
-
- type=find_attribute(state, "type", 1);
- if (! type)
- return 0;
- value=find_attribute(state, "value", 1);
- if (! value)
- return 0;
- v=convert_number(value);
- type_str=g_strdup(type);
- str=type_str;
- while ((tok=strtok(str, ","))) {
- itype=item_from_name(tok);
- route_set_speed(state->parent->element_attr.u.data, itype, v);
- str=NULL;
- }
- g_free(type_str);
-
- return 1;
-}
-
-
-static int
xmlconfig_announce(struct xmlstate *state)
{
const char *type,*value;
@@ -323,7 +294,6 @@ struct element_func {
{ "speech", "navit", NULL, attr_speech},
{ "tracking", "navit", NULL, attr_tracking},
{ "route", "navit", NULL, attr_route},
- { "speed", "route", xmlconfig_speed},
{ "mapset", "navit", NULL, attr_mapset},
{ "map", "mapset", NULL, attr_map},
{ "debug", "config", NULL, attr_debug},