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 757 - (show annotations) (download) (as text)
Fri Jun 3 18:06:21 2011 UTC (13 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 27511 byte(s)
Rationalise the increment of the numbers used for the output when not
--loggable.

1 /***************************************
2 OSM XML file parser (either JOSM or planet)
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2011 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include "typesx.h"
29 #include "functionsx.h"
30
31 #include "nodesx.h"
32 #include "segmentsx.h"
33 #include "waysx.h"
34 #include "relationsx.h"
35
36 #include "xmlparse.h"
37 #include "tagging.h"
38
39 #include "logging.h"
40
41
42 /* Macros */
43
44 /*+ Checks if a value in the XML is one of the allowed values for true. +*/
45 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
46
47
48 /* Local variables */
49
50 static long nnodes=0,nways=0,nrelations=0;
51 static TagList *current_tags=NULL;
52
53 static node_t *way_nodes=NULL;
54 static int way_nnodes=0;
55
56 static node_t *relation_nodes=NULL;
57 static int relation_nnodes=0;
58 static way_t *relation_ways=NULL;
59 static int relation_nways=0;
60 static relation_t *relation_relations=NULL;
61 static int relation_nrelations=0;
62 static way_t relation_from=NO_WAY_ID;
63 static way_t relation_to=NO_WAY_ID;
64 static node_t relation_via=NO_NODE_ID;
65
66 static NodesX *nodes;
67 static SegmentsX *segments;
68 static WaysX *ways;
69 static RelationsX *relations;
70
71
72 /* Local functions */
73
74 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
75 static void process_way_tags(TagList *tags,way_t id);
76 static void process_relation_tags(TagList *tags,relation_t id);
77
78
79 /* The XML tag processing function prototypes */
80
81 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
82 //static int osmType_function(const char *_tag_,int _type_);
83 static int relationType_function(const char *_tag_,int _type_,const char *id);
84 static int wayType_function(const char *_tag_,int _type_,const char *id);
85 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
86 static int ndType_function(const char *_tag_,int _type_,const char *ref);
87 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
88 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
89 //static int boundType_function(const char *_tag_,int _type_);
90 //static int boundsType_function(const char *_tag_,int _type_);
91
92
93 /* The XML tag definitions */
94
95 /*+ The boundsType type tag. +*/
96 static xmltag boundsType_tag=
97 {"bounds",
98 0, {NULL},
99 NULL,
100 {NULL}};
101
102 /*+ The boundType type tag. +*/
103 static xmltag boundType_tag=
104 {"bound",
105 0, {NULL},
106 NULL,
107 {NULL}};
108
109 /*+ The tagType type tag. +*/
110 static xmltag tagType_tag=
111 {"tag",
112 2, {"k","v"},
113 tagType_function,
114 {NULL}};
115
116 /*+ The nodeType type tag. +*/
117 static xmltag nodeType_tag=
118 {"node",
119 3, {"id","lat","lon"},
120 nodeType_function,
121 {&tagType_tag,NULL}};
122
123 /*+ The ndType type tag. +*/
124 static xmltag ndType_tag=
125 {"nd",
126 1, {"ref"},
127 ndType_function,
128 {NULL}};
129
130 /*+ The memberType type tag. +*/
131 static xmltag memberType_tag=
132 {"member",
133 3, {"type","ref","role"},
134 memberType_function,
135 {NULL}};
136
137 /*+ The wayType type tag. +*/
138 static xmltag wayType_tag=
139 {"way",
140 1, {"id"},
141 wayType_function,
142 {&ndType_tag,&tagType_tag,NULL}};
143
144 /*+ The relationType type tag. +*/
145 static xmltag relationType_tag=
146 {"relation",
147 1, {"id"},
148 relationType_function,
149 {&memberType_tag,&tagType_tag,NULL}};
150
151 /*+ The osmType type tag. +*/
152 static xmltag osmType_tag=
153 {"osm",
154 0, {NULL},
155 NULL,
156 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
157
158 /*+ The xmlDeclaration type tag. +*/
159 static xmltag xmlDeclaration_tag=
160 {"xml",
161 2, {"version","encoding"},
162 NULL,
163 {NULL}};
164
165
166 /*+ The complete set of tags at the top level. +*/
167 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
168
169
170 /* The XML tag processing functions */
171
172
173 /*++++++++++++++++++++++++++++++++++++++
174 The function that is called when the boundsType XSD type is seen
175
176 int boundsType_function Returns 0 if no error occured or something else otherwise.
177
178 const char *_tag_ Set to the name of the element tag that triggered this function call.
179
180 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
181 ++++++++++++++++++++++++++++++++++++++*/
182
183 //static int boundsType_function(const char *_tag_,int _type_)
184 //{
185 // return(0);
186 //}
187
188
189 /*++++++++++++++++++++++++++++++++++++++
190 The function that is called when the boundType XSD type is seen
191
192 int boundType_function Returns 0 if no error occured or something else otherwise.
193
194 const char *_tag_ Set to the name of the element tag that triggered this function call.
195
196 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 ++++++++++++++++++++++++++++++++++++++*/
198
199 //static int boundType_function(const char *_tag_,int _type_)
200 //{
201 // return(0);
202 //}
203
204
205 /*++++++++++++++++++++++++++++++++++++++
206 The function that is called when the tagType XSD type is seen
207
208 int tagType_function Returns 0 if no error occured or something else otherwise.
209
210 const char *_tag_ Set to the name of the element tag that triggered this function call.
211
212 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
213
214 const char *k The contents of the 'k' attribute (or NULL if not defined).
215
216 const char *v The contents of the 'v' attribute (or NULL if not defined).
217 ++++++++++++++++++++++++++++++++++++++*/
218
219 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
220 {
221 if(_type_&XMLPARSE_TAG_START && current_tags)
222 {
223 XMLPARSE_ASSERT_STRING(_tag_,k);
224 XMLPARSE_ASSERT_STRING(_tag_,v);
225
226 AppendTag(current_tags,k,v);
227 }
228
229 return(0);
230 }
231
232
233 /*++++++++++++++++++++++++++++++++++++++
234 The function that is called when the nodeType XSD type is seen
235
236 int nodeType_function Returns 0 if no error occured or something else otherwise.
237
238 const char *_tag_ Set to the name of the element tag that triggered this function call.
239
240 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
241
242 const char *id The contents of the 'id' attribute (or NULL if not defined).
243
244 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
245
246 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
247 ++++++++++++++++++++++++++++++++++++++*/
248
249 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
250 {
251 static node_t node_id;
252 static double latitude,longitude;
253
254 if(_type_&XMLPARSE_TAG_START)
255 {
256 nnodes++;
257
258 if(!(nnodes%10000))
259 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
260
261 current_tags=NewTagList();
262
263 /* Handle the node information */
264
265 XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
266 XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
267 XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
268 }
269
270 if(_type_&XMLPARSE_TAG_END)
271 {
272 TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
273
274 process_node_tags(result,node_id,latitude,longitude);
275
276 DeleteTagList(current_tags);
277 DeleteTagList(result);
278 }
279
280 return(0);
281 }
282
283
284 /*++++++++++++++++++++++++++++++++++++++
285 The function that is called when the ndType XSD type is seen
286
287 int ndType_function Returns 0 if no error occured or something else otherwise.
288
289 const char *_tag_ Set to the name of the element tag that triggered this function call.
290
291 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
293 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
294 ++++++++++++++++++++++++++++++++++++++*/
295
296 static int ndType_function(const char *_tag_,int _type_,const char *ref)
297 {
298 if(_type_&XMLPARSE_TAG_START)
299 {
300 node_t node_id;
301
302 XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
303
304 if(way_nnodes && (way_nnodes%256)==0)
305 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
306
307 way_nodes[way_nnodes++]=node_id;
308 }
309
310 return(0);
311 }
312
313
314 /*++++++++++++++++++++++++++++++++++++++
315 The function that is called when the memberType XSD type is seen
316
317 int memberType_function Returns 0 if no error occured or something else otherwise.
318
319 const char *_tag_ Set to the name of the element tag that triggered this function call.
320
321 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
323 const char *type The contents of the 'type' attribute (or NULL if not defined).
324
325 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
326
327 const char *role The contents of the 'role' attribute (or NULL if not defined).
328 ++++++++++++++++++++++++++++++++++++++*/
329
330 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
331 {
332 if(_type_&XMLPARSE_TAG_START)
333 {
334 XMLPARSE_ASSERT_STRING(_tag_,type);
335 XMLPARSE_ASSERT_STRING(_tag_,ref);
336
337 if(!strcmp(type,"node"))
338 {
339 node_t node_id=atoll(ref); /* need long long conversion */
340
341 if(relation_nnodes && (relation_nnodes%256)==0)
342 relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
343
344 relation_nodes[relation_nnodes++]=node_id;
345
346 if(role)
347 {
348 if(!strcmp(role,"via"))
349 relation_via=node_id;
350 }
351 }
352 else if(!strcmp(type,"way"))
353 {
354 way_t way_id=atoll(ref); /* need long long conversion */
355
356 if(relation_nways && (relation_nways%256)==0)
357 relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
358
359 relation_ways[relation_nways++]=way_id;
360
361 if(role)
362 {
363 if(!strcmp(role,"from"))
364 relation_from=way_id;
365 if(!strcmp(role,"to"))
366 relation_to=way_id;
367 }
368 }
369 else if(!strcmp(type,"relation"))
370 {
371 relation_t relation_id=atoll(ref); /* need long long conversion */
372
373 if(relation_nrelations && (relation_nrelations%256)==0)
374 relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
375
376 relation_relations[relation_nrelations++]=relation_id;
377 }
378 }
379
380 return(0);
381 }
382
383
384 /*++++++++++++++++++++++++++++++++++++++
385 The function that is called when the wayType XSD type is seen
386
387 int wayType_function Returns 0 if no error occured or something else otherwise.
388
389 const char *_tag_ Set to the name of the element tag that triggered this function call.
390
391 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
392
393 const char *id The contents of the 'id' attribute (or NULL if not defined).
394 ++++++++++++++++++++++++++++++++++++++*/
395
396 static int wayType_function(const char *_tag_,int _type_,const char *id)
397 {
398 static way_t way_id;
399
400 if(_type_&XMLPARSE_TAG_START)
401 {
402 nways++;
403
404 if(!(nways%1000))
405 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
406
407 current_tags=NewTagList();
408
409 way_nnodes=0;
410
411 /* Handle the way information */
412
413 XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */
414 }
415
416 if(_type_&XMLPARSE_TAG_END)
417 {
418 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
419
420 process_way_tags(result,way_id);
421
422 DeleteTagList(current_tags);
423 DeleteTagList(result);
424 }
425
426 return(0);
427 }
428
429
430 /*++++++++++++++++++++++++++++++++++++++
431 The function that is called when the relationType XSD type is seen
432
433 int relationType_function Returns 0 if no error occured or something else otherwise.
434
435 const char *_tag_ Set to the name of the element tag that triggered this function call.
436
437 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
438
439 const char *id The contents of the 'id' attribute (or NULL if not defined).
440 ++++++++++++++++++++++++++++++++++++++*/
441
442 static int relationType_function(const char *_tag_,int _type_,const char *id)
443 {
444 static relation_t relation_id;
445
446 if(_type_&XMLPARSE_TAG_START)
447 {
448 nrelations++;
449
450 if(!(nrelations%1000))
451 printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
452
453 current_tags=NewTagList();
454
455 relation_nnodes=relation_nways=relation_nrelations=0;
456
457 relation_from=NO_WAY_ID;
458 relation_to=NO_WAY_ID;
459 relation_via=NO_NODE_ID;
460
461 /* Handle the relation information */
462
463 XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */
464 }
465
466 if(_type_&XMLPARSE_TAG_END)
467 {
468 TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
469
470 process_relation_tags(result,relation_id);
471
472 DeleteTagList(current_tags);
473 DeleteTagList(result);
474 }
475
476 return(0);
477 }
478
479
480 /*++++++++++++++++++++++++++++++++++++++
481 The function that is called when the osmType XSD type is seen
482
483 int osmType_function Returns 0 if no error occured or something else otherwise.
484
485 const char *_tag_ Set to the name of the element tag that triggered this function call.
486
487 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
488 ++++++++++++++++++++++++++++++++++++++*/
489
490 //static int osmType_function(const char *_tag_,int _type_)
491 //{
492 // return(0);
493 //}
494
495
496 /*++++++++++++++++++++++++++++++++++++++
497 The function that is called when the XML declaration is seen
498
499 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
500
501 const char *_tag_ Set to the name of the element tag that triggered this function call.
502
503 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
504
505 const char *version The contents of the 'version' attribute (or NULL if not defined).
506
507 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
508 ++++++++++++++++++++++++++++++++++++++*/
509
510 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
511 //{
512 // return(0);
513 //}
514
515
516 /*++++++++++++++++++++++++++++++++++++++
517 Parse an OSM XML file (from JOSM or planet download).
518
519 int ParseOSM Returns 0 if OK or something else in case of an error.
520
521 FILE *file The file to read from.
522
523 NodesX *OSMNodes The data structure of nodes to fill in.
524
525 SegmentsX *OSMSegments The data structure of segments to fill in.
526
527 WaysX *OSMWays The data structure of ways to fill in.
528
529 RelationsX *OSMRelations The data structure of relations to fill in.
530 ++++++++++++++++++++++++++++++++++++++*/
531
532 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
533 {
534 int retval;
535
536 /* Copy the function parameters and initialise the variables. */
537
538 nodes=OSMNodes;
539 segments=OSMSegments;
540 ways=OSMWays;
541 relations=OSMRelations;
542
543 way_nodes=(node_t*)malloc(256*sizeof(node_t));
544
545 relation_nodes =(node_t *)malloc(256*sizeof(node_t));
546 relation_ways =(way_t *)malloc(256*sizeof(way_t));
547 relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
548
549 /* Parse the file */
550
551 nnodes=0,nways=0,nrelations=0;
552
553 printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
554
555 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
556
557 printf_last("Read: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
558
559 return(retval);
560 }
561
562
563 /*++++++++++++++++++++++++++++++++++++++
564 Process the tags associated with a node.
565
566 TagList *tags The list of node tags.
567
568 node_t id The id of the node.
569
570 double latitude The latitude of the node.
571
572 double longitude The longitude of the node.
573 ++++++++++++++++++++++++++++++++++++++*/
574
575 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
576 {
577 transports_t allow=Transports_ALL;
578 uint16_t flags=0;
579 int i;
580
581 /* Parse the tags */
582
583 for(i=0;i<tags->ntags;i++)
584 {
585 char *k=tags->k[i];
586 char *v=tags->v[i];
587
588 switch(*k)
589 {
590 case 'b':
591 if(!strcmp(k,"bicycle"))
592 if(!ISTRUE(v))
593 allow&=~Transports_Bicycle;
594
595 break;
596
597 case 'f':
598 if(!strcmp(k,"foot"))
599 if(!ISTRUE(v))
600 allow&=~Transports_Foot;
601
602 break;
603
604 case 'g':
605 if(!strcmp(k,"goods"))
606 if(!ISTRUE(v))
607 allow&=~Transports_Goods;
608
609 break;
610
611 case 'h':
612 if(!strcmp(k,"highway"))
613 if(!strcmp(v,"mini_roundabout"))
614 flags|=NODE_MINIRNDBT;
615
616 if(!strcmp(k,"horse"))
617 if(!ISTRUE(v))
618 allow&=~Transports_Horse;
619
620 if(!strcmp(k,"hgv"))
621 if(!ISTRUE(v))
622 allow&=~Transports_HGV;
623
624 break;
625
626 case 'm':
627 if(!strcmp(k,"moped"))
628 if(!ISTRUE(v))
629 allow&=~Transports_Moped;
630
631 if(!strcmp(k,"motorbike"))
632 if(!ISTRUE(v))
633 allow&=~Transports_Motorbike;
634
635 if(!strcmp(k,"motorcar"))
636 if(!ISTRUE(v))
637 allow&=~Transports_Motorcar;
638
639 break;
640
641 case 'p':
642 if(!strcmp(k,"psv"))
643 if(!ISTRUE(v))
644 allow&=~Transports_PSV;
645
646 break;
647
648 case 'w':
649 if(!strcmp(k,"wheelchair"))
650 if(!ISTRUE(v))
651 allow&=~Transports_Wheelchair;
652
653 break;
654
655 default:
656 ;
657 }
658 }
659
660 /* Create the node */
661
662 AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags);
663 }
664
665
666 /*++++++++++++++++++++++++++++++++++++++
667 Process the tags associated with a way.
668
669 TagList *tags The list of way tags.
670
671 way_t id The id of the way.
672 ++++++++++++++++++++++++++++++++++++++*/
673
674 static void process_way_tags(TagList *tags,way_t id)
675 {
676 Way way={0};
677 int oneway=0;
678 char *name=NULL,*ref=NULL;
679 int i;
680
681 /* Parse the tags */
682
683 for(i=0;i<tags->ntags;i++)
684 {
685 char *k=tags->k[i];
686 char *v=tags->v[i];
687
688 switch(*k)
689 {
690 case 'b':
691 if(!strcmp(k,"bicycle"))
692 if(ISTRUE(v))
693 way.allow|= Transports_Bicycle;
694
695 if(!strcmp(k,"bicycleroute"))
696 if(ISTRUE(v))
697 way.props|=Properties_BicycleRoute;
698
699 if(!strcmp(k,"bridge"))
700 if(ISTRUE(v))
701 way.props|=Properties_Bridge;
702
703 break;
704
705 case 'f':
706 if(!strcmp(k,"foot"))
707 if(ISTRUE(v))
708 way.allow|= Transports_Foot;
709
710 if(!strcmp(k,"footroute"))
711 if(ISTRUE(v))
712 way.props|=Properties_FootRoute;
713
714 break;
715
716 case 'g':
717 if(!strcmp(k,"goods"))
718 if(ISTRUE(v))
719 way.allow|=Transports_Goods;
720
721 break;
722
723 case 'h':
724 if(!strcmp(k,"highway"))
725 way.type=HighwayType(v);
726
727 if(!strcmp(k,"horse"))
728 if(ISTRUE(v))
729 way.allow|=Transports_Horse;
730
731 if(!strcmp(k,"hgv"))
732 if(ISTRUE(v))
733 way.allow|=Transports_HGV;
734
735 break;
736
737 case 'm':
738 if(!strcmp(k,"maxspeed"))
739 {
740 if(strstr(v,"mph"))
741 way.speed=kph_to_speed(1.609*atof(v));
742 else
743 way.speed=kph_to_speed(atof(v));
744 }
745
746 if(!strcmp(k,"maxweight"))
747 {
748 if(strstr(v,"kg"))
749 way.weight=tonnes_to_weight(atof(v)/1000);
750 else
751 way.weight=tonnes_to_weight(atof(v));
752 }
753
754 if(!strcmp(k,"maxheight"))
755 {
756 if(strchr(v,'\''))
757 {
758 int feet,inches;
759
760 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
761 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
762 else if(sscanf(v,"%d'",&feet)==1)
763 way.height=metres_to_height((feet+(double)inches/12.0)*0.254);
764 }
765 else if(strstr(v,"ft") || strstr(v,"feet"))
766 way.height=metres_to_height(atof(v)*0.254);
767 else
768 way.height=metres_to_height(atof(v));
769 }
770
771 if(!strcmp(k,"maxwidth"))
772 {
773 if(strchr(v,'\''))
774 {
775 int feet,inches;
776
777 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
778 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
779 else if(sscanf(v,"%d'",&feet)==1)
780 way.width=metres_to_height((feet+(double)inches/12.0)*0.254);
781 }
782 else if(strstr(v,"ft") || strstr(v,"feet"))
783 way.width=metres_to_width(atof(v)*0.254);
784 else
785 way.width=metres_to_width(atof(v));
786 }
787
788 if(!strcmp(k,"maxlength"))
789 {
790 if(strchr(v,'\''))
791 {
792 int feet,inches;
793
794 if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
795 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
796 else if(sscanf(v,"%d'",&feet)==1)
797 way.length=metres_to_height((feet+(double)inches/12.0)*0.254);
798 }
799 else if(strstr(v,"ft") || strstr(v,"feet"))
800 way.length=metres_to_length(atof(v)*0.254);
801 else
802 way.length=metres_to_length(atof(v));
803 }
804
805 if(!strcmp(k,"moped"))
806 if(ISTRUE(v))
807 way.allow|=Transports_Moped;
808
809 if(!strcmp(k,"motorbike"))
810 if(ISTRUE(v))
811 way.allow|=Transports_Motorbike;
812
813 if(!strcmp(k,"motorcar"))
814 if(ISTRUE(v))
815 way.allow|=Transports_Motorcar;
816
817 if(!strcmp(k,"multilane"))
818 if(ISTRUE(v))
819 way.props|=Properties_Multilane;
820
821 break;
822
823 case 'n':
824 if(!strcmp(k,"name"))
825 name=v;
826
827 break;
828
829 case 'o':
830 if(!strcmp(k,"oneway"))
831 {
832 if(ISTRUE(v))
833 oneway=1;
834 else if(!strcmp(v,"-1"))
835 oneway=-1;
836 }
837
838 break;
839
840 case 'p':
841 if(!strcmp(k,"paved"))
842 if(ISTRUE(v))
843 way.props|=Properties_Paved;
844
845 if(!strcmp(k,"psv"))
846 if(ISTRUE(v))
847 way.allow|=Transports_PSV;
848
849 break;
850
851 case 'r':
852 if(!strcmp(k,"ref"))
853 ref=v;
854
855 break;
856
857 case 't':
858 if(!strcmp(k,"tunnel"))
859 if(ISTRUE(v))
860 way.props|=Properties_Tunnel;
861
862 break;
863
864 case 'w':
865 if(!strcmp(k,"wheelchair"))
866 if(ISTRUE(v))
867 way.allow|=Transports_Wheelchair;
868
869 break;
870
871 default:
872 ;
873 }
874 }
875
876 /* Create the way */
877
878 if(way.type>0 && way.type<Way_Count)
879 {
880 if(way.allow)
881 {
882 char *refname;
883
884 if(oneway)
885 way.type|=Way_OneWay;
886
887 if(ref && name)
888 {
889 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
890 sprintf(refname,"%s (%s)",name,ref);
891 }
892 else if(ref && !name)
893 refname=ref;
894 else if(!ref && name)
895 refname=name;
896 else /* if(!ref && !name) */
897 refname="";
898
899 AppendWay(ways,id,&way,refname);
900
901 if(ref && name)
902 free(refname);
903
904 for(i=1;i<way_nnodes;i++)
905 {
906 node_t from=way_nodes[i-1];
907 node_t to =way_nodes[i];
908
909 if(oneway>0)
910 AppendSegment(segments,id,from,to,ONEWAY_1TO2);
911 else if(oneway<0)
912 AppendSegment(segments,id,from,to,ONEWAY_2TO1);
913 else
914 AppendSegment(segments,id,from,to,0);
915 }
916 }
917 }
918 }
919
920
921 /*++++++++++++++++++++++++++++++++++++++
922 Process the tags associated with a relation.
923
924 TagList *tags The list of relation tags.
925
926 relation_t id The id of the relation.
927 ++++++++++++++++++++++++++++++++++++++*/
928
929 static void process_relation_tags(TagList *tags,relation_t id)
930 {
931 transports_t routes=Transports_None;
932 transports_t except=Transports_None;
933 int relation_turn_restriction=0;
934 TurnRestriction restriction=TurnRestrict_None;
935 int i;
936
937 /* Parse the tags */
938
939 for(i=0;i<tags->ntags;i++)
940 {
941 char *k=tags->k[i];
942 char *v=tags->v[i];
943
944 switch(*k)
945 {
946 case 'b':
947 if(!strcmp(k,"bicycleroute"))
948 if(ISTRUE(v))
949 routes|=Transports_Bicycle;
950
951 break;
952
953 case 'e':
954 if(!strcmp(k,"except"))
955 for(i=1;i<Transport_Count;i++)
956 if(!strstr(v,TransportName(i)))
957 except|=TRANSPORTS(i);
958
959 break;
960
961 case 'f':
962 if(!strcmp(k,"footroute"))
963 if(ISTRUE(v))
964 routes|=Transports_Foot;
965
966 break;
967
968 case 'r':
969 if(!strcmp(k,"restriction"))
970 {
971 if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn;
972 if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn;
973 if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn;
974 if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on;
975 if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn;
976 if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn;
977 if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on;
978 }
979
980 break;
981
982 case 't':
983 if(!strcmp(k,"type"))
984 if(!strcmp(v,"restriction"))
985 relation_turn_restriction=1;
986 break;
987
988 default:
989 ;
990 }
991 }
992
993 /* Create the route relation (must store all relations that have ways or
994 relations even if they are not routes because they might be referenced by
995 other relations that are routes) */
996
997 if((relation_nways || relation_nrelations) && !relation_turn_restriction)
998 AppendRouteRelation(relations,id,routes,
999 relation_ways,relation_nways,
1000 relation_relations,relation_nrelations);
1001
1002 /* Create the turn restriction relation. */
1003
1004 if(relation_turn_restriction && restriction!=TurnRestrict_None &&
1005 relation_from!=NO_WAY_ID && relation_to!=NO_WAY_ID && relation_via!=NO_NODE_ID)
1006 AppendTurnRestrictRelation(relations,id,
1007 relation_from,relation_to,relation_via,
1008 restriction,except);
1009 }

Properties

Name Value
cvs:description OSM XML file parser.