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 411 - (show annotations) (download) (as text)
Sat May 29 13:54:43 2010 UTC (14 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20360 byte(s)
Translate the names given to unnamed roads (the highway type).

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.69 2010-05-29 13:54:23 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=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 && current_tags)
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=NewTagList();
256 current_tags=NULL;
257 }
258
259 // if(_type_&XMLPARSE_TAG_END)
260 // {
261 // TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
262 //
263 // DeleteTagList(current_tags);
264 // DeleteTagList(result);
265 // }
266
267 return(0);
268 }
269
270
271 /*++++++++++++++++++++++++++++++++++++++
272 The function that is called when the ndType XSD type is seen
273
274 int ndType_function Returns 0 if no error occured or something else otherwise.
275
276 const char *_tag_ Set to the name of the element tag that triggered this function call.
277
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.
279
280 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
281 ++++++++++++++++++++++++++++++++++++++*/
282
283 static int ndType_function(const char *_tag_,int _type_,const char *ref)
284 {
285 if(_type_&XMLPARSE_TAG_START)
286 {
287 node_t node_id;
288
289 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
290
291 if((way_nnodes%256)==0)
292 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
293
294 way_nodes[way_nnodes++]=node_id;
295 }
296
297 return(0);
298 }
299
300
301 /*++++++++++++++++++++++++++++++++++++++
302 The function that is called when the memberType XSD type is seen
303
304 int memberType_function Returns 0 if no error occured or something else otherwise.
305
306 const char *_tag_ Set to the name of the element tag that triggered this function call.
307
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.
309
310 const char *type The contents of the 'type' attribute (or NULL if not defined).
311
312 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
313
314 const char *role The contents of the 'role' attribute (or NULL if not defined).
315 ++++++++++++++++++++++++++++++++++++++*/
316
317 //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
318 //{
319 // return(0);
320 //}
321
322
323 /*++++++++++++++++++++++++++++++++++++++
324 The function that is called when the wayType XSD type is seen
325
326 int wayType_function Returns 0 if no error occured or something else otherwise.
327
328 const char *_tag_ Set to the name of the element tag that triggered this function call.
329
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.
331
332 const char *id The contents of the 'id' attribute (or NULL if not defined).
333 ++++++++++++++++++++++++++++++++++++++*/
334
335 static int wayType_function(const char *_tag_,int _type_,const char *id)
336 {
337 static way_t way_id;
338
339 if(_type_&XMLPARSE_TAG_START)
340 {
341 nways++;
342
343 if(!(nways%1000))
344 {
345 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
346 fflush(stdout);
347 }
348
349 current_tags=NewTagList();
350 way_nnodes=0;
351
352 /* Handle the way information */
353
354 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
355 }
356
357 if(_type_&XMLPARSE_TAG_END)
358 {
359 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
360
361 process_way_tags(result,way_id);
362
363 DeleteTagList(current_tags);
364 DeleteTagList(result);
365 }
366
367 return(0);
368 }
369
370
371 /*++++++++++++++++++++++++++++++++++++++
372 The function that is called when the relationType XSD type is seen
373
374 int relationType_function Returns 0 if no error occured or something else otherwise.
375
376 const char *_tag_ Set to the name of the element tag that triggered this function call.
377
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.
379
380 const char *id The contents of the 'id' attribute (or NULL if not defined).
381 ++++++++++++++++++++++++++++++++++++++*/
382
383 static int relationType_function(const char *_tag_,int _type_,const char *id)
384 {
385 if(_type_&XMLPARSE_TAG_START)
386 {
387 nrelations++;
388
389 if(!(nrelations%1000))
390 {
391 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
392 fflush(stdout);
393 }
394
395 // current_tags=NewTagList();
396 current_tags=NULL;
397 }
398
399 // if(_type_&XMLPARSE_TAG_END)
400 // {
401 // TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
402 //
403 // DeleteTagList(current_tags);
404 // DeleteTagList(result);
405 // }
406
407 return(0);
408 }
409
410
411 /*++++++++++++++++++++++++++++++++++++++
412 The function that is called when the osmType XSD type is seen
413
414 int osmType_function Returns 0 if no error occured or something else otherwise.
415
416 const char *_tag_ Set to the name of the element tag that triggered this function call.
417
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 ++++++++++++++++++++++++++++++++++++++*/
420
421 //static int osmType_function(const char *_tag_,int _type_)
422 //{
423 // return(0);
424 //}
425
426
427 /*++++++++++++++++++++++++++++++++++++++
428 The function that is called when the XML declaration is seen
429
430 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
431
432 const char *_tag_ Set to the name of the element tag that triggered this function call.
433
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.
435
436 const char *version The contents of the 'version' attribute (or NULL if not defined).
437
438 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
439 ++++++++++++++++++++++++++++++++++++++*/
440
441 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
442 //{
443 // return(0);
444 //}
445
446
447 /*++++++++++++++++++++++++++++++++++++++
448 Parse an OSM XML file (from JOSM or planet download).
449
450 int ParseOSM Returns 0 if OK or something else in case of an error.
451
452 FILE *file The file to read from.
453
454 NodesX *OSMNodes The array of nodes to fill in.
455
456 SegmentsX *OSMSegments The array of segments to fill in.
457
458 WaysX *OSMWays The arrray of ways to fill in.
459 ++++++++++++++++++++++++++++++++++++++*/
460
461 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays)
462 {
463 int retval;
464
465 /* Parse the file */
466
467 nodes=OSMNodes;
468 segments=OSMSegments;
469 ways=OSMWays;
470
471 nnodes=0,nways=0,nrelations=0;
472
473 printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
474 fflush(stdout);
475
476 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
477
478 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
479 fflush(stdout);
480
481 return(retval);
482 }
483
484
485 /*++++++++++++++++++++++++++++++++++++++
486 Process the tags associated with a way.
487
488 TagList *tags The list of way tags.
489
490 way_t id The id of the way.
491 ++++++++++++++++++++++++++++++++++++++*/
492
493 static void process_way_tags(TagList *tags,way_t id)
494 {
495 Way way={0};
496 int oneway=0,roundabout=0;
497 char *name=NULL,*ref=NULL;
498
499 int i;
500
501 /* Parse the tags */
502
503 for(i=0;i<tags->ntags;i++)
504 {
505 char *k=tags->k[i];
506 char *v=tags->v[i];
507
508 switch(*k)
509 {
510 case 'b':
511 if(!strcmp(k,"bicycle"))
512 if(ISTRUE(v))
513 way.allow|= Allow_Bicycle;
514
515 if(!strcmp(k,"bridge"))
516 if(ISTRUE(v))
517 way.props|=Properties_Bridge;
518
519 break;
520
521 case 'f':
522 if(!strcmp(k,"foot"))
523 if(ISTRUE(v))
524 way.allow|= Allow_Foot;
525
526 break;
527
528 case 'g':
529 if(!strcmp(k,"goods"))
530 if(ISTRUE(v))
531 way.allow|=Allow_Goods;
532
533 break;
534
535 case 'h':
536 if(!strcmp(k,"highway"))
537 way.type=HighwayType(v);
538
539 if(!strcmp(k,"horse"))
540 if(ISTRUE(v))
541 way.allow|=Allow_Horse;
542
543 if(!strcmp(k,"hgv"))
544 if(ISTRUE(v))
545 way.allow|=Allow_HGV;
546
547 break;
548
549 case 'j':
550 if(!strcmp(k,"junction") && !strcmp(v,"roundabout"))
551 roundabout=1;
552
553 break;
554
555 case 'm':
556 if(!strcmp(k,"maxspeed"))
557 {
558 if(strstr(v,"mph"))
559 way.speed=kph_to_speed(1.609*atof(v));
560 else
561 way.speed=kph_to_speed(atof(v));
562 }
563
564 if(!strcmp(k,"maxweight"))
565 {
566 if(strstr(v,"kg"))
567 way.weight=tonnes_to_weight(atof(v)/1000);
568 else
569 way.weight=tonnes_to_weight(atof(v));
570 }
571
572 if(!strcmp(k,"maxheight"))
573 {
574 if(strchr(v,'\''))
575 {
576 int feet,inches;
577
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);
582 }
583 else if(strstr(v,"ft") || strstr(v,"feet"))
584 way.height=metres_to_height(atof(v)*0.254);
585 else
586 way.height=metres_to_height(atof(v));
587 }
588
589 if(!strcmp(k,"maxwidth"))
590 {
591 if(strchr(v,'\''))
592 {
593 int feet,inches;
594
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);
599 }
600 else if(strstr(v,"ft") || strstr(v,"feet"))
601 way.width=metres_to_width(atof(v)*0.254);
602 else
603 way.width=metres_to_width(atof(v));
604 }
605
606 if(!strcmp(k,"maxlength"))
607 {
608 if(strchr(v,'\''))
609 {
610 int feet,inches;
611
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);
616 }
617 else if(strstr(v,"ft") || strstr(v,"feet"))
618 way.length=metres_to_length(atof(v)*0.254);
619 else
620 way.length=metres_to_length(atof(v));
621 }
622
623 if(!strcmp(k,"moped"))
624 if(ISTRUE(v))
625 way.allow|=Allow_Moped;
626
627 if(!strcmp(k,"motorbike"))
628 if(ISTRUE(v))
629 way.allow|=Allow_Motorbike;
630
631 if(!strcmp(k,"motorcar"))
632 if(ISTRUE(v))
633 way.allow|=Allow_Motorcar;
634
635 if(!strcmp(k,"multilane"))
636 if(ISTRUE(v))
637 way.props|=Properties_Multilane;
638
639 break;
640
641 case 'n':
642 if(!strcmp(k,"name"))
643 name=v;
644
645 break;
646
647 case 'o':
648 if(!strcmp(k,"oneway"))
649 {
650 if(ISTRUE(v))
651 oneway=1;
652 else if(!strcmp(v,"-1"))
653 oneway=-1;
654 }
655
656 break;
657
658 case 'p':
659 if(!strcmp(k,"paved"))
660 if(ISTRUE(v))
661 way.props|=Properties_Paved;
662
663 if(!strcmp(k,"psv"))
664 if(ISTRUE(v))
665 way.allow|=Allow_PSV;
666
667 break;
668
669 case 'r':
670 if(!strcmp(k,"ref"))
671 ref=v;
672
673 break;
674
675 case 't':
676 if(!strcmp(k,"tunnel"))
677 if(ISTRUE(v))
678 way.props|=Properties_Tunnel;
679
680 break;
681
682 case 'w':
683 if(!strcmp(k,"wheelchair"))
684 if(ISTRUE(v))
685 way.allow|=Allow_Wheelchair;
686
687 break;
688
689 default:
690 ;
691 }
692 }
693
694 /* Create the way */
695
696 if(way.type>0 && way.type<Way_Count)
697 {
698 if(way.allow)
699 {
700 char *refname;
701
702 if(oneway)
703 way.type|=Way_OneWay;
704
705 if(roundabout)
706 way.type|=Way_Roundabout;
707
708 if(ref && name)
709 {
710 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
711 sprintf(refname,"%s (%s)",name,ref);
712 }
713 else if(ref && !name)
714 refname=ref;
715 else if(!ref && name)
716 refname=name;
717 else /* if(!ref && !name) */
718 refname="";
719
720 AppendWay(ways,id,&way,refname);
721
722 if(ref && name)
723 free(refname);
724
725 for(i=1;i<way_nnodes;i++)
726 {
727 node_t from=way_nodes[i-1];
728 node_t to =way_nodes[i];
729
730 if(oneway>0)
731 {
732 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
733 AppendSegment(segments,id,to,from,ONEWAY_2TO1);
734 }
735 else if(oneway<0)
736 {
737 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
738 AppendSegment(segments,id,to,from,ONEWAY_1TO2);
739 }
740 else
741 {
742 AppendSegment(segments,id,from,to,0);
743 AppendSegment(segments,id,to,from,0);
744 }
745 }
746 }
747 }
748 }

Properties

Name Value
cvs:description OSM XML file parser.