1 /***************************************
2 $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.73 2010/11/13 14:22:28 amb Exp $
4 OSM XML file parser (either JOSM or planet)
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
31 #include "functionsx.h"
34 #include "segmentsx.h"
36 #include "relationsx.h"
46 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
51 static long nnodes=0,nways=0,nrelations=0;
52 static TagList *current_tags=NULL;
54 static node_t *way_nodes=NULL;
55 static int way_nnodes=0;
57 static node_t *relation_nodes=NULL;
58 static int relation_nnodes=0;
59 static way_t *relation_ways=NULL;
60 static int relation_nways=0;
61 static relation_t *relation_relations=NULL;
62 static int relation_nrelations=0;
65 static SegmentsX *segments;
67 static RelationsX *relations;
72 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
73 static void process_way_tags(TagList *tags,way_t id);
74 static void process_relation_tags(TagList *tags,relation_t id);
77 /* The XML tag processing function prototypes */
79 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
80 //static int osmType_function(const char *_tag_,int _type_);
81 static int relationType_function(const char *_tag_,int _type_,const char *id);
82 static int wayType_function(const char *_tag_,int _type_,const char *id);
83 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
84 static int ndType_function(const char *_tag_,int _type_,const char *ref);
85 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
86 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
87 //static int boundType_function(const char *_tag_,int _type_);
88 //static int boundsType_function(const char *_tag_,int _type_);
91 /* The XML tag definitions */
93 /*+ The boundsType type tag. +*/
94 static xmltag boundsType_tag=
100 /*+ The boundType type tag. +*/
101 static xmltag boundType_tag=
107 /*+ The tagType type tag. +*/
108 static xmltag tagType_tag=
114 /*+ The nodeType type tag. +*/
115 static xmltag nodeType_tag=
117 3, {"id","lat","lon"},
119 {&tagType_tag,NULL}};
121 /*+ The ndType type tag. +*/
122 static xmltag ndType_tag=
128 /*+ The memberType type tag. +*/
129 static xmltag memberType_tag=
131 3, {"type","ref","role"},
135 /*+ The wayType type tag. +*/
136 static xmltag wayType_tag=
140 {&ndType_tag,&tagType_tag,NULL}};
142 /*+ The relationType type tag. +*/
143 static xmltag relationType_tag=
146 relationType_function,
147 {&memberType_tag,&tagType_tag,NULL}};
149 /*+ The osmType type tag. +*/
150 static xmltag osmType_tag=
154 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
156 /*+ The xmlDeclaration type tag. +*/
157 static xmltag xmlDeclaration_tag=
159 2, {"version","encoding"},
164 /*+ The complete set of tags at the top level. +*/
165 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
168 /* The XML tag processing functions */
171 /*++++++++++++++++++++++++++++++++++++++
172 The function that is called when the boundsType XSD type is seen
174 int boundsType_function Returns 0 if no error occured or something else otherwise.
176 const char *_tag_ Set to the name of the element tag that triggered this function call.
178 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
179 ++++++++++++++++++++++++++++++++++++++*/
181 //static int boundsType_function(const char *_tag_,int _type_)
187 /*++++++++++++++++++++++++++++++++++++++
188 The function that is called when the boundType XSD type is seen
190 int boundType_function Returns 0 if no error occured or something else otherwise.
192 const char *_tag_ Set to the name of the element tag that triggered this function call.
194 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
195 ++++++++++++++++++++++++++++++++++++++*/
197 //static int boundType_function(const char *_tag_,int _type_)
203 /*++++++++++++++++++++++++++++++++++++++
204 The function that is called when the tagType XSD type is seen
206 int tagType_function Returns 0 if no error occured or something else otherwise.
208 const char *_tag_ Set to the name of the element tag that triggered this function call.
210 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
212 const char *k The contents of the 'k' attribute (or NULL if not defined).
214 const char *v The contents of the 'v' attribute (or NULL if not defined).
215 ++++++++++++++++++++++++++++++++++++++*/
217 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
219 if(_type_&XMLPARSE_TAG_START && current_tags)
221 XMLPARSE_ASSERT_STRING(_tag_,k);
222 XMLPARSE_ASSERT_STRING(_tag_,v);
224 AppendTag(current_tags,k,v);
231 /*++++++++++++++++++++++++++++++++++++++
232 The function that is called when the nodeType XSD type is seen
234 int nodeType_function Returns 0 if no error occured or something else otherwise.
236 const char *_tag_ Set to the name of the element tag that triggered this function call.
238 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
240 const char *id The contents of the 'id' attribute (or NULL if not defined).
242 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
244 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
245 ++++++++++++++++++++++++++++++++++++++*/
247 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
249 static node_t node_id;
250 static double latitude,longitude;
252 if(_type_&XMLPARSE_TAG_START)
257 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
259 current_tags=NewTagList();
261 /* Handle the node information */
263 XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
264 XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
265 XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
268 if(_type_&XMLPARSE_TAG_END)
270 TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
272 process_node_tags(result,node_id,latitude,longitude);
274 DeleteTagList(current_tags);
275 DeleteTagList(result);
282 /*++++++++++++++++++++++++++++++++++++++
283 The function that is called when the ndType XSD type is seen
285 int ndType_function Returns 0 if no error occured or something else otherwise.
287 const char *_tag_ Set to the name of the element tag that triggered this function call.
289 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
291 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
292 ++++++++++++++++++++++++++++++++++++++*/
294 static int ndType_function(const char *_tag_,int _type_,const char *ref)
296 if(_type_&XMLPARSE_TAG_START)
300 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
302 if(way_nnodes && (way_nnodes%256)==0)
303 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
305 way_nodes[way_nnodes++]=node_id;
312 /*++++++++++++++++++++++++++++++++++++++
313 The function that is called when the memberType XSD type is seen
315 int memberType_function Returns 0 if no error occured or something else otherwise.
317 const char *_tag_ Set to the name of the element tag that triggered this function call.
319 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
321 const char *type The contents of the 'type' attribute (or NULL if not defined).
323 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
325 const char *role The contents of the 'role' attribute (or NULL if not defined).
326 ++++++++++++++++++++++++++++++++++++++*/
328 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
330 if(_type_&XMLPARSE_TAG_START)
332 XMLPARSE_ASSERT_STRING(_tag_,type);
333 XMLPARSE_ASSERT_STRING(_tag_,ref);
335 if(!strcmp(type,"node"))
337 node_t node_id=atoll(ref); /* need long long conversion */
339 if(relation_nnodes && (relation_nnodes%256)==0)
340 relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
342 relation_nodes[relation_nnodes++]=node_id;
344 else if(!strcmp(type,"way"))
346 way_t way_id=atoll(ref); /* need long long conversion */
348 if(relation_nways && (relation_nways%256)==0)
349 relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
351 relation_ways[relation_nways++]=way_id;
353 else if(!strcmp(type,"relation"))
355 relation_t relation_id=atoll(ref); /* need long long conversion */
357 if(relation_nrelations && (relation_nrelations%256)==0)
358 relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
360 relation_relations[relation_nrelations++]=relation_id;
368 /*++++++++++++++++++++++++++++++++++++++
369 The function that is called when the wayType XSD type is seen
371 int wayType_function Returns 0 if no error occured or something else otherwise.
373 const char *_tag_ Set to the name of the element tag that triggered this function call.
375 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
377 const char *id The contents of the 'id' attribute (or NULL if not defined).
378 ++++++++++++++++++++++++++++++++++++++*/
380 static int wayType_function(const char *_tag_,int _type_,const char *id)
384 if(_type_&XMLPARSE_TAG_START)
389 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
391 current_tags=NewTagList();
395 /* Handle the way information */
397 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
400 if(_type_&XMLPARSE_TAG_END)
402 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
404 process_way_tags(result,way_id);
406 DeleteTagList(current_tags);
407 DeleteTagList(result);
414 /*++++++++++++++++++++++++++++++++++++++
415 The function that is called when the relationType XSD type is seen
417 int relationType_function Returns 0 if no error occured or something else otherwise.
419 const char *_tag_ Set to the name of the element tag that triggered this function call.
421 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
423 const char *id The contents of the 'id' attribute (or NULL if not defined).
424 ++++++++++++++++++++++++++++++++++++++*/
426 static int relationType_function(const char *_tag_,int _type_,const char *id)
428 static relation_t relation_id;
430 if(_type_&XMLPARSE_TAG_START)
434 if(!(nrelations%1000))
435 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
437 current_tags=NewTagList();
439 relation_nnodes=relation_nways=relation_nrelations=0;
441 /* Handle the relation information */
443 XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */
446 if(_type_&XMLPARSE_TAG_END)
448 TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
450 process_relation_tags(result,relation_id);
452 DeleteTagList(current_tags);
453 DeleteTagList(result);
460 /*++++++++++++++++++++++++++++++++++++++
461 The function that is called when the osmType XSD type is seen
463 int osmType_function Returns 0 if no error occured or something else otherwise.
465 const char *_tag_ Set to the name of the element tag that triggered this function call.
467 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
468 ++++++++++++++++++++++++++++++++++++++*/
470 //static int osmType_function(const char *_tag_,int _type_)
476 /*++++++++++++++++++++++++++++++++++++++
477 The function that is called when the XML declaration is seen
479 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
481 const char *_tag_ Set to the name of the element tag that triggered this function call.
483 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
485 const char *version The contents of the 'version' attribute (or NULL if not defined).
487 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
488 ++++++++++++++++++++++++++++++++++++++*/
490 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
496 /*++++++++++++++++++++++++++++++++++++++
497 Parse an OSM XML file (from JOSM or planet download).
499 int ParseOSM Returns 0 if OK or something else in case of an error.
501 FILE *file The file to read from.
503 NodesX *OSMNodes The data structure of nodes to fill in.
505 SegmentsX *OSMSegments The data structure of segments to fill in.
507 WaysX *OSMWays The data structure of ways to fill in.
509 RelationsX *OSMRelations The data structure of relations to fill in.
510 ++++++++++++++++++++++++++++++++++++++*/
512 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
516 /* Copy the function parameters and initialise the variables. */
519 segments=OSMSegments;
521 relations=OSMRelations;
523 way_nodes=(node_t*)malloc(256*sizeof(node_t));
525 relation_nodes =(node_t *)malloc(256*sizeof(node_t));
526 relation_ways =(way_t *)malloc(256*sizeof(way_t));
527 relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
531 nnodes=0,nways=0,nrelations=0;
533 printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
535 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
537 printf_last("Read: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
543 /*++++++++++++++++++++++++++++++++++++++
544 Process the tags associated with a node.
546 TagList *tags The list of node tags.
548 node_t id The id of the node.
550 double latitude The latitude of the node.
552 double longitude The longitude of the node.
553 ++++++++++++++++++++++++++++++++++++++*/
555 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
557 allow_t allow=Allow_ALL;
563 for(i=0;i<tags->ntags;i++)
571 if(!strcmp(k,"bicycle"))
573 allow&=~Allow_Bicycle;
578 if(!strcmp(k,"foot"))
585 if(!strcmp(k,"goods"))
592 if(!strcmp(k,"horse"))
603 if(!strcmp(k,"moped"))
607 if(!strcmp(k,"motorbike"))
609 allow&=~Allow_Motorbike;
611 if(!strcmp(k,"motorcar"))
613 allow&=~Allow_Motorcar;
625 if(!strcmp(k,"wheelchair"))
627 allow&=~Allow_Wheelchair;
636 /* Create the node */
638 AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow);
642 /*++++++++++++++++++++++++++++++++++++++
643 Process the tags associated with a way.
645 TagList *tags The list of way tags.
647 way_t id The id of the way.
648 ++++++++++++++++++++++++++++++++++++++*/
650 static void process_way_tags(TagList *tags,way_t id)
653 int oneway=0,roundabout=0;
654 char *name=NULL,*ref=NULL;
660 for(i=0;i<tags->ntags;i++)
668 if(!strcmp(k,"bicycle"))
670 way.allow|= Allow_Bicycle;
672 if(!strcmp(k,"bicycleroute"))
674 way.props|=Properties_BicycleRoute;
676 if(!strcmp(k,"bridge"))
678 way.props|=Properties_Bridge;
683 if(!strcmp(k,"foot"))
685 way.allow|= Allow_Foot;
687 if(!strcmp(k,"footroute"))
689 way.props|=Properties_FootRoute;
694 if(!strcmp(k,"goods"))
696 way.allow|=Allow_Goods;
701 if(!strcmp(k,"highway"))
702 way.type=HighwayType(v);
704 if(!strcmp(k,"horse"))
706 way.allow|=Allow_Horse;
710 way.allow|=Allow_HGV;
715 if(!strcmp(k,"junction") && !strcmp(v,"roundabout"))
721 if(!strcmp(k,"maxspeed"))
724 way.speed=kph_to_speed(1.609*atof(v));
726 way.speed=kph_to_speed(atof(v));
729 if(!strcmp(k,"maxweight"))
732 way.weight=tonnes_to_weight(atof(v)/1000);
734 way.weight=tonnes_to_weight(atof(v));
737 if(!strcmp(k,"maxheight"))
743 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
744 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
745 else if(sscanf(v,"%d'",&feet)==1)
746 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
748 else if(strstr(v,"ft") || strstr(v,"feet"))
749 way.height=metres_to_height(atof(v)*0.254);
751 way.height=metres_to_height(atof(v));
754 if(!strcmp(k,"maxwidth"))
760 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
761 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
762 else if(sscanf(v,"%d'",&feet)==1)
763 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
765 else if(strstr(v,"ft") || strstr(v,"feet"))
766 way.width=metres_to_width(atof(v)*0.254);
768 way.width=metres_to_width(atof(v));
771 if(!strcmp(k,"maxlength"))
777 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
778 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
779 else if(sscanf(v,"%d'",&feet)==1)
780 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
782 else if(strstr(v,"ft") || strstr(v,"feet"))
783 way.length=metres_to_length(atof(v)*0.254);
785 way.length=metres_to_length(atof(v));
788 if(!strcmp(k,"moped"))
790 way.allow|=Allow_Moped;
792 if(!strcmp(k,"motorbike"))
794 way.allow|=Allow_Motorbike;
796 if(!strcmp(k,"motorcar"))
798 way.allow|=Allow_Motorcar;
800 if(!strcmp(k,"multilane"))
802 way.props|=Properties_Multilane;
807 if(!strcmp(k,"name"))
813 if(!strcmp(k,"oneway"))
817 else if(!strcmp(v,"-1"))
824 if(!strcmp(k,"paved"))
826 way.props|=Properties_Paved;
830 way.allow|=Allow_PSV;
841 if(!strcmp(k,"tunnel"))
843 way.props|=Properties_Tunnel;
848 if(!strcmp(k,"wheelchair"))
850 way.allow|=Allow_Wheelchair;
861 if(way.type>0 && way.type<Way_Count)
868 way.type|=Way_OneWay;
871 way.type|=Way_Roundabout;
875 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
876 sprintf(refname,"%s (%s)",name,ref);
878 else if(ref && !name)
880 else if(!ref && name)
882 else /* if(!ref && !name) */
885 AppendWay(ways,id,&way,refname);
890 for(i=1;i<way_nnodes;i++)
892 node_t from=way_nodes[i-1];
893 node_t to =way_nodes[i];
897 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
898 AppendSegment(segments,id,to,from,ONEWAY_2TO1);
902 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
903 AppendSegment(segments,id,to,from,ONEWAY_1TO2);
907 AppendSegment(segments,id,from,to,0);
908 AppendSegment(segments,id,to,from,0);
916 /*++++++++++++++++++++++++++++++++++++++
917 Process the tags associated with a relation.
919 TagList *tags The list of relation tags.
921 relation_t id The id of the relation.
922 ++++++++++++++++++++++++++++++++++++++*/
924 static void process_relation_tags(TagList *tags,relation_t id)
926 allow_t routes=Allow_None;
931 for(i=0;i<tags->ntags;i++)
939 if(!strcmp(k,"bicycleroute"))
941 routes|=Allow_Bicycle;
946 if(!strcmp(k,"footroute"))
957 /* Create the route relation (must store all relations that have ways or
958 relations even if they are not routes because they might be referenced by
959 other relations that are routes) */
961 if(relation_nways || relation_nrelations)
962 AppendRouteRelation(relations,id,routes,
963 relation_ways,relation_nways,
964 relation_relations,relation_nrelations);