1 /***************************************
2 $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.72 2010/09/25 18:47:32 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"
44 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
49 static long nnodes=0,nways=0,nrelations=0;
50 static TagList *current_tags=NULL;
52 static node_t *way_nodes=NULL;
53 static int way_nnodes=0;
55 static node_t *relation_nodes=NULL;
56 static int relation_nnodes=0;
57 static way_t *relation_ways=NULL;
58 static int relation_nways=0;
59 static relation_t *relation_relations=NULL;
60 static int relation_nrelations=0;
63 static SegmentsX *segments;
65 static RelationsX *relations;
70 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
71 static void process_way_tags(TagList *tags,way_t id);
72 static void process_relation_tags(TagList *tags,relation_t id);
75 /* The XML tag processing function prototypes */
77 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
78 //static int osmType_function(const char *_tag_,int _type_);
79 static int relationType_function(const char *_tag_,int _type_,const char *id);
80 static int wayType_function(const char *_tag_,int _type_,const char *id);
81 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
82 static int ndType_function(const char *_tag_,int _type_,const char *ref);
83 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
84 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
85 //static int boundType_function(const char *_tag_,int _type_);
86 //static int boundsType_function(const char *_tag_,int _type_);
89 /* The XML tag definitions */
91 /*+ The boundsType type tag. +*/
92 static xmltag boundsType_tag=
98 /*+ The boundType type tag. +*/
99 static xmltag boundType_tag=
105 /*+ The tagType type tag. +*/
106 static xmltag tagType_tag=
112 /*+ The nodeType type tag. +*/
113 static xmltag nodeType_tag=
115 3, {"id","lat","lon"},
117 {&tagType_tag,NULL}};
119 /*+ The ndType type tag. +*/
120 static xmltag ndType_tag=
126 /*+ The memberType type tag. +*/
127 static xmltag memberType_tag=
129 3, {"type","ref","role"},
133 /*+ The wayType type tag. +*/
134 static xmltag wayType_tag=
138 {&ndType_tag,&tagType_tag,NULL}};
140 /*+ The relationType type tag. +*/
141 static xmltag relationType_tag=
144 relationType_function,
145 {&memberType_tag,&tagType_tag,NULL}};
147 /*+ The osmType type tag. +*/
148 static xmltag osmType_tag=
152 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
154 /*+ The xmlDeclaration type tag. +*/
155 static xmltag xmlDeclaration_tag=
157 2, {"version","encoding"},
162 /*+ The complete set of tags at the top level. +*/
163 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
166 /* The XML tag processing functions */
169 /*++++++++++++++++++++++++++++++++++++++
170 The function that is called when the boundsType XSD type is seen
172 int boundsType_function Returns 0 if no error occured or something else otherwise.
174 const char *_tag_ Set to the name of the element tag that triggered this function call.
176 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
177 ++++++++++++++++++++++++++++++++++++++*/
179 //static int boundsType_function(const char *_tag_,int _type_)
185 /*++++++++++++++++++++++++++++++++++++++
186 The function that is called when the boundType XSD type is seen
188 int boundType_function Returns 0 if no error occured or something else otherwise.
190 const char *_tag_ Set to the name of the element tag that triggered this function call.
192 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
193 ++++++++++++++++++++++++++++++++++++++*/
195 //static int boundType_function(const char *_tag_,int _type_)
201 /*++++++++++++++++++++++++++++++++++++++
202 The function that is called when the tagType XSD type is seen
204 int tagType_function Returns 0 if no error occured or something else otherwise.
206 const char *_tag_ Set to the name of the element tag that triggered this function call.
208 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
210 const char *k The contents of the 'k' attribute (or NULL if not defined).
212 const char *v The contents of the 'v' attribute (or NULL if not defined).
213 ++++++++++++++++++++++++++++++++++++++*/
215 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
217 if(_type_&XMLPARSE_TAG_START && current_tags)
219 XMLPARSE_ASSERT_STRING(_tag_,k);
220 XMLPARSE_ASSERT_STRING(_tag_,v);
222 AppendTag(current_tags,k,v);
229 /*++++++++++++++++++++++++++++++++++++++
230 The function that is called when the nodeType XSD type is seen
232 int nodeType_function Returns 0 if no error occured or something else otherwise.
234 const char *_tag_ Set to the name of the element tag that triggered this function call.
236 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
238 const char *id The contents of the 'id' attribute (or NULL if not defined).
240 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
242 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
243 ++++++++++++++++++++++++++++++++++++++*/
245 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
247 static node_t node_id;
248 static double latitude,longitude;
250 if(_type_&XMLPARSE_TAG_START)
256 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
260 current_tags=NewTagList();
262 /* Handle the node information */
264 XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
265 XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
266 XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
269 if(_type_&XMLPARSE_TAG_END)
271 TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
273 process_node_tags(result,node_id,latitude,longitude);
275 DeleteTagList(current_tags);
276 DeleteTagList(result);
283 /*++++++++++++++++++++++++++++++++++++++
284 The function that is called when the ndType XSD type is seen
286 int ndType_function Returns 0 if no error occured or something else otherwise.
288 const char *_tag_ Set to the name of the element tag that triggered this function call.
290 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
292 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
293 ++++++++++++++++++++++++++++++++++++++*/
295 static int ndType_function(const char *_tag_,int _type_,const char *ref)
297 if(_type_&XMLPARSE_TAG_START)
301 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
303 if(way_nnodes && (way_nnodes%256)==0)
304 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
306 way_nodes[way_nnodes++]=node_id;
313 /*++++++++++++++++++++++++++++++++++++++
314 The function that is called when the memberType XSD type is seen
316 int memberType_function Returns 0 if no error occured or something else otherwise.
318 const char *_tag_ Set to the name of the element tag that triggered this function call.
320 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
322 const char *type The contents of the 'type' attribute (or NULL if not defined).
324 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
326 const char *role The contents of the 'role' attribute (or NULL if not defined).
327 ++++++++++++++++++++++++++++++++++++++*/
329 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
331 if(_type_&XMLPARSE_TAG_START)
333 XMLPARSE_ASSERT_STRING(_tag_,type);
334 XMLPARSE_ASSERT_STRING(_tag_,ref);
336 if(!strcmp(type,"node"))
338 node_t node_id=atoll(ref); /* need long long conversion */
340 if(relation_nnodes && (relation_nnodes%256)==0)
341 relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
343 relation_nodes[relation_nnodes++]=node_id;
345 else if(!strcmp(type,"way"))
347 way_t way_id=atoll(ref); /* need long long conversion */
349 if(relation_nways && (relation_nways%256)==0)
350 relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
352 relation_ways[relation_nways++]=way_id;
354 else if(!strcmp(type,"relation"))
356 relation_t relation_id=atoll(ref); /* need long long conversion */
358 if(relation_nrelations && (relation_nrelations%256)==0)
359 relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
361 relation_relations[relation_nrelations++]=relation_id;
369 /*++++++++++++++++++++++++++++++++++++++
370 The function that is called when the wayType XSD type is seen
372 int wayType_function Returns 0 if no error occured or something else otherwise.
374 const char *_tag_ Set to the name of the element tag that triggered this function call.
376 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
378 const char *id The contents of the 'id' attribute (or NULL if not defined).
379 ++++++++++++++++++++++++++++++++++++++*/
381 static int wayType_function(const char *_tag_,int _type_,const char *id)
385 if(_type_&XMLPARSE_TAG_START)
391 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
395 current_tags=NewTagList();
399 /* Handle the way information */
401 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
404 if(_type_&XMLPARSE_TAG_END)
406 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
408 process_way_tags(result,way_id);
410 DeleteTagList(current_tags);
411 DeleteTagList(result);
418 /*++++++++++++++++++++++++++++++++++++++
419 The function that is called when the relationType XSD type is seen
421 int relationType_function Returns 0 if no error occured or something else otherwise.
423 const char *_tag_ Set to the name of the element tag that triggered this function call.
425 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
427 const char *id The contents of the 'id' attribute (or NULL if not defined).
428 ++++++++++++++++++++++++++++++++++++++*/
430 static int relationType_function(const char *_tag_,int _type_,const char *id)
432 static relation_t relation_id;
434 if(_type_&XMLPARSE_TAG_START)
438 if(!(nrelations%1000))
440 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
444 current_tags=NewTagList();
446 relation_nnodes=relation_nways=relation_nrelations=0;
448 /* Handle the relation information */
450 XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */
453 if(_type_&XMLPARSE_TAG_END)
455 TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
457 process_relation_tags(result,relation_id);
459 DeleteTagList(current_tags);
460 DeleteTagList(result);
467 /*++++++++++++++++++++++++++++++++++++++
468 The function that is called when the osmType XSD type is seen
470 int osmType_function Returns 0 if no error occured or something else otherwise.
472 const char *_tag_ Set to the name of the element tag that triggered this function call.
474 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
475 ++++++++++++++++++++++++++++++++++++++*/
477 //static int osmType_function(const char *_tag_,int _type_)
483 /*++++++++++++++++++++++++++++++++++++++
484 The function that is called when the XML declaration is seen
486 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
488 const char *_tag_ Set to the name of the element tag that triggered this function call.
490 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
492 const char *version The contents of the 'version' attribute (or NULL if not defined).
494 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
495 ++++++++++++++++++++++++++++++++++++++*/
497 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
503 /*++++++++++++++++++++++++++++++++++++++
504 Parse an OSM XML file (from JOSM or planet download).
506 int ParseOSM Returns 0 if OK or something else in case of an error.
508 FILE *file The file to read from.
510 NodesX *OSMNodes The data structure of nodes to fill in.
512 SegmentsX *OSMSegments The data structure of segments to fill in.
514 WaysX *OSMWays The data structure of ways to fill in.
516 RelationsX *OSMRelations The data structure of relations to fill in.
517 ++++++++++++++++++++++++++++++++++++++*/
519 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
523 /* Copy the function parameters and initialise the variables. */
526 segments=OSMSegments;
528 relations=OSMRelations;
530 way_nodes=(node_t*)malloc(256*sizeof(node_t));
532 relation_nodes =(node_t *)malloc(256*sizeof(node_t));
533 relation_ways =(way_t *)malloc(256*sizeof(way_t));
534 relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
538 nnodes=0,nways=0,nrelations=0;
540 printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
543 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
545 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
552 /*++++++++++++++++++++++++++++++++++++++
553 Process the tags associated with a node.
555 TagList *tags The list of node tags.
557 node_t id The id of the node.
559 double latitude The latitude of the node.
561 double longitude The longitude of the node.
562 ++++++++++++++++++++++++++++++++++++++*/
564 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
566 allow_t allow=Allow_ALL;
572 for(i=0;i<tags->ntags;i++)
580 if(!strcmp(k,"bicycle"))
582 allow&=~Allow_Bicycle;
587 if(!strcmp(k,"foot"))
594 if(!strcmp(k,"goods"))
601 if(!strcmp(k,"horse"))
612 if(!strcmp(k,"moped"))
616 if(!strcmp(k,"motorbike"))
618 allow&=~Allow_Motorbike;
620 if(!strcmp(k,"motorcar"))
622 allow&=~Allow_Motorcar;
634 if(!strcmp(k,"wheelchair"))
636 allow&=~Allow_Wheelchair;
645 /* Create the node */
647 AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow);
651 /*++++++++++++++++++++++++++++++++++++++
652 Process the tags associated with a way.
654 TagList *tags The list of way tags.
656 way_t id The id of the way.
657 ++++++++++++++++++++++++++++++++++++++*/
659 static void process_way_tags(TagList *tags,way_t id)
662 int oneway=0,roundabout=0;
663 char *name=NULL,*ref=NULL;
669 for(i=0;i<tags->ntags;i++)
677 if(!strcmp(k,"bicycle"))
679 way.allow|= Allow_Bicycle;
681 if(!strcmp(k,"bicycleroute"))
683 way.props|=Properties_BicycleRoute;
685 if(!strcmp(k,"bridge"))
687 way.props|=Properties_Bridge;
692 if(!strcmp(k,"foot"))
694 way.allow|= Allow_Foot;
696 if(!strcmp(k,"footroute"))
698 way.props|=Properties_FootRoute;
703 if(!strcmp(k,"goods"))
705 way.allow|=Allow_Goods;
710 if(!strcmp(k,"highway"))
711 way.type=HighwayType(v);
713 if(!strcmp(k,"horse"))
715 way.allow|=Allow_Horse;
719 way.allow|=Allow_HGV;
724 if(!strcmp(k,"junction") && !strcmp(v,"roundabout"))
730 if(!strcmp(k,"maxspeed"))
733 way.speed=kph_to_speed(1.609*atof(v));
735 way.speed=kph_to_speed(atof(v));
738 if(!strcmp(k,"maxweight"))
741 way.weight=tonnes_to_weight(atof(v)/1000);
743 way.weight=tonnes_to_weight(atof(v));
746 if(!strcmp(k,"maxheight"))
752 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
753 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
754 else if(sscanf(v,"%d'",&feet)==1)
755 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
757 else if(strstr(v,"ft") || strstr(v,"feet"))
758 way.height=metres_to_height(atof(v)*0.254);
760 way.height=metres_to_height(atof(v));
763 if(!strcmp(k,"maxwidth"))
769 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
770 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
771 else if(sscanf(v,"%d'",&feet)==1)
772 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
774 else if(strstr(v,"ft") || strstr(v,"feet"))
775 way.width=metres_to_width(atof(v)*0.254);
777 way.width=metres_to_width(atof(v));
780 if(!strcmp(k,"maxlength"))
786 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
787 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
788 else if(sscanf(v,"%d'",&feet)==1)
789 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
791 else if(strstr(v,"ft") || strstr(v,"feet"))
792 way.length=metres_to_length(atof(v)*0.254);
794 way.length=metres_to_length(atof(v));
797 if(!strcmp(k,"moped"))
799 way.allow|=Allow_Moped;
801 if(!strcmp(k,"motorbike"))
803 way.allow|=Allow_Motorbike;
805 if(!strcmp(k,"motorcar"))
807 way.allow|=Allow_Motorcar;
809 if(!strcmp(k,"multilane"))
811 way.props|=Properties_Multilane;
816 if(!strcmp(k,"name"))
822 if(!strcmp(k,"oneway"))
826 else if(!strcmp(v,"-1"))
833 if(!strcmp(k,"paved"))
835 way.props|=Properties_Paved;
839 way.allow|=Allow_PSV;
850 if(!strcmp(k,"tunnel"))
852 way.props|=Properties_Tunnel;
857 if(!strcmp(k,"wheelchair"))
859 way.allow|=Allow_Wheelchair;
870 if(way.type>0 && way.type<Way_Count)
877 way.type|=Way_OneWay;
880 way.type|=Way_Roundabout;
884 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
885 sprintf(refname,"%s (%s)",name,ref);
887 else if(ref && !name)
889 else if(!ref && name)
891 else /* if(!ref && !name) */
894 AppendWay(ways,id,&way,refname);
899 for(i=1;i<way_nnodes;i++)
901 node_t from=way_nodes[i-1];
902 node_t to =way_nodes[i];
906 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
907 AppendSegment(segments,id,to,from,ONEWAY_2TO1);
911 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
912 AppendSegment(segments,id,to,from,ONEWAY_1TO2);
916 AppendSegment(segments,id,from,to,0);
917 AppendSegment(segments,id,to,from,0);
925 /*++++++++++++++++++++++++++++++++++++++
926 Process the tags associated with a relation.
928 TagList *tags The list of relation tags.
930 relation_t id The id of the relation.
931 ++++++++++++++++++++++++++++++++++++++*/
933 static void process_relation_tags(TagList *tags,relation_t id)
935 allow_t routes=Allow_None;
940 for(i=0;i<tags->ntags;i++)
948 if(!strcmp(k,"bicycleroute"))
950 routes|=Allow_Bicycle;
955 if(!strcmp(k,"footroute"))
966 /* Create the route relation (must store all relations that have ways or
967 relations even if they are not routes because they might be referenced by
968 other relations that are routes) */
970 if(relation_nways || relation_nrelations)
971 AppendRouteRelation(relations,id,routes,
972 relation_ways,relation_nways,
973 relation_relations,relation_nrelations);