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 1168 - (hide annotations) (download) (as text)
Wed Nov 21 09:20:57 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 48337 byte(s)
Revert r1164 - some super-segments are longer than 65535 metres even if no
individual segment is.

1 amb 2 /***************************************
2     OSM XML 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 <stdio.h>
24     #include <stdlib.h>
25     #include <string.h>
26     #include <ctype.h>
27    
28 amb 199 #include "typesx.h"
29 amb 109 #include "nodesx.h"
30     #include "segmentsx.h"
31     #include "waysx.h"
32 amb 498 #include "relationsx.h"
33    
34 amb 955 #include "osmparser.h"
35    
36 amb 394 #include "xmlparse.h"
37     #include "tagging.h"
38 amb 2
39 amb 519 #include "logging.h"
40 amb 26
41 amb 519
42 amb 394 /* Macros */
43 amb 2
44 amb 680 /*+ Checks if a value in the XML is one of the allowed values for true. +*/
45 amb 812 #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1"))
46 amb 297
47 amb 812 /*+ 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 amb 298
50 amb 812
51 amb 1140 /* Constants */
52    
53 amb 1145 #define MODE_NORMAL 3
54 amb 1140 #define MODE_CREATE 2
55     #define MODE_MODIFY 1
56     #define MODE_DELETE -1
57    
58    
59 amb 394 /* Local variables */
60    
61 amb 1145 static int mode=MODE_NORMAL;
62 amb 1140
63 amb 790 static index_t nnodes=0;
64     static index_t nways=0;
65     static index_t nrelations=0;
66    
67 amb 401 static TagList *current_tags=NULL;
68 amb 394
69     static node_t *way_nodes=NULL;
70     static int way_nnodes=0;
71    
72 amb 498 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 amb 755 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 amb 394
82 amb 498 static NodesX *nodes;
83     static SegmentsX *segments;
84     static WaysX *ways;
85     static RelationsX *relations;
86 amb 394
87 amb 498
88 amb 228 /* Local functions */
89    
90 amb 469 static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
91 amb 394 static void process_way_tags(TagList *tags,way_t id);
92 amb 498 static void process_relation_tags(TagList *tags,relation_t id);
93 amb 2
94 amb 812 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 amb 2
98 amb 812
99 amb 394 /* The XML tag processing function prototypes */
100 amb 2
101 amb 394 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
102 amb 919 static int osmType_function(const char *_tag_,int _type_,const char *version);
103 amb 1140 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 amb 394 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 amb 498 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
110 amb 394 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 amb 990 static int changesetType_function(const char *_tag_,int _type_);
113 amb 394 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
114 amb 399 //static int boundType_function(const char *_tag_,int _type_);
115 amb 394 //static int boundsType_function(const char *_tag_,int _type_);
116 amb 2
117 amb 26
118 amb 394 /* The XML tag definitions */
119 amb 26
120 amb 394 /*+ The boundsType type tag. +*/
121     static xmltag boundsType_tag=
122     {"bounds",
123     0, {NULL},
124     NULL,
125     {NULL}};
126 amb 26
127 amb 399 /*+ The boundType type tag. +*/
128     static xmltag boundType_tag=
129     {"bound",
130     0, {NULL},
131     NULL,
132     {NULL}};
133    
134 amb 394 /*+ The tagType type tag. +*/
135     static xmltag tagType_tag=
136     {"tag",
137     2, {"k","v"},
138     tagType_function,
139     {NULL}};
140 amb 75
141 amb 990 /*+ The changesetType type tag. +*/
142     static xmltag changesetType_tag=
143     {"changeset",
144     0, {NULL},
145     changesetType_function,
146     {&tagType_tag,NULL}};
147    
148 amb 394 /*+ The nodeType type tag. +*/
149     static xmltag nodeType_tag=
150     {"node",
151     3, {"id","lat","lon"},
152     nodeType_function,
153     {&tagType_tag,NULL}};
154 amb 2
155 amb 394 /*+ The ndType type tag. +*/
156     static xmltag ndType_tag=
157     {"nd",
158     1, {"ref"},
159     ndType_function,
160     {NULL}};
161 amb 2
162 amb 394 /*+ The memberType type tag. +*/
163     static xmltag memberType_tag=
164     {"member",
165     3, {"type","ref","role"},
166 amb 498 memberType_function,
167 amb 394 {NULL}};
168 amb 227
169 amb 394 /*+ The wayType type tag. +*/
170     static xmltag wayType_tag=
171     {"way",
172     1, {"id"},
173     wayType_function,
174     {&ndType_tag,&tagType_tag,NULL}};
175 amb 2
176 amb 394 /*+ The relationType type tag. +*/
177     static xmltag relationType_tag=
178     {"relation",
179     1, {"id"},
180     relationType_function,
181     {&memberType_tag,&tagType_tag,NULL}};
182 amb 2
183 amb 1140 /*+ 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 amb 394 /*+ The osmType type tag. +*/
212     static xmltag osmType_tag=
213     {"osm",
214 amb 919 1, {"version"},
215     osmType_function,
216 amb 990 {&boundsType_tag,&boundType_tag,&changesetType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
217 amb 2
218 amb 394 /*+ The xmlDeclaration type tag. +*/
219     static xmltag xmlDeclaration_tag=
220     {"xml",
221     2, {"version","encoding"},
222     NULL,
223     {NULL}};
224 amb 2
225    
226 amb 1140 /*+ The complete set of tags at the top level for OSM. +*/
227     static xmltag *xml_osm_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
228 amb 2
229 amb 1140 /*+ The complete set of tags at the top level for OSC. +*/
230     static xmltag *xml_osc_toplevel_tags[]={&xmlDeclaration_tag,&osmChangeType_tag,NULL};
231 amb 2
232 amb 1140
233 amb 394 /* The XML tag processing functions */
234 amb 2
235 amb 159
236 amb 394 /*++++++++++++++++++++++++++++++++++++++
237     The function that is called when the boundsType XSD type is seen
238 amb 2
239 amb 394 int boundsType_function Returns 0 if no error occured or something else otherwise.
240 amb 2
241 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
242 amb 203
243 amb 394 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 amb 2
246 amb 394 //static int boundsType_function(const char *_tag_,int _type_)
247     //{
248     // return(0);
249     //}
250 amb 2
251 amb 6
252 amb 394 /*++++++++++++++++++++++++++++++++++++++
253 amb 399 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 amb 394 The function that is called when the tagType XSD type is seen
270 amb 2
271 amb 394 int tagType_function Returns 0 if no error occured or something else otherwise.
272 amb 314
273 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
274 amb 2
275 amb 394 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 amb 30
277 amb 394 const char *k The contents of the 'k' attribute (or NULL if not defined).
278 amb 30
279 amb 394 const char *v The contents of the 'v' attribute (or NULL if not defined).
280     ++++++++++++++++++++++++++++++++++++++*/
281 amb 30
282 amb 394 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
283     {
284 amb 401 if(_type_&XMLPARSE_TAG_START && current_tags)
285 amb 394 {
286     XMLPARSE_ASSERT_STRING(_tag_,k);
287     XMLPARSE_ASSERT_STRING(_tag_,v);
288 amb 30
289 amb 401 AppendTag(current_tags,k,v);
290 amb 394 }
291 amb 262
292 amb 394 return(0);
293     }
294 amb 308
295 amb 313
296 amb 394 /*++++++++++++++++++++++++++++++++++++++
297 amb 990 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 amb 394 The function that is called when the nodeType XSD type is seen
316 amb 313
317 amb 394 int nodeType_function Returns 0 if no error occured or something else otherwise.
318 amb 298
319 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
320 amb 298
321 amb 394 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 amb 298
323 amb 394 const char *id The contents of the 'id' attribute (or NULL if not defined).
324 amb 298
325 amb 394 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
326 amb 298
327 amb 394 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
328     ++++++++++++++++++++++++++++++++++++++*/
329 amb 2
330 amb 394 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
331     {
332 amb 469 static node_t node_id;
333     static double latitude,longitude;
334    
335 amb 394 if(_type_&XMLPARSE_TAG_START)
336     {
337 amb 775 long long llid;
338 amb 825
339 amb 394 nnodes++;
340    
341 amb 757 if(!(nnodes%10000))
342 amb 791 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
343 amb 2
344 amb 469 current_tags=NewTagList();
345    
346 amb 394 /* Handle the node information */
347 amb 2
348 amb 775 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
349     node_id=(node_t)llid;
350 amb 1166 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 amb 775
352 amb 1140 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 amb 469 }
358 amb 2
359 amb 469 if(_type_&XMLPARSE_TAG_END)
360     {
361 amb 826 TagList *result=ApplyTaggingRules(&NodeRules,current_tags,node_id);
362 amb 2
363 amb 469 process_node_tags(result,node_id,latitude,longitude);
364    
365 amb 990 DeleteTagList(current_tags); current_tags=NULL;
366 amb 469 DeleteTagList(result);
367 amb 394 }
368 amb 2
369 amb 394 return(0);
370     }
371 amb 2
372    
373 amb 394 /*++++++++++++++++++++++++++++++++++++++
374     The function that is called when the ndType XSD type is seen
375 amb 313
376 amb 394 int ndType_function Returns 0 if no error occured or something else otherwise.
377 amb 2
378 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
379 amb 297
380 amb 394 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 amb 2
382 amb 394 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
383     ++++++++++++++++++++++++++++++++++++++*/
384 amb 2
385 amb 394 static int ndType_function(const char *_tag_,int _type_,const char *ref)
386     {
387     if(_type_&XMLPARSE_TAG_START)
388     {
389 amb 775 long long llid;
390 amb 394 node_t node_id;
391 amb 2
392 amb 775 XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need long long conversion */
393     node_id=(node_t)llid;
394 amb 1166 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 amb 298
396 amb 498 if(way_nnodes && (way_nnodes%256)==0)
397 amb 394 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
398 amb 8
399 amb 394 way_nodes[way_nnodes++]=node_id;
400     }
401 amb 51
402 amb 394 return(0);
403     }
404 amb 308
405 amb 298
406 amb 394 /*++++++++++++++++++++++++++++++++++++++
407     The function that is called when the memberType XSD type is seen
408 amb 298
409 amb 394 int memberType_function Returns 0 if no error occured or something else otherwise.
410 amb 298
411 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
412 amb 183
413 amb 394 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 amb 298
415 amb 394 const char *type The contents of the 'type' attribute (or NULL if not defined).
416 amb 183
417 amb 394 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
418 amb 298
419 amb 394 const char *role The contents of the 'role' attribute (or NULL if not defined).
420     ++++++++++++++++++++++++++++++++++++++*/
421 amb 183
422 amb 498 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 amb 775 long long llid;
427    
428 amb 498 XMLPARSE_ASSERT_STRING(_tag_,type);
429 amb 775 XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need long long conversion */
430 amb 298
431 amb 498 if(!strcmp(type,"node"))
432     {
433 amb 775 node_t node_id;
434 amb 298
435 amb 775 node_id=(node_t)llid;
436 amb 1166 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 amb 775
438 amb 498 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 amb 540
443     if(role)
444     {
445     if(!strcmp(role,"via"))
446     relation_via=node_id;
447     }
448 amb 498 }
449     else if(!strcmp(type,"way"))
450     {
451 amb 775 way_t way_id;
452 amb 498
453 amb 775 way_id=(way_t)llid;
454 amb 1166 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 amb 775
456 amb 498 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 amb 540
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 amb 498 }
469     else if(!strcmp(type,"relation"))
470     {
471 amb 775 relation_t relation_id;
472 amb 498
473 amb 775 relation_id=(relation_t)llid;
474 amb 1166 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 amb 775
476 amb 498 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 amb 394 /*++++++++++++++++++++++++++++++++++++++
488     The function that is called when the wayType XSD type is seen
489 amb 298
490 amb 394 int wayType_function Returns 0 if no error occured or something else otherwise.
491 amb 298
492 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
493 amb 51
494 amb 394 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 amb 51
496 amb 394 const char *id The contents of the 'id' attribute (or NULL if not defined).
497     ++++++++++++++++++++++++++++++++++++++*/
498 amb 51
499 amb 394 static int wayType_function(const char *_tag_,int _type_,const char *id)
500     {
501     static way_t way_id;
502 amb 299
503 amb 394 if(_type_&XMLPARSE_TAG_START)
504     {
505 amb 775 long long llid;
506    
507 amb 394 nways++;
508 amb 51
509 amb 394 if(!(nways%1000))
510 amb 791 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
511 amb 51
512 amb 401 current_tags=NewTagList();
513 amb 498
514 amb 394 way_nnodes=0;
515 amb 298
516 amb 394 /* Handle the way information */
517 amb 313
518 amb 775 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
519    
520     way_id=(way_t)llid;
521 amb 1166 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 amb 394 }
523 amb 196
524 amb 394 if(_type_&XMLPARSE_TAG_END)
525     {
526 amb 826 TagList *result=ApplyTaggingRules(&WayRules,current_tags,way_id);
527 amb 314
528 amb 394 process_way_tags(result,way_id);
529 amb 2
530 amb 990 DeleteTagList(current_tags); current_tags=NULL;
531 amb 394 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 amb 498 static relation_t relation_id;
553    
554 amb 394 if(_type_&XMLPARSE_TAG_START)
555     {
556 amb 775 long long llid;
557    
558 amb 394 nrelations++;
559    
560     if(!(nrelations%1000))
561 amb 791 printf_middle("Reading: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
562 amb 394
563 amb 498 current_tags=NewTagList();
564    
565     relation_nnodes=relation_nways=relation_nrelations=0;
566    
567 amb 755 relation_from=NO_WAY_ID;
568     relation_to=NO_WAY_ID;
569     relation_via=NO_NODE_ID;
570 amb 540
571 amb 498 /* Handle the relation information */
572    
573 amb 775 XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need long long conversion */
574    
575     relation_id=(relation_t)llid;
576 amb 1166 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 amb 2 }
578    
579 amb 498 if(_type_&XMLPARSE_TAG_END)
580     {
581 amb 826 TagList *result=ApplyTaggingRules(&RelationRules,current_tags,relation_id);
582 amb 2
583 amb 498 process_relation_tags(result,relation_id);
584    
585 amb 990 DeleteTagList(current_tags); current_tags=NULL;
586 amb 498 DeleteTagList(result);
587     }
588    
589 amb 2 return(0);
590     }
591    
592    
593     /*++++++++++++++++++++++++++++++++++++++
594 amb 1140 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 amb 394 The function that is called when the osmType XSD type is seen
676 amb 2
677 amb 394 int osmType_function Returns 0 if no error occured or something else otherwise.
678 amb 2
679 amb 394 const char *_tag_ Set to the name of the element tag that triggered this function call.
680 amb 2
681 amb 394 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 amb 919
683     const char *version The contents of the 'version' attribute (or NULL if not defined).
684 amb 394 ++++++++++++++++++++++++++++++++++++++*/
685    
686 amb 919 static int osmType_function(const char *_tag_,int _type_,const char *version)
687     {
688     if(_type_&XMLPARSE_TAG_START)
689     {
690 amb 1145 mode=MODE_NORMAL;
691 amb 1140
692 amb 919 if(!version || strcmp(version,"0.6"))
693     XMLPARSE_MESSAGE(_tag_,"Invalid value for 'version' (only '0.6' accepted)");
694     }
695 amb 394
696 amb 919 return(0);
697     }
698 amb 394
699 amb 919
700 amb 394 /*++++++++++++++++++++++++++++++++++++++
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 amb 2 FILE *file The file to read from.
726 amb 394
727 amb 498 NodesX *OSMNodes The data structure of nodes to fill in.
728 amb 394
729 amb 498 SegmentsX *OSMSegments The data structure of segments to fill in.
730 amb 394
731 amb 498 WaysX *OSMWays The data structure of ways to fill in.
732    
733     RelationsX *OSMRelations The data structure of relations to fill in.
734 amb 2 ++++++++++++++++++++++++++++++++++++++*/
735    
736 amb 498 int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
737 amb 2 {
738 amb 394 int retval;
739 amb 2
740 amb 498 /* Copy the function parameters and initialise the variables. */
741 amb 2
742 amb 394 nodes=OSMNodes;
743     segments=OSMSegments;
744     ways=OSMWays;
745 amb 498 relations=OSMRelations;
746 amb 394
747 amb 498 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 amb 394 nnodes=0,nways=0,nrelations=0;
756    
757 amb 519 printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
758 amb 394
759 amb 1140 retval=ParseXML(file,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
760 amb 394
761 amb 791 printf_last("Read: Lines=%llu Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,ParseXML_LineNumber(),nnodes,nways,nrelations);
762 amb 394
763 amb 796 free(way_nodes);
764    
765     free(relation_nodes);
766     free(relation_ways);
767     free(relation_relations);
768    
769 amb 394 return(retval);
770     }
771    
772    
773     /*++++++++++++++++++++++++++++++++++++++
774 amb 1140 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 amb 469 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 amb 529 transports_t allow=Transports_ALL;
841 amb 1165 nodeflags_t flags=0;
842 amb 469 int i;
843    
844 amb 1140 /* Delete */
845    
846     if(mode==MODE_DELETE)
847     {
848 amb 1161 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED);
849 amb 1140
850     return;
851     }
852    
853 amb 469 /* Parse the tags */
854    
855     for(i=0;i<tags->ntags;i++)
856     {
857 amb 1025 int recognised=0;
858 amb 469 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 amb 812 {
866     if(ISFALSE(v))
867 amb 529 allow&=~Transports_Bicycle;
868 amb 812 else if(!ISTRUE(v))
869 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",id,v);
870 amb 1025 recognised=1; break;
871 amb 812 }
872 amb 469
873     break;
874    
875     case 'f':
876     if(!strcmp(k,"foot"))
877 amb 812 {
878     if(ISFALSE(v))
879 amb 529 allow&=~Transports_Foot;
880 amb 812 else if(!ISTRUE(v))
881 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'yes'.\n",id,v);
882 amb 1025 recognised=1; break;
883 amb 812 }
884 amb 469
885     break;
886    
887     case 'g':
888     if(!strcmp(k,"goods"))
889 amb 812 {
890     if(ISFALSE(v))
891 amb 529 allow&=~Transports_Goods;
892 amb 812 else if(!ISTRUE(v))
893 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'yes'.\n",id,v);
894 amb 1025 recognised=1; break;
895 amb 812 }
896 amb 469
897     break;
898    
899     case 'h':
900 amb 537 if(!strcmp(k,"highway"))
901     if(!strcmp(v,"mini_roundabout"))
902 amb 1025 {
903 amb 538 flags|=NODE_MINIRNDBT;
904 amb 1025 recognised=1; break;
905     }
906 amb 537
907 amb 469 if(!strcmp(k,"horse"))
908 amb 812 {
909     if(ISFALSE(v))
910 amb 529 allow&=~Transports_Horse;
911 amb 812 else if(!ISTRUE(v))
912 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'yes'.\n",id,v);
913 amb 1025 recognised=1; break;
914 amb 812 }
915 amb 469
916     if(!strcmp(k,"hgv"))
917 amb 812 {
918     if(ISFALSE(v))
919 amb 529 allow&=~Transports_HGV;
920 amb 812 else if(!ISTRUE(v))
921 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
922 amb 1025 recognised=1; break;
923 amb 812 }
924 amb 469
925     break;
926    
927     case 'm':
928     if(!strcmp(k,"moped"))
929 amb 812 {
930     if(ISFALSE(v))
931 amb 529 allow&=~Transports_Moped;
932 amb 812 else if(!ISTRUE(v))
933 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'yes'.\n",id,v);
934 amb 1025 recognised=1; break;
935 amb 812 }
936 amb 469
937     if(!strcmp(k,"motorbike"))
938 amb 812 {
939     if(ISFALSE(v))
940 amb 529 allow&=~Transports_Motorbike;
941 amb 812 else if(!ISTRUE(v))
942 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'yes'.\n",id,v);
943 amb 1025 recognised=1; break;
944 amb 812 }
945 amb 469
946     if(!strcmp(k,"motorcar"))
947 amb 812 {
948     if(ISFALSE(v))
949 amb 529 allow&=~Transports_Motorcar;
950 amb 812 else if(!ISTRUE(v))
951 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",id,v);
952 amb 1025 recognised=1; break;
953 amb 812 }
954 amb 469
955     break;
956    
957     case 'p':
958     if(!strcmp(k,"psv"))
959 amb 812 {
960     if(ISFALSE(v))
961 amb 529 allow&=~Transports_PSV;
962 amb 812 else if(!ISTRUE(v))
963 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'yes'.\n",id,v);
964 amb 1025 recognised=1; break;
965 amb 812 }
966 amb 469
967     break;
968    
969     case 'w':
970     if(!strcmp(k,"wheelchair"))
971 amb 812 {
972     if(ISFALSE(v))
973 amb 529 allow&=~Transports_Wheelchair;
974 amb 812 else if(!ISTRUE(v))
975 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",id,v);
976 amb 1025 recognised=1; break;
977 amb 812 }
978 amb 469
979     break;
980    
981     default:
982 amb 1025 break;
983     }
984    
985     if(!recognised)
986 amb 813 logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
987 amb 469 }
988    
989     /* Create the node */
990    
991 amb 1161 AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags);
992 amb 469 }
993    
994    
995     /*++++++++++++++++++++++++++++++++++++++
996 amb 394 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 amb 1137 Way way={0};
1006 amb 1168 distance_t oneway=0,area=0;
1007 amb 1137 int roundabout=0;
1008 amb 812 char *name=NULL,*ref=NULL,*refname=NULL;
1009 amb 394 int i;
1010    
1011 amb 1140 /* Delete */
1012    
1013 amb 1159 if(mode==MODE_DELETE || mode==MODE_MODIFY)
1014 amb 1140 {
1015     way.type=WAY_DELETED;
1016    
1017 amb 1161 AppendWayList(ways,id,&way,"");
1018 amb 1140
1019 amb 1154 way.type=0;
1020    
1021 amb 1168 AppendSegmentList(segments,id,NO_NODE_ID,NO_NODE_ID,0);
1022 amb 1145 }
1023 amb 1140
1024 amb 1145 if(mode==MODE_DELETE)
1025 amb 1140 return;
1026    
1027 amb 1125 /* 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 amb 833 /* Parse the tags - just look for highway */
1042 amb 394
1043     for(i=0;i<tags->ntags;i++)
1044 amb 2 {
1045 amb 394 char *k=tags->k[i];
1046     char *v=tags->v[i];
1047 amb 2
1048 amb 833 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 amb 1025 int recognised=0;
1067 amb 833 char *k=tags->k[i];
1068     char *v=tags->v[i];
1069    
1070 amb 394 switch(*k)
1071     {
1072 amb 914 case 'a':
1073     if(!strcmp(k,"area"))
1074     {
1075     if(ISTRUE(v))
1076 amb 1137 area=SEGMENT_AREA;
1077 amb 914 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 amb 1025 recognised=1; break;
1080 amb 914 }
1081    
1082     break;
1083    
1084 amb 394 case 'b':
1085     if(!strcmp(k,"bicycle"))
1086 amb 812 {
1087 amb 394 if(ISTRUE(v))
1088 amb 813 way.allow|=Transports_Bicycle;
1089 amb 812 else if(!ISFALSE(v))
1090 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'no'.\n",id,v);
1091 amb 1025 recognised=1; break;
1092 amb 812 }
1093 amb 394
1094 amb 498 if(!strcmp(k,"bicycleroute"))
1095 amb 812 {
1096 amb 498 if(ISTRUE(v))
1097     way.props|=Properties_BicycleRoute;
1098 amb 812 else if(!ISFALSE(v))
1099 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1100 amb 1025 recognised=1; break;
1101 amb 812 }
1102 amb 498
1103 amb 394 if(!strcmp(k,"bridge"))
1104 amb 812 {
1105 amb 394 if(ISTRUE(v))
1106     way.props|=Properties_Bridge;
1107 amb 812 else if(!ISFALSE(v))
1108 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bridge' = '%s' (after tagging rules); using 'no'.\n",id,v);
1109 amb 1025 recognised=1; break;
1110 amb 812 }
1111 amb 394
1112 amb 2 break;
1113 amb 394
1114     case 'f':
1115     if(!strcmp(k,"foot"))
1116 amb 812 {
1117 amb 394 if(ISTRUE(v))
1118 amb 813 way.allow|=Transports_Foot;
1119 amb 812 else if(!ISFALSE(v))
1120 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'no'.\n",id,v);
1121 amb 1025 recognised=1; break;
1122 amb 812 }
1123 amb 394
1124 amb 498 if(!strcmp(k,"footroute"))
1125 amb 812 {
1126 amb 498 if(ISTRUE(v))
1127     way.props|=Properties_FootRoute;
1128 amb 812 else if(!ISFALSE(v))
1129 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1130 amb 1025 recognised=1; break;
1131 amb 812 }
1132 amb 498
1133 amb 394 break;
1134    
1135     case 'g':
1136     if(!strcmp(k,"goods"))
1137 amb 812 {
1138 amb 394 if(ISTRUE(v))
1139 amb 529 way.allow|=Transports_Goods;
1140 amb 812 else if(!ISFALSE(v))
1141 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'no'.\n",id,v);
1142 amb 1025 recognised=1; break;
1143 amb 812 }
1144 amb 394
1145     break;
1146    
1147     case 'h':
1148     if(!strcmp(k,"highway"))
1149 amb 1025 {recognised=1; break;}
1150 amb 394
1151     if(!strcmp(k,"horse"))
1152 amb 812 {
1153 amb 394 if(ISTRUE(v))
1154 amb 529 way.allow|=Transports_Horse;
1155 amb 812 else if(!ISFALSE(v))
1156 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'no'.\n",id,v);
1157 amb 1025 recognised=1; break;
1158 amb 812 }
1159 amb 394
1160     if(!strcmp(k,"hgv"))
1161 amb 812 {
1162 amb 394 if(ISTRUE(v))
1163 amb 529 way.allow|=Transports_HGV;
1164 amb 812 else if(!ISFALSE(v))
1165 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1166 amb 1025 recognised=1; break;
1167 amb 812 }
1168 amb 394
1169     break;
1170    
1171     case 'm':
1172 amb 1025 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 amb 394
1180 amb 1025 if(!strcmp(k+3,"weight"))
1181     {
1182     way.weight=tonnes_to_weight(parse_weight(id,k,v));
1183     recognised=1; break;
1184     }
1185 amb 394
1186 amb 1025 if(!strcmp(k+3,"height"))
1187     {
1188     way.height=metres_to_height(parse_length(id,k,v));
1189     recognised=1; break;
1190     }
1191 amb 394
1192 amb 1025 if(!strcmp(k+3,"width"))
1193     {
1194     way.width=metres_to_height(parse_length(id,k,v));
1195     recognised=1; break;
1196     }
1197 amb 394
1198 amb 1025 if(!strcmp(k+3,"length"))
1199     {
1200     way.length=metres_to_height(parse_length(id,k,v));
1201     recognised=1; break;
1202     }
1203     }
1204 amb 394
1205     if(!strcmp(k,"moped"))
1206 amb 812 {
1207 amb 394 if(ISTRUE(v))
1208 amb 529 way.allow|=Transports_Moped;
1209 amb 812 else if(!ISFALSE(v))
1210 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'no'.\n",id,v);
1211 amb 1025 recognised=1; break;
1212 amb 812 }
1213 amb 394
1214     if(!strcmp(k,"motorbike"))
1215 amb 812 {
1216 amb 394 if(ISTRUE(v))
1217 amb 529 way.allow|=Transports_Motorbike;
1218 amb 812 else if(!ISFALSE(v))
1219 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'no'.\n",id,v);
1220 amb 1025 recognised=1; break;
1221 amb 812 }
1222 amb 394
1223     if(!strcmp(k,"motorcar"))
1224 amb 812 {
1225 amb 394 if(ISTRUE(v))
1226 amb 529 way.allow|=Transports_Motorcar;
1227 amb 812 else if(!ISFALSE(v))
1228 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'no'.\n",id,v);
1229 amb 1025 recognised=1; break;
1230 amb 812 }
1231 amb 394
1232     if(!strcmp(k,"multilane"))
1233 amb 812 {
1234 amb 394 if(ISTRUE(v))
1235     way.props|=Properties_Multilane;
1236 amb 812 else if(!ISFALSE(v))
1237 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'multilane' = '%s' (after tagging rules); using 'no'.\n",id,v);
1238 amb 1025 recognised=1; break;
1239 amb 812 }
1240 amb 394
1241     break;
1242    
1243     case 'n':
1244     if(!strcmp(k,"name"))
1245 amb 1025 {
1246 amb 394 name=v;
1247 amb 1025 recognised=1; break;
1248     }
1249 amb 394
1250     break;
1251    
1252     case 'o':
1253     if(!strcmp(k,"oneway"))
1254     {
1255     if(ISTRUE(v))
1256 amb 1137 oneway=ONEWAY_1TO2;
1257 amb 394 else if(!strcmp(v,"-1"))
1258 amb 1137 oneway=ONEWAY_2TO1;
1259 amb 812 else if(!ISFALSE(v))
1260 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'oneway' = '%s' (after tagging rules); using 'no'.\n",id,v);
1261 amb 1025 recognised=1; break;
1262 amb 394 }
1263    
1264     break;
1265    
1266     case 'p':
1267     if(!strcmp(k,"paved"))
1268 amb 812 {
1269 amb 394 if(ISTRUE(v))
1270     way.props|=Properties_Paved;
1271 amb 812 else if(!ISFALSE(v))
1272 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'paved' = '%s' (after tagging rules); using 'no'.\n",id,v);
1273 amb 1025 recognised=1; break;
1274 amb 812 }
1275 amb 394
1276     if(!strcmp(k,"psv"))
1277 amb 812 {
1278 amb 394 if(ISTRUE(v))
1279 amb 529 way.allow|=Transports_PSV;
1280 amb 812 else if(!ISFALSE(v))
1281 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1282 amb 1025 recognised=1; break;
1283 amb 812 }
1284 amb 394
1285     break;
1286    
1287     case 'r':
1288     if(!strcmp(k,"ref"))
1289 amb 1025 {
1290 amb 394 ref=v;
1291 amb 1025 recognised=1; break;
1292     }
1293 amb 394
1294 amb 923 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 amb 1025 recognised=1; break;
1301 amb 923 }
1302    
1303 amb 394 break;
1304    
1305     case 't':
1306     if(!strcmp(k,"tunnel"))
1307 amb 812 {
1308 amb 394 if(ISTRUE(v))
1309     way.props|=Properties_Tunnel;
1310 amb 812 else if(!ISFALSE(v))
1311 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'tunnel' = '%s' (after tagging rules); using 'no'.\n",id,v);
1312 amb 1025 recognised=1; break;
1313 amb 812 }
1314 amb 394
1315     break;
1316    
1317     case 'w':
1318     if(!strcmp(k,"wheelchair"))
1319 amb 812 {
1320 amb 394 if(ISTRUE(v))
1321 amb 529 way.allow|=Transports_Wheelchair;
1322 amb 812 else if(!ISFALSE(v))
1323 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",id,v);
1324 amb 1025 recognised=1; break;
1325 amb 812 }
1326 amb 394
1327     break;
1328    
1329     default:
1330 amb 1025 break;
1331     }
1332    
1333     if(!recognised)
1334 amb 813 logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1335 amb 2 }
1336    
1337 amb 394 /* Create the way */
1338 amb 2
1339 amb 812 if(!way.allow)
1340     return;
1341    
1342     if(oneway)
1343     way.type|=Way_OneWay;
1344 amb 394
1345 amb 923 if(roundabout)
1346     way.type|=Way_Roundabout;
1347    
1348 amb 812 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 amb 394
1360 amb 1161 AppendWayList(ways,id,&way,refname);
1361 amb 394
1362 amb 812 if(ref && name)
1363     free(refname);
1364 amb 394
1365 amb 812 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 amb 1168 AppendSegmentList(segments,id,from,to,area+oneway);
1371 amb 394 }
1372 amb 2 }
1373 amb 498
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 amb 529 transports_t routes=Transports_None;
1386 amb 540 transports_t except=Transports_None;
1387     int relation_turn_restriction=0;
1388 amb 541 TurnRestriction restriction=TurnRestrict_None;
1389 amb 498 int i;
1390    
1391 amb 1140 /* Delete */
1392    
1393 amb 1152 if(mode==MODE_DELETE || mode==MODE_MODIFY)
1394 amb 1140 {
1395 amb 1161 AppendRouteRelationList(relations,id,RELATION_DELETED,
1396     relation_ways,relation_nways,
1397     relation_relations,relation_nrelations);
1398 amb 1140
1399 amb 1161 AppendTurnRelationList(relations,id,
1400     relation_from,relation_to,relation_via,
1401     restriction,RELATION_DELETED);
1402 amb 1152 }
1403 amb 1140
1404 amb 1152 if(mode==MODE_DELETE)
1405 amb 1140 return;
1406    
1407 amb 1125 /* 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 amb 498 /* Parse the tags */
1416    
1417     for(i=0;i<tags->ntags;i++)
1418     {
1419 amb 1025 int recognised=0;
1420 amb 498 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 amb 812 {
1428 amb 498 if(ISTRUE(v))
1429 amb 529 routes|=Transports_Bicycle;
1430 amb 812 else if(!ISFALSE(v))
1431 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1432 amb 1025 recognised=1; break;
1433 amb 812 }
1434 amb 498
1435     break;
1436    
1437 amb 540 case 'e':
1438     if(!strcmp(k,"except"))
1439 amb 812 {
1440 amb 540 for(i=1;i<Transport_Count;i++)
1441 amb 876 if(strstr(v,TransportName(i)))
1442 amb 540 except|=TRANSPORTS(i);
1443    
1444 amb 812 if(except==Transports_None)
1445 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'except' = '%s' (after tagging rules); ignoring it.\n",id,v);
1446 amb 1025
1447     recognised=1; break;
1448 amb 812 }
1449    
1450 amb 540 break;
1451    
1452 amb 498 case 'f':
1453     if(!strcmp(k,"footroute"))
1454 amb 812 {
1455 amb 498 if(ISTRUE(v))
1456 amb 529 routes|=Transports_Foot;
1457 amb 812 else if(!ISFALSE(v))
1458 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1459 amb 1025 recognised=1; break;
1460 amb 812 }
1461 amb 498
1462     break;
1463    
1464 amb 540 case 'r':
1465     if(!strcmp(k,"restriction"))
1466     {
1467 amb 541 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 amb 812
1475     if(restriction==TurnRestrict_None)
1476 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'restriction' = '%s' (after tagging rules); ignoring it.\n",id,v);
1477 amb 1025
1478     recognised=1; break;
1479 amb 540 }
1480    
1481     break;
1482    
1483     case 't':
1484     if(!strcmp(k,"type"))
1485 amb 1025 {
1486 amb 540 if(!strcmp(v,"restriction"))
1487     relation_turn_restriction=1;
1488 amb 1025
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 amb 540 break;
1494    
1495 amb 498 default:
1496 amb 1025 break;
1497     }
1498    
1499     if(!recognised)
1500 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1501 amb 498 }
1502    
1503 amb 505 /* 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 amb 498
1507 amb 540 if((relation_nways || relation_nrelations) && !relation_turn_restriction)
1508 amb 1161 AppendRouteRelationList(relations,id,routes,
1509     relation_ways,relation_nways,
1510     relation_relations,relation_nrelations);
1511 amb 540
1512     /* Create the turn restriction relation. */
1513    
1514 amb 812 if(relation_turn_restriction && restriction!=TurnRestrict_None)
1515     {
1516     if(relation_from==NO_WAY_ID)
1517 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",id);
1518 amb 812 else if(relation_to==NO_WAY_ID)
1519 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",id);
1520 amb 812 else if(relation_via==NO_NODE_ID)
1521 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",id);
1522 amb 812 else
1523 amb 1161 AppendTurnRelationList(relations,id,
1524     relation_from,relation_to,relation_via,
1525     restriction,except);
1526 amb 812 }
1527 amb 498 }
1528 amb 812
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 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1549 amb 812 else
1550     {
1551     while(isspace(*ev)) ev++;
1552    
1553     if(!strcmp(ev,"mph"))
1554     return(1.609*value);
1555 amb 813
1556     if(*ev==0 || !strcmp(ev,"kph"))
1557 amb 812 return(value);
1558 amb 813
1559     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1560 amb 812 }
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 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1585 amb 812 else
1586     {
1587     while(isspace(*ev)) ev++;
1588    
1589     if(!strcmp(ev,"kg"))
1590     return(value/1000.0);
1591 amb 813
1592 amb 825 if(*ev==0 || !strcmp(ev,"T") || !strcmp(ev,"t")
1593     || !strcmp(ev,"ton") || !strcmp(ev,"tons")
1594     || !strcmp(ev,"tonne") || !strcmp(ev,"tonnes"))
1595 amb 812 return(value);
1596 amb 813
1597     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1598 amb 812 }
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 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1623 amb 812 else
1624     {
1625 amb 813 int en=0;
1626     int feet=0,inches=0;
1627 amb 812
1628 amb 813 if(sscanf(v,"%d' %d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1629 amb 812 return((feet+(double)inches/12.0)*0.254);
1630 amb 813
1631 amb 1127 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 amb 813 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 amb 825 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 amb 812 return(feet*0.254);
1648 amb 813
1649     while(isspace(*ev)) ev++;
1650    
1651     if(!strcmp(ev,"ft") || !strcmp(ev,"feet"))
1652 amb 812 return(value*0.254);
1653 amb 813
1654 amb 825 if(*ev==0 || !strcmp(ev,"m") || !strcmp(ev,"metre") || !strcmp(ev,"metres"))
1655 amb 812 return(value);
1656 amb 813
1657     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1658 amb 812 }
1659    
1660     return(0);
1661     }

Properties

Name Value
cvs:description OSM XML file parser.