Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/osmparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1226 - (hide annotations) (download) (as text)
Mon Dec 24 11:02:10 2012 UTC (12 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 29895 byte(s)
The PBF format does not support change files (the 'visible' part of the info
message is only for historical data and not for changes).

1 amb 2 /***************************************
2 amb 1221 OSM file parser (either JOSM or planet)
3 amb 151
4     Part of the Routino routing software.
5 amb 2 ******************/ /******************
6 amb 955 This file Copyright 2008-2012 Andrew M. Bishop
7 amb 2
8 amb 151 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 amb 2 ***************************************/
21    
22    
23     #include <stdlib.h>
24     #include <string.h>
25     #include <ctype.h>
26    
27 amb 199 #include "typesx.h"
28 amb 109 #include "nodesx.h"
29     #include "segmentsx.h"
30     #include "waysx.h"
31 amb 498 #include "relationsx.h"
32    
33 amb 955 #include "osmparser.h"
34 amb 394 #include "tagging.h"
35 amb 519 #include "logging.h"
36 amb 26
37 amb 519
38 amb 394 /* Macros */
39 amb 2
40 amb 680 /*+ Checks if a value in the XML is one of the allowed values for true. +*/
41 amb 812 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
42 amb 297
43 amb 812 /*+ Checks if a value in the XML is one of the allowed values for false. +*/
44     #define ISFALSE(xx) (!strcmp(xx,"false") || !strcmp(xx,"no") || !strcmp(xx,"0"))
45 amb 298
46 amb 1221 /* Global variables */
47 amb 812
48 amb 1221 node_t *osmparser_way_nodes=NULL;
49     int osmparser_way_nnodes=0;
50 amb 1140
51 amb 1221 node_t *osmparser_relation_nodes=NULL;
52     int osmparser_relation_nnodes=0;
53     way_t *osmparser_relation_ways=NULL;
54     int osmparser_relation_nways=0;
55     relation_t *osmparser_relation_relations=NULL;
56     int osmparser_relation_nrelations=0;
57     way_t osmparser_relation_from=NO_WAY_ID;
58     way_t osmparser_relation_to=NO_WAY_ID;
59     node_t osmparser_relation_via=NO_NODE_ID;
60 amb 1140
61 amb 394 /* Local variables */
62    
63 amb 498 static NodesX *nodes;
64     static SegmentsX *segments;
65     static WaysX *ways;
66     static RelationsX *relations;
67 amb 394
68 amb 228 /* Local functions */
69    
70 amb 812 static double parse_speed(way_t id,const char *k,const char *v);
71     static double parse_weight(way_t id,const char *k,const char *v);
72     static double parse_length(way_t id,const char *k,const char *v);
73 amb 2
74 amb 812
75 amb 1204 /*++++++++++++++++++++++++++++++++++++++
76 amb 1221 Parse an OSM XML file (from JOSM or planet download).
77 amb 1140
78 amb 1221 int ParseOSMFile Returns 0 if OK or something else in case of an error.
79 amb 1140
80 amb 1221 int fd The file descriptor of the file to read from.
81 amb 1140
82 amb 1221 NodesX *OSMNodes The data structure of nodes to fill in.
83 amb 2
84 amb 1221 SegmentsX *OSMSegments The data structure of segments to fill in.
85 amb 2
86 amb 1221 WaysX *OSMWays The data structure of ways to fill in.
87 amb 2
88 amb 1221 RelationsX *OSMRelations The data structure of relations to fill in.
89 amb 1204 ++++++++++++++++++++++++++++++++++++++*/
90    
91 amb 1221 int ParseOSMFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
92 amb 1204 {
93 amb 1221 int retval;
94 amb 1204
95 amb 1221 /* Copy the function parameters and initialise the variables */
96 amb 1204
97 amb 1221 nodes=OSMNodes;
98     segments=OSMSegments;
99     ways=OSMWays;
100     relations=OSMRelations;
101 amb 1204
102 amb 1221 osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t));
103 amb 1204
104 amb 1221 osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t));
105     osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t));
106     osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
107 amb 1204
108 amb 1221 /* Parse the file */
109 amb 1204
110 amb 1221 retval=ParseXML(fd,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
111 amb 1204
112 amb 1221 /* Free the variables */
113 amb 1204
114 amb 1221 free(osmparser_way_nodes);
115 amb 1204
116 amb 1221 free(osmparser_relation_nodes);
117     free(osmparser_relation_ways);
118     free(osmparser_relation_relations);
119 amb 1204
120 amb 1221 return(retval);
121 amb 1204 }
122    
123    
124     /*++++++++++++++++++++++++++++++++++++++
125 amb 1221 Parse an OSC XML file (from planet download).
126 amb 2
127 amb 1221 int ParseOSCFile Returns 0 if OK or something else in case of an error.
128 amb 2
129 amb 1186 int fd The file descriptor of the file to read from.
130 amb 394
131 amb 498 NodesX *OSMNodes The data structure of nodes to fill in.
132 amb 394
133 amb 498 SegmentsX *OSMSegments The data structure of segments to fill in.
134 amb 394
135 amb 498 WaysX *OSMWays The data structure of ways to fill in.
136    
137     RelationsX *OSMRelations The data structure of relations to fill in.
138 amb 2 ++++++++++++++++++++++++++++++++++++++*/
139    
140 amb 1221 int ParseOSCFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
141 amb 2 {
142 amb 394 int retval;
143 amb 2
144 amb 1221 /* Copy the function parameters and initialise the variables */
145 amb 2
146 amb 394 nodes=OSMNodes;
147     segments=OSMSegments;
148     ways=OSMWays;
149 amb 498 relations=OSMRelations;
150 amb 394
151 amb 1221 osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t));
152 amb 498
153 amb 1221 osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t));
154     osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t));
155     osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
156 amb 498
157     /* Parse the file */
158    
159 amb 1221 retval=ParseXML(fd,xml_osc_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
160 amb 394
161 amb 1221 /* Free the variables */
162 amb 394
163 amb 1221 free(osmparser_way_nodes);
164 amb 394
165 amb 1221 free(osmparser_relation_nodes);
166     free(osmparser_relation_ways);
167     free(osmparser_relation_relations);
168 amb 394
169     return(retval);
170     }
171    
172    
173     /*++++++++++++++++++++++++++++++++++++++
174 amb 1221 Parse a PBF format OSM file (from planet download).
175 amb 1140
176 amb 1221 int ParsePBFFile Returns 0 if OK or something else in case of an error.
177 amb 1140
178 amb 1186 int fd The file descriptor of the file to read from.
179 amb 1140
180     NodesX *OSMNodes The data structure of nodes to fill in.
181    
182     SegmentsX *OSMSegments The data structure of segments to fill in.
183    
184     WaysX *OSMWays The data structure of ways to fill in.
185    
186     RelationsX *OSMRelations The data structure of relations to fill in.
187     ++++++++++++++++++++++++++++++++++++++*/
188    
189 amb 1226 int ParsePBFFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
190 amb 1140 {
191     int retval;
192    
193 amb 1221 /* Copy the function parameters and initialise the variables */
194 amb 1140
195     nodes=OSMNodes;
196     segments=OSMSegments;
197     ways=OSMWays;
198     relations=OSMRelations;
199    
200 amb 1221 osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t));
201 amb 1140
202 amb 1221 osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t));
203     osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t));
204     osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
205 amb 1140
206     /* Parse the file */
207    
208 amb 1226 retval=ParsePBF(fd);
209 amb 1140
210 amb 1221 /* Free the variables */
211 amb 1140
212 amb 1221 free(osmparser_way_nodes);
213 amb 1140
214 amb 1221 free(osmparser_relation_nodes);
215     free(osmparser_relation_ways);
216     free(osmparser_relation_relations);
217 amb 1140
218     return(retval);
219     }
220    
221    
222     /*++++++++++++++++++++++++++++++++++++++
223 amb 469 Process the tags associated with a node.
224    
225     TagList *tags The list of node tags.
226    
227     node_t id The id of the node.
228    
229     double latitude The latitude of the node.
230    
231     double longitude The longitude of the node.
232 amb 1221
233     int mode The mode of operation to take (create, modify, delete).
234 amb 469 ++++++++++++++++++++++++++++++++++++++*/
235    
236 amb 1221 void ProcessNodeTags(TagList *tags,node_t id,double latitude,double longitude,int mode)
237 amb 469 {
238 amb 529 transports_t allow=Transports_ALL;
239 amb 1165 nodeflags_t flags=0;
240 amb 469 int i;
241    
242 amb 1140 /* Delete */
243    
244     if(mode==MODE_DELETE)
245     {
246 amb 1161 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED);
247 amb 1140
248     return;
249     }
250    
251 amb 469 /* Parse the tags */
252    
253     for(i=0;i<tags->ntags;i++)
254     {
255 amb 1025 int recognised=0;
256 amb 469 char *k=tags->k[i];
257     char *v=tags->v[i];
258    
259     switch(*k)
260     {
261     case 'b':
262     if(!strcmp(k,"bicycle"))
263 amb 812 {
264     if(ISFALSE(v))
265 amb 529 allow&=~Transports_Bicycle;
266 amb 812 else if(!ISTRUE(v))
267 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",id,v);
268 amb 1025 recognised=1; break;
269 amb 812 }
270 amb 469
271     break;
272    
273     case 'f':
274     if(!strcmp(k,"foot"))
275 amb 812 {
276     if(ISFALSE(v))
277 amb 529 allow&=~Transports_Foot;
278 amb 812 else if(!ISTRUE(v))
279 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'yes'.\n",id,v);
280 amb 1025 recognised=1; break;
281 amb 812 }
282 amb 469
283     break;
284    
285     case 'g':
286     if(!strcmp(k,"goods"))
287 amb 812 {
288     if(ISFALSE(v))
289 amb 529 allow&=~Transports_Goods;
290 amb 812 else if(!ISTRUE(v))
291 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'yes'.\n",id,v);
292 amb 1025 recognised=1; break;
293 amb 812 }
294 amb 469
295     break;
296    
297     case 'h':
298 amb 537 if(!strcmp(k,"highway"))
299     if(!strcmp(v,"mini_roundabout"))
300 amb 1025 {
301 amb 538 flags|=NODE_MINIRNDBT;
302 amb 1025 recognised=1; break;
303     }
304 amb 537
305 amb 469 if(!strcmp(k,"horse"))
306 amb 812 {
307     if(ISFALSE(v))
308 amb 529 allow&=~Transports_Horse;
309 amb 812 else if(!ISTRUE(v))
310 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'yes'.\n",id,v);
311 amb 1025 recognised=1; break;
312 amb 812 }
313 amb 469
314     if(!strcmp(k,"hgv"))
315 amb 812 {
316     if(ISFALSE(v))
317 amb 529 allow&=~Transports_HGV;
318 amb 812 else if(!ISTRUE(v))
319 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
320 amb 1025 recognised=1; break;
321 amb 812 }
322 amb 469
323     break;
324    
325     case 'm':
326     if(!strcmp(k,"moped"))
327 amb 812 {
328     if(ISFALSE(v))
329 amb 529 allow&=~Transports_Moped;
330 amb 812 else if(!ISTRUE(v))
331 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'yes'.\n",id,v);
332 amb 1025 recognised=1; break;
333 amb 812 }
334 amb 469
335     if(!strcmp(k,"motorbike"))
336 amb 812 {
337     if(ISFALSE(v))
338 amb 529 allow&=~Transports_Motorbike;
339 amb 812 else if(!ISTRUE(v))
340 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'yes'.\n",id,v);
341 amb 1025 recognised=1; break;
342 amb 812 }
343 amb 469
344     if(!strcmp(k,"motorcar"))
345 amb 812 {
346     if(ISFALSE(v))
347 amb 529 allow&=~Transports_Motorcar;
348 amb 812 else if(!ISTRUE(v))
349 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",id,v);
350 amb 1025 recognised=1; break;
351 amb 812 }
352 amb 469
353     break;
354    
355     case 'p':
356     if(!strcmp(k,"psv"))
357 amb 812 {
358     if(ISFALSE(v))
359 amb 529 allow&=~Transports_PSV;
360 amb 812 else if(!ISTRUE(v))
361 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
362 amb 1025 recognised=1; break;
363 amb 812 }
364 amb 469
365     break;
366    
367     case 'w':
368     if(!strcmp(k,"wheelchair"))
369 amb 812 {
370     if(ISFALSE(v))
371 amb 529 allow&=~Transports_Wheelchair;
372 amb 812 else if(!ISTRUE(v))
373 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",id,v);
374 amb 1025 recognised=1; break;
375 amb 812 }
376 amb 469
377     break;
378    
379     default:
380 amb 1025 break;
381     }
382    
383     if(!recognised)
384 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
385 amb 469 }
386    
387     /* Create the node */
388    
389 amb 1161 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags);
390 amb 469 }
391    
392    
393     /*++++++++++++++++++++++++++++++++++++++
394 amb 394 Process the tags associated with a way.
395    
396     TagList *tags The list of way tags.
397    
398     way_t id The id of the way.
399 amb 1221
400     int mode The mode of operation to take (create, modify, delete).
401 amb 394 ++++++++++++++++++++++++++++++++++++++*/
402    
403 amb 1221 void ProcessWayTags(TagList *tags,way_t id,int mode)
404 amb 394 {
405 amb 1137 Way way={0};
406 amb 1168 distance_t oneway=0,area=0;
407 amb 1137 int roundabout=0;
408 amb 812 char *name=NULL,*ref=NULL,*refname=NULL;
409 amb 1173 int i,j;
410 amb 394
411 amb 1140 /* Delete */
412    
413 amb 1159 if(mode==MODE_DELETE || mode==MODE_MODIFY)
414 amb 1140 {
415     way.type=WAY_DELETED;
416    
417 amb 1161 AppendWayList(ways,id,&way,"");
418 amb 1140
419 amb 1174 way.type=Highway_None;
420 amb 1154
421 amb 1168 AppendSegmentList(segments,id,NO_NODE_ID,NO_NODE_ID,0);
422 amb 1145 }
423 amb 1140
424 amb 1145 if(mode==MODE_DELETE)
425 amb 1140 return;
426    
427 amb 1125 /* Sanity check */
428    
429 amb 1221 if(osmparser_way_nnodes==0)
430 amb 1125 {
431     logerror("Way %"Pway_t" has no nodes.\n",id);
432     return;
433     }
434    
435 amb 1221 if(osmparser_way_nnodes==1)
436 amb 1125 {
437     logerror("Way %"Pway_t" has only one node.\n",id);
438     return;
439     }
440    
441 amb 833 /* Parse the tags - just look for highway */
442 amb 394
443     for(i=0;i<tags->ntags;i++)
444 amb 2 {
445 amb 394 char *k=tags->k[i];
446     char *v=tags->v[i];
447 amb 2
448 amb 833 if(!strcmp(k,"highway"))
449     {
450     way.type=HighwayType(v);
451    
452 amb 1174 if(way.type==Highway_None)
453 amb 833 logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",id,v);
454 amb 1174
455     break;
456 amb 833 }
457     }
458    
459     /* Don't continue if this is not a highway (bypass error logging) */
460    
461 amb 1174 if(way.type==Highway_None)
462 amb 833 return;
463    
464     /* Parse the tags - look for the others */
465    
466     for(i=0;i<tags->ntags;i++)
467     {
468 amb 1025 int recognised=0;
469 amb 833 char *k=tags->k[i];
470     char *v=tags->v[i];
471    
472 amb 394 switch(*k)
473     {
474 amb 914 case 'a':
475     if(!strcmp(k,"area"))
476     {
477     if(ISTRUE(v))
478 amb 1137 area=SEGMENT_AREA;
479 amb 914 else if(!ISFALSE(v))
480     logerror("Way %"Pway_t" has an unrecognised tag value 'area' = '%s' (after tagging rules); using 'no'.\n",id,v);
481 amb 1025 recognised=1; break;
482 amb 914 }
483    
484     break;
485    
486 amb 394 case 'b':
487     if(!strcmp(k,"bicycle"))
488 amb 812 {
489 amb 394 if(ISTRUE(v))
490 amb 813 way.allow|=Transports_Bicycle;
491 amb 812 else if(!ISFALSE(v))
492 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'no'.\n",id,v);
493 amb 1025 recognised=1; break;
494 amb 812 }
495 amb 394
496 amb 498 if(!strcmp(k,"bicycleroute"))
497 amb 812 {
498 amb 498 if(ISTRUE(v))
499     way.props|=Properties_BicycleRoute;
500 amb 812 else if(!ISFALSE(v))
501 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
502 amb 1025 recognised=1; break;
503 amb 812 }
504 amb 498
505 amb 394 if(!strcmp(k,"bridge"))
506 amb 812 {
507 amb 394 if(ISTRUE(v))
508     way.props|=Properties_Bridge;
509 amb 812 else if(!ISFALSE(v))
510 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bridge' = '%s' (after tagging rules); using 'no'.\n",id,v);
511 amb 1025 recognised=1; break;
512 amb 812 }
513 amb 394
514 amb 2 break;
515 amb 394
516     case 'f':
517     if(!strcmp(k,"foot"))
518 amb 812 {
519 amb 394 if(ISTRUE(v))
520 amb 813 way.allow|=Transports_Foot;
521 amb 812 else if(!ISFALSE(v))
522 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'no'.\n",id,v);
523 amb 1025 recognised=1; break;
524 amb 812 }
525 amb 394
526 amb 498 if(!strcmp(k,"footroute"))
527 amb 812 {
528 amb 498 if(ISTRUE(v))
529     way.props|=Properties_FootRoute;
530 amb 812 else if(!ISFALSE(v))
531 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
532 amb 1025 recognised=1; break;
533 amb 812 }
534 amb 498
535 amb 394 break;
536    
537     case 'g':
538     if(!strcmp(k,"goods"))
539 amb 812 {
540 amb 394 if(ISTRUE(v))
541 amb 529 way.allow|=Transports_Goods;
542 amb 812 else if(!ISFALSE(v))
543 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'no'.\n",id,v);
544 amb 1025 recognised=1; break;
545 amb 812 }
546 amb 394
547     break;
548    
549     case 'h':
550     if(!strcmp(k,"highway"))
551 amb 1025 {recognised=1; break;}
552 amb 394
553     if(!strcmp(k,"horse"))
554 amb 812 {
555 amb 394 if(ISTRUE(v))
556 amb 529 way.allow|=Transports_Horse;
557 amb 812 else if(!ISFALSE(v))
558 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'no'.\n",id,v);
559 amb 1025 recognised=1; break;
560 amb 812 }
561 amb 394
562     if(!strcmp(k,"hgv"))
563 amb 812 {
564 amb 394 if(ISTRUE(v))
565 amb 529 way.allow|=Transports_HGV;
566 amb 812 else if(!ISFALSE(v))
567 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'no'.\n",id,v);
568 amb 1025 recognised=1; break;
569 amb 812 }
570 amb 394
571     break;
572    
573     case 'm':
574 amb 1025 if(!strncmp(k,"max",3))
575     {
576     if(!strcmp(k+3,"speed"))
577     {
578     way.speed=kph_to_speed(parse_speed(id,k,v));
579     recognised=1; break;
580     }
581 amb 394
582 amb 1025 if(!strcmp(k+3,"weight"))
583     {
584     way.weight=tonnes_to_weight(parse_weight(id,k,v));
585     recognised=1; break;
586     }
587 amb 394
588 amb 1025 if(!strcmp(k+3,"height"))
589     {
590     way.height=metres_to_height(parse_length(id,k,v));
591     recognised=1; break;
592     }
593 amb 394
594 amb 1025 if(!strcmp(k+3,"width"))
595     {
596     way.width=metres_to_height(parse_length(id,k,v));
597     recognised=1; break;
598     }
599 amb 394
600 amb 1025 if(!strcmp(k+3,"length"))
601     {
602     way.length=metres_to_height(parse_length(id,k,v));
603     recognised=1; break;
604     }
605     }
606 amb 394
607     if(!strcmp(k,"moped"))
608 amb 812 {
609 amb 394 if(ISTRUE(v))
610 amb 529 way.allow|=Transports_Moped;
611 amb 812 else if(!ISFALSE(v))
612 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'no'.\n",id,v);
613 amb 1025 recognised=1; break;
614 amb 812 }
615 amb 394
616     if(!strcmp(k,"motorbike"))
617 amb 812 {
618 amb 394 if(ISTRUE(v))
619 amb 529 way.allow|=Transports_Motorbike;
620 amb 812 else if(!ISFALSE(v))
621 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'no'.\n",id,v);
622 amb 1025 recognised=1; break;
623 amb 812 }
624 amb 394
625     if(!strcmp(k,"motorcar"))
626 amb 812 {
627 amb 394 if(ISTRUE(v))
628 amb 529 way.allow|=Transports_Motorcar;
629 amb 812 else if(!ISFALSE(v))
630 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'no'.\n",id,v);
631 amb 1025 recognised=1; break;
632 amb 812 }
633 amb 394
634     if(!strcmp(k,"multilane"))
635 amb 812 {
636 amb 394 if(ISTRUE(v))
637     way.props|=Properties_Multilane;
638 amb 812 else if(!ISFALSE(v))
639 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'multilane' = '%s' (after tagging rules); using 'no'.\n",id,v);
640 amb 1025 recognised=1; break;
641 amb 812 }
642 amb 394
643     break;
644    
645     case 'n':
646     if(!strcmp(k,"name"))
647 amb 1025 {
648 amb 394 name=v;
649 amb 1025 recognised=1; break;
650     }
651 amb 394
652     break;
653    
654     case 'o':
655     if(!strcmp(k,"oneway"))
656     {
657     if(ISTRUE(v))
658 amb 1137 oneway=ONEWAY_1TO2;
659 amb 394 else if(!strcmp(v,"-1"))
660 amb 1137 oneway=ONEWAY_2TO1;
661 amb 812 else if(!ISFALSE(v))
662 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'oneway' = '%s' (after tagging rules); using 'no'.\n",id,v);
663 amb 1025 recognised=1; break;
664 amb 394 }
665    
666     break;
667    
668     case 'p':
669     if(!strcmp(k,"paved"))
670 amb 812 {
671 amb 394 if(ISTRUE(v))
672     way.props|=Properties_Paved;
673 amb 812 else if(!ISFALSE(v))
674 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'paved' = '%s' (after tagging rules); using 'no'.\n",id,v);
675 amb 1025 recognised=1; break;
676 amb 812 }
677 amb 394
678     if(!strcmp(k,"psv"))
679 amb 812 {
680 amb 394 if(ISTRUE(v))
681 amb 529 way.allow|=Transports_PSV;
682 amb 812 else if(!ISFALSE(v))
683 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'no'.\n",id,v);
684 amb 1025 recognised=1; break;
685 amb 812 }
686 amb 394
687     break;
688    
689     case 'r':
690     if(!strcmp(k,"ref"))
691 amb 1025 {
692 amb 394 ref=v;
693 amb 1025 recognised=1; break;
694     }
695 amb 394
696 amb 923 if(!strcmp(k,"roundabout"))
697     {
698     if(ISTRUE(v))
699     roundabout=1;
700     else if(!ISFALSE(v))
701     logerror("Way %"Pway_t" has an unrecognised tag value 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v);
702 amb 1025 recognised=1; break;
703 amb 923 }
704    
705 amb 394 break;
706    
707     case 't':
708     if(!strcmp(k,"tunnel"))
709 amb 812 {
710 amb 394 if(ISTRUE(v))
711     way.props|=Properties_Tunnel;
712 amb 812 else if(!ISFALSE(v))
713 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'tunnel' = '%s' (after tagging rules); using 'no'.\n",id,v);
714 amb 1025 recognised=1; break;
715 amb 812 }
716 amb 394
717     break;
718    
719     case 'w':
720     if(!strcmp(k,"wheelchair"))
721 amb 812 {
722 amb 394 if(ISTRUE(v))
723 amb 529 way.allow|=Transports_Wheelchair;
724 amb 812 else if(!ISFALSE(v))
725 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",id,v);
726 amb 1025 recognised=1; break;
727 amb 812 }
728 amb 394
729     break;
730    
731     default:
732 amb 1025 break;
733     }
734    
735     if(!recognised)
736 amb 813 logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
737 amb 2 }
738    
739 amb 394 /* Create the way */
740 amb 2
741 amb 812 if(!way.allow)
742     return;
743    
744     if(oneway)
745 amb 1174 way.type|=Highway_OneWay;
746 amb 394
747 amb 923 if(roundabout)
748 amb 1174 way.type|=Highway_Roundabout;
749 amb 923
750 amb 812 if(ref && name)
751     {
752     refname=(char*)malloc(strlen(ref)+strlen(name)+4);
753     sprintf(refname,"%s (%s)",name,ref);
754     }
755     else if(ref && !name)
756     refname=ref;
757     else if(!ref && name)
758     refname=name;
759     else /* if(!ref && !name) */
760     refname="";
761 amb 394
762 amb 1161 AppendWayList(ways,id,&way,refname);
763 amb 394
764 amb 812 if(ref && name)
765     free(refname);
766 amb 394
767 amb 1221 for(i=1;i<osmparser_way_nnodes;i++)
768 amb 812 {
769 amb 1221 node_t from=osmparser_way_nodes[i-1];
770     node_t to =osmparser_way_nodes[i];
771 amb 812
772 amb 1173 for(j=1;j<i;j++)
773     {
774 amb 1221 node_t n1=osmparser_way_nodes[j-1];
775     node_t n2=osmparser_way_nodes[j];
776 amb 1173
777     if((n1==from && n2==to) || (n2==from && n1==to))
778     logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" in way %"Pway_t" is duplicated.\n",n1,n2,id);
779     }
780    
781 amb 1168 AppendSegmentList(segments,id,from,to,area+oneway);
782 amb 394 }
783 amb 2 }
784 amb 498
785    
786     /*++++++++++++++++++++++++++++++++++++++
787     Process the tags associated with a relation.
788    
789     TagList *tags The list of relation tags.
790    
791     relation_t id The id of the relation.
792 amb 1221
793     int mode The mode of operation to take (create, modify, delete).
794 amb 498 ++++++++++++++++++++++++++++++++++++++*/
795    
796 amb 1221 void ProcessRelationTags(TagList *tags,relation_t id,int mode)
797 amb 498 {
798 amb 529 transports_t routes=Transports_None;
799 amb 540 transports_t except=Transports_None;
800     int relation_turn_restriction=0;
801 amb 541 TurnRestriction restriction=TurnRestrict_None;
802 amb 498 int i;
803    
804 amb 1140 /* Delete */
805    
806 amb 1152 if(mode==MODE_DELETE || mode==MODE_MODIFY)
807 amb 1140 {
808 amb 1161 AppendRouteRelationList(relations,id,RELATION_DELETED,
809 amb 1221 osmparser_relation_ways,osmparser_relation_nways,
810     osmparser_relation_relations,osmparser_relation_nrelations);
811 amb 1140
812 amb 1161 AppendTurnRelationList(relations,id,
813 amb 1221 osmparser_relation_from,osmparser_relation_to,osmparser_relation_via,
814 amb 1161 restriction,RELATION_DELETED);
815 amb 1152 }
816 amb 1140
817 amb 1152 if(mode==MODE_DELETE)
818 amb 1140 return;
819    
820 amb 1125 /* Sanity check */
821    
822 amb 1221 if(osmparser_relation_nnodes==0 && osmparser_relation_nways==0 && osmparser_relation_nrelations==0)
823 amb 1125 {
824     logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",id);
825     return;
826     }
827    
828 amb 498 /* Parse the tags */
829    
830     for(i=0;i<tags->ntags;i++)
831     {
832 amb 1025 int recognised=0;
833 amb 498 char *k=tags->k[i];
834     char *v=tags->v[i];
835    
836     switch(*k)
837     {
838     case 'b':
839     if(!strcmp(k,"bicycleroute"))
840 amb 812 {
841 amb 498 if(ISTRUE(v))
842 amb 529 routes|=Transports_Bicycle;
843 amb 812 else if(!ISFALSE(v))
844 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
845 amb 1025 recognised=1; break;
846 amb 812 }
847 amb 498
848     break;
849    
850 amb 540 case 'e':
851     if(!strcmp(k,"except"))
852 amb 812 {
853 amb 540 for(i=1;i<Transport_Count;i++)
854 amb 876 if(strstr(v,TransportName(i)))
855 amb 540 except|=TRANSPORTS(i);
856    
857 amb 812 if(except==Transports_None)
858 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'except' = '%s' (after tagging rules); ignoring it.\n",id,v);
859 amb 1025
860     recognised=1; break;
861 amb 812 }
862    
863 amb 540 break;
864    
865 amb 498 case 'f':
866     if(!strcmp(k,"footroute"))
867 amb 812 {
868 amb 498 if(ISTRUE(v))
869 amb 529 routes|=Transports_Foot;
870 amb 812 else if(!ISFALSE(v))
871 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
872 amb 1025 recognised=1; break;
873 amb 812 }
874 amb 498
875     break;
876    
877 amb 540 case 'r':
878     if(!strcmp(k,"restriction"))
879     {
880 amb 541 if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn;
881     if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn;
882     if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn;
883     if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on;
884     if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn;
885     if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn;
886     if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on;
887 amb 812
888     if(restriction==TurnRestrict_None)
889 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'restriction' = '%s' (after tagging rules); ignoring it.\n",id,v);
890 amb 1025
891     recognised=1; break;
892 amb 540 }
893    
894     break;
895    
896     case 't':
897     if(!strcmp(k,"type"))
898 amb 1025 {
899 amb 540 if(!strcmp(v,"restriction"))
900     relation_turn_restriction=1;
901 amb 1025
902     /* Don't log an error for relations of types that we don't handle - there are so many */
903     recognised=1; break;
904     }
905    
906 amb 540 break;
907    
908 amb 498 default:
909 amb 1025 break;
910     }
911    
912     if(!recognised)
913 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
914 amb 498 }
915    
916 amb 505 /* Create the route relation (must store all relations that have ways or
917     relations even if they are not routes because they might be referenced by
918     other relations that are routes) */
919 amb 498
920 amb 1221 if((osmparser_relation_nways || osmparser_relation_nrelations) && !relation_turn_restriction)
921 amb 1161 AppendRouteRelationList(relations,id,routes,
922 amb 1221 osmparser_relation_ways,osmparser_relation_nways,
923     osmparser_relation_relations,osmparser_relation_nrelations);
924 amb 540
925     /* Create the turn restriction relation. */
926    
927 amb 812 if(relation_turn_restriction && restriction!=TurnRestrict_None)
928     {
929 amb 1221 if(osmparser_relation_from==NO_WAY_ID)
930 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",id);
931 amb 1221 else if(osmparser_relation_to==NO_WAY_ID)
932 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",id);
933 amb 1221 else if(osmparser_relation_via==NO_NODE_ID)
934 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",id);
935 amb 812 else
936 amb 1161 AppendTurnRelationList(relations,id,
937 amb 1221 osmparser_relation_from,osmparser_relation_to,osmparser_relation_via,
938 amb 1161 restriction,except);
939 amb 812 }
940 amb 498 }
941 amb 812
942    
943     /*++++++++++++++++++++++++++++++++++++++
944     Convert a string containing a speed into a double precision.
945    
946     double parse_speed Returns the speed in km/h if it can be parsed.
947    
948     way_t id The way being processed.
949    
950     const char *k The tag key.
951    
952     const char *v The tag value.
953     ++++++++++++++++++++++++++++++++++++++*/
954    
955     static double parse_speed(way_t id,const char *k,const char *v)
956     {
957     char *ev;
958     double value=strtod(v,&ev);
959    
960     if(v==ev)
961 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
962 amb 812 else
963     {
964     while(isspace(*ev)) ev++;
965    
966     if(!strcmp(ev,"mph"))
967     return(1.609*value);
968 amb 813
969     if(*ev==0 || !strcmp(ev,"kph"))
970 amb 812 return(value);
971 amb 813
972     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
973 amb 812 }
974    
975     return(0);
976     }
977    
978    
979     /*++++++++++++++++++++++++++++++++++++++
980     Convert a string containing a weight into a double precision.
981    
982     double parse_weight Returns the weight in tonnes if it can be parsed.
983    
984     way_t id The way being processed.
985    
986     const char *k The tag key.
987    
988     const char *v The tag value.
989     ++++++++++++++++++++++++++++++++++++++*/
990    
991     static double parse_weight(way_t id,const char *k,const char *v)
992     {
993     char *ev;
994     double value=strtod(v,&ev);
995    
996     if(v==ev)
997 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
998 amb 812 else
999     {
1000     while(isspace(*ev)) ev++;
1001    
1002     if(!strcmp(ev,"kg"))
1003     return(value/1000.0);
1004 amb 813
1005 amb 825 if(*ev==0 || !strcmp(ev,"T") || !strcmp(ev,"t")
1006     || !strcmp(ev,"ton") || !strcmp(ev,"tons")
1007     || !strcmp(ev,"tonne") || !strcmp(ev,"tonnes"))
1008 amb 812 return(value);
1009 amb 813
1010     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1011 amb 812 }
1012    
1013     return(0);
1014     }
1015    
1016    
1017     /*++++++++++++++++++++++++++++++++++++++
1018     Convert a string containing a length into a double precision.
1019    
1020     double parse_length Returns the length in metres if it can be parsed.
1021    
1022     way_t id The way being processed.
1023    
1024     const char *k The tag key.
1025    
1026     const char *v The tag value.
1027     ++++++++++++++++++++++++++++++++++++++*/
1028    
1029     static double parse_length(way_t id,const char *k,const char *v)
1030     {
1031     char *ev;
1032     double value=strtod(v,&ev);
1033    
1034     if(v==ev)
1035 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1036 amb 812 else
1037     {
1038 amb 813 int en=0;
1039     int feet=0,inches=0;
1040 amb 812
1041 amb 813 if(sscanf(v,"%d' %d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1042 amb 812 return((feet+(double)inches/12.0)*0.254);
1043 amb 813
1044 amb 1127 if(sscanf(v,"%d'%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1045     return((feet+(double)inches/12.0)*0.254);
1046    
1047     if(sscanf(v,"%d'-%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1048     return((feet+(double)inches/12.0)*0.254);
1049    
1050 amb 813 if(sscanf(v,"%d - %d%n",&feet,&inches,&en)==2 && en && !v[en])
1051     return((feet+(double)inches/12.0)*0.254);
1052    
1053     if(sscanf(v,"%d ft %d in%n",&feet,&inches,&en)==2 && en && !v[en])
1054     return((feet+(double)inches/12.0)*0.254);
1055    
1056 amb 825 if(sscanf(v,"%d feet %d inches%n",&feet,&inches,&en)==2 && en && !v[en])
1057     return((feet+(double)inches/12.0)*0.254);
1058    
1059     if(!strcmp(ev,"'"))
1060 amb 812 return(feet*0.254);
1061 amb 813
1062     while(isspace(*ev)) ev++;
1063    
1064     if(!strcmp(ev,"ft") || !strcmp(ev,"feet"))
1065 amb 812 return(value*0.254);
1066 amb 813
1067 amb 825 if(*ev==0 || !strcmp(ev,"m") || !strcmp(ev,"metre") || !strcmp(ev,"metres"))
1068 amb 812 return(value);
1069 amb 813
1070     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1071 amb 812 }
1072    
1073     return(0);
1074     }

Properties

Name Value
cvs:description OSM XML file parser.