From 4d5bf9a1cd75584b00499f4c4b677ad8d274416f Mon Sep 17 00:00:00 2001 From: martin-s Date: Tue, 27 Jan 2009 12:09:14 +0000 Subject: [PATCH] Add:Core:Initial working on turn restrictions git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1978 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/navit/attr.c | 2 + navit/navit/attr_def.h | 3 + navit/navit/item_def.h | 2 + navit/navit/osm2navit.c | 182 ++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 151 insertions(+), 38 deletions(-) diff --git a/navit/navit/attr.c b/navit/navit/attr.c index 62d4b5b..ae31152 100644 --- a/navit/navit/attr.c +++ b/navit/navit/attr.c @@ -302,6 +302,8 @@ attr_data_size(struct attr *attr) return sizeof(*attr->u.color); if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end) return sizeof(void *); + if (attr->type >= attr_type_int64_begin && attr->type <= attr_type_int64_end) + return sizeof(*attr->u.num64); dbg(0,"size for %s unknown\n", attr_to_name(attr->type)); return 0; } diff --git a/navit/navit/attr_def.h b/navit/navit/attr_def.h index 1f34a1c..3047cf1 100644 --- a/navit/navit/attr_def.h +++ b/navit/navit/attr_def.h @@ -92,6 +92,7 @@ ATTR(cps) ATTR(fast) ATTR(osd_configuration) ATTR(columns) +ATTR(align) ATTR2(0x00028000,type_boolean_begin) /* boolean */ ATTR(overwrite) @@ -179,6 +180,8 @@ ATTR(gc_terrain) ATTR(icon_src) ATTR(position_time_iso8601) ATTR(house_number) +ATTR(osm_member) +ATTR(osm_tag) ATTR2(0x0003ffff,type_string_end) ATTR2(0x00040000,type_special_begin) ATTR(order) diff --git a/navit/navit/item_def.h b/navit/navit/item_def.h index 80310d3..4f4fad9 100644 --- a/navit/navit/item_def.h +++ b/navit/navit/item_def.h @@ -413,6 +413,8 @@ ITEM(fence) ITEM(wall) ITEM(retaining_wall) ITEM(city_wall) +ITEM(street_turn_restriction_no) +ITEM(street_turn_restriction_only) /* Area */ ITEM2(0xc0000000,area) ITEM2(0xc0000001,area_unspecified) diff --git a/navit/navit/osm2navit.c b/navit/navit/osm2navit.c index f58edcc..dc3d1e7 100644 --- a/navit/navit/osm2navit.c +++ b/navit/navit/osm2navit.c @@ -365,6 +365,9 @@ static char *attrmap={ "w barrier=city_wall city_wall\n" }; + +static char buffer[400000]; + struct coord coord_buffer[65536]; #define IS_REF(c) ((c).x >= (1 << 30)) @@ -599,6 +602,54 @@ char is_in_buffer[BUFFER_SIZE]; static void write_zipmember(FILE *out, FILE *dir_out, char *name, int filelen, char *data, int data_size, int compression_level); static void +item_buffer_set_type(char *buffer, enum item_type type) +{ + struct item_bin *ib=(struct item_bin *) buffer; + ib->clen=0; + ib->len=2; + ib->type=type; +} + +static void +item_buffer_change_type(char *buffer, enum item_type type) +{ + struct item_bin *ib=(struct item_bin *) buffer; + ib->type=type; +} + +static void +item_buffer_add_coord(char *buffer, struct coord *c, int count) +{ + struct item_bin *ib=(struct item_bin *) buffer; + struct coord *c2=(struct coord *)(ib+1); + c2+=ib->clen/2; + memcpy(c2, c, count*sizeof(struct coord)); + ib->clen+=count*2; + ib->len+=count*2; +} + +static void +item_buffer_add_attr(char *buffer, struct attr *attr) +{ + struct item_bin *ib=(struct item_bin *) buffer; + struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1); + int size=attr_data_size(attr); + int pad=(4-(size%4))%4; + ab->type=attr->type; + memcpy(ab+1, attr_data_get(attr), size); + memset((unsigned char *)(ab+1)+size, 0, pad); + ab->len=(size+pad)/4+1; + ib->len+=ab->len+1; +} + +static void +item_buffer_write(char *buffer, FILE *out) +{ + struct item_bin *ib=(struct item_bin *) buffer; + fwrite(buffer, (ib->len+1)*4, 1, out); +} + +static void pad_text_attr(struct attr_bin *a, char *buffer) { int l; @@ -638,6 +689,7 @@ xml_get_attribute(char *xml, char *attribute, char *buffer, int buffer_size) } static int node_is_tagged; +static void relation_add_tag(char *k, char *v); static void add_tag(char *k, char *v) @@ -801,7 +853,10 @@ parse_tag(char *p) if (!xml_get_attribute(p, "v", v_buffer, BUFFER_SIZE)) return 0; decode_entities(v_buffer); - add_tag(k_buffer, v_buffer); + if (in_relation) + relation_add_tag(k_buffer, v_buffer); + else + add_tag(k_buffer, v_buffer); return 1; } @@ -1029,51 +1084,77 @@ parse_way(char *p) } static int +add_id_attr(char *p, enum attr_type attr_type) +{ + long long id; + struct attr idattr = { attr_type }; + char id_buffer[BUFFER_SIZE]; + if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) + return 0; + id=atoll(id_buffer); + idattr.u.num64=&id; + item_buffer_add_attr(buffer, &idattr); + return 1; +} + +char relation_type[BUFFER_SIZE]; + + +static int parse_relation(char *p) { debug_attr_buffer[0]='\0'; + relation_type[0]='\0'; + item_buffer_set_type(buffer, type_none); + if (!add_id_attr(p, attr_osm_relationid)) + return 0; return 1; } static void -item_buffer_set_type(char *buffer, enum item_type type) +end_relation(FILE *turn_restrictions) { - struct item_bin *ib=(struct item_bin *) buffer; - ib->clen=0; - ib->len=2; - ib->type=type; + struct item_bin *ib=(struct item_bin *)buffer; + if (!strcmp(relation_type, "restriction") && (ib->type == type_street_turn_restriction_no || ib->type == type_street_turn_restriction_only)) + item_buffer_write(buffer, turn_restrictions); } -static void -item_buffer_add_coord(char *buffer, struct coord *c, int count) +static int +parse_member(char *p) { - struct item_bin *ib=(struct item_bin *) buffer; - struct coord *c2=(struct coord *)(ib+1); - c2+=ib->clen/2; - memcpy(c2, c, count*sizeof(struct coord)); - ib->clen+=count*2; - ib->len+=count*2; + char type_buffer[BUFFER_SIZE]; + char ref_buffer[BUFFER_SIZE]; + char role_buffer[BUFFER_SIZE]; + char member_buffer[BUFFER_SIZE*3+3]; + struct attr memberattr = { attr_osm_member }; + if (!xml_get_attribute(p, "type", type_buffer, BUFFER_SIZE)) + return 0; + if (!xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) + return 0; + if (!xml_get_attribute(p, "role", role_buffer, BUFFER_SIZE)) + return 0; + sprintf(member_buffer,"%s:%s:%s", type_buffer, ref_buffer, role_buffer); + memberattr.u.str=member_buffer; + item_buffer_add_attr(buffer, &memberattr); + + return 1; } + static void -item_buffer_add_attr(char *buffer, struct attr *attr) -{ - struct item_bin *ib=(struct item_bin *) buffer; - struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1); - if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) { - ab->type=attr->type; - strcpy((char *)(ab+1),attr->u.str); - pad_text_attr(ab, (char *)(ab+1)); - ib->len+=ab->len+1; +relation_add_tag(char *k, char *v) +{ + if (!strcmp(k,"type")) + strcpy(relation_type, v); + else if (!strcmp(k,"restriction")) { + if (strncmp(k,"no_",3)) { + item_buffer_change_type(buffer, type_street_turn_restriction_no); + } else if (strncmp(k,"only_",5)) { + item_buffer_change_type(buffer, type_street_turn_restriction_only); + } } } -static void -item_buffer_write(char *buffer, FILE *out) -{ - struct item_bin *ib=(struct item_bin *) buffer; - fwrite(buffer, (ib->len+1)*4, 1, out); -} static void write_attr(FILE *out, struct attr_bin *attr, void *buffer) @@ -1375,7 +1456,7 @@ load_buffer(char *filename, struct buffer *b) } static int -phase1(FILE *in, FILE *out_ways, FILE *out_nodes) +phase1(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions) { int size=4096; char buffer[size]; @@ -1412,6 +1493,8 @@ phase1(FILE *in, FILE *out_ways, FILE *out_nodes) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); processed_relations++; } else if (!strncmp(p, "",7)) { in_node=0; end_node(out_nodes); @@ -1420,6 +1503,7 @@ phase1(FILE *in, FILE *out_ways, FILE *out_nodes) end_way(out_ways); } else if (!strncmp(p, "",11)) { in_relation=0; + end_relation(out_turn_restrictions); } else if (!strncmp(p, "",6)) { } else { fprintf(stderr,"WARNING: unknown tag in %s\n", buffer); @@ -1599,7 +1683,6 @@ phase1_db(char *dbstr, FILE *out_ways, FILE *out_nodes) } #endif -static char buffer[400000]; static void phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes) @@ -1910,7 +1993,7 @@ write_item(char *tile, struct item_bin *ib) } static void -write_item_part(FILE *out, struct item_bin *orig, int first, int last) +write_item_part(FILE *out, FILE *out_graph, struct item_bin *orig, int first, int last) { struct item_bin new; struct coord *c=(struct coord *)(orig+1); @@ -1926,10 +2009,15 @@ write_item_part(FILE *out, struct item_bin *orig, int first, int last) fwrite(&new, sizeof(new), 1, out); fwrite(c+first, new.clen*4, 1, out); fwrite(attr, attr_len*4, 1, out); +#if 0 + fwrite(&new, sizeof(new), 1, out_graph); + fwrite(c+first, new.clen*4, 1, out_graph); + fwrite(attr, attr_len*4, 1, out_graph); +#endif } static int -phase2(FILE *in, FILE *out) +phase2(FILE *in, FILE *out, FILE *out_graph) { struct coord *c; int i,ccount,last,ndref; @@ -1943,6 +2031,8 @@ phase2(FILE *in, FILE *out) fprintf(stderr,"type 0x%x len %d clen %d\n", ib->type, ib->len, ib->clen); #endif ccount=ib->clen/2; + if (ccount <= 1) + continue; c=(struct coord *)(ib+1); last=0; for (i = 0 ; i < ccount ; i++) { @@ -1954,12 +2044,13 @@ phase2(FILE *in, FILE *out) #endif c[i]=ni->c; if (ni->ref_way > 1 && i != 0 && i != ccount-1 && item_is_street(*ib)) { - write_item_part(out, ib, last, i); + write_item_part(out, out_graph, ib, last, i); last=i; } } } - write_item_part(out, ib, last, ccount-1); + if (ccount) + write_item_part(out, out_graph, ib, last, ccount-1); } sig_alrm(0); #ifndef _WIN32 @@ -2746,7 +2837,7 @@ static void add_plugin(char *path) int main(int argc, char **argv) { - FILE *ways=NULL,*ways_split=NULL,*nodes=NULL,*tilesdir,*zipdir,*res; + FILE *ways=NULL,*ways_split=NULL,*nodes=NULL,*turn_restrictions=NULL,*graph=NULL,*tilesdir,*zipdir,*res; char *map=g_strdup(attrmap); int c,start=1,end=4,dump_coordinates=0; int keep_tmpfiles=0; @@ -2898,6 +2989,8 @@ int main(int argc, char **argv) ways=fopen("ways.tmp","wb+"); if (process_nodes) nodes=fopen("nodes.tmp","wb+"); + if (process_ways && process_nodes) + turn_restrictions=fopen("turn_restrictions.tmp","wb+"); phase=1; fprintf(stderr,"PROGRESS: Phase 1: collecting data\n"); #ifdef HAVE_POSTGRESQL @@ -2910,11 +3003,13 @@ int main(int argc, char **argv) map_destroy(map_handle); } else - phase1(input_file,ways,nodes); + phase1(input_file,ways,nodes,turn_restrictions); if (ways) fclose(ways); if (nodes) fclose(nodes); + if (turn_restrictions) + fclose(turn_restrictions); #ifdef GENERATE_INDEX fprintf(stderr,"PROGRESS: Phase 1: sorting countries\n"); sort_countries(); @@ -2930,11 +3025,13 @@ int main(int argc, char **argv) if (process_ways) { ways=fopen("ways.tmp","rb"); ways_split=fopen("ways_split.tmp","wb+"); + graph=fopen("graph.tmp","wb+"); phase=2; fprintf(stderr,"PROGRESS: Phase 2: finding intersections\n"); - phase2(ways,ways_split); + phase2(ways,ways_split,graph); fclose(ways_split); fclose(ways); + fclose(graph); if(!keep_tmpfiles) unlink("ways.tmp"); } else @@ -2967,6 +3064,13 @@ int main(int argc, char **argv) fclose(ways_split); } } + if (process_ways && process_nodes) { + turn_restrictions=fopen("turn_restrictions.tmp","rb"); + if (turn_restrictions) { + dump(turn_restrictions); + fclose(turn_restrictions); + } + } exit(0); } if (start <= 3) { @@ -3005,6 +3109,8 @@ int main(int argc, char **argv) if(!keep_tmpfiles) { unlink("nodes.tmp"); unlink("ways_split.tmp"); + unlink("turn_restrictions.tmp"); + unlink("graph.tmp"); unlink("tilesdir.tmp"); unlink("zipdir.tmp"); #ifdef GENERATE_INDEX -- 2.7.4