diff options
author | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2011-01-03 10:17:02 +0000 |
---|---|---|
committer | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2011-01-03 10:17:02 +0000 |
commit | f5d10e09acc391946ce42ce00695b168c164962f (patch) | |
tree | ba614db1acd55901240b129ed9b3174a2a550aee /navit/maptool/osm_xml.c | |
parent | 54dec565b889162d6ea1c4a29974d603de5818ce (diff) | |
download | navit-svn-f5d10e09acc391946ce42ce00695b168c164962f.tar.gz |
Fix:maptool:Some cleanups
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@3853 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/maptool/osm_xml.c')
-rw-r--r-- | navit/maptool/osm_xml.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/navit/maptool/osm_xml.c b/navit/maptool/osm_xml.c new file mode 100644 index 00000000..21a7efa7 --- /dev/null +++ b/navit/maptool/osm_xml.c @@ -0,0 +1,211 @@ +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <unistd.h> +#include "maptool.h" + +static int +osm_xml_get_attribute(char *xml, char *attribute, char *buffer, int buffer_size) +{ + int len=strlen(attribute); + char *pos,*i,s,attr[len+2]; + strcpy(attr, attribute); + strcpy(attr+len, "="); + pos=strstr(xml, attr); + if (! pos) + return 0; + pos+=len+1; + s=*pos++; + if (! s) + return 0; + i=strchr(pos, s); + if (! i) + return 0; + if (i - pos > buffer_size) { + fprintf(stderr,"Buffer overflow %ld vs %d\n", (long)(i-pos), buffer_size); + return 0; + } + strncpy(buffer, pos, i-pos); + buffer[i-pos]='\0'; + return 1; +} + +static struct entity { + char *entity; + char c; +} entities[]= { + {""",'"'}, + {"'",'\''}, + {"&",'&'}, + {"<",'<'}, + {">",'>'}, + {""",'"'}, + {"'",'\''}, + {"&",'&'}, + {"<",'<'}, + {">",'>'}, +}; + +static void +osm_xml_decode_entities(char *buffer) +{ + char *pos=buffer; + int i,len,found; + + while ((pos=strchr(pos, '&'))) { + found=0; + for (i = 0 ; i < sizeof(entities)/sizeof(struct entity); i++) { + len=strlen(entities[i].entity); + if (!strncmp(pos, entities[i].entity, len)) { + *pos=entities[i].c; + memmove(pos+1, pos+len, strlen(pos+len)+1); + found=1; + break; + } + } + pos++; + } +} + +static int +parse_tag(char *p) +{ + char k_buffer[BUFFER_SIZE]; + char v_buffer[BUFFER_SIZE]; + if (!osm_xml_get_attribute(p, "k", k_buffer, BUFFER_SIZE)) + return 0; + if (!osm_xml_get_attribute(p, "v", v_buffer, BUFFER_SIZE)) + return 0; + osm_xml_decode_entities(v_buffer); + osm_add_tag(k_buffer, v_buffer); + return 1; +} + + +static int +parse_node(char *p) +{ + char id_buffer[BUFFER_SIZE]; + char lat_buffer[BUFFER_SIZE]; + char lon_buffer[BUFFER_SIZE]; + if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) + return 0; + if (!osm_xml_get_attribute(p, "lat", lat_buffer, BUFFER_SIZE)) + return 0; + if (!osm_xml_get_attribute(p, "lon", lon_buffer, BUFFER_SIZE)) + return 0; + osm_add_node(atoll(id_buffer), atof(lat_buffer), atof(lon_buffer)); + return 1; +} + + +static int +parse_way(char *p) +{ + char id_buffer[BUFFER_SIZE]; + if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) + return 0; + osm_add_way(atoll(id_buffer)); + return 1; +} + +static int +parse_relation(char *p) +{ + char id_buffer[BUFFER_SIZE]; + if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) + return 0; + osm_add_relation(atoll(id_buffer)); + return 1; +} + +static int +parse_member(char *p) +{ + char type_buffer[BUFFER_SIZE]; + char ref_buffer[BUFFER_SIZE]; + char role_buffer[BUFFER_SIZE]; + int type; + if (!osm_xml_get_attribute(p, "type", type_buffer, BUFFER_SIZE)) + return 0; + if (!osm_xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) + return 0; + if (!osm_xml_get_attribute(p, "role", role_buffer, BUFFER_SIZE)) + return 0; + if (!strcmp(type_buffer,"node")) + type=1; + else if (!strcmp(type_buffer,"way")) + type=2; + else if (!strcmp(type_buffer,"relation")) + type=3; + else { + fprintf(stderr,"Unknown type %s\n",type_buffer); + type=0; + } + osm_add_member(type, atoll(ref_buffer), role_buffer); + + return 1; +} + +static int +parse_nd(char *p) +{ + char ref_buffer[BUFFER_SIZE]; + if (!osm_xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) + return 0; + osm_add_nd(atoll(ref_buffer)); + return 1; +} + +int +map_collect_data_osm(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions, FILE *out_boundaries) +{ + int size=BUFFER_SIZE; + char buffer[size]; + char *p; + sig_alrm(0); + while (fgets(buffer, size, in)) { + p=strchr(buffer,'<'); + if (! p) { + fprintf(stderr,"WARNING: wrong line %s\n", buffer); + continue; + } + if (!strncmp(p, "<?xml ",6)) { + } else if (!strncmp(p, "<osm ",5)) { + } else if (!strncmp(p, "<bound ",7)) { + } else if (!strncmp(p, "<node ",6)) { + if (!parse_node(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + processed_nodes++; + } else if (!strncmp(p, "<tag ",5)) { + if (!parse_tag(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + } else if (!strncmp(p, "<way ",5)) { + if (!parse_way(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + processed_ways++; + } else if (!strncmp(p, "<nd ",4)) { + if (!parse_nd(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + } else if (!strncmp(p, "<relation ",10)) { + if (!parse_relation(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + processed_relations++; + } else if (!strncmp(p, "<member ",8)) { + if (!parse_member(p)) + fprintf(stderr,"WARNING: failed to parse %s\n", buffer); + } else if (!strncmp(p, "</node>",7)) { + osm_end_node(out_nodes); + } else if (!strncmp(p, "</way>",6)) { + osm_end_way(out_ways); + } else if (!strncmp(p, "</relation>",11)) { + osm_end_relation(out_turn_restrictions, out_boundaries); + } else if (!strncmp(p, "</osm>",6)) { + } else { + fprintf(stderr,"WARNING: unknown tag in %s\n", buffer); + } + } + sig_alrm(0); + sig_alrm_end(); + return 1; +} |