X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fosmparser.c;fp=src%2Fosmparser.c;h=03e17b7f37e993fde038bf748ba2613693f19276;hb=9dffc9de96014e24d1fd1030a79317ba34c504e8;hp=3af039d12e41c44b5f7a0cbcbad62886cf2084fc;hpb=42c9226fc71c19af4d755c6900120bfa07f7e99c;p=routino diff --git a/src/osmparser.c b/src/osmparser.c index 3af039d..03e17b7 100644 --- a/src/osmparser.c +++ b/src/osmparser.c @@ -1,5 +1,5 @@ /*************************************** - $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.69 2010/05/29 13:54:23 amb Exp $ + $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.73 2010/11/13 14:22:28 amb Exp $ OSM XML file parser (either JOSM or planet) @@ -29,12 +29,17 @@ #include "typesx.h" #include "functionsx.h" + #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" +#include "relationsx.h" + #include "xmlparse.h" #include "tagging.h" +#include "logging.h" + /* Macros */ @@ -49,14 +54,24 @@ static TagList *current_tags=NULL; static node_t *way_nodes=NULL; static int way_nnodes=0; -static NodesX *nodes; -static SegmentsX *segments; -static WaysX *ways; +static node_t *relation_nodes=NULL; +static int relation_nnodes=0; +static way_t *relation_ways=NULL; +static int relation_nways=0; +static relation_t *relation_relations=NULL; +static int relation_nrelations=0; + +static NodesX *nodes; +static SegmentsX *segments; +static WaysX *ways; +static RelationsX *relations; /* Local functions */ +static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude); static void process_way_tags(TagList *tags,way_t id); +static void process_relation_tags(TagList *tags,relation_t id); /* The XML tag processing function prototypes */ @@ -65,7 +80,7 @@ static void process_way_tags(TagList *tags,way_t id); //static int osmType_function(const char *_tag_,int _type_); static int relationType_function(const char *_tag_,int _type_,const char *id); static int wayType_function(const char *_tag_,int _type_,const char *id); -//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); +static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); static int ndType_function(const char *_tag_,int _type_,const char *ref); static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon); static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v); @@ -114,7 +129,7 @@ static xmltag ndType_tag= static xmltag memberType_tag= {"member", 3, {"type","ref","role"}, - NULL, + memberType_function, {NULL}}; /*+ The wayType type tag. +*/ @@ -231,38 +246,34 @@ static int tagType_function(const char *_tag_,int _type_,const char *k,const cha static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon) { + static node_t node_id; + static double latitude,longitude; + if(_type_&XMLPARSE_TAG_START) { - node_t node_id; - double latitude,longitude; - nnodes++; if(!(nnodes%1000)) - { - printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); - fflush(stdout); - } + printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); + + current_tags=NewTagList(); /* Handle the node information */ XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */ XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude); XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude); + } - AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude)); + if(_type_&XMLPARSE_TAG_END) + { + TagList *result=ApplyTaggingRules(&NodeRules,current_tags); -// current_tags=NewTagList(); - current_tags=NULL; - } + process_node_tags(result,node_id,latitude,longitude); -// if(_type_&XMLPARSE_TAG_END) -// { -// TagList *result=ApplyTaggingRules(&NodeRules,current_tags); -// -// DeleteTagList(current_tags); -// DeleteTagList(result); -// } + DeleteTagList(current_tags); + DeleteTagList(result); + } return(0); } @@ -288,7 +299,7 @@ static int ndType_function(const char *_tag_,int _type_,const char *ref) XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */ - if((way_nnodes%256)==0) + if(way_nnodes && (way_nnodes%256)==0) way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); way_nodes[way_nnodes++]=node_id; @@ -314,10 +325,44 @@ static int ndType_function(const char *_tag_,int _type_,const char *ref) const char *role The contents of the 'role' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ -//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) -//{ -// return(0); -//} +static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) +{ + if(_type_&XMLPARSE_TAG_START) + { + XMLPARSE_ASSERT_STRING(_tag_,type); + XMLPARSE_ASSERT_STRING(_tag_,ref); + + if(!strcmp(type,"node")) + { + node_t node_id=atoll(ref); /* need long long conversion */ + + if(relation_nnodes && (relation_nnodes%256)==0) + relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t)); + + relation_nodes[relation_nnodes++]=node_id; + } + else if(!strcmp(type,"way")) + { + way_t way_id=atoll(ref); /* need long long conversion */ + + if(relation_nways && (relation_nways%256)==0) + relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t)); + + relation_ways[relation_nways++]=way_id; + } + else if(!strcmp(type,"relation")) + { + relation_t relation_id=atoll(ref); /* need long long conversion */ + + if(relation_nrelations && (relation_nrelations%256)==0) + relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t)); + + relation_relations[relation_nrelations++]=relation_id; + } + } + + return(0); +} /*++++++++++++++++++++++++++++++++++++++ @@ -341,12 +386,10 @@ static int wayType_function(const char *_tag_,int _type_,const char *id) nways++; if(!(nways%1000)) - { - printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); - fflush(stdout); - } + printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); + way_nnodes=0; /* Handle the way information */ @@ -382,27 +425,33 @@ static int wayType_function(const char *_tag_,int _type_,const char *id) static int relationType_function(const char *_tag_,int _type_,const char *id) { + static relation_t relation_id; + if(_type_&XMLPARSE_TAG_START) { nrelations++; if(!(nrelations%1000)) - { - printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); - fflush(stdout); - } + printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); + + current_tags=NewTagList(); -// current_tags=NewTagList(); - current_tags=NULL; + relation_nnodes=relation_nways=relation_nrelations=0; + + /* Handle the relation information */ + + XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */ } -// if(_type_&XMLPARSE_TAG_END) -// { -// TagList *result=ApplyTaggingRules(&RelationRules,current_tags); -// -// DeleteTagList(current_tags); -// DeleteTagList(result); -// } + if(_type_&XMLPARSE_TAG_END) + { + TagList *result=ApplyTaggingRules(&RelationRules,current_tags); + + process_relation_tags(result,relation_id); + + DeleteTagList(current_tags); + DeleteTagList(result); + } return(0); } @@ -451,38 +500,146 @@ static int relationType_function(const char *_tag_,int _type_,const char *id) FILE *file The file to read from. - NodesX *OSMNodes The array of nodes to fill in. + NodesX *OSMNodes The data structure of nodes to fill in. + + SegmentsX *OSMSegments The data structure of segments to fill in. - SegmentsX *OSMSegments The array of segments to fill in. + WaysX *OSMWays The data structure of ways to fill in. - WaysX *OSMWays The arrray of ways to fill in. + RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ -int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays) +int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations) { int retval; - /* Parse the file */ + /* Copy the function parameters and initialise the variables. */ nodes=OSMNodes; segments=OSMSegments; ways=OSMWays; + relations=OSMRelations; + + way_nodes=(node_t*)malloc(256*sizeof(node_t)); + + relation_nodes =(node_t *)malloc(256*sizeof(node_t)); + relation_ways =(way_t *)malloc(256*sizeof(way_t)); + relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); + + /* Parse the file */ nnodes=0,nways=0,nrelations=0; - printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0"); - fflush(stdout); + printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0"); retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); - printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations); - fflush(stdout); + printf_last("Read: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); return(retval); } /*++++++++++++++++++++++++++++++++++++++ + Process the tags associated with a node. + + TagList *tags The list of node tags. + + node_t id The id of the node. + + double latitude The latitude of the node. + + double longitude The longitude of the node. + ++++++++++++++++++++++++++++++++++++++*/ + +static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude) +{ + allow_t allow=Allow_ALL; + + int i; + + /* Parse the tags */ + + for(i=0;intags;i++) + { + char *k=tags->k[i]; + char *v=tags->v[i]; + + switch(*k) + { + case 'b': + if(!strcmp(k,"bicycle")) + if(!ISTRUE(v)) + allow&=~Allow_Bicycle; + + break; + + case 'f': + if(!strcmp(k,"foot")) + if(!ISTRUE(v)) + allow&=~Allow_Foot; + + break; + + case 'g': + if(!strcmp(k,"goods")) + if(!ISTRUE(v)) + allow&=~Allow_Goods; + + break; + + case 'h': + if(!strcmp(k,"horse")) + if(!ISTRUE(v)) + allow&=~Allow_Horse; + + if(!strcmp(k,"hgv")) + if(!ISTRUE(v)) + allow&=~Allow_HGV; + + break; + + case 'm': + if(!strcmp(k,"moped")) + if(!ISTRUE(v)) + allow&=~Allow_Moped; + + if(!strcmp(k,"motorbike")) + if(!ISTRUE(v)) + allow&=~Allow_Motorbike; + + if(!strcmp(k,"motorcar")) + if(!ISTRUE(v)) + allow&=~Allow_Motorcar; + + break; + + case 'p': + if(!strcmp(k,"psv")) + if(!ISTRUE(v)) + allow&=~Allow_PSV; + + break; + + case 'w': + if(!strcmp(k,"wheelchair")) + if(!ISTRUE(v)) + allow&=~Allow_Wheelchair; + + break; + + default: + ; + } + } + + /* Create the node */ + + AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow); +} + + +/*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a way. TagList *tags The list of way tags. @@ -512,6 +669,10 @@ static void process_way_tags(TagList *tags,way_t id) if(ISTRUE(v)) way.allow|= Allow_Bicycle; + if(!strcmp(k,"bicycleroute")) + if(ISTRUE(v)) + way.props|=Properties_BicycleRoute; + if(!strcmp(k,"bridge")) if(ISTRUE(v)) way.props|=Properties_Bridge; @@ -523,6 +684,10 @@ static void process_way_tags(TagList *tags,way_t id) if(ISTRUE(v)) way.allow|= Allow_Foot; + if(!strcmp(k,"footroute")) + if(ISTRUE(v)) + way.props|=Properties_FootRoute; + break; case 'g': @@ -746,3 +911,55 @@ static void process_way_tags(TagList *tags,way_t id) } } } + + +/*++++++++++++++++++++++++++++++++++++++ + Process the tags associated with a relation. + + TagList *tags The list of relation tags. + + relation_t id The id of the relation. + ++++++++++++++++++++++++++++++++++++++*/ + +static void process_relation_tags(TagList *tags,relation_t id) +{ + allow_t routes=Allow_None; + int i; + + /* Parse the tags */ + + for(i=0;intags;i++) + { + char *k=tags->k[i]; + char *v=tags->v[i]; + + switch(*k) + { + case 'b': + if(!strcmp(k,"bicycleroute")) + if(ISTRUE(v)) + routes|=Allow_Bicycle; + + break; + + case 'f': + if(!strcmp(k,"footroute")) + if(ISTRUE(v)) + routes|=Allow_Foot; + + break; + + default: + ; + } + } + + /* Create the route relation (must store all relations that have ways or + relations even if they are not routes because they might be referenced by + other relations that are routes) */ + + if(relation_nways || relation_nrelations) + AppendRouteRelation(relations,id,routes, + relation_ways,relation_nways, + relation_relations,relation_nrelations); +}