1 /***************************************
2 $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.69 2010/05/29 13:54:23 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"
33 #include "segmentsx.h"
41 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
46 static long nnodes=0,nways=0,nrelations=0;
47 static TagList *current_tags=NULL;
49 static node_t *way_nodes=NULL;
50 static int way_nnodes=0;
53 static SegmentsX *segments;
59 static void process_way_tags(TagList *tags,way_t id);
62 /* The XML tag processing function prototypes */
64 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
65 //static int osmType_function(const char *_tag_,int _type_);
66 static int relationType_function(const char *_tag_,int _type_,const char *id);
67 static int wayType_function(const char *_tag_,int _type_,const char *id);
68 //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
69 static int ndType_function(const char *_tag_,int _type_,const char *ref);
70 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
71 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
72 //static int boundType_function(const char *_tag_,int _type_);
73 //static int boundsType_function(const char *_tag_,int _type_);
76 /* The XML tag definitions */
78 /*+ The boundsType type tag. +*/
79 static xmltag boundsType_tag=
85 /*+ The boundType type tag. +*/
86 static xmltag boundType_tag=
92 /*+ The tagType type tag. +*/
93 static xmltag tagType_tag=
99 /*+ The nodeType type tag. +*/
100 static xmltag nodeType_tag=
102 3, {"id","lat","lon"},
104 {&tagType_tag,NULL}};
106 /*+ The ndType type tag. +*/
107 static xmltag ndType_tag=
113 /*+ The memberType type tag. +*/
114 static xmltag memberType_tag=
116 3, {"type","ref","role"},
120 /*+ The wayType type tag. +*/
121 static xmltag wayType_tag=
125 {&ndType_tag,&tagType_tag,NULL}};
127 /*+ The relationType type tag. +*/
128 static xmltag relationType_tag=
131 relationType_function,
132 {&memberType_tag,&tagType_tag,NULL}};
134 /*+ The osmType type tag. +*/
135 static xmltag osmType_tag=
139 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
141 /*+ The xmlDeclaration type tag. +*/
142 static xmltag xmlDeclaration_tag=
144 2, {"version","encoding"},
149 /*+ The complete set of tags at the top level. +*/
150 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
153 /* The XML tag processing functions */
156 /*++++++++++++++++++++++++++++++++++++++
157 The function that is called when the boundsType XSD type is seen
159 int boundsType_function Returns 0 if no error occured or something else otherwise.
161 const char *_tag_ Set to the name of the element tag that triggered this function call.
163 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
164 ++++++++++++++++++++++++++++++++++++++*/
166 //static int boundsType_function(const char *_tag_,int _type_)
172 /*++++++++++++++++++++++++++++++++++++++
173 The function that is called when the boundType XSD type is seen
175 int boundType_function Returns 0 if no error occured or something else otherwise.
177 const char *_tag_ Set to the name of the element tag that triggered this function call.
179 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
180 ++++++++++++++++++++++++++++++++++++++*/
182 //static int boundType_function(const char *_tag_,int _type_)
188 /*++++++++++++++++++++++++++++++++++++++
189 The function that is called when the tagType XSD type is seen
191 int tagType_function Returns 0 if no error occured or something else otherwise.
193 const char *_tag_ Set to the name of the element tag that triggered this function call.
195 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
197 const char *k The contents of the 'k' attribute (or NULL if not defined).
199 const char *v The contents of the 'v' attribute (or NULL if not defined).
200 ++++++++++++++++++++++++++++++++++++++*/
202 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
204 if(_type_&XMLPARSE_TAG_START && current_tags)
206 XMLPARSE_ASSERT_STRING(_tag_,k);
207 XMLPARSE_ASSERT_STRING(_tag_,v);
209 AppendTag(current_tags,k,v);
216 /*++++++++++++++++++++++++++++++++++++++
217 The function that is called when the nodeType XSD type is seen
219 int nodeType_function Returns 0 if no error occured or something else otherwise.
221 const char *_tag_ Set to the name of the element tag that triggered this function call.
223 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
225 const char *id The contents of the 'id' attribute (or NULL if not defined).
227 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
229 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
230 ++++++++++++++++++++++++++++++++++++++*/
232 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
234 if(_type_&XMLPARSE_TAG_START)
237 double latitude,longitude;
243 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
247 /* Handle the node information */
249 XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
250 XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
251 XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
253 AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude));
255 // current_tags=NewTagList();
259 // if(_type_&XMLPARSE_TAG_END)
261 // TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
263 // DeleteTagList(current_tags);
264 // DeleteTagList(result);
271 /*++++++++++++++++++++++++++++++++++++++
272 The function that is called when the ndType XSD type is seen
274 int ndType_function Returns 0 if no error occured or something else otherwise.
276 const char *_tag_ Set to the name of the element tag that triggered this function call.
278 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
280 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
281 ++++++++++++++++++++++++++++++++++++++*/
283 static int ndType_function(const char *_tag_,int _type_,const char *ref)
285 if(_type_&XMLPARSE_TAG_START)
289 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
291 if((way_nnodes%256)==0)
292 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
294 way_nodes[way_nnodes++]=node_id;
301 /*++++++++++++++++++++++++++++++++++++++
302 The function that is called when the memberType XSD type is seen
304 int memberType_function Returns 0 if no error occured or something else otherwise.
306 const char *_tag_ Set to the name of the element tag that triggered this function call.
308 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
310 const char *type The contents of the 'type' attribute (or NULL if not defined).
312 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
314 const char *role The contents of the 'role' attribute (or NULL if not defined).
315 ++++++++++++++++++++++++++++++++++++++*/
317 //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
323 /*++++++++++++++++++++++++++++++++++++++
324 The function that is called when the wayType XSD type is seen
326 int wayType_function Returns 0 if no error occured or something else otherwise.
328 const char *_tag_ Set to the name of the element tag that triggered this function call.
330 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
332 const char *id The contents of the 'id' attribute (or NULL if not defined).
333 ++++++++++++++++++++++++++++++++++++++*/
335 static int wayType_function(const char *_tag_,int _type_,const char *id)
339 if(_type_&XMLPARSE_TAG_START)
345 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
349 current_tags=NewTagList();
352 /* Handle the way information */
354 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
357 if(_type_&XMLPARSE_TAG_END)
359 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
361 process_way_tags(result,way_id);
363 DeleteTagList(current_tags);
364 DeleteTagList(result);
371 /*++++++++++++++++++++++++++++++++++++++
372 The function that is called when the relationType XSD type is seen
374 int relationType_function Returns 0 if no error occured or something else otherwise.
376 const char *_tag_ Set to the name of the element tag that triggered this function call.
378 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
380 const char *id The contents of the 'id' attribute (or NULL if not defined).
381 ++++++++++++++++++++++++++++++++++++++*/
383 static int relationType_function(const char *_tag_,int _type_,const char *id)
385 if(_type_&XMLPARSE_TAG_START)
389 if(!(nrelations%1000))
391 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
395 // current_tags=NewTagList();
399 // if(_type_&XMLPARSE_TAG_END)
401 // TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
403 // DeleteTagList(current_tags);
404 // DeleteTagList(result);
411 /*++++++++++++++++++++++++++++++++++++++
412 The function that is called when the osmType XSD type is seen
414 int osmType_function Returns 0 if no error occured or something else otherwise.
416 const char *_tag_ Set to the name of the element tag that triggered this function call.
418 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
419 ++++++++++++++++++++++++++++++++++++++*/
421 //static int osmType_function(const char *_tag_,int _type_)
427 /*++++++++++++++++++++++++++++++++++++++
428 The function that is called when the XML declaration is seen
430 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
432 const char *_tag_ Set to the name of the element tag that triggered this function call.
434 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
436 const char *version The contents of the 'version' attribute (or NULL if not defined).
438 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
439 ++++++++++++++++++++++++++++++++++++++*/
441 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
447 /*++++++++++++++++++++++++++++++++++++++
448 Parse an OSM XML file (from JOSM or planet download).
450 int ParseOSM Returns 0 if OK or something else in case of an error.
452 FILE *file The file to read from.
454 NodesX *OSMNodes The array of nodes to fill in.
456 SegmentsX *OSMSegments The array of segments to fill in.
458 WaysX *OSMWays The arrray of ways to fill in.
459 ++++++++++++++++++++++++++++++++++++++*/
461 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays)
468 segments=OSMSegments;
471 nnodes=0,nways=0,nrelations=0;
473 printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
476 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
478 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
485 /*++++++++++++++++++++++++++++++++++++++
486 Process the tags associated with a way.
488 TagList *tags The list of way tags.
490 way_t id The id of the way.
491 ++++++++++++++++++++++++++++++++++++++*/
493 static void process_way_tags(TagList *tags,way_t id)
496 int oneway=0,roundabout=0;
497 char *name=NULL,*ref=NULL;
503 for(i=0;i<tags->ntags;i++)
511 if(!strcmp(k,"bicycle"))
513 way.allow|= Allow_Bicycle;
515 if(!strcmp(k,"bridge"))
517 way.props|=Properties_Bridge;
522 if(!strcmp(k,"foot"))
524 way.allow|= Allow_Foot;
529 if(!strcmp(k,"goods"))
531 way.allow|=Allow_Goods;
536 if(!strcmp(k,"highway"))
537 way.type=HighwayType(v);
539 if(!strcmp(k,"horse"))
541 way.allow|=Allow_Horse;
545 way.allow|=Allow_HGV;
550 if(!strcmp(k,"junction") && !strcmp(v,"roundabout"))
556 if(!strcmp(k,"maxspeed"))
559 way.speed=kph_to_speed(1.609*atof(v));
561 way.speed=kph_to_speed(atof(v));
564 if(!strcmp(k,"maxweight"))
567 way.weight=tonnes_to_weight(atof(v)/1000);
569 way.weight=tonnes_to_weight(atof(v));
572 if(!strcmp(k,"maxheight"))
578 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
579 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
580 else if(sscanf(v,"%d'",&feet)==1)
581 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
583 else if(strstr(v,"ft") || strstr(v,"feet"))
584 way.height=metres_to_height(atof(v)*0.254);
586 way.height=metres_to_height(atof(v));
589 if(!strcmp(k,"maxwidth"))
595 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
596 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
597 else if(sscanf(v,"%d'",&feet)==1)
598 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
600 else if(strstr(v,"ft") || strstr(v,"feet"))
601 way.width=metres_to_width(atof(v)*0.254);
603 way.width=metres_to_width(atof(v));
606 if(!strcmp(k,"maxlength"))
612 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
613 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
614 else if(sscanf(v,"%d'",&feet)==1)
615 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
617 else if(strstr(v,"ft") || strstr(v,"feet"))
618 way.length=metres_to_length(atof(v)*0.254);
620 way.length=metres_to_length(atof(v));
623 if(!strcmp(k,"moped"))
625 way.allow|=Allow_Moped;
627 if(!strcmp(k,"motorbike"))
629 way.allow|=Allow_Motorbike;
631 if(!strcmp(k,"motorcar"))
633 way.allow|=Allow_Motorcar;
635 if(!strcmp(k,"multilane"))
637 way.props|=Properties_Multilane;
642 if(!strcmp(k,"name"))
648 if(!strcmp(k,"oneway"))
652 else if(!strcmp(v,"-1"))
659 if(!strcmp(k,"paved"))
661 way.props|=Properties_Paved;
665 way.allow|=Allow_PSV;
676 if(!strcmp(k,"tunnel"))
678 way.props|=Properties_Tunnel;
683 if(!strcmp(k,"wheelchair"))
685 way.allow|=Allow_Wheelchair;
696 if(way.type>0 && way.type<Way_Count)
703 way.type|=Way_OneWay;
706 way.type|=Way_Roundabout;
710 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
711 sprintf(refname,"%s (%s)",name,ref);
713 else if(ref && !name)
715 else if(!ref && name)
717 else /* if(!ref && !name) */
720 AppendWay(ways,id,&way,refname);
725 for(i=1;i<way_nnodes;i++)
727 node_t from=way_nodes[i-1];
728 node_t to =way_nodes[i];
732 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
733 AppendSegment(segments,id,to,from,ONEWAY_2TO1);
737 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
738 AppendSegment(segments,id,to,from,ONEWAY_1TO2);
742 AppendSegment(segments,id,from,to,0);
743 AppendSegment(segments,id,to,from,0);