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 1164 - (hide annotations) (download) (as text)
Tue Nov 20 15:24:30 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 48009 byte(s)
Replace the 32-bit combined distance and flags in the segment with 16 bits for
each.

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

Properties

Name Value
cvs:description OSM XML file parser.