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/osmxmlparse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1186 - (hide annotations) (download) (as text)
Mon Dec 10 18:36:08 2012 UTC (12 years, 3 months ago) by amb
Original Path: trunk/src/osmparser.c
File MIME type: text/x-csrc
File size: 48647 byte(s)
New XML parser doesn't use stdio buffered file access but lower level read
functions.

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

Properties

Name Value
cvs:description OSM XML file parser.