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 1166 - (show annotations) (download) (as text)
Tue Nov 20 16:12:08 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 48341 byte(s)
Replace all assert statements with a custom error message that explains the
cause and suggests a solution.

1 /***************************************
2 OSM XML file parser (either JOSM or planet)
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2012 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 "nodesx.h"
30 #include "segmentsx.h"
31 #include "waysx.h"
32 #include "relationsx.h"
33
34 #include "osmparser.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 /*+ Checks if a value in the XML is one of the allowed values for false. +*/
48 #define ISFALSE(xx) (!strcmp(xx,"false") || !strcmp(xx,"no") || !strcmp(xx,"0"))
49
50
51 /* Constants */
52
53 #define MODE_NORMAL 3
54 #define MODE_CREATE 2
55 #define MODE_MODIFY 1
56 #define MODE_DELETE -1
57
58
59 /* Local variables */
60
61 static int mode=MODE_NORMAL;
62
63 static index_t nnodes=0;
64 static index_t nways=0;
65 static index_t nrelations=0;
66
67 static TagList *current_tags=NULL;
68
69 static node_t *way_nodes=NULL;
70 static int way_nnodes=0;
71
72 static node_t *relation_nodes=NULL;
73 static int relation_nnodes=0;
74 static way_t *relation_ways=NULL;
75 static int relation_nways=0;
76 static relation_t *relation_relations=NULL;
77 static int relation_nrelations=0;
78 static way_t relation_from=NO_WAY_ID;
79 static way_t relation_to=NO_WAY_ID;
80 static node_t relation_via=NO_NODE_ID;
81
82 static NodesX *nodes;
83 static SegmentsX *segments;
84 static WaysX *ways;
85 static RelationsX *relations;
86
87
88 /* Local functions */
89
90 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
91 static void process_way_tags(TagList *tags,way_t id);
92 static void process_relation_tags(TagList *tags,relation_t id);
93
94 static double parse_speed(way_t id,const char *k,const char *v);
95 static double parse_weight(way_t id,const char *k,const char *v);
96 static double parse_length(way_t id,const char *k,const char *v);
97
98
99 /* The XML tag processing function prototypes */
100
101 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
102 static int osmType_function(const char *_tag_,int _type_,const char *version);
103 static int osmChangeType_function(const char *_tag_,int _type_,const char *version);
104 static int deleteType_function(const char *_tag_,int _type_);
105 static int createType_function(const char *_tag_,int _type_);
106 static int modifyType_function(const char *_tag_,int _type_);
107 static int relationType_function(const char *_tag_,int _type_,const char *id);
108 static int wayType_function(const char *_tag_,int _type_,const char *id);
109 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
110 static int ndType_function(const char *_tag_,int _type_,const char *ref);
111 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
112 static int changesetType_function(const char *_tag_,int _type_);
113 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
114 //static int boundType_function(const char *_tag_,int _type_);
115 //static int boundsType_function(const char *_tag_,int _type_);
116
117
118 /* The XML tag definitions */
119
120 /*+ The boundsType type tag. +*/
121 static xmltag boundsType_tag=
122 {"bounds",
123 0, {NULL},
124 NULL,
125 {NULL}};
126
127 /*+ The boundType type tag. +*/
128 static xmltag boundType_tag=
129 {"bound",
130 0, {NULL},
131 NULL,
132 {NULL}};
133
134 /*+ The tagType type tag. +*/
135 static xmltag tagType_tag=
136 {"tag",
137 2, {"k","v"},
138 tagType_function,
139 {NULL}};
140
141 /*+ The changesetType type tag. +*/
142 static xmltag changesetType_tag=
143 {"changeset",
144 0, {NULL},
145 changesetType_function,
146 {&tagType_tag,NULL}};
147
148 /*+ The nodeType type tag. +*/
149 static xmltag nodeType_tag=
150 {"node",
151 3, {"id","lat","lon"},
152 nodeType_function,
153 {&tagType_tag,NULL}};
154
155 /*+ The ndType type tag. +*/
156 static xmltag ndType_tag=
157 {"nd",
158 1, {"ref"},
159 ndType_function,
160 {NULL}};
161
162 /*+ The memberType type tag. +*/
163 static xmltag memberType_tag=
164 {"member",
165 3, {"type","ref","role"},
166 memberType_function,
167 {NULL}};
168
169 /*+ The wayType type tag. +*/
170 static xmltag wayType_tag=
171 {"way",
172 1, {"id"},
173 wayType_function,
174 {&ndType_tag,&tagType_tag,NULL}};
175
176 /*+ The relationType type tag. +*/
177 static xmltag relationType_tag=
178 {"relation",
179 1, {"id"},
180 relationType_function,
181 {&memberType_tag,&tagType_tag,NULL}};
182
183 /*+ The deleteType type tag. +*/
184 static xmltag deleteType_tag=
185 {"delete",
186 0, {NULL},
187 deleteType_function,
188 {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
189
190 /*+ The createType type tag. +*/
191 static xmltag createType_tag=
192 {"create",
193 0, {NULL},
194 createType_function,
195 {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
196
197 /*+ The modifyType type tag. +*/
198 static xmltag modifyType_tag=
199 {"modify",
200 0, {NULL},
201 modifyType_function,
202 {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
203
204 /*+ The osmChangeType type tag. +*/
205 static xmltag osmChangeType_tag=
206 {"osmChange",
207 1, {"version"},
208 osmChangeType_function,
209 {&boundsType_tag,&modifyType_tag,&createType_tag,&deleteType_tag,NULL}};
210
211 /*+ The osmType type tag. +*/
212 static xmltag osmType_tag=
213 {"osm",
214 1, {"version"},
215 osmType_function,
216 {&boundsType_tag,&boundType_tag,&changesetType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
217
218 /*+ The xmlDeclaration type tag. +*/
219 static xmltag xmlDeclaration_tag=
220 {"xml",
221 2, {"version","encoding"},
222 NULL,
223 {NULL}};
224
225
226 /*+ The complete set of tags at the top level for OSM. +*/
227 static xmltag *xml_osm_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
228
229 /*+ The complete set of tags at the top level for OSC. +*/
230 static xmltag *xml_osc_toplevel_tags[]={&xmlDeclaration_tag,&osmChangeType_tag,NULL};
231
232
233 /* The XML tag processing functions */
234
235
236 /*++++++++++++++++++++++++++++++++++++++
237 The function that is called when the boundsType XSD type is seen
238
239 int boundsType_function Returns 0 if no error occured or something else otherwise.
240
241 const char *_tag_ Set to the name of the element tag that triggered this function call.
242
243 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
244 ++++++++++++++++++++++++++++++++++++++*/
245
246 //static int boundsType_function(const char *_tag_,int _type_)
247 //{
248 // return(0);
249 //}
250
251
252 /*++++++++++++++++++++++++++++++++++++++
253 The function that is called when the boundType XSD type is seen
254
255 int boundType_function Returns 0 if no error occured or something else otherwise.
256
257 const char *_tag_ Set to the name of the element tag that triggered this function call.
258
259 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
260 ++++++++++++++++++++++++++++++++++++++*/
261
262 //static int boundType_function(const char *_tag_,int _type_)
263 //{
264 // return(0);
265 //}
266
267
268 /*++++++++++++++++++++++++++++++++++++++
269 The function that is called when the tagType XSD type is seen
270
271 int tagType_function Returns 0 if no error occured or something else otherwise.
272
273 const char *_tag_ Set to the name of the element tag that triggered this function call.
274
275 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
276
277 const char *k The contents of the 'k' attribute (or NULL if not defined).
278
279 const char *v The contents of the 'v' attribute (or NULL if not defined).
280 ++++++++++++++++++++++++++++++++++++++*/
281
282 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
283 {
284 if(_type_&XMLPARSE_TAG_START && current_tags)
285 {
286 XMLPARSE_ASSERT_STRING(_tag_,k);
287 XMLPARSE_ASSERT_STRING(_tag_,v);
288
289 AppendTag(current_tags,k,v);
290 }
291
292 return(0);
293 }
294
295
296 /*++++++++++++++++++++++++++++++++++++++
297 The function that is called when the changesetType XSD type is seen
298
299 int changesetType_function Returns 0 if no error occured or something else otherwise.
300
301 const char *_tag_ Set to the name of the element tag that triggered this function call.
302
303 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
304 ++++++++++++++++++++++++++++++++++++++*/
305
306 static int changesetType_function(const char *_tag_,int _type_)
307 {
308 current_tags=NULL;
309
310 return(0);
311 }
312
313
314 /*++++++++++++++++++++++++++++++++++++++
315 The function that is called when the nodeType XSD type is seen
316
317 int nodeType_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 *id The contents of the 'id' attribute (or NULL if not defined).
324
325 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
326
327 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
328 ++++++++++++++++++++++++++++++++++++++*/
329
330 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
331 {
332 static node_t node_id;
333 static double latitude,longitude;
334
335 if(_type_&XMLPARSE_TAG_START)
336 {
337 long long llid;
338
339 nnodes++;
340
341 if(!(nnodes%10000))
342 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
343
344 current_tags=NewTagList();
345
346 /* Handle the node information */
347
348 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
349 node_id=(node_t)llid;
350 logassert((long long)node_id==llid,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */
351
352 if(mode!=MODE_DELETE)
353 {
354 XMLPARSE_ASSERT_FLOATING(_tag_,lat); latitude =atof(lat);
355 XMLPARSE_ASSERT_FLOATING(_tag_,lon); longitude=atof(lon);
356 }
357 }
358
359 if(_type_&XMLPARSE_TAG_END)
360 {
361 TagList *result=ApplyTaggingRules(&NodeRules,current_tags,node_id);
362
363 process_node_tags(result,node_id,latitude,longitude);
364
365 DeleteTagList(current_tags); current_tags=NULL;
366 DeleteTagList(result);
367 }
368
369 return(0);
370 }
371
372
373 /*++++++++++++++++++++++++++++++++++++++
374 The function that is called when the ndType XSD type is seen
375
376 int ndType_function Returns 0 if no error occured or something else otherwise.
377
378 const char *_tag_ Set to the name of the element tag that triggered this function call.
379
380 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
381
382 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
383 ++++++++++++++++++++++++++++++++++++++*/
384
385 static int ndType_function(const char *_tag_,int _type_,const char *ref)
386 {
387 if(_type_&XMLPARSE_TAG_START)
388 {
389 long long llid;
390 node_t node_id;
391
392 XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need long long conversion */
393 node_id=(node_t)llid;
394 logassert((long long)node_id==llid,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */
395
396 if(way_nnodes && (way_nnodes%256)==0)
397 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
398
399 way_nodes[way_nnodes++]=node_id;
400 }
401
402 return(0);
403 }
404
405
406 /*++++++++++++++++++++++++++++++++++++++
407 The function that is called when the memberType XSD type is seen
408
409 int memberType_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 const char *type The contents of the 'type' attribute (or NULL if not defined).
416
417 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
418
419 const char *role The contents of the 'role' attribute (or NULL if not defined).
420 ++++++++++++++++++++++++++++++++++++++*/
421
422 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
423 {
424 if(_type_&XMLPARSE_TAG_START)
425 {
426 long long llid;
427
428 XMLPARSE_ASSERT_STRING(_tag_,type);
429 XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need long long conversion */
430
431 if(!strcmp(type,"node"))
432 {
433 node_t node_id;
434
435 node_id=(node_t)llid;
436 logassert((long long)node_id==llid,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */
437
438 if(relation_nnodes && (relation_nnodes%256)==0)
439 relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
440
441 relation_nodes[relation_nnodes++]=node_id;
442
443 if(role)
444 {
445 if(!strcmp(role,"via"))
446 relation_via=node_id;
447 }
448 }
449 else if(!strcmp(type,"way"))
450 {
451 way_t way_id;
452
453 way_id=(way_t)llid;
454 logassert((long long)way_id==llid,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */
455
456 if(relation_nways && (relation_nways%256)==0)
457 relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
458
459 relation_ways[relation_nways++]=way_id;
460
461 if(role)
462 {
463 if(!strcmp(role,"from"))
464 relation_from=way_id;
465 if(!strcmp(role,"to"))
466 relation_to=way_id;
467 }
468 }
469 else if(!strcmp(type,"relation"))
470 {
471 relation_t relation_id;
472
473 relation_id=(relation_t)llid;
474 logassert((long long)relation_id==llid,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */
475
476 if(relation_nrelations && (relation_nrelations%256)==0)
477 relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
478
479 relation_relations[relation_nrelations++]=relation_id;
480 }
481 }
482
483 return(0);
484 }
485
486
487 /*++++++++++++++++++++++++++++++++++++++
488 The function that is called when the wayType XSD type is seen
489
490 int wayType_function Returns 0 if no error occured or something else otherwise.
491
492 const char *_tag_ Set to the name of the element tag that triggered this function call.
493
494 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
495
496 const char *id The contents of the 'id' attribute (or NULL if not defined).
497 ++++++++++++++++++++++++++++++++++++++*/
498
499 static int wayType_function(const char *_tag_,int _type_,const char *id)
500 {
501 static way_t way_id;
502
503 if(_type_&XMLPARSE_TAG_START)
504 {
505 long long llid;
506
507 nways++;
508
509 if(!(nways%1000))
510 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
511
512 current_tags=NewTagList();
513
514 way_nnodes=0;
515
516 /* Handle the way information */
517
518 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
519
520 way_id=(way_t)llid;
521 logassert((long long)way_id==llid,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */
522 }
523
524 if(_type_&XMLPARSE_TAG_END)
525 {
526 TagList *result=ApplyTaggingRules(&WayRules,current_tags,way_id);
527
528 process_way_tags(result,way_id);
529
530 DeleteTagList(current_tags); current_tags=NULL;
531 DeleteTagList(result);
532 }
533
534 return(0);
535 }
536
537
538 /*++++++++++++++++++++++++++++++++++++++
539 The function that is called when the relationType XSD type is seen
540
541 int relationType_function Returns 0 if no error occured or something else otherwise.
542
543 const char *_tag_ Set to the name of the element tag that triggered this function call.
544
545 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
546
547 const char *id The contents of the 'id' attribute (or NULL if not defined).
548 ++++++++++++++++++++++++++++++++++++++*/
549
550 static int relationType_function(const char *_tag_,int _type_,const char *id)
551 {
552 static relation_t relation_id;
553
554 if(_type_&XMLPARSE_TAG_START)
555 {
556 long long llid;
557
558 nrelations++;
559
560 if(!(nrelations%1000))
561 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
562
563 current_tags=NewTagList();
564
565 relation_nnodes=relation_nways=relation_nrelations=0;
566
567 relation_from=NO_WAY_ID;
568 relation_to=NO_WAY_ID;
569 relation_via=NO_NODE_ID;
570
571 /* Handle the relation information */
572
573 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
574
575 relation_id=(relation_t)llid;
576 logassert((long long)relation_id==llid,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */
577 }
578
579 if(_type_&XMLPARSE_TAG_END)
580 {
581 TagList *result=ApplyTaggingRules(&RelationRules,current_tags,relation_id);
582
583 process_relation_tags(result,relation_id);
584
585 DeleteTagList(current_tags); current_tags=NULL;
586 DeleteTagList(result);
587 }
588
589 return(0);
590 }
591
592
593 /*++++++++++++++++++++++++++++++++++++++
594 The function that is called when the deleteType XSD type is seen
595
596 int deleteType_function Returns 0 if no error occured or something else otherwise.
597
598 const char *_tag_ Set to the name of the element tag that triggered this function call.
599
600 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
601 ++++++++++++++++++++++++++++++++++++++*/
602
603 static int deleteType_function(const char *_tag_,int _type_)
604 {
605 if(_type_&XMLPARSE_TAG_START)
606 mode=MODE_DELETE;
607
608 return(0);
609 }
610
611
612 /*++++++++++++++++++++++++++++++++++++++
613 The function that is called when the createType XSD type is seen
614
615 int createType_function Returns 0 if no error occured or something else otherwise.
616
617 const char *_tag_ Set to the name of the element tag that triggered this function call.
618
619 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
620 ++++++++++++++++++++++++++++++++++++++*/
621
622 static int createType_function(const char *_tag_,int _type_)
623 {
624 if(_type_&XMLPARSE_TAG_START)
625 mode=MODE_CREATE;
626
627 return(0);
628 }
629
630
631 /*++++++++++++++++++++++++++++++++++++++
632 The function that is called when the modifyType XSD type is seen
633
634 int modifyType_function Returns 0 if no error occured or something else otherwise.
635
636 const char *_tag_ Set to the name of the element tag that triggered this function call.
637
638 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
639 ++++++++++++++++++++++++++++++++++++++*/
640
641 static int modifyType_function(const char *_tag_,int _type_)
642 {
643 if(_type_&XMLPARSE_TAG_START)
644 mode=MODE_MODIFY;
645
646 return(0);
647 }
648
649
650 /*++++++++++++++++++++++++++++++++++++++
651 The function that is called when the osmChangeType XSD type is seen
652
653 int osmChangeType_function Returns 0 if no error occured or something else otherwise.
654
655 const char *_tag_ Set to the name of the element tag that triggered this function call.
656
657 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
658
659 const char *version The contents of the 'version' attribute (or NULL if not defined).
660 ++++++++++++++++++++++++++++++++++++++*/
661
662 static int osmChangeType_function(const char *_tag_,int _type_,const char *version)
663 {
664 if(_type_&XMLPARSE_TAG_START)
665 {
666 if(!version || strcmp(version,"0.6"))
667 XMLPARSE_MESSAGE(_tag_,"Invalid value for 'version' (only '0.6' accepted)");
668 }
669
670 return(0);
671 }
672
673
674 /*++++++++++++++++++++++++++++++++++++++
675 The function that is called when the osmType XSD type is seen
676
677 int osmType_function Returns 0 if no error occured or something else otherwise.
678
679 const char *_tag_ Set to the name of the element tag that triggered this function call.
680
681 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
682
683 const char *version The contents of the 'version' attribute (or NULL if not defined).
684 ++++++++++++++++++++++++++++++++++++++*/
685
686 static int osmType_function(const char *_tag_,int _type_,const char *version)
687 {
688 if(_type_&XMLPARSE_TAG_START)
689 {
690 mode=MODE_NORMAL;
691
692 if(!version || strcmp(version,"0.6"))
693 XMLPARSE_MESSAGE(_tag_,"Invalid value for 'version' (only '0.6' accepted)");
694 }
695
696 return(0);
697 }
698
699
700 /*++++++++++++++++++++++++++++++++++++++
701 The function that is called when the XML declaration is seen
702
703 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
704
705 const char *_tag_ Set to the name of the element tag that triggered this function call.
706
707 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
708
709 const char *version The contents of the 'version' attribute (or NULL if not defined).
710
711 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
712 ++++++++++++++++++++++++++++++++++++++*/
713
714 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
715 //{
716 // return(0);
717 //}
718
719
720 /*++++++++++++++++++++++++++++++++++++++
721 Parse an OSM XML file (from JOSM or planet download).
722
723 int ParseOSM Returns 0 if OK or something else in case of an error.
724
725 FILE *file The file to read from.
726
727 NodesX *OSMNodes The data structure of nodes to fill in.
728
729 SegmentsX *OSMSegments The data structure of segments to fill in.
730
731 WaysX *OSMWays The data structure of ways to fill in.
732
733 RelationsX *OSMRelations The data structure of relations to fill in.
734 ++++++++++++++++++++++++++++++++++++++*/
735
736 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
737 {
738 int retval;
739
740 /* Copy the function parameters and initialise the variables. */
741
742 nodes=OSMNodes;
743 segments=OSMSegments;
744 ways=OSMWays;
745 relations=OSMRelations;
746
747 way_nodes=(node_t*)malloc(256*sizeof(node_t));
748
749 relation_nodes =(node_t *)malloc(256*sizeof(node_t));
750 relation_ways =(way_t *)malloc(256*sizeof(way_t));
751 relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
752
753 /* Parse the file */
754
755 nnodes=0,nways=0,nrelations=0;
756
757 printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
758
759 retval=ParseXML(file,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
760
761 printf_last("Read: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
762
763 free(way_nodes);
764
765 free(relation_nodes);
766 free(relation_ways);
767 free(relation_relations);
768
769 return(retval);
770 }
771
772
773 /*++++++++++++++++++++++++++++++++++++++
774 Parse an OSC XML file (from planet download).
775
776 int ParseOSC Returns 0 if OK or something else in case of an error.
777
778 FILE *file The file to read from.
779
780 NodesX *OSMNodes The data structure of nodes to fill in.
781
782 SegmentsX *OSMSegments The data structure of segments to fill in.
783
784 WaysX *OSMWays The data structure of ways to fill in.
785
786 RelationsX *OSMRelations The data structure of relations to fill in.
787 ++++++++++++++++++++++++++++++++++++++*/
788
789 int ParseOSC(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
790 {
791 int retval;
792
793 /* Copy the function parameters and initialise the variables. */
794
795 nodes=OSMNodes;
796 segments=OSMSegments;
797 ways=OSMWays;
798 relations=OSMRelations;
799
800 way_nodes=(node_t*)malloc(256*sizeof(node_t));
801
802 relation_nodes =(node_t *)malloc(256*sizeof(node_t));
803 relation_ways =(way_t *)malloc(256*sizeof(way_t));
804 relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
805
806 /* Parse the file */
807
808 nnodes=0,nways=0,nrelations=0;
809
810 printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
811
812 retval=ParseXML(file,xml_osc_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
813
814 printf_last("Read: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
815
816 free(way_nodes);
817
818 free(relation_nodes);
819 free(relation_ways);
820 free(relation_relations);
821
822 return(retval);
823 }
824
825
826 /*++++++++++++++++++++++++++++++++++++++
827 Process the tags associated with a node.
828
829 TagList *tags The list of node tags.
830
831 node_t id The id of the node.
832
833 double latitude The latitude of the node.
834
835 double longitude The longitude of the node.
836 ++++++++++++++++++++++++++++++++++++++*/
837
838 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
839 {
840 transports_t allow=Transports_ALL;
841 nodeflags_t flags=0;
842 int i;
843
844 /* Delete */
845
846 if(mode==MODE_DELETE)
847 {
848 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED);
849
850 return;
851 }
852
853 /* Parse the tags */
854
855 for(i=0;i<tags->ntags;i++)
856 {
857 int recognised=0;
858 char *k=tags->k[i];
859 char *v=tags->v[i];
860
861 switch(*k)
862 {
863 case 'b':
864 if(!strcmp(k,"bicycle"))
865 {
866 if(ISFALSE(v))
867 allow&=~Transports_Bicycle;
868 else if(!ISTRUE(v))
869 logerror("Node %"Pnode_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",id,v);
870 recognised=1; break;
871 }
872
873 break;
874
875 case 'f':
876 if(!strcmp(k,"foot"))
877 {
878 if(ISFALSE(v))
879 allow&=~Transports_Foot;
880 else if(!ISTRUE(v))
881 logerror("Node %"Pnode_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'yes'.\n",id,v);
882 recognised=1; break;
883 }
884
885 break;
886
887 case 'g':
888 if(!strcmp(k,"goods"))
889 {
890 if(ISFALSE(v))
891 allow&=~Transports_Goods;
892 else if(!ISTRUE(v))
893 logerror("Node %"Pnode_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'yes'.\n",id,v);
894 recognised=1; break;
895 }
896
897 break;
898
899 case 'h':
900 if(!strcmp(k,"highway"))
901 if(!strcmp(v,"mini_roundabout"))
902 {
903 flags|=NODE_MINIRNDBT;
904 recognised=1; break;
905 }
906
907 if(!strcmp(k,"horse"))
908 {
909 if(ISFALSE(v))
910 allow&=~Transports_Horse;
911 else if(!ISTRUE(v))
912 logerror("Node %"Pnode_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'yes'.\n",id,v);
913 recognised=1; break;
914 }
915
916 if(!strcmp(k,"hgv"))
917 {
918 if(ISFALSE(v))
919 allow&=~Transports_HGV;
920 else if(!ISTRUE(v))
921 logerror("Node %"Pnode_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
922 recognised=1; break;
923 }
924
925 break;
926
927 case 'm':
928 if(!strcmp(k,"moped"))
929 {
930 if(ISFALSE(v))
931 allow&=~Transports_Moped;
932 else if(!ISTRUE(v))
933 logerror("Node %"Pnode_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'yes'.\n",id,v);
934 recognised=1; break;
935 }
936
937 if(!strcmp(k,"motorbike"))
938 {
939 if(ISFALSE(v))
940 allow&=~Transports_Motorbike;
941 else if(!ISTRUE(v))
942 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'yes'.\n",id,v);
943 recognised=1; break;
944 }
945
946 if(!strcmp(k,"motorcar"))
947 {
948 if(ISFALSE(v))
949 allow&=~Transports_Motorcar;
950 else if(!ISTRUE(v))
951 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",id,v);
952 recognised=1; break;
953 }
954
955 break;
956
957 case 'p':
958 if(!strcmp(k,"psv"))
959 {
960 if(ISFALSE(v))
961 allow&=~Transports_PSV;
962 else if(!ISTRUE(v))
963 logerror("Node %"Pnode_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
964 recognised=1; break;
965 }
966
967 break;
968
969 case 'w':
970 if(!strcmp(k,"wheelchair"))
971 {
972 if(ISFALSE(v))
973 allow&=~Transports_Wheelchair;
974 else if(!ISTRUE(v))
975 logerror("Node %"Pnode_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",id,v);
976 recognised=1; break;
977 }
978
979 break;
980
981 default:
982 break;
983 }
984
985 if(!recognised)
986 logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
987 }
988
989 /* Create the node */
990
991 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags);
992 }
993
994
995 /*++++++++++++++++++++++++++++++++++++++
996 Process the tags associated with a way.
997
998 TagList *tags The list of way tags.
999
1000 way_t id The id of the way.
1001 ++++++++++++++++++++++++++++++++++++++*/
1002
1003 static void process_way_tags(TagList *tags,way_t id)
1004 {
1005 Way way={0};
1006 segflags_t oneway=0,area=0;
1007 int roundabout=0;
1008 char *name=NULL,*ref=NULL,*refname=NULL;
1009 int i;
1010
1011 /* Delete */
1012
1013 if(mode==MODE_DELETE || mode==MODE_MODIFY)
1014 {
1015 way.type=WAY_DELETED;
1016
1017 AppendWayList(ways,id,&way,"");
1018
1019 way.type=0;
1020
1021 AppendSegmentList(segments,id,NO_NODE_ID,NO_NODE_ID,0,0);
1022 }
1023
1024 if(mode==MODE_DELETE)
1025 return;
1026
1027 /* Sanity check */
1028
1029 if(way_nnodes==0)
1030 {
1031 logerror("Way %"Pway_t" has no nodes.\n",id);
1032 return;
1033 }
1034
1035 if(way_nnodes==1)
1036 {
1037 logerror("Way %"Pway_t" has only one node.\n",id);
1038 return;
1039 }
1040
1041 /* Parse the tags - just look for highway */
1042
1043 for(i=0;i<tags->ntags;i++)
1044 {
1045 char *k=tags->k[i];
1046 char *v=tags->v[i];
1047
1048 if(!strcmp(k,"highway"))
1049 {
1050 way.type=HighwayType(v);
1051
1052 if(way.type==Way_Count)
1053 logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",id,v);
1054 }
1055 }
1056
1057 /* Don't continue if this is not a highway (bypass error logging) */
1058
1059 if(way.type==0 || way.type==Way_Count)
1060 return;
1061
1062 /* Parse the tags - look for the others */
1063
1064 for(i=0;i<tags->ntags;i++)
1065 {
1066 int recognised=0;
1067 char *k=tags->k[i];
1068 char *v=tags->v[i];
1069
1070 switch(*k)
1071 {
1072 case 'a':
1073 if(!strcmp(k,"area"))
1074 {
1075 if(ISTRUE(v))
1076 area=SEGMENT_AREA;
1077 else if(!ISFALSE(v))
1078 logerror("Way %"Pway_t" has an unrecognised tag value 'area' = '%s' (after tagging rules); using 'no'.\n",id,v);
1079 recognised=1; break;
1080 }
1081
1082 break;
1083
1084 case 'b':
1085 if(!strcmp(k,"bicycle"))
1086 {
1087 if(ISTRUE(v))
1088 way.allow|=Transports_Bicycle;
1089 else if(!ISFALSE(v))
1090 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'no'.\n",id,v);
1091 recognised=1; break;
1092 }
1093
1094 if(!strcmp(k,"bicycleroute"))
1095 {
1096 if(ISTRUE(v))
1097 way.props|=Properties_BicycleRoute;
1098 else if(!ISFALSE(v))
1099 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1100 recognised=1; break;
1101 }
1102
1103 if(!strcmp(k,"bridge"))
1104 {
1105 if(ISTRUE(v))
1106 way.props|=Properties_Bridge;
1107 else if(!ISFALSE(v))
1108 logerror("Way %"Pway_t" has an unrecognised tag value 'bridge' = '%s' (after tagging rules); using 'no'.\n",id,v);
1109 recognised=1; break;
1110 }
1111
1112 break;
1113
1114 case 'f':
1115 if(!strcmp(k,"foot"))
1116 {
1117 if(ISTRUE(v))
1118 way.allow|=Transports_Foot;
1119 else if(!ISFALSE(v))
1120 logerror("Way %"Pway_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'no'.\n",id,v);
1121 recognised=1; break;
1122 }
1123
1124 if(!strcmp(k,"footroute"))
1125 {
1126 if(ISTRUE(v))
1127 way.props|=Properties_FootRoute;
1128 else if(!ISFALSE(v))
1129 logerror("Way %"Pway_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1130 recognised=1; break;
1131 }
1132
1133 break;
1134
1135 case 'g':
1136 if(!strcmp(k,"goods"))
1137 {
1138 if(ISTRUE(v))
1139 way.allow|=Transports_Goods;
1140 else if(!ISFALSE(v))
1141 logerror("Way %"Pway_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'no'.\n",id,v);
1142 recognised=1; break;
1143 }
1144
1145 break;
1146
1147 case 'h':
1148 if(!strcmp(k,"highway"))
1149 {recognised=1; break;}
1150
1151 if(!strcmp(k,"horse"))
1152 {
1153 if(ISTRUE(v))
1154 way.allow|=Transports_Horse;
1155 else if(!ISFALSE(v))
1156 logerror("Way %"Pway_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'no'.\n",id,v);
1157 recognised=1; break;
1158 }
1159
1160 if(!strcmp(k,"hgv"))
1161 {
1162 if(ISTRUE(v))
1163 way.allow|=Transports_HGV;
1164 else if(!ISFALSE(v))
1165 logerror("Way %"Pway_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1166 recognised=1; break;
1167 }
1168
1169 break;
1170
1171 case 'm':
1172 if(!strncmp(k,"max",3))
1173 {
1174 if(!strcmp(k+3,"speed"))
1175 {
1176 way.speed=kph_to_speed(parse_speed(id,k,v));
1177 recognised=1; break;
1178 }
1179
1180 if(!strcmp(k+3,"weight"))
1181 {
1182 way.weight=tonnes_to_weight(parse_weight(id,k,v));
1183 recognised=1; break;
1184 }
1185
1186 if(!strcmp(k+3,"height"))
1187 {
1188 way.height=metres_to_height(parse_length(id,k,v));
1189 recognised=1; break;
1190 }
1191
1192 if(!strcmp(k+3,"width"))
1193 {
1194 way.width=metres_to_height(parse_length(id,k,v));
1195 recognised=1; break;
1196 }
1197
1198 if(!strcmp(k+3,"length"))
1199 {
1200 way.length=metres_to_height(parse_length(id,k,v));
1201 recognised=1; break;
1202 }
1203 }
1204
1205 if(!strcmp(k,"moped"))
1206 {
1207 if(ISTRUE(v))
1208 way.allow|=Transports_Moped;
1209 else if(!ISFALSE(v))
1210 logerror("Way %"Pway_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'no'.\n",id,v);
1211 recognised=1; break;
1212 }
1213
1214 if(!strcmp(k,"motorbike"))
1215 {
1216 if(ISTRUE(v))
1217 way.allow|=Transports_Motorbike;
1218 else if(!ISFALSE(v))
1219 logerror("Way %"Pway_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'no'.\n",id,v);
1220 recognised=1; break;
1221 }
1222
1223 if(!strcmp(k,"motorcar"))
1224 {
1225 if(ISTRUE(v))
1226 way.allow|=Transports_Motorcar;
1227 else if(!ISFALSE(v))
1228 logerror("Way %"Pway_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'no'.\n",id,v);
1229 recognised=1; break;
1230 }
1231
1232 if(!strcmp(k,"multilane"))
1233 {
1234 if(ISTRUE(v))
1235 way.props|=Properties_Multilane;
1236 else if(!ISFALSE(v))
1237 logerror("Way %"Pway_t" has an unrecognised tag value 'multilane' = '%s' (after tagging rules); using 'no'.\n",id,v);
1238 recognised=1; break;
1239 }
1240
1241 break;
1242
1243 case 'n':
1244 if(!strcmp(k,"name"))
1245 {
1246 name=v;
1247 recognised=1; break;
1248 }
1249
1250 break;
1251
1252 case 'o':
1253 if(!strcmp(k,"oneway"))
1254 {
1255 if(ISTRUE(v))
1256 oneway=ONEWAY_1TO2;
1257 else if(!strcmp(v,"-1"))
1258 oneway=ONEWAY_2TO1;
1259 else if(!ISFALSE(v))
1260 logerror("Way %"Pway_t" has an unrecognised tag value 'oneway' = '%s' (after tagging rules); using 'no'.\n",id,v);
1261 recognised=1; break;
1262 }
1263
1264 break;
1265
1266 case 'p':
1267 if(!strcmp(k,"paved"))
1268 {
1269 if(ISTRUE(v))
1270 way.props|=Properties_Paved;
1271 else if(!ISFALSE(v))
1272 logerror("Way %"Pway_t" has an unrecognised tag value 'paved' = '%s' (after tagging rules); using 'no'.\n",id,v);
1273 recognised=1; break;
1274 }
1275
1276 if(!strcmp(k,"psv"))
1277 {
1278 if(ISTRUE(v))
1279 way.allow|=Transports_PSV;
1280 else if(!ISFALSE(v))
1281 logerror("Way %"Pway_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1282 recognised=1; break;
1283 }
1284
1285 break;
1286
1287 case 'r':
1288 if(!strcmp(k,"ref"))
1289 {
1290 ref=v;
1291 recognised=1; break;
1292 }
1293
1294 if(!strcmp(k,"roundabout"))
1295 {
1296 if(ISTRUE(v))
1297 roundabout=1;
1298 else if(!ISFALSE(v))
1299 logerror("Way %"Pway_t" has an unrecognised tag value 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v);
1300 recognised=1; break;
1301 }
1302
1303 break;
1304
1305 case 't':
1306 if(!strcmp(k,"tunnel"))
1307 {
1308 if(ISTRUE(v))
1309 way.props|=Properties_Tunnel;
1310 else if(!ISFALSE(v))
1311 logerror("Way %"Pway_t" has an unrecognised tag value 'tunnel' = '%s' (after tagging rules); using 'no'.\n",id,v);
1312 recognised=1; break;
1313 }
1314
1315 break;
1316
1317 case 'w':
1318 if(!strcmp(k,"wheelchair"))
1319 {
1320 if(ISTRUE(v))
1321 way.allow|=Transports_Wheelchair;
1322 else if(!ISFALSE(v))
1323 logerror("Way %"Pway_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",id,v);
1324 recognised=1; break;
1325 }
1326
1327 break;
1328
1329 default:
1330 break;
1331 }
1332
1333 if(!recognised)
1334 logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1335 }
1336
1337 /* Create the way */
1338
1339 if(!way.allow)
1340 return;
1341
1342 if(oneway)
1343 way.type|=Way_OneWay;
1344
1345 if(roundabout)
1346 way.type|=Way_Roundabout;
1347
1348 if(ref && name)
1349 {
1350 refname=(char*)malloc(strlen(ref)+strlen(name)+4);
1351 sprintf(refname,"%s (%s)",name,ref);
1352 }
1353 else if(ref && !name)
1354 refname=ref;
1355 else if(!ref && name)
1356 refname=name;
1357 else /* if(!ref && !name) */
1358 refname="";
1359
1360 AppendWayList(ways,id,&way,refname);
1361
1362 if(ref && name)
1363 free(refname);
1364
1365 for(i=1;i<way_nnodes;i++)
1366 {
1367 node_t from=way_nodes[i-1];
1368 node_t to =way_nodes[i];
1369
1370 AppendSegmentList(segments,id,from,to,0,area+oneway);
1371 }
1372 }
1373
1374
1375 /*++++++++++++++++++++++++++++++++++++++
1376 Process the tags associated with a relation.
1377
1378 TagList *tags The list of relation tags.
1379
1380 relation_t id The id of the relation.
1381 ++++++++++++++++++++++++++++++++++++++*/
1382
1383 static void process_relation_tags(TagList *tags,relation_t id)
1384 {
1385 transports_t routes=Transports_None;
1386 transports_t except=Transports_None;
1387 int relation_turn_restriction=0;
1388 TurnRestriction restriction=TurnRestrict_None;
1389 int i;
1390
1391 /* Delete */
1392
1393 if(mode==MODE_DELETE || mode==MODE_MODIFY)
1394 {
1395 AppendRouteRelationList(relations,id,RELATION_DELETED,
1396 relation_ways,relation_nways,
1397 relation_relations,relation_nrelations);
1398
1399 AppendTurnRelationList(relations,id,
1400 relation_from,relation_to,relation_via,
1401 restriction,RELATION_DELETED);
1402 }
1403
1404 if(mode==MODE_DELETE)
1405 return;
1406
1407 /* Sanity check */
1408
1409 if(relation_nnodes==0 && relation_nways==0 && relation_nrelations==0)
1410 {
1411 logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",id);
1412 return;
1413 }
1414
1415 /* Parse the tags */
1416
1417 for(i=0;i<tags->ntags;i++)
1418 {
1419 int recognised=0;
1420 char *k=tags->k[i];
1421 char *v=tags->v[i];
1422
1423 switch(*k)
1424 {
1425 case 'b':
1426 if(!strcmp(k,"bicycleroute"))
1427 {
1428 if(ISTRUE(v))
1429 routes|=Transports_Bicycle;
1430 else if(!ISFALSE(v))
1431 logerror("Relation %"Prelation_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1432 recognised=1; break;
1433 }
1434
1435 break;
1436
1437 case 'e':
1438 if(!strcmp(k,"except"))
1439 {
1440 for(i=1;i<Transport_Count;i++)
1441 if(strstr(v,TransportName(i)))
1442 except|=TRANSPORTS(i);
1443
1444 if(except==Transports_None)
1445 logerror("Relation %"Prelation_t" has an unrecognised tag value 'except' = '%s' (after tagging rules); ignoring it.\n",id,v);
1446
1447 recognised=1; break;
1448 }
1449
1450 break;
1451
1452 case 'f':
1453 if(!strcmp(k,"footroute"))
1454 {
1455 if(ISTRUE(v))
1456 routes|=Transports_Foot;
1457 else if(!ISFALSE(v))
1458 logerror("Relation %"Prelation_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1459 recognised=1; break;
1460 }
1461
1462 break;
1463
1464 case 'r':
1465 if(!strcmp(k,"restriction"))
1466 {
1467 if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn;
1468 if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn;
1469 if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn;
1470 if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on;
1471 if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn;
1472 if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn;
1473 if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on;
1474
1475 if(restriction==TurnRestrict_None)
1476 logerror("Relation %"Prelation_t" has an unrecognised tag value 'restriction' = '%s' (after tagging rules); ignoring it.\n",id,v);
1477
1478 recognised=1; break;
1479 }
1480
1481 break;
1482
1483 case 't':
1484 if(!strcmp(k,"type"))
1485 {
1486 if(!strcmp(v,"restriction"))
1487 relation_turn_restriction=1;
1488
1489 /* Don't log an error for relations of types that we don't handle - there are so many */
1490 recognised=1; break;
1491 }
1492
1493 break;
1494
1495 default:
1496 break;
1497 }
1498
1499 if(!recognised)
1500 logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1501 }
1502
1503 /* Create the route relation (must store all relations that have ways or
1504 relations even if they are not routes because they might be referenced by
1505 other relations that are routes) */
1506
1507 if((relation_nways || relation_nrelations) && !relation_turn_restriction)
1508 AppendRouteRelationList(relations,id,routes,
1509 relation_ways,relation_nways,
1510 relation_relations,relation_nrelations);
1511
1512 /* Create the turn restriction relation. */
1513
1514 if(relation_turn_restriction && restriction!=TurnRestrict_None)
1515 {
1516 if(relation_from==NO_WAY_ID)
1517 logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",id);
1518 else if(relation_to==NO_WAY_ID)
1519 logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",id);
1520 else if(relation_via==NO_NODE_ID)
1521 logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",id);
1522 else
1523 AppendTurnRelationList(relations,id,
1524 relation_from,relation_to,relation_via,
1525 restriction,except);
1526 }
1527 }
1528
1529
1530 /*++++++++++++++++++++++++++++++++++++++
1531 Convert a string containing a speed into a double precision.
1532
1533 double parse_speed Returns the speed in km/h if it can be parsed.
1534
1535 way_t id The way being processed.
1536
1537 const char *k The tag key.
1538
1539 const char *v The tag value.
1540 ++++++++++++++++++++++++++++++++++++++*/
1541
1542 static double parse_speed(way_t id,const char *k,const char *v)
1543 {
1544 char *ev;
1545 double value=strtod(v,&ev);
1546
1547 if(v==ev)
1548 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1549 else
1550 {
1551 while(isspace(*ev)) ev++;
1552
1553 if(!strcmp(ev,"mph"))
1554 return(1.609*value);
1555
1556 if(*ev==0 || !strcmp(ev,"kph"))
1557 return(value);
1558
1559 logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1560 }
1561
1562 return(0);
1563 }
1564
1565
1566 /*++++++++++++++++++++++++++++++++++++++
1567 Convert a string containing a weight into a double precision.
1568
1569 double parse_weight Returns the weight in tonnes if it can be parsed.
1570
1571 way_t id The way being processed.
1572
1573 const char *k The tag key.
1574
1575 const char *v The tag value.
1576 ++++++++++++++++++++++++++++++++++++++*/
1577
1578 static double parse_weight(way_t id,const char *k,const char *v)
1579 {
1580 char *ev;
1581 double value=strtod(v,&ev);
1582
1583 if(v==ev)
1584 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1585 else
1586 {
1587 while(isspace(*ev)) ev++;
1588
1589 if(!strcmp(ev,"kg"))
1590 return(value/1000.0);
1591
1592 if(*ev==0 || !strcmp(ev,"T") || !strcmp(ev,"t")
1593 || !strcmp(ev,"ton") || !strcmp(ev,"tons")
1594 || !strcmp(ev,"tonne") || !strcmp(ev,"tonnes"))
1595 return(value);
1596
1597 logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1598 }
1599
1600 return(0);
1601 }
1602
1603
1604 /*++++++++++++++++++++++++++++++++++++++
1605 Convert a string containing a length into a double precision.
1606
1607 double parse_length Returns the length in metres if it can be parsed.
1608
1609 way_t id The way being processed.
1610
1611 const char *k The tag key.
1612
1613 const char *v The tag value.
1614 ++++++++++++++++++++++++++++++++++++++*/
1615
1616 static double parse_length(way_t id,const char *k,const char *v)
1617 {
1618 char *ev;
1619 double value=strtod(v,&ev);
1620
1621 if(v==ev)
1622 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1623 else
1624 {
1625 int en=0;
1626 int feet=0,inches=0;
1627
1628 if(sscanf(v,"%d' %d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1629 return((feet+(double)inches/12.0)*0.254);
1630
1631 if(sscanf(v,"%d'%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1632 return((feet+(double)inches/12.0)*0.254);
1633
1634 if(sscanf(v,"%d'-%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1635 return((feet+(double)inches/12.0)*0.254);
1636
1637 if(sscanf(v,"%d - %d%n",&feet,&inches,&en)==2 && en && !v[en])
1638 return((feet+(double)inches/12.0)*0.254);
1639
1640 if(sscanf(v,"%d ft %d in%n",&feet,&inches,&en)==2 && en && !v[en])
1641 return((feet+(double)inches/12.0)*0.254);
1642
1643 if(sscanf(v,"%d feet %d inches%n",&feet,&inches,&en)==2 && en && !v[en])
1644 return((feet+(double)inches/12.0)*0.254);
1645
1646 if(!strcmp(ev,"'"))
1647 return(feet*0.254);
1648
1649 while(isspace(*ev)) ev++;
1650
1651 if(!strcmp(ev,"ft") || !strcmp(ev,"feet"))
1652 return(value*0.254);
1653
1654 if(*ev==0 || !strcmp(ev,"m") || !strcmp(ev,"metre") || !strcmp(ev,"metres"))
1655 return(value);
1656
1657 logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1658 }
1659
1660 return(0);
1661 }

Properties

Name Value
cvs:description OSM XML file parser.