Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/osmparser.c
Parent Directory
|
Revision Log
Revision 757 -
(show annotations)
(download)
(as text)
Fri Jun 3 18:06:21 2011 UTC (13 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 27511 byte(s)
Fri Jun 3 18:06:21 2011 UTC (13 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 27511 byte(s)
Rationalise the increment of the numbers used for the output when not --loggable.
1 | /*************************************** |
2 | OSM XML file parser (either JOSM or planet) |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2008-2011 Andrew M. Bishop |
7 | |
8 | 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 | ***************************************/ |
21 | |
22 | |
23 | #include <stdio.h> |
24 | #include <stdlib.h> |
25 | #include <string.h> |
26 | #include <ctype.h> |
27 | |
28 | #include "typesx.h" |
29 | #include "functionsx.h" |
30 | |
31 | #include "nodesx.h" |
32 | #include "segmentsx.h" |
33 | #include "waysx.h" |
34 | #include "relationsx.h" |
35 | |
36 | #include "xmlparse.h" |
37 | #include "tagging.h" |
38 | |
39 | #include "logging.h" |
40 | |
41 | |
42 | /* Macros */ |
43 | |
44 | /*+ Checks if a value in the XML is one of the allowed values for true. +*/ |
45 | #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1")) |
46 | |
47 | |
48 | /* Local variables */ |
49 | |
50 | static long nnodes=0,nways=0,nrelations=0; |
51 | static TagList *current_tags=NULL; |
52 | |
53 | static node_t *way_nodes=NULL; |
54 | static int way_nnodes=0; |
55 | |
56 | static node_t *relation_nodes=NULL; |
57 | static int relation_nnodes=0; |
58 | static way_t *relation_ways=NULL; |
59 | static int relation_nways=0; |
60 | static relation_t *relation_relations=NULL; |
61 | static int relation_nrelations=0; |
62 | static way_t relation_from=NO_WAY_ID; |
63 | static way_t relation_to=NO_WAY_ID; |
64 | static node_t relation_via=NO_NODE_ID; |
65 | |
66 | static NodesX *nodes; |
67 | static SegmentsX *segments; |
68 | static WaysX *ways; |
69 | static RelationsX *relations; |
70 | |
71 | |
72 | /* Local functions */ |
73 | |
74 | static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude); |
75 | static void process_way_tags(TagList *tags,way_t id); |
76 | static void process_relation_tags(TagList *tags,relation_t id); |
77 | |
78 | |
79 | /* The XML tag processing function prototypes */ |
80 | |
81 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); |
82 | //static int osmType_function(const char *_tag_,int _type_); |
83 | static int relationType_function(const char *_tag_,int _type_,const char *id); |
84 | static int wayType_function(const char *_tag_,int _type_,const char *id); |
85 | static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); |
86 | static int ndType_function(const char *_tag_,int _type_,const char *ref); |
87 | static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon); |
88 | static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v); |
89 | //static int boundType_function(const char *_tag_,int _type_); |
90 | //static int boundsType_function(const char *_tag_,int _type_); |
91 | |
92 | |
93 | /* The XML tag definitions */ |
94 | |
95 | /*+ The boundsType type tag. +*/ |
96 | static xmltag boundsType_tag= |
97 | {"bounds", |
98 | 0, {NULL}, |
99 | NULL, |
100 | {NULL}}; |
101 | |
102 | /*+ The boundType type tag. +*/ |
103 | static xmltag boundType_tag= |
104 | {"bound", |
105 | 0, {NULL}, |
106 | NULL, |
107 | {NULL}}; |
108 | |
109 | /*+ The tagType type tag. +*/ |
110 | static xmltag tagType_tag= |
111 | {"tag", |
112 | 2, {"k","v"}, |
113 | tagType_function, |
114 | {NULL}}; |
115 | |
116 | /*+ The nodeType type tag. +*/ |
117 | static xmltag nodeType_tag= |
118 | {"node", |
119 | 3, {"id","lat","lon"}, |
120 | nodeType_function, |
121 | {&tagType_tag,NULL}}; |
122 | |
123 | /*+ The ndType type tag. +*/ |
124 | static xmltag ndType_tag= |
125 | {"nd", |
126 | 1, {"ref"}, |
127 | ndType_function, |
128 | {NULL}}; |
129 | |
130 | /*+ The memberType type tag. +*/ |
131 | static xmltag memberType_tag= |
132 | {"member", |
133 | 3, {"type","ref","role"}, |
134 | memberType_function, |
135 | {NULL}}; |
136 | |
137 | /*+ The wayType type tag. +*/ |
138 | static xmltag wayType_tag= |
139 | {"way", |
140 | 1, {"id"}, |
141 | wayType_function, |
142 | {&ndType_tag,&tagType_tag,NULL}}; |
143 | |
144 | /*+ The relationType type tag. +*/ |
145 | static xmltag relationType_tag= |
146 | {"relation", |
147 | 1, {"id"}, |
148 | relationType_function, |
149 | {&memberType_tag,&tagType_tag,NULL}}; |
150 | |
151 | /*+ The osmType type tag. +*/ |
152 | static xmltag osmType_tag= |
153 | {"osm", |
154 | 0, {NULL}, |
155 | NULL, |
156 | {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; |
157 | |
158 | /*+ The xmlDeclaration type tag. +*/ |
159 | static xmltag xmlDeclaration_tag= |
160 | {"xml", |
161 | 2, {"version","encoding"}, |
162 | NULL, |
163 | {NULL}}; |
164 | |
165 | |
166 | /*+ The complete set of tags at the top level. +*/ |
167 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL}; |
168 | |
169 | |
170 | /* The XML tag processing functions */ |
171 | |
172 | |
173 | /*++++++++++++++++++++++++++++++++++++++ |
174 | The function that is called when the boundsType XSD type is seen |
175 | |
176 | int boundsType_function Returns 0 if no error occured or something else otherwise. |
177 | |
178 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
179 | |
180 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
181 | ++++++++++++++++++++++++++++++++++++++*/ |
182 | |
183 | //static int boundsType_function(const char *_tag_,int _type_) |
184 | //{ |
185 | // return(0); |
186 | //} |
187 | |
188 | |
189 | /*++++++++++++++++++++++++++++++++++++++ |
190 | The function that is called when the boundType XSD type is seen |
191 | |
192 | int boundType_function Returns 0 if no error occured or something else otherwise. |
193 | |
194 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
195 | |
196 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
197 | ++++++++++++++++++++++++++++++++++++++*/ |
198 | |
199 | //static int boundType_function(const char *_tag_,int _type_) |
200 | //{ |
201 | // return(0); |
202 | //} |
203 | |
204 | |
205 | /*++++++++++++++++++++++++++++++++++++++ |
206 | The function that is called when the tagType XSD type is seen |
207 | |
208 | int tagType_function Returns 0 if no error occured or something else otherwise. |
209 | |
210 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
211 | |
212 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
213 | |
214 | const char *k The contents of the 'k' attribute (or NULL if not defined). |
215 | |
216 | const char *v The contents of the 'v' attribute (or NULL if not defined). |
217 | ++++++++++++++++++++++++++++++++++++++*/ |
218 | |
219 | static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v) |
220 | { |
221 | if(_type_&XMLPARSE_TAG_START && current_tags) |
222 | { |
223 | XMLPARSE_ASSERT_STRING(_tag_,k); |
224 | XMLPARSE_ASSERT_STRING(_tag_,v); |
225 | |
226 | AppendTag(current_tags,k,v); |
227 | } |
228 | |
229 | return(0); |
230 | } |
231 | |
232 | |
233 | /*++++++++++++++++++++++++++++++++++++++ |
234 | The function that is called when the nodeType XSD type is seen |
235 | |
236 | int nodeType_function Returns 0 if no error occured or something else otherwise. |
237 | |
238 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
239 | |
240 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
241 | |
242 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
243 | |
244 | const char *lat The contents of the 'lat' attribute (or NULL if not defined). |
245 | |
246 | const char *lon The contents of the 'lon' attribute (or NULL if not defined). |
247 | ++++++++++++++++++++++++++++++++++++++*/ |
248 | |
249 | static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon) |
250 | { |
251 | static node_t node_id; |
252 | static double latitude,longitude; |
253 | |
254 | if(_type_&XMLPARSE_TAG_START) |
255 | { |
256 | nnodes++; |
257 | |
258 | if(!(nnodes%10000)) |
259 | printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
260 | |
261 | current_tags=NewTagList(); |
262 | |
263 | /* Handle the node information */ |
264 | |
265 | XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */ |
266 | XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude); |
267 | XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude); |
268 | } |
269 | |
270 | if(_type_&XMLPARSE_TAG_END) |
271 | { |
272 | TagList *result=ApplyTaggingRules(&NodeRules,current_tags); |
273 | |
274 | process_node_tags(result,node_id,latitude,longitude); |
275 | |
276 | DeleteTagList(current_tags); |
277 | DeleteTagList(result); |
278 | } |
279 | |
280 | return(0); |
281 | } |
282 | |
283 | |
284 | /*++++++++++++++++++++++++++++++++++++++ |
285 | The function that is called when the ndType XSD type is seen |
286 | |
287 | int ndType_function Returns 0 if no error occured or something else otherwise. |
288 | |
289 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
290 | |
291 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
292 | |
293 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
294 | ++++++++++++++++++++++++++++++++++++++*/ |
295 | |
296 | static int ndType_function(const char *_tag_,int _type_,const char *ref) |
297 | { |
298 | if(_type_&XMLPARSE_TAG_START) |
299 | { |
300 | node_t node_id; |
301 | |
302 | XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */ |
303 | |
304 | if(way_nnodes && (way_nnodes%256)==0) |
305 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); |
306 | |
307 | way_nodes[way_nnodes++]=node_id; |
308 | } |
309 | |
310 | return(0); |
311 | } |
312 | |
313 | |
314 | /*++++++++++++++++++++++++++++++++++++++ |
315 | The function that is called when the memberType XSD type is seen |
316 | |
317 | int memberType_function Returns 0 if no error occured or something else otherwise. |
318 | |
319 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
320 | |
321 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
322 | |
323 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
324 | |
325 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
326 | |
327 | const char *role The contents of the 'role' attribute (or NULL if not defined). |
328 | ++++++++++++++++++++++++++++++++++++++*/ |
329 | |
330 | static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) |
331 | { |
332 | if(_type_&XMLPARSE_TAG_START) |
333 | { |
334 | XMLPARSE_ASSERT_STRING(_tag_,type); |
335 | XMLPARSE_ASSERT_STRING(_tag_,ref); |
336 | |
337 | if(!strcmp(type,"node")) |
338 | { |
339 | node_t node_id=atoll(ref); /* need long long conversion */ |
340 | |
341 | if(relation_nnodes && (relation_nnodes%256)==0) |
342 | relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t)); |
343 | |
344 | relation_nodes[relation_nnodes++]=node_id; |
345 | |
346 | if(role) |
347 | { |
348 | if(!strcmp(role,"via")) |
349 | relation_via=node_id; |
350 | } |
351 | } |
352 | else if(!strcmp(type,"way")) |
353 | { |
354 | way_t way_id=atoll(ref); /* need long long conversion */ |
355 | |
356 | if(relation_nways && (relation_nways%256)==0) |
357 | relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t)); |
358 | |
359 | relation_ways[relation_nways++]=way_id; |
360 | |
361 | if(role) |
362 | { |
363 | if(!strcmp(role,"from")) |
364 | relation_from=way_id; |
365 | if(!strcmp(role,"to")) |
366 | relation_to=way_id; |
367 | } |
368 | } |
369 | else if(!strcmp(type,"relation")) |
370 | { |
371 | relation_t relation_id=atoll(ref); /* need long long conversion */ |
372 | |
373 | if(relation_nrelations && (relation_nrelations%256)==0) |
374 | relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t)); |
375 | |
376 | relation_relations[relation_nrelations++]=relation_id; |
377 | } |
378 | } |
379 | |
380 | return(0); |
381 | } |
382 | |
383 | |
384 | /*++++++++++++++++++++++++++++++++++++++ |
385 | The function that is called when the wayType XSD type is seen |
386 | |
387 | int wayType_function Returns 0 if no error occured or something else otherwise. |
388 | |
389 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
390 | |
391 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
392 | |
393 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
394 | ++++++++++++++++++++++++++++++++++++++*/ |
395 | |
396 | static int wayType_function(const char *_tag_,int _type_,const char *id) |
397 | { |
398 | static way_t way_id; |
399 | |
400 | if(_type_&XMLPARSE_TAG_START) |
401 | { |
402 | nways++; |
403 | |
404 | if(!(nways%1000)) |
405 | printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
406 | |
407 | current_tags=NewTagList(); |
408 | |
409 | way_nnodes=0; |
410 | |
411 | /* Handle the way information */ |
412 | |
413 | XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */ |
414 | } |
415 | |
416 | if(_type_&XMLPARSE_TAG_END) |
417 | { |
418 | TagList *result=ApplyTaggingRules(&WayRules,current_tags); |
419 | |
420 | process_way_tags(result,way_id); |
421 | |
422 | DeleteTagList(current_tags); |
423 | DeleteTagList(result); |
424 | } |
425 | |
426 | return(0); |
427 | } |
428 | |
429 | |
430 | /*++++++++++++++++++++++++++++++++++++++ |
431 | The function that is called when the relationType XSD type is seen |
432 | |
433 | int relationType_function Returns 0 if no error occured or something else otherwise. |
434 | |
435 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
436 | |
437 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
438 | |
439 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
440 | ++++++++++++++++++++++++++++++++++++++*/ |
441 | |
442 | static int relationType_function(const char *_tag_,int _type_,const char *id) |
443 | { |
444 | static relation_t relation_id; |
445 | |
446 | if(_type_&XMLPARSE_TAG_START) |
447 | { |
448 | nrelations++; |
449 | |
450 | if(!(nrelations%1000)) |
451 | printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
452 | |
453 | current_tags=NewTagList(); |
454 | |
455 | relation_nnodes=relation_nways=relation_nrelations=0; |
456 | |
457 | relation_from=NO_WAY_ID; |
458 | relation_to=NO_WAY_ID; |
459 | relation_via=NO_NODE_ID; |
460 | |
461 | /* Handle the relation information */ |
462 | |
463 | XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */ |
464 | } |
465 | |
466 | if(_type_&XMLPARSE_TAG_END) |
467 | { |
468 | TagList *result=ApplyTaggingRules(&RelationRules,current_tags); |
469 | |
470 | process_relation_tags(result,relation_id); |
471 | |
472 | DeleteTagList(current_tags); |
473 | DeleteTagList(result); |
474 | } |
475 | |
476 | return(0); |
477 | } |
478 | |
479 | |
480 | /*++++++++++++++++++++++++++++++++++++++ |
481 | The function that is called when the osmType XSD type is seen |
482 | |
483 | int osmType_function Returns 0 if no error occured or something else otherwise. |
484 | |
485 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
486 | |
487 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
488 | ++++++++++++++++++++++++++++++++++++++*/ |
489 | |
490 | //static int osmType_function(const char *_tag_,int _type_) |
491 | //{ |
492 | // return(0); |
493 | //} |
494 | |
495 | |
496 | /*++++++++++++++++++++++++++++++++++++++ |
497 | The function that is called when the XML declaration is seen |
498 | |
499 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. |
500 | |
501 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
502 | |
503 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
504 | |
505 | const char *version The contents of the 'version' attribute (or NULL if not defined). |
506 | |
507 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). |
508 | ++++++++++++++++++++++++++++++++++++++*/ |
509 | |
510 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) |
511 | //{ |
512 | // return(0); |
513 | //} |
514 | |
515 | |
516 | /*++++++++++++++++++++++++++++++++++++++ |
517 | Parse an OSM XML file (from JOSM or planet download). |
518 | |
519 | int ParseOSM Returns 0 if OK or something else in case of an error. |
520 | |
521 | FILE *file The file to read from. |
522 | |
523 | NodesX *OSMNodes The data structure of nodes to fill in. |
524 | |
525 | SegmentsX *OSMSegments The data structure of segments to fill in. |
526 | |
527 | WaysX *OSMWays The data structure of ways to fill in. |
528 | |
529 | RelationsX *OSMRelations The data structure of relations to fill in. |
530 | ++++++++++++++++++++++++++++++++++++++*/ |
531 | |
532 | int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations) |
533 | { |
534 | int retval; |
535 | |
536 | /* Copy the function parameters and initialise the variables. */ |
537 | |
538 | nodes=OSMNodes; |
539 | segments=OSMSegments; |
540 | ways=OSMWays; |
541 | relations=OSMRelations; |
542 | |
543 | way_nodes=(node_t*)malloc(256*sizeof(node_t)); |
544 | |
545 | relation_nodes =(node_t *)malloc(256*sizeof(node_t)); |
546 | relation_ways =(way_t *)malloc(256*sizeof(way_t)); |
547 | relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); |
548 | |
549 | /* Parse the file */ |
550 | |
551 | nnodes=0,nways=0,nrelations=0; |
552 | |
553 | printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0"); |
554 | |
555 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); |
556 | |
557 | printf_last("Read: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
558 | |
559 | return(retval); |
560 | } |
561 | |
562 | |
563 | /*++++++++++++++++++++++++++++++++++++++ |
564 | Process the tags associated with a node. |
565 | |
566 | TagList *tags The list of node tags. |
567 | |
568 | node_t id The id of the node. |
569 | |
570 | double latitude The latitude of the node. |
571 | |
572 | double longitude The longitude of the node. |
573 | ++++++++++++++++++++++++++++++++++++++*/ |
574 | |
575 | static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude) |
576 | { |
577 | transports_t allow=Transports_ALL; |
578 | uint16_t flags=0; |
579 | int i; |
580 | |
581 | /* Parse the tags */ |
582 | |
583 | for(i=0;i<tags->ntags;i++) |
584 | { |
585 | char *k=tags->k[i]; |
586 | char *v=tags->v[i]; |
587 | |
588 | switch(*k) |
589 | { |
590 | case 'b': |
591 | if(!strcmp(k,"bicycle")) |
592 | if(!ISTRUE(v)) |
593 | allow&=~Transports_Bicycle; |
594 | |
595 | break; |
596 | |
597 | case 'f': |
598 | if(!strcmp(k,"foot")) |
599 | if(!ISTRUE(v)) |
600 | allow&=~Transports_Foot; |
601 | |
602 | break; |
603 | |
604 | case 'g': |
605 | if(!strcmp(k,"goods")) |
606 | if(!ISTRUE(v)) |
607 | allow&=~Transports_Goods; |
608 | |
609 | break; |
610 | |
611 | case 'h': |
612 | if(!strcmp(k,"highway")) |
613 | if(!strcmp(v,"mini_roundabout")) |
614 | flags|=NODE_MINIRNDBT; |
615 | |
616 | if(!strcmp(k,"horse")) |
617 | if(!ISTRUE(v)) |
618 | allow&=~Transports_Horse; |
619 | |
620 | if(!strcmp(k,"hgv")) |
621 | if(!ISTRUE(v)) |
622 | allow&=~Transports_HGV; |
623 | |
624 | break; |
625 | |
626 | case 'm': |
627 | if(!strcmp(k,"moped")) |
628 | if(!ISTRUE(v)) |
629 | allow&=~Transports_Moped; |
630 | |
631 | if(!strcmp(k,"motorbike")) |
632 | if(!ISTRUE(v)) |
633 | allow&=~Transports_Motorbike; |
634 | |
635 | if(!strcmp(k,"motorcar")) |
636 | if(!ISTRUE(v)) |
637 | allow&=~Transports_Motorcar; |
638 | |
639 | break; |
640 | |
641 | case 'p': |
642 | if(!strcmp(k,"psv")) |
643 | if(!ISTRUE(v)) |
644 | allow&=~Transports_PSV; |
645 | |
646 | break; |
647 | |
648 | case 'w': |
649 | if(!strcmp(k,"wheelchair")) |
650 | if(!ISTRUE(v)) |
651 | allow&=~Transports_Wheelchair; |
652 | |
653 | break; |
654 | |
655 | default: |
656 | ; |
657 | } |
658 | } |
659 | |
660 | /* Create the node */ |
661 | |
662 | AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags); |
663 | } |
664 | |
665 | |
666 | /*++++++++++++++++++++++++++++++++++++++ |
667 | Process the tags associated with a way. |
668 | |
669 | TagList *tags The list of way tags. |
670 | |
671 | way_t id The id of the way. |
672 | ++++++++++++++++++++++++++++++++++++++*/ |
673 | |
674 | static void process_way_tags(TagList *tags,way_t id) |
675 | { |
676 | Way way={0}; |
677 | int oneway=0; |
678 | char *name=NULL,*ref=NULL; |
679 | int i; |
680 | |
681 | /* Parse the tags */ |
682 | |
683 | for(i=0;i<tags->ntags;i++) |
684 | { |
685 | char *k=tags->k[i]; |
686 | char *v=tags->v[i]; |
687 | |
688 | switch(*k) |
689 | { |
690 | case 'b': |
691 | if(!strcmp(k,"bicycle")) |
692 | if(ISTRUE(v)) |
693 | way.allow|= Transports_Bicycle; |
694 | |
695 | if(!strcmp(k,"bicycleroute")) |
696 | if(ISTRUE(v)) |
697 | way.props|=Properties_BicycleRoute; |
698 | |
699 | if(!strcmp(k,"bridge")) |
700 | if(ISTRUE(v)) |
701 | way.props|=Properties_Bridge; |
702 | |
703 | break; |
704 | |
705 | case 'f': |
706 | if(!strcmp(k,"foot")) |
707 | if(ISTRUE(v)) |
708 | way.allow|= Transports_Foot; |
709 | |
710 | if(!strcmp(k,"footroute")) |
711 | if(ISTRUE(v)) |
712 | way.props|=Properties_FootRoute; |
713 | |
714 | break; |
715 | |
716 | case 'g': |
717 | if(!strcmp(k,"goods")) |
718 | if(ISTRUE(v)) |
719 | way.allow|=Transports_Goods; |
720 | |
721 | break; |
722 | |
723 | case 'h': |
724 | if(!strcmp(k,"highway")) |
725 | way.type=HighwayType(v); |
726 | |
727 | if(!strcmp(k,"horse")) |
728 | if(ISTRUE(v)) |
729 | way.allow|=Transports_Horse; |
730 | |
731 | if(!strcmp(k,"hgv")) |
732 | if(ISTRUE(v)) |
733 | way.allow|=Transports_HGV; |
734 | |
735 | break; |
736 | |
737 | case 'm': |
738 | if(!strcmp(k,"maxspeed")) |
739 | { |
740 | if(strstr(v,"mph")) |
741 | way.speed=kph_to_speed(1.609*atof(v)); |
742 | else |
743 | way.speed=kph_to_speed(atof(v)); |
744 | } |
745 | |
746 | if(!strcmp(k,"maxweight")) |
747 | { |
748 | if(strstr(v,"kg")) |
749 | way.weight=tonnes_to_weight(atof(v)/1000); |
750 | else |
751 | way.weight=tonnes_to_weight(atof(v)); |
752 | } |
753 | |
754 | if(!strcmp(k,"maxheight")) |
755 | { |
756 | if(strchr(v,'\'')) |
757 | { |
758 | int feet,inches; |
759 | |
760 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
761 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
762 | else if(sscanf(v,"%d'",&feet)==1) |
763 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
764 | } |
765 | else if(strstr(v,"ft") || strstr(v,"feet")) |
766 | way.height=metres_to_height(atof(v)*0.254); |
767 | else |
768 | way.height=metres_to_height(atof(v)); |
769 | } |
770 | |
771 | if(!strcmp(k,"maxwidth")) |
772 | { |
773 | if(strchr(v,'\'')) |
774 | { |
775 | int feet,inches; |
776 | |
777 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
778 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
779 | else if(sscanf(v,"%d'",&feet)==1) |
780 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
781 | } |
782 | else if(strstr(v,"ft") || strstr(v,"feet")) |
783 | way.width=metres_to_width(atof(v)*0.254); |
784 | else |
785 | way.width=metres_to_width(atof(v)); |
786 | } |
787 | |
788 | if(!strcmp(k,"maxlength")) |
789 | { |
790 | if(strchr(v,'\'')) |
791 | { |
792 | int feet,inches; |
793 | |
794 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
795 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
796 | else if(sscanf(v,"%d'",&feet)==1) |
797 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
798 | } |
799 | else if(strstr(v,"ft") || strstr(v,"feet")) |
800 | way.length=metres_to_length(atof(v)*0.254); |
801 | else |
802 | way.length=metres_to_length(atof(v)); |
803 | } |
804 | |
805 | if(!strcmp(k,"moped")) |
806 | if(ISTRUE(v)) |
807 | way.allow|=Transports_Moped; |
808 | |
809 | if(!strcmp(k,"motorbike")) |
810 | if(ISTRUE(v)) |
811 | way.allow|=Transports_Motorbike; |
812 | |
813 | if(!strcmp(k,"motorcar")) |
814 | if(ISTRUE(v)) |
815 | way.allow|=Transports_Motorcar; |
816 | |
817 | if(!strcmp(k,"multilane")) |
818 | if(ISTRUE(v)) |
819 | way.props|=Properties_Multilane; |
820 | |
821 | break; |
822 | |
823 | case 'n': |
824 | if(!strcmp(k,"name")) |
825 | name=v; |
826 | |
827 | break; |
828 | |
829 | case 'o': |
830 | if(!strcmp(k,"oneway")) |
831 | { |
832 | if(ISTRUE(v)) |
833 | oneway=1; |
834 | else if(!strcmp(v,"-1")) |
835 | oneway=-1; |
836 | } |
837 | |
838 | break; |
839 | |
840 | case 'p': |
841 | if(!strcmp(k,"paved")) |
842 | if(ISTRUE(v)) |
843 | way.props|=Properties_Paved; |
844 | |
845 | if(!strcmp(k,"psv")) |
846 | if(ISTRUE(v)) |
847 | way.allow|=Transports_PSV; |
848 | |
849 | break; |
850 | |
851 | case 'r': |
852 | if(!strcmp(k,"ref")) |
853 | ref=v; |
854 | |
855 | break; |
856 | |
857 | case 't': |
858 | if(!strcmp(k,"tunnel")) |
859 | if(ISTRUE(v)) |
860 | way.props|=Properties_Tunnel; |
861 | |
862 | break; |
863 | |
864 | case 'w': |
865 | if(!strcmp(k,"wheelchair")) |
866 | if(ISTRUE(v)) |
867 | way.allow|=Transports_Wheelchair; |
868 | |
869 | break; |
870 | |
871 | default: |
872 | ; |
873 | } |
874 | } |
875 | |
876 | /* Create the way */ |
877 | |
878 | if(way.type>0 && way.type<Way_Count) |
879 | { |
880 | if(way.allow) |
881 | { |
882 | char *refname; |
883 | |
884 | if(oneway) |
885 | way.type|=Way_OneWay; |
886 | |
887 | if(ref && name) |
888 | { |
889 | refname=(char*)malloc(strlen(ref)+strlen(name)+4); |
890 | sprintf(refname,"%s (%s)",name,ref); |
891 | } |
892 | else if(ref && !name) |
893 | refname=ref; |
894 | else if(!ref && name) |
895 | refname=name; |
896 | else /* if(!ref && !name) */ |
897 | refname=""; |
898 | |
899 | AppendWay(ways,id,&way,refname); |
900 | |
901 | if(ref && name) |
902 | free(refname); |
903 | |
904 | for(i=1;i<way_nnodes;i++) |
905 | { |
906 | node_t from=way_nodes[i-1]; |
907 | node_t to =way_nodes[i]; |
908 | |
909 | if(oneway>0) |
910 | AppendSegment(segments,id,from,to,ONEWAY_1TO2); |
911 | else if(oneway<0) |
912 | AppendSegment(segments,id,from,to,ONEWAY_2TO1); |
913 | else |
914 | AppendSegment(segments,id,from,to,0); |
915 | } |
916 | } |
917 | } |
918 | } |
919 | |
920 | |
921 | /*++++++++++++++++++++++++++++++++++++++ |
922 | Process the tags associated with a relation. |
923 | |
924 | TagList *tags The list of relation tags. |
925 | |
926 | relation_t id The id of the relation. |
927 | ++++++++++++++++++++++++++++++++++++++*/ |
928 | |
929 | static void process_relation_tags(TagList *tags,relation_t id) |
930 | { |
931 | transports_t routes=Transports_None; |
932 | transports_t except=Transports_None; |
933 | int relation_turn_restriction=0; |
934 | TurnRestriction restriction=TurnRestrict_None; |
935 | int i; |
936 | |
937 | /* Parse the tags */ |
938 | |
939 | for(i=0;i<tags->ntags;i++) |
940 | { |
941 | char *k=tags->k[i]; |
942 | char *v=tags->v[i]; |
943 | |
944 | switch(*k) |
945 | { |
946 | case 'b': |
947 | if(!strcmp(k,"bicycleroute")) |
948 | if(ISTRUE(v)) |
949 | routes|=Transports_Bicycle; |
950 | |
951 | break; |
952 | |
953 | case 'e': |
954 | if(!strcmp(k,"except")) |
955 | for(i=1;i<Transport_Count;i++) |
956 | if(!strstr(v,TransportName(i))) |
957 | except|=TRANSPORTS(i); |
958 | |
959 | break; |
960 | |
961 | case 'f': |
962 | if(!strcmp(k,"footroute")) |
963 | if(ISTRUE(v)) |
964 | routes|=Transports_Foot; |
965 | |
966 | break; |
967 | |
968 | case 'r': |
969 | if(!strcmp(k,"restriction")) |
970 | { |
971 | if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn; |
972 | if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn; |
973 | if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn; |
974 | if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on; |
975 | if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn; |
976 | if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn; |
977 | if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on; |
978 | } |
979 | |
980 | break; |
981 | |
982 | case 't': |
983 | if(!strcmp(k,"type")) |
984 | if(!strcmp(v,"restriction")) |
985 | relation_turn_restriction=1; |
986 | break; |
987 | |
988 | default: |
989 | ; |
990 | } |
991 | } |
992 | |
993 | /* Create the route relation (must store all relations that have ways or |
994 | relations even if they are not routes because they might be referenced by |
995 | other relations that are routes) */ |
996 | |
997 | if((relation_nways || relation_nrelations) && !relation_turn_restriction) |
998 | AppendRouteRelation(relations,id,routes, |
999 | relation_ways,relation_nways, |
1000 | relation_relations,relation_nrelations); |
1001 | |
1002 | /* Create the turn restriction relation. */ |
1003 | |
1004 | if(relation_turn_restriction && restriction!=TurnRestrict_None && |
1005 | relation_from!=NO_WAY_ID && relation_to!=NO_WAY_ID && relation_via!=NO_NODE_ID) |
1006 | AppendTurnRestrictRelation(relations,id, |
1007 | relation_from,relation_to,relation_via, |
1008 | restriction,except); |
1009 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |