Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/osmparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 399 - (show annotations) (download) (as text)
Sun May 23 08:24:26 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20611 byte(s)
Add the 'bound' element to the XML parser.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.67 2010-05-23 08:24:10 amb Exp $
3
4 OSM XML file parser (either JOSM or planet)
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
9
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.
14
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.
19
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 ***************************************/
23
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29
30 #include "typesx.h"
31 #include "functionsx.h"
32 #include "nodesx.h"
33 #include "segmentsx.h"
34 #include "waysx.h"
35 #include "xmlparse.h"
36 #include "tagging.h"
37
38
39 /* Macros */
40
41 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
42
43
44 /* Local variables */
45
46 static long nnodes=0,nways=0,nrelations=0;
47 static TagList current_tags={0,NULL,NULL};
48
49 static node_t *way_nodes=NULL;
50 static int way_nnodes=0;
51
52 static NodesX *nodes;
53 static SegmentsX *segments;
54 static WaysX *ways;
55
56
57 /* Local functions */
58
59 static void process_way_tags(TagList *tags,way_t id);
60
61
62 /* The XML tag processing function prototypes */
63
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_);
74
75
76 /* The XML tag definitions */
77
78 /*+ The boundsType type tag. +*/
79 static xmltag boundsType_tag=
80 {"bounds",
81 0, {NULL},
82 NULL,
83 {NULL}};
84
85 /*+ The boundType type tag. +*/
86 static xmltag boundType_tag=
87 {"bound",
88 0, {NULL},
89 NULL,
90 {NULL}};
91
92 /*+ The tagType type tag. +*/
93 static xmltag tagType_tag=
94 {"tag",
95 2, {"k","v"},
96 tagType_function,
97 {NULL}};
98
99 /*+ The nodeType type tag. +*/
100 static xmltag nodeType_tag=
101 {"node",
102 3, {"id","lat","lon"},
103 nodeType_function,
104 {&tagType_tag,NULL}};
105
106 /*+ The ndType type tag. +*/
107 static xmltag ndType_tag=
108 {"nd",
109 1, {"ref"},
110 ndType_function,
111 {NULL}};
112
113 /*+ The memberType type tag. +*/
114 static xmltag memberType_tag=
115 {"member",
116 3, {"type","ref","role"},
117 NULL,
118 {NULL}};
119
120 /*+ The wayType type tag. +*/
121 static xmltag wayType_tag=
122 {"way",
123 1, {"id"},
124 wayType_function,
125 {&ndType_tag,&tagType_tag,NULL}};
126
127 /*+ The relationType type tag. +*/
128 static xmltag relationType_tag=
129 {"relation",
130 1, {"id"},
131 relationType_function,
132 {&memberType_tag,&tagType_tag,NULL}};
133
134 /*+ The osmType type tag. +*/
135 static xmltag osmType_tag=
136 {"osm",
137 0, {NULL},
138 NULL,
139 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
140
141 /*+ The xmlDeclaration type tag. +*/
142 static xmltag xmlDeclaration_tag=
143 {"xml",
144 2, {"version","encoding"},
145 NULL,
146 {NULL}};
147
148
149 /*+ The complete set of tags at the top level. +*/
150 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
151
152
153 /* The XML tag processing functions */
154
155
156 /*++++++++++++++++++++++++++++++++++++++
157 The function that is called when the boundsType XSD type is seen
158
159 int boundsType_function Returns 0 if no error occured or something else otherwise.
160
161 const char *_tag_ Set to the name of the element tag that triggered this function call.
162
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 ++++++++++++++++++++++++++++++++++++++*/
165
166 //static int boundsType_function(const char *_tag_,int _type_)
167 //{
168 // return(0);
169 //}
170
171
172 /*++++++++++++++++++++++++++++++++++++++
173 The function that is called when the boundType XSD type is seen
174
175 int boundType_function Returns 0 if no error occured or something else otherwise.
176
177 const char *_tag_ Set to the name of the element tag that triggered this function call.
178
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 ++++++++++++++++++++++++++++++++++++++*/
181
182 //static int boundType_function(const char *_tag_,int _type_)
183 //{
184 // return(0);
185 //}
186
187
188 /*++++++++++++++++++++++++++++++++++++++
189 The function that is called when the tagType XSD type is seen
190
191 int tagType_function Returns 0 if no error occured or something else otherwise.
192
193 const char *_tag_ Set to the name of the element tag that triggered this function call.
194
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.
196
197 const char *k The contents of the 'k' attribute (or NULL if not defined).
198
199 const char *v The contents of the 'v' attribute (or NULL if not defined).
200 ++++++++++++++++++++++++++++++++++++++*/
201
202 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
203 {
204 if(_type_&XMLPARSE_TAG_START)
205 {
206 XMLPARSE_ASSERT_STRING(_tag_,k);
207 XMLPARSE_ASSERT_STRING(_tag_,v);
208
209 AppendTag(&current_tags,k,v);
210 }
211
212 return(0);
213 }
214
215
216 /*++++++++++++++++++++++++++++++++++++++
217 The function that is called when the nodeType XSD type is seen
218
219 int nodeType_function Returns 0 if no error occured or something else otherwise.
220
221 const char *_tag_ Set to the name of the element tag that triggered this function call.
222
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.
224
225 const char *id The contents of the 'id' attribute (or NULL if not defined).
226
227 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
228
229 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
230 ++++++++++++++++++++++++++++++++++++++*/
231
232 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
233 {
234 if(_type_&XMLPARSE_TAG_START)
235 {
236 node_t node_id;
237 double latitude,longitude;
238
239 nnodes++;
240
241 if(!(nnodes%1000))
242 {
243 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
244 fflush(stdout);
245 }
246
247 /* Handle the node information */
248
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);
252
253 AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude));
254
255 current_tags.ntags=0;
256 }
257
258 // if(_type_&XMLPARSE_TAG_END)
259 // {
260 // TagList *result=ApplyTaggingRules(&NodeRules,&current_tags);
261 //
262 // DeleteTagList(result);
263 // }
264
265 return(0);
266 }
267
268
269 /*++++++++++++++++++++++++++++++++++++++
270 The function that is called when the ndType XSD type is seen
271
272 int ndType_function Returns 0 if no error occured or something else otherwise.
273
274 const char *_tag_ Set to the name of the element tag that triggered this function call.
275
276 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
277
278 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
279 ++++++++++++++++++++++++++++++++++++++*/
280
281 static int ndType_function(const char *_tag_,int _type_,const char *ref)
282 {
283 if(_type_&XMLPARSE_TAG_START)
284 {
285 node_t node_id;
286
287 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
288
289 if((way_nnodes%256)==0)
290 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
291
292 way_nodes[way_nnodes++]=node_id;
293 }
294
295 return(0);
296 }
297
298
299 /*++++++++++++++++++++++++++++++++++++++
300 The function that is called when the memberType XSD type is seen
301
302 int memberType_function Returns 0 if no error occured or something else otherwise.
303
304 const char *_tag_ Set to the name of the element tag that triggered this function call.
305
306 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
307
308 const char *type The contents of the 'type' attribute (or NULL if not defined).
309
310 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
311
312 const char *role The contents of the 'role' attribute (or NULL if not defined).
313 ++++++++++++++++++++++++++++++++++++++*/
314
315 //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
316 //{
317 // return(0);
318 //}
319
320
321 /*++++++++++++++++++++++++++++++++++++++
322 The function that is called when the wayType XSD type is seen
323
324 int wayType_function Returns 0 if no error occured or something else otherwise.
325
326 const char *_tag_ Set to the name of the element tag that triggered this function call.
327
328 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
329
330 const char *id The contents of the 'id' attribute (or NULL if not defined).
331 ++++++++++++++++++++++++++++++++++++++*/
332
333 static int wayType_function(const char *_tag_,int _type_,const char *id)
334 {
335 static way_t way_id;
336
337 if(_type_&XMLPARSE_TAG_START)
338 {
339 nways++;
340
341 if(!(nways%1000))
342 {
343 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
344 fflush(stdout);
345 }
346
347 current_tags.ntags=0;
348 way_nnodes=0;
349
350 /* Handle the way information */
351
352 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
353 }
354
355 if(_type_&XMLPARSE_TAG_END)
356 {
357 TagList *result=ApplyTaggingRules(&WayRules,&current_tags);
358
359 process_way_tags(result,way_id);
360
361 DeleteTagList(result);
362 }
363
364 return(0);
365 }
366
367
368 /*++++++++++++++++++++++++++++++++++++++
369 The function that is called when the relationType XSD type is seen
370
371 int relationType_function Returns 0 if no error occured or something else otherwise.
372
373 const char *_tag_ Set to the name of the element tag that triggered this function call.
374
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.
376
377 const char *id The contents of the 'id' attribute (or NULL if not defined).
378 ++++++++++++++++++++++++++++++++++++++*/
379
380 static int relationType_function(const char *_tag_,int _type_,const char *id)
381 {
382 if(_type_&XMLPARSE_TAG_START)
383 {
384 nrelations++;
385
386 if(!(nrelations%1000))
387 {
388 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
389 fflush(stdout);
390 }
391
392 current_tags.ntags=0;
393 }
394
395 if(_type_&XMLPARSE_TAG_END)
396 {
397 TagList *result=ApplyTaggingRules(&RelationRules,&current_tags);
398
399 DeleteTagList(result);
400 }
401
402 return(0);
403 }
404
405
406 /*++++++++++++++++++++++++++++++++++++++
407 The function that is called when the osmType XSD type is seen
408
409 int osmType_function Returns 0 if no error occured or something else otherwise.
410
411 const char *_tag_ Set to the name of the element tag that triggered this function call.
412
413 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
414 ++++++++++++++++++++++++++++++++++++++*/
415
416 //static int osmType_function(const char *_tag_,int _type_)
417 //{
418 // return(0);
419 //}
420
421
422 /*++++++++++++++++++++++++++++++++++++++
423 The function that is called when the XML declaration is seen
424
425 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
426
427 const char *_tag_ Set to the name of the element tag that triggered this function call.
428
429 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
430
431 const char *version The contents of the 'version' attribute (or NULL if not defined).
432
433 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
434 ++++++++++++++++++++++++++++++++++++++*/
435
436 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
437 //{
438 // return(0);
439 //}
440
441
442 /*++++++++++++++++++++++++++++++++++++++
443 Parse an OSM XML file (from JOSM or planet download).
444
445 int ParseOSM Returns 0 if OK or something else in case of an error.
446
447 FILE *file The file to read from.
448
449 NodesX *OSMNodes The array of nodes to fill in.
450
451 SegmentsX *OSMSegments The array of segments to fill in.
452
453 WaysX *OSMWays The arrray of ways to fill in.
454 ++++++++++++++++++++++++++++++++++++++*/
455
456 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays)
457 {
458 int retval;
459
460 /* Parse the file */
461
462 nodes=OSMNodes;
463 segments=OSMSegments;
464 ways=OSMWays;
465
466 nnodes=0,nways=0,nrelations=0;
467
468 printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
469 fflush(stdout);
470
471 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
472
473 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
474 fflush(stdout);
475
476 return(retval);
477 }
478
479
480 /*++++++++++++++++++++++++++++++++++++++
481 Process the tags associated with a way.
482
483 TagList *tags The list of way tags.
484
485 way_t id The id of the way.
486 ++++++++++++++++++++++++++++++++++++++*/
487
488 static void process_way_tags(TagList *tags,way_t id)
489 {
490 Way way={0};
491 int oneway=0,roundabout=0;
492 char *highway=NULL,*name=NULL,*ref=NULL;
493
494 int i;
495
496 /* Parse the tags */
497
498 for(i=0;i<tags->ntags;i++)
499 {
500 char *k=tags->k[i];
501 char *v=tags->v[i];
502
503 switch(*k)
504 {
505 case 'b':
506 if(!strcmp(k,"bicycle"))
507 if(ISTRUE(v))
508 way.allow|= Allow_Bicycle;
509
510 if(!strcmp(k,"bridge"))
511 if(ISTRUE(v))
512 way.props|=Properties_Bridge;
513
514 break;
515
516 case 'f':
517 if(!strcmp(k,"foot"))
518 if(ISTRUE(v))
519 way.allow|= Allow_Foot;
520
521 break;
522
523 case 'g':
524 if(!strcmp(k,"goods"))
525 if(ISTRUE(v))
526 way.allow|=Allow_Goods;
527
528 break;
529
530 case 'h':
531 if(!strcmp(k,"highway"))
532 {
533 highway=v;
534 way.type=HighwayType(v);
535 }
536
537 if(!strcmp(k,"horse"))
538 if(ISTRUE(v))
539 way.allow|=Allow_Horse;
540
541 if(!strcmp(k,"hgv"))
542 if(ISTRUE(v))
543 way.allow|=Allow_HGV;
544
545 break;
546
547 case 'j':
548 if(!strcmp(k,"junction") && !strcmp(v,"roundabout"))
549 roundabout=1;
550
551 break;
552
553 case 'm':
554 if(!strcmp(k,"maxspeed"))
555 {
556 if(strstr(v,"mph"))
557 way.speed=kph_to_speed(1.609*atof(v));
558 else
559 way.speed=kph_to_speed(atof(v));
560 }
561
562 if(!strcmp(k,"maxweight"))
563 {
564 if(strstr(v,"kg"))
565 way.weight=tonnes_to_weight(atof(v)/1000);
566 else
567 way.weight=tonnes_to_weight(atof(v));
568 }
569
570 if(!strcmp(k,"maxheight"))
571 {
572 if(strchr(v,'\''))
573 {
574 int feet,inches;
575
576 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
577 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
578 else if(sscanf(v,"%d'",&feet)==1)
579 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
580 }
581 else if(strstr(v,"ft") || strstr(v,"feet"))
582 way.height=metres_to_height(atof(v)*0.254);
583 else
584 way.height=metres_to_height(atof(v));
585 }
586
587 if(!strcmp(k,"maxwidth"))
588 {
589 if(strchr(v,'\''))
590 {
591 int feet,inches;
592
593 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
594 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
595 else if(sscanf(v,"%d'",&feet)==1)
596 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
597 }
598 else if(strstr(v,"ft") || strstr(v,"feet"))
599 way.width=metres_to_width(atof(v)*0.254);
600 else
601 way.width=metres_to_width(atof(v));
602 }
603
604 if(!strcmp(k,"maxlength"))
605 {
606 if(strchr(v,'\''))
607 {
608 int feet,inches;
609
610 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
611 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
612 else if(sscanf(v,"%d'",&feet)==1)
613 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
614 }
615 else if(strstr(v,"ft") || strstr(v,"feet"))
616 way.length=metres_to_length(atof(v)*0.254);
617 else
618 way.length=metres_to_length(atof(v));
619 }
620
621 if(!strcmp(k,"moped"))
622 if(ISTRUE(v))
623 way.allow|=Allow_Moped;
624
625 if(!strcmp(k,"motorbike"))
626 if(ISTRUE(v))
627 way.allow|=Allow_Motorbike;
628
629 if(!strcmp(k,"motorcar"))
630 if(ISTRUE(v))
631 way.allow|=Allow_Motorcar;
632
633 if(!strcmp(k,"multilane"))
634 if(ISTRUE(v))
635 way.props|=Properties_Multilane;
636
637 break;
638
639 case 'n':
640 if(!strcmp(k,"name"))
641 name=v;
642
643 break;
644
645 case 'o':
646 if(!strcmp(k,"oneway"))
647 {
648 if(ISTRUE(v))
649 oneway=1;
650 else if(!strcmp(v,"-1"))
651 oneway=-1;
652 }
653
654 break;
655
656 case 'p':
657 if(!strcmp(k,"paved"))
658 if(ISTRUE(v))
659 way.props|=Properties_Paved;
660
661 if(!strcmp(k,"psv"))
662 if(ISTRUE(v))
663 way.allow|=Allow_PSV;
664
665 break;
666
667 case 'r':
668 if(!strcmp(k,"ref"))
669 ref=v;
670
671 break;
672
673 case 't':
674 if(!strcmp(k,"tunnel"))
675 if(ISTRUE(v))
676 way.props|=Properties_Tunnel;
677
678 break;
679
680 case 'w':
681 if(!strcmp(k,"wheelchair"))
682 if(ISTRUE(v))
683 way.allow|=Allow_Wheelchair;
684
685 break;
686
687 default:
688 ;
689 }
690 }
691
692 /* Create the way */
693
694 if(way.type>0 && way.type<Way_Count)
695 {
696 if(way.allow)
697 {
698 char *refname;
699
700 if(oneway)
701 way.type|=Way_OneWay;
702
703 if(roundabout)
704 way.type|=Way_Roundabout;
705
706 if(ref && name)
707 {
708 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
709 sprintf(refname,"%s (%s)",name,ref);
710 }
711 else if(ref && !name && roundabout)
712 {
713 refname=(char*)malloc(strlen(ref)+14);
714 sprintf(refname,"%s (roundabout)",ref);
715 }
716 else if(ref && !name)
717 refname=ref;
718 else if(!ref && name)
719 refname=name;
720 else if(roundabout)
721 {
722 refname=(char*)malloc(strlen(highway)+14);
723 sprintf(refname,"%s (roundabout)",highway);
724 }
725 else /* if(!ref && !name && !roundabout) */
726 refname=highway;
727
728 AppendWay(ways,id,&way,refname);
729
730 if(refname!=ref && refname!=name && refname!=highway)
731 free(refname);
732
733 for(i=1;i<way_nnodes;i++)
734 {
735 node_t from=way_nodes[i-1];
736 node_t to =way_nodes[i];
737
738 if(oneway>0)
739 {
740 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
741 AppendSegment(segments,id,to,from,ONEWAY_2TO1);
742 }
743 else if(oneway<0)
744 {
745 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
746 AppendSegment(segments,id,to,from,ONEWAY_1TO2);
747 }
748 else
749 {
750 AppendSegment(segments,id,from,to,0);
751 AppendSegment(segments,id,to,from,0);
752 }
753 }
754 }
755 }
756 }

Properties

Name Value
cvs:description OSM XML file parser.