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 1145 - (hide annotations) (download) (as text)
Sat Nov 17 13:31:14 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 47952 byte(s)
Fix applying changes for ways (highways that have been modified to be
non-highways were not added to the database so the original remains).

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     AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED);
850    
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 538 AppendNode(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     distance_t oneway=0,area=0;
1008     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 1145 if(mode==MODE_DELETE || (mode!=MODE_NORMAL && IndexWayX(ways,id)!=NO_WAY))
1015 amb 1140 {
1016     way.type=WAY_DELETED;
1017    
1018     AppendWay(ways,id,&way,"");
1019    
1020     AppendSegment(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     if(way.type==Way_Count)
1052     logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",id,v);
1053     }
1054     }
1055    
1056     /* Don't continue if this is not a highway (bypass error logging) */
1057    
1058     if(way.type==0 || way.type==Way_Count)
1059     return;
1060    
1061     /* Parse the tags - look for the others */
1062    
1063     for(i=0;i<tags->ntags;i++)
1064     {
1065 amb 1025 int recognised=0;
1066 amb 833 char *k=tags->k[i];
1067     char *v=tags->v[i];
1068    
1069 amb 394 switch(*k)
1070     {
1071 amb 914 case 'a':
1072     if(!strcmp(k,"area"))
1073     {
1074     if(ISTRUE(v))
1075 amb 1137 area=SEGMENT_AREA;
1076 amb 914 else if(!ISFALSE(v))
1077     logerror("Way %"Pway_t" has an unrecognised tag value 'area' = '%s' (after tagging rules); using 'no'.\n",id,v);
1078 amb 1025 recognised=1; break;
1079 amb 914 }
1080    
1081     break;
1082    
1083 amb 394 case 'b':
1084     if(!strcmp(k,"bicycle"))
1085 amb 812 {
1086 amb 394 if(ISTRUE(v))
1087 amb 813 way.allow|=Transports_Bicycle;
1088 amb 812 else if(!ISFALSE(v))
1089 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'no'.\n",id,v);
1090 amb 1025 recognised=1; break;
1091 amb 812 }
1092 amb 394
1093 amb 498 if(!strcmp(k,"bicycleroute"))
1094 amb 812 {
1095 amb 498 if(ISTRUE(v))
1096     way.props|=Properties_BicycleRoute;
1097 amb 812 else if(!ISFALSE(v))
1098 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1099 amb 1025 recognised=1; break;
1100 amb 812 }
1101 amb 498
1102 amb 394 if(!strcmp(k,"bridge"))
1103 amb 812 {
1104 amb 394 if(ISTRUE(v))
1105     way.props|=Properties_Bridge;
1106 amb 812 else if(!ISFALSE(v))
1107 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'bridge' = '%s' (after tagging rules); using 'no'.\n",id,v);
1108 amb 1025 recognised=1; break;
1109 amb 812 }
1110 amb 394
1111 amb 2 break;
1112 amb 394
1113     case 'f':
1114     if(!strcmp(k,"foot"))
1115 amb 812 {
1116 amb 394 if(ISTRUE(v))
1117 amb 813 way.allow|=Transports_Foot;
1118 amb 812 else if(!ISFALSE(v))
1119 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'no'.\n",id,v);
1120 amb 1025 recognised=1; break;
1121 amb 812 }
1122 amb 394
1123 amb 498 if(!strcmp(k,"footroute"))
1124 amb 812 {
1125 amb 498 if(ISTRUE(v))
1126     way.props|=Properties_FootRoute;
1127 amb 812 else if(!ISFALSE(v))
1128 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1129 amb 1025 recognised=1; break;
1130 amb 812 }
1131 amb 498
1132 amb 394 break;
1133    
1134     case 'g':
1135     if(!strcmp(k,"goods"))
1136 amb 812 {
1137 amb 394 if(ISTRUE(v))
1138 amb 529 way.allow|=Transports_Goods;
1139 amb 812 else if(!ISFALSE(v))
1140 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'no'.\n",id,v);
1141 amb 1025 recognised=1; break;
1142 amb 812 }
1143 amb 394
1144     break;
1145    
1146     case 'h':
1147     if(!strcmp(k,"highway"))
1148 amb 1025 {recognised=1; break;}
1149 amb 394
1150     if(!strcmp(k,"horse"))
1151 amb 812 {
1152 amb 394 if(ISTRUE(v))
1153 amb 529 way.allow|=Transports_Horse;
1154 amb 812 else if(!ISFALSE(v))
1155 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'no'.\n",id,v);
1156 amb 1025 recognised=1; break;
1157 amb 812 }
1158 amb 394
1159     if(!strcmp(k,"hgv"))
1160 amb 812 {
1161 amb 394 if(ISTRUE(v))
1162 amb 529 way.allow|=Transports_HGV;
1163 amb 812 else if(!ISFALSE(v))
1164 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1165 amb 1025 recognised=1; break;
1166 amb 812 }
1167 amb 394
1168     break;
1169    
1170     case 'm':
1171 amb 1025 if(!strncmp(k,"max",3))
1172     {
1173     if(!strcmp(k+3,"speed"))
1174     {
1175     way.speed=kph_to_speed(parse_speed(id,k,v));
1176     recognised=1; break;
1177     }
1178 amb 394
1179 amb 1025 if(!strcmp(k+3,"weight"))
1180     {
1181     way.weight=tonnes_to_weight(parse_weight(id,k,v));
1182     recognised=1; break;
1183     }
1184 amb 394
1185 amb 1025 if(!strcmp(k+3,"height"))
1186     {
1187     way.height=metres_to_height(parse_length(id,k,v));
1188     recognised=1; break;
1189     }
1190 amb 394
1191 amb 1025 if(!strcmp(k+3,"width"))
1192     {
1193     way.width=metres_to_height(parse_length(id,k,v));
1194     recognised=1; break;
1195     }
1196 amb 394
1197 amb 1025 if(!strcmp(k+3,"length"))
1198     {
1199     way.length=metres_to_height(parse_length(id,k,v));
1200     recognised=1; break;
1201     }
1202     }
1203 amb 394
1204     if(!strcmp(k,"moped"))
1205 amb 812 {
1206 amb 394 if(ISTRUE(v))
1207 amb 529 way.allow|=Transports_Moped;
1208 amb 812 else if(!ISFALSE(v))
1209 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'no'.\n",id,v);
1210 amb 1025 recognised=1; break;
1211 amb 812 }
1212 amb 394
1213     if(!strcmp(k,"motorbike"))
1214 amb 812 {
1215 amb 394 if(ISTRUE(v))
1216 amb 529 way.allow|=Transports_Motorbike;
1217 amb 812 else if(!ISFALSE(v))
1218 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'no'.\n",id,v);
1219 amb 1025 recognised=1; break;
1220 amb 812 }
1221 amb 394
1222     if(!strcmp(k,"motorcar"))
1223 amb 812 {
1224 amb 394 if(ISTRUE(v))
1225 amb 529 way.allow|=Transports_Motorcar;
1226 amb 812 else if(!ISFALSE(v))
1227 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'no'.\n",id,v);
1228 amb 1025 recognised=1; break;
1229 amb 812 }
1230 amb 394
1231     if(!strcmp(k,"multilane"))
1232 amb 812 {
1233 amb 394 if(ISTRUE(v))
1234     way.props|=Properties_Multilane;
1235 amb 812 else if(!ISFALSE(v))
1236 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'multilane' = '%s' (after tagging rules); using 'no'.\n",id,v);
1237 amb 1025 recognised=1; break;
1238 amb 812 }
1239 amb 394
1240     break;
1241    
1242     case 'n':
1243     if(!strcmp(k,"name"))
1244 amb 1025 {
1245 amb 394 name=v;
1246 amb 1025 recognised=1; break;
1247     }
1248 amb 394
1249     break;
1250    
1251     case 'o':
1252     if(!strcmp(k,"oneway"))
1253     {
1254     if(ISTRUE(v))
1255 amb 1137 oneway=ONEWAY_1TO2;
1256 amb 394 else if(!strcmp(v,"-1"))
1257 amb 1137 oneway=ONEWAY_2TO1;
1258 amb 812 else if(!ISFALSE(v))
1259 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'oneway' = '%s' (after tagging rules); using 'no'.\n",id,v);
1260 amb 1025 recognised=1; break;
1261 amb 394 }
1262    
1263     break;
1264    
1265     case 'p':
1266     if(!strcmp(k,"paved"))
1267 amb 812 {
1268 amb 394 if(ISTRUE(v))
1269     way.props|=Properties_Paved;
1270 amb 812 else if(!ISFALSE(v))
1271 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'paved' = '%s' (after tagging rules); using 'no'.\n",id,v);
1272 amb 1025 recognised=1; break;
1273 amb 812 }
1274 amb 394
1275     if(!strcmp(k,"psv"))
1276 amb 812 {
1277 amb 394 if(ISTRUE(v))
1278 amb 529 way.allow|=Transports_PSV;
1279 amb 812 else if(!ISFALSE(v))
1280 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'no'.\n",id,v);
1281 amb 1025 recognised=1; break;
1282 amb 812 }
1283 amb 394
1284     break;
1285    
1286     case 'r':
1287     if(!strcmp(k,"ref"))
1288 amb 1025 {
1289 amb 394 ref=v;
1290 amb 1025 recognised=1; break;
1291     }
1292 amb 394
1293 amb 923 if(!strcmp(k,"roundabout"))
1294     {
1295     if(ISTRUE(v))
1296     roundabout=1;
1297     else if(!ISFALSE(v))
1298     logerror("Way %"Pway_t" has an unrecognised tag value 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v);
1299 amb 1025 recognised=1; break;
1300 amb 923 }
1301    
1302 amb 394 break;
1303    
1304     case 't':
1305     if(!strcmp(k,"tunnel"))
1306 amb 812 {
1307 amb 394 if(ISTRUE(v))
1308     way.props|=Properties_Tunnel;
1309 amb 812 else if(!ISFALSE(v))
1310 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'tunnel' = '%s' (after tagging rules); using 'no'.\n",id,v);
1311 amb 1025 recognised=1; break;
1312 amb 812 }
1313 amb 394
1314     break;
1315    
1316     case 'w':
1317     if(!strcmp(k,"wheelchair"))
1318 amb 812 {
1319 amb 394 if(ISTRUE(v))
1320 amb 529 way.allow|=Transports_Wheelchair;
1321 amb 812 else if(!ISFALSE(v))
1322 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",id,v);
1323 amb 1025 recognised=1; break;
1324 amb 812 }
1325 amb 394
1326     break;
1327    
1328     default:
1329 amb 1025 break;
1330     }
1331    
1332     if(!recognised)
1333 amb 813 logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1334 amb 2 }
1335    
1336 amb 394 /* Create the way */
1337 amb 2
1338 amb 812 if(!way.allow)
1339     return;
1340    
1341     if(oneway)
1342     way.type|=Way_OneWay;
1343 amb 394
1344 amb 923 if(roundabout)
1345     way.type|=Way_Roundabout;
1346    
1347 amb 812 if(ref && name)
1348     {
1349     refname=(char*)malloc(strlen(ref)+strlen(name)+4);
1350     sprintf(refname,"%s (%s)",name,ref);
1351     }
1352     else if(ref && !name)
1353     refname=ref;
1354     else if(!ref && name)
1355     refname=name;
1356     else /* if(!ref && !name) */
1357     refname="";
1358 amb 394
1359 amb 812 AppendWay(ways,id,&way,refname);
1360 amb 394
1361 amb 812 if(ref && name)
1362     free(refname);
1363 amb 394
1364 amb 812 for(i=1;i<way_nnodes;i++)
1365     {
1366     node_t from=way_nodes[i-1];
1367     node_t to =way_nodes[i];
1368    
1369 amb 1137 AppendSegment(segments,id,from,to,area+oneway);
1370 amb 394 }
1371 amb 2 }
1372 amb 498
1373    
1374     /*++++++++++++++++++++++++++++++++++++++
1375     Process the tags associated with a relation.
1376    
1377     TagList *tags The list of relation tags.
1378    
1379     relation_t id The id of the relation.
1380     ++++++++++++++++++++++++++++++++++++++*/
1381    
1382     static void process_relation_tags(TagList *tags,relation_t id)
1383     {
1384 amb 529 transports_t routes=Transports_None;
1385 amb 540 transports_t except=Transports_None;
1386     int relation_turn_restriction=0;
1387 amb 541 TurnRestriction restriction=TurnRestrict_None;
1388 amb 498 int i;
1389    
1390 amb 1140 /* Delete */
1391    
1392     if(mode==MODE_DELETE)
1393     {
1394     AppendRouteRelation(relations,id,RELATION_DELETED,
1395     relation_ways,relation_nways,
1396     relation_relations,relation_nrelations);
1397    
1398     AppendTurnRestrictRelation(relations,id,
1399     relation_from,relation_to,relation_via,
1400     restriction,RELATION_DELETED);
1401    
1402     return;
1403     }
1404    
1405 amb 1125 /* Sanity check */
1406    
1407     if(relation_nnodes==0 && relation_nways==0 && relation_nrelations==0)
1408     {
1409     logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",id);
1410     return;
1411     }
1412    
1413 amb 498 /* Parse the tags */
1414    
1415     for(i=0;i<tags->ntags;i++)
1416     {
1417 amb 1025 int recognised=0;
1418 amb 498 char *k=tags->k[i];
1419     char *v=tags->v[i];
1420    
1421     switch(*k)
1422     {
1423     case 'b':
1424     if(!strcmp(k,"bicycleroute"))
1425 amb 812 {
1426 amb 498 if(ISTRUE(v))
1427 amb 529 routes|=Transports_Bicycle;
1428 amb 812 else if(!ISFALSE(v))
1429 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1430 amb 1025 recognised=1; break;
1431 amb 812 }
1432 amb 498
1433     break;
1434    
1435 amb 540 case 'e':
1436     if(!strcmp(k,"except"))
1437 amb 812 {
1438 amb 540 for(i=1;i<Transport_Count;i++)
1439 amb 876 if(strstr(v,TransportName(i)))
1440 amb 540 except|=TRANSPORTS(i);
1441    
1442 amb 812 if(except==Transports_None)
1443 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'except' = '%s' (after tagging rules); ignoring it.\n",id,v);
1444 amb 1025
1445     recognised=1; break;
1446 amb 812 }
1447    
1448 amb 540 break;
1449    
1450 amb 498 case 'f':
1451     if(!strcmp(k,"footroute"))
1452 amb 812 {
1453 amb 498 if(ISTRUE(v))
1454 amb 529 routes|=Transports_Foot;
1455 amb 812 else if(!ISFALSE(v))
1456 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v);
1457 amb 1025 recognised=1; break;
1458 amb 812 }
1459 amb 498
1460     break;
1461    
1462 amb 540 case 'r':
1463     if(!strcmp(k,"restriction"))
1464     {
1465 amb 541 if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn;
1466     if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn;
1467     if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn;
1468     if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on;
1469     if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn;
1470     if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn;
1471     if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on;
1472 amb 812
1473     if(restriction==TurnRestrict_None)
1474 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag value 'restriction' = '%s' (after tagging rules); ignoring it.\n",id,v);
1475 amb 1025
1476     recognised=1; break;
1477 amb 540 }
1478    
1479     break;
1480    
1481     case 't':
1482     if(!strcmp(k,"type"))
1483 amb 1025 {
1484 amb 540 if(!strcmp(v,"restriction"))
1485     relation_turn_restriction=1;
1486 amb 1025
1487     /* Don't log an error for relations of types that we don't handle - there are so many */
1488     recognised=1; break;
1489     }
1490    
1491 amb 540 break;
1492    
1493 amb 498 default:
1494 amb 1025 break;
1495     }
1496    
1497     if(!recognised)
1498 amb 813 logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1499 amb 498 }
1500    
1501 amb 505 /* Create the route relation (must store all relations that have ways or
1502     relations even if they are not routes because they might be referenced by
1503     other relations that are routes) */
1504 amb 498
1505 amb 540 if((relation_nways || relation_nrelations) && !relation_turn_restriction)
1506 amb 498 AppendRouteRelation(relations,id,routes,
1507     relation_ways,relation_nways,
1508     relation_relations,relation_nrelations);
1509 amb 540
1510     /* Create the turn restriction relation. */
1511    
1512 amb 812 if(relation_turn_restriction && restriction!=TurnRestrict_None)
1513     {
1514     if(relation_from==NO_WAY_ID)
1515 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",id);
1516 amb 812 else if(relation_to==NO_WAY_ID)
1517 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",id);
1518 amb 812 else if(relation_via==NO_NODE_ID)
1519 amb 813 logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",id);
1520 amb 812 else
1521     AppendTurnRestrictRelation(relations,id,
1522     relation_from,relation_to,relation_via,
1523     restriction,except);
1524     }
1525 amb 498 }
1526 amb 812
1527    
1528     /*++++++++++++++++++++++++++++++++++++++
1529     Convert a string containing a speed into a double precision.
1530    
1531     double parse_speed Returns the speed in km/h if it can be parsed.
1532    
1533     way_t id The way being processed.
1534    
1535     const char *k The tag key.
1536    
1537     const char *v The tag value.
1538     ++++++++++++++++++++++++++++++++++++++*/
1539    
1540     static double parse_speed(way_t id,const char *k,const char *v)
1541     {
1542     char *ev;
1543     double value=strtod(v,&ev);
1544    
1545     if(v==ev)
1546 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1547 amb 812 else
1548     {
1549     while(isspace(*ev)) ev++;
1550    
1551     if(!strcmp(ev,"mph"))
1552     return(1.609*value);
1553 amb 813
1554     if(*ev==0 || !strcmp(ev,"kph"))
1555 amb 812 return(value);
1556 amb 813
1557     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1558 amb 812 }
1559    
1560     return(0);
1561     }
1562    
1563    
1564     /*++++++++++++++++++++++++++++++++++++++
1565     Convert a string containing a weight into a double precision.
1566    
1567     double parse_weight Returns the weight in tonnes if it can be parsed.
1568    
1569     way_t id The way being processed.
1570    
1571     const char *k The tag key.
1572    
1573     const char *v The tag value.
1574     ++++++++++++++++++++++++++++++++++++++*/
1575    
1576     static double parse_weight(way_t id,const char *k,const char *v)
1577     {
1578     char *ev;
1579     double value=strtod(v,&ev);
1580    
1581     if(v==ev)
1582 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1583 amb 812 else
1584     {
1585     while(isspace(*ev)) ev++;
1586    
1587     if(!strcmp(ev,"kg"))
1588     return(value/1000.0);
1589 amb 813
1590 amb 825 if(*ev==0 || !strcmp(ev,"T") || !strcmp(ev,"t")
1591     || !strcmp(ev,"ton") || !strcmp(ev,"tons")
1592     || !strcmp(ev,"tonne") || !strcmp(ev,"tonnes"))
1593 amb 812 return(value);
1594 amb 813
1595     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1596 amb 812 }
1597    
1598     return(0);
1599     }
1600    
1601    
1602     /*++++++++++++++++++++++++++++++++++++++
1603     Convert a string containing a length into a double precision.
1604    
1605     double parse_length Returns the length in metres if it can be parsed.
1606    
1607     way_t id The way being processed.
1608    
1609     const char *k The tag key.
1610    
1611     const char *v The tag value.
1612     ++++++++++++++++++++++++++++++++++++++*/
1613    
1614     static double parse_length(way_t id,const char *k,const char *v)
1615     {
1616     char *ev;
1617     double value=strtod(v,&ev);
1618    
1619     if(v==ev)
1620 amb 813 logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1621 amb 812 else
1622     {
1623 amb 813 int en=0;
1624     int feet=0,inches=0;
1625 amb 812
1626 amb 813 if(sscanf(v,"%d' %d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1627 amb 812 return((feet+(double)inches/12.0)*0.254);
1628 amb 813
1629 amb 1127 if(sscanf(v,"%d'%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1630     return((feet+(double)inches/12.0)*0.254);
1631    
1632     if(sscanf(v,"%d'-%d\"%n",&feet,&inches,&en)==2 && en && !v[en])
1633     return((feet+(double)inches/12.0)*0.254);
1634    
1635 amb 813 if(sscanf(v,"%d - %d%n",&feet,&inches,&en)==2 && en && !v[en])
1636     return((feet+(double)inches/12.0)*0.254);
1637    
1638     if(sscanf(v,"%d ft %d in%n",&feet,&inches,&en)==2 && en && !v[en])
1639     return((feet+(double)inches/12.0)*0.254);
1640    
1641 amb 825 if(sscanf(v,"%d feet %d inches%n",&feet,&inches,&en)==2 && en && !v[en])
1642     return((feet+(double)inches/12.0)*0.254);
1643    
1644     if(!strcmp(ev,"'"))
1645 amb 812 return(feet*0.254);
1646 amb 813
1647     while(isspace(*ev)) ev++;
1648    
1649     if(!strcmp(ev,"ft") || !strcmp(ev,"feet"))
1650 amb 812 return(value*0.254);
1651 amb 813
1652 amb 825 if(*ev==0 || !strcmp(ev,"m") || !strcmp(ev,"metre") || !strcmp(ev,"metres"))
1653 amb 812 return(value);
1654 amb 813
1655     logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v);
1656 amb 812 }
1657    
1658     return(0);
1659     }

Properties

Name Value
cvs:description OSM XML file parser.