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 399 -
(show annotations)
(download)
(as text)
Sun May 23 08:24:26 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20611 byte(s)
Sun May 23 08:24:26 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20611 byte(s)
Add the 'bound' element to the XML parser.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.67 2010-05-23 08:24:10 amb Exp $ |
3 | |
4 | OSM XML file parser (either JOSM or planet) |
5 | |
6 | Part of the Routino routing software. |
7 | ******************/ /****************** |
8 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | |
10 | This program is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU Affero General Public License as published by |
12 | the Free Software Foundation, either version 3 of the License, or |
13 | (at your option) any later version. |
14 | |
15 | This program is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public License |
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
22 | ***************************************/ |
23 | |
24 | |
25 | #include <stdio.h> |
26 | #include <stdlib.h> |
27 | #include <string.h> |
28 | #include <ctype.h> |
29 | |
30 | #include "typesx.h" |
31 | #include "functionsx.h" |
32 | #include "nodesx.h" |
33 | #include "segmentsx.h" |
34 | #include "waysx.h" |
35 | #include "xmlparse.h" |
36 | #include "tagging.h" |
37 | |
38 | |
39 | /* Macros */ |
40 | |
41 | #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1")) |
42 | |
43 | |
44 | /* Local variables */ |
45 | |
46 | static long nnodes=0,nways=0,nrelations=0; |
47 | static TagList current_tags={0,NULL,NULL}; |
48 | |
49 | static node_t *way_nodes=NULL; |
50 | static int way_nnodes=0; |
51 | |
52 | static NodesX *nodes; |
53 | static SegmentsX *segments; |
54 | static WaysX *ways; |
55 | |
56 | |
57 | /* Local functions */ |
58 | |
59 | static void process_way_tags(TagList *tags,way_t id); |
60 | |
61 | |
62 | /* The XML tag processing function prototypes */ |
63 | |
64 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); |
65 | //static int osmType_function(const char *_tag_,int _type_); |
66 | static int relationType_function(const char *_tag_,int _type_,const char *id); |
67 | static int wayType_function(const char *_tag_,int _type_,const char *id); |
68 | //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); |
69 | static int ndType_function(const char *_tag_,int _type_,const char *ref); |
70 | static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon); |
71 | static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v); |
72 | //static int boundType_function(const char *_tag_,int _type_); |
73 | //static int boundsType_function(const char *_tag_,int _type_); |
74 | |
75 | |
76 | /* The XML tag definitions */ |
77 | |
78 | /*+ The boundsType type tag. +*/ |
79 | static xmltag boundsType_tag= |
80 | {"bounds", |
81 | 0, {NULL}, |
82 | NULL, |
83 | {NULL}}; |
84 | |
85 | /*+ The boundType type tag. +*/ |
86 | static xmltag boundType_tag= |
87 | {"bound", |
88 | 0, {NULL}, |
89 | NULL, |
90 | {NULL}}; |
91 | |
92 | /*+ The tagType type tag. +*/ |
93 | static xmltag tagType_tag= |
94 | {"tag", |
95 | 2, {"k","v"}, |
96 | tagType_function, |
97 | {NULL}}; |
98 | |
99 | /*+ The nodeType type tag. +*/ |
100 | static xmltag nodeType_tag= |
101 | {"node", |
102 | 3, {"id","lat","lon"}, |
103 | nodeType_function, |
104 | {&tagType_tag,NULL}}; |
105 | |
106 | /*+ The ndType type tag. +*/ |
107 | static xmltag ndType_tag= |
108 | {"nd", |
109 | 1, {"ref"}, |
110 | ndType_function, |
111 | {NULL}}; |
112 | |
113 | /*+ The memberType type tag. +*/ |
114 | static xmltag memberType_tag= |
115 | {"member", |
116 | 3, {"type","ref","role"}, |
117 | NULL, |
118 | {NULL}}; |
119 | |
120 | /*+ The wayType type tag. +*/ |
121 | static xmltag wayType_tag= |
122 | {"way", |
123 | 1, {"id"}, |
124 | wayType_function, |
125 | {&ndType_tag,&tagType_tag,NULL}}; |
126 | |
127 | /*+ The relationType type tag. +*/ |
128 | static xmltag relationType_tag= |
129 | {"relation", |
130 | 1, {"id"}, |
131 | relationType_function, |
132 | {&memberType_tag,&tagType_tag,NULL}}; |
133 | |
134 | /*+ The osmType type tag. +*/ |
135 | static xmltag osmType_tag= |
136 | {"osm", |
137 | 0, {NULL}, |
138 | NULL, |
139 | {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; |
140 | |
141 | /*+ The xmlDeclaration type tag. +*/ |
142 | static xmltag xmlDeclaration_tag= |
143 | {"xml", |
144 | 2, {"version","encoding"}, |
145 | NULL, |
146 | {NULL}}; |
147 | |
148 | |
149 | /*+ The complete set of tags at the top level. +*/ |
150 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL}; |
151 | |
152 | |
153 | /* The XML tag processing functions */ |
154 | |
155 | |
156 | /*++++++++++++++++++++++++++++++++++++++ |
157 | The function that is called when the boundsType XSD type is seen |
158 | |
159 | int boundsType_function Returns 0 if no error occured or something else otherwise. |
160 | |
161 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
162 | |
163 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
164 | ++++++++++++++++++++++++++++++++++++++*/ |
165 | |
166 | //static int boundsType_function(const char *_tag_,int _type_) |
167 | //{ |
168 | // return(0); |
169 | //} |
170 | |
171 | |
172 | /*++++++++++++++++++++++++++++++++++++++ |
173 | The function that is called when the boundType XSD type is seen |
174 | |
175 | int boundType_function Returns 0 if no error occured or something else otherwise. |
176 | |
177 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
178 | |
179 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
180 | ++++++++++++++++++++++++++++++++++++++*/ |
181 | |
182 | //static int boundType_function(const char *_tag_,int _type_) |
183 | //{ |
184 | // return(0); |
185 | //} |
186 | |
187 | |
188 | /*++++++++++++++++++++++++++++++++++++++ |
189 | The function that is called when the tagType XSD type is seen |
190 | |
191 | int tagType_function Returns 0 if no error occured or something else otherwise. |
192 | |
193 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
194 | |
195 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
196 | |
197 | const char *k The contents of the 'k' attribute (or NULL if not defined). |
198 | |
199 | const char *v The contents of the 'v' attribute (or NULL if not defined). |
200 | ++++++++++++++++++++++++++++++++++++++*/ |
201 | |
202 | static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v) |
203 | { |
204 | if(_type_&XMLPARSE_TAG_START) |
205 | { |
206 | XMLPARSE_ASSERT_STRING(_tag_,k); |
207 | XMLPARSE_ASSERT_STRING(_tag_,v); |
208 | |
209 | AppendTag(¤t_tags,k,v); |
210 | } |
211 | |
212 | return(0); |
213 | } |
214 | |
215 | |
216 | /*++++++++++++++++++++++++++++++++++++++ |
217 | The function that is called when the nodeType XSD type is seen |
218 | |
219 | int nodeType_function Returns 0 if no error occured or something else otherwise. |
220 | |
221 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
222 | |
223 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
224 | |
225 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
226 | |
227 | const char *lat The contents of the 'lat' attribute (or NULL if not defined). |
228 | |
229 | const char *lon The contents of the 'lon' attribute (or NULL if not defined). |
230 | ++++++++++++++++++++++++++++++++++++++*/ |
231 | |
232 | static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon) |
233 | { |
234 | if(_type_&XMLPARSE_TAG_START) |
235 | { |
236 | node_t node_id; |
237 | double latitude,longitude; |
238 | |
239 | nnodes++; |
240 | |
241 | if(!(nnodes%1000)) |
242 | { |
243 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
244 | fflush(stdout); |
245 | } |
246 | |
247 | /* Handle the node information */ |
248 | |
249 | XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */ |
250 | XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude); |
251 | XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude); |
252 | |
253 | AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude)); |
254 | |
255 | current_tags.ntags=0; |
256 | } |
257 | |
258 | // if(_type_&XMLPARSE_TAG_END) |
259 | // { |
260 | // TagList *result=ApplyTaggingRules(&NodeRules,¤t_tags); |
261 | // |
262 | // DeleteTagList(result); |
263 | // } |
264 | |
265 | return(0); |
266 | } |
267 | |
268 | |
269 | /*++++++++++++++++++++++++++++++++++++++ |
270 | The function that is called when the ndType XSD type is seen |
271 | |
272 | int ndType_function Returns 0 if no error occured or something else otherwise. |
273 | |
274 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
275 | |
276 | 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 | |
278 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
279 | ++++++++++++++++++++++++++++++++++++++*/ |
280 | |
281 | static int ndType_function(const char *_tag_,int _type_,const char *ref) |
282 | { |
283 | if(_type_&XMLPARSE_TAG_START) |
284 | { |
285 | node_t node_id; |
286 | |
287 | XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */ |
288 | |
289 | if((way_nnodes%256)==0) |
290 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); |
291 | |
292 | way_nodes[way_nnodes++]=node_id; |
293 | } |
294 | |
295 | return(0); |
296 | } |
297 | |
298 | |
299 | /*++++++++++++++++++++++++++++++++++++++ |
300 | The function that is called when the memberType XSD type is seen |
301 | |
302 | int memberType_function Returns 0 if no error occured or something else otherwise. |
303 | |
304 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
305 | |
306 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
307 | |
308 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
309 | |
310 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
311 | |
312 | const char *role The contents of the 'role' attribute (or NULL if not defined). |
313 | ++++++++++++++++++++++++++++++++++++++*/ |
314 | |
315 | //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) |
316 | //{ |
317 | // return(0); |
318 | //} |
319 | |
320 | |
321 | /*++++++++++++++++++++++++++++++++++++++ |
322 | The function that is called when the wayType XSD type is seen |
323 | |
324 | int wayType_function Returns 0 if no error occured or something else otherwise. |
325 | |
326 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
327 | |
328 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
329 | |
330 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
331 | ++++++++++++++++++++++++++++++++++++++*/ |
332 | |
333 | static int wayType_function(const char *_tag_,int _type_,const char *id) |
334 | { |
335 | static way_t way_id; |
336 | |
337 | if(_type_&XMLPARSE_TAG_START) |
338 | { |
339 | nways++; |
340 | |
341 | if(!(nways%1000)) |
342 | { |
343 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
344 | fflush(stdout); |
345 | } |
346 | |
347 | current_tags.ntags=0; |
348 | way_nnodes=0; |
349 | |
350 | /* Handle the way information */ |
351 | |
352 | XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */ |
353 | } |
354 | |
355 | if(_type_&XMLPARSE_TAG_END) |
356 | { |
357 | TagList *result=ApplyTaggingRules(&WayRules,¤t_tags); |
358 | |
359 | process_way_tags(result,way_id); |
360 | |
361 | DeleteTagList(result); |
362 | } |
363 | |
364 | return(0); |
365 | } |
366 | |
367 | |
368 | /*++++++++++++++++++++++++++++++++++++++ |
369 | The function that is called when the relationType XSD type is seen |
370 | |
371 | int relationType_function Returns 0 if no error occured or something else otherwise. |
372 | |
373 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
374 | |
375 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
376 | |
377 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
378 | ++++++++++++++++++++++++++++++++++++++*/ |
379 | |
380 | static int relationType_function(const char *_tag_,int _type_,const char *id) |
381 | { |
382 | if(_type_&XMLPARSE_TAG_START) |
383 | { |
384 | nrelations++; |
385 | |
386 | if(!(nrelations%1000)) |
387 | { |
388 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
389 | fflush(stdout); |
390 | } |
391 | |
392 | current_tags.ntags=0; |
393 | } |
394 | |
395 | if(_type_&XMLPARSE_TAG_END) |
396 | { |
397 | TagList *result=ApplyTaggingRules(&RelationRules,¤t_tags); |
398 | |
399 | DeleteTagList(result); |
400 | } |
401 | |
402 | return(0); |
403 | } |
404 | |
405 | |
406 | /*++++++++++++++++++++++++++++++++++++++ |
407 | The function that is called when the osmType XSD type is seen |
408 | |
409 | int osmType_function Returns 0 if no error occured or something else otherwise. |
410 | |
411 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
412 | |
413 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
414 | ++++++++++++++++++++++++++++++++++++++*/ |
415 | |
416 | //static int osmType_function(const char *_tag_,int _type_) |
417 | //{ |
418 | // return(0); |
419 | //} |
420 | |
421 | |
422 | /*++++++++++++++++++++++++++++++++++++++ |
423 | The function that is called when the XML declaration is seen |
424 | |
425 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. |
426 | |
427 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
428 | |
429 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
430 | |
431 | const char *version The contents of the 'version' attribute (or NULL if not defined). |
432 | |
433 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). |
434 | ++++++++++++++++++++++++++++++++++++++*/ |
435 | |
436 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) |
437 | //{ |
438 | // return(0); |
439 | //} |
440 | |
441 | |
442 | /*++++++++++++++++++++++++++++++++++++++ |
443 | Parse an OSM XML file (from JOSM or planet download). |
444 | |
445 | int ParseOSM Returns 0 if OK or something else in case of an error. |
446 | |
447 | FILE *file The file to read from. |
448 | |
449 | NodesX *OSMNodes The array of nodes to fill in. |
450 | |
451 | SegmentsX *OSMSegments The array of segments to fill in. |
452 | |
453 | WaysX *OSMWays The arrray of ways to fill in. |
454 | ++++++++++++++++++++++++++++++++++++++*/ |
455 | |
456 | int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays) |
457 | { |
458 | int retval; |
459 | |
460 | /* Parse the file */ |
461 | |
462 | nodes=OSMNodes; |
463 | segments=OSMSegments; |
464 | ways=OSMWays; |
465 | |
466 | nnodes=0,nways=0,nrelations=0; |
467 | |
468 | printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0"); |
469 | fflush(stdout); |
470 | |
471 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); |
472 | |
473 | printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations); |
474 | fflush(stdout); |
475 | |
476 | return(retval); |
477 | } |
478 | |
479 | |
480 | /*++++++++++++++++++++++++++++++++++++++ |
481 | Process the tags associated with a way. |
482 | |
483 | TagList *tags The list of way tags. |
484 | |
485 | way_t id The id of the way. |
486 | ++++++++++++++++++++++++++++++++++++++*/ |
487 | |
488 | static void process_way_tags(TagList *tags,way_t id) |
489 | { |
490 | Way way={0}; |
491 | int oneway=0,roundabout=0; |
492 | char *highway=NULL,*name=NULL,*ref=NULL; |
493 | |
494 | int i; |
495 | |
496 | /* Parse the tags */ |
497 | |
498 | for(i=0;i<tags->ntags;i++) |
499 | { |
500 | char *k=tags->k[i]; |
501 | char *v=tags->v[i]; |
502 | |
503 | switch(*k) |
504 | { |
505 | case 'b': |
506 | if(!strcmp(k,"bicycle")) |
507 | if(ISTRUE(v)) |
508 | way.allow|= Allow_Bicycle; |
509 | |
510 | if(!strcmp(k,"bridge")) |
511 | if(ISTRUE(v)) |
512 | way.props|=Properties_Bridge; |
513 | |
514 | break; |
515 | |
516 | case 'f': |
517 | if(!strcmp(k,"foot")) |
518 | if(ISTRUE(v)) |
519 | way.allow|= Allow_Foot; |
520 | |
521 | break; |
522 | |
523 | case 'g': |
524 | if(!strcmp(k,"goods")) |
525 | if(ISTRUE(v)) |
526 | way.allow|=Allow_Goods; |
527 | |
528 | break; |
529 | |
530 | case 'h': |
531 | if(!strcmp(k,"highway")) |
532 | { |
533 | highway=v; |
534 | way.type=HighwayType(v); |
535 | } |
536 | |
537 | if(!strcmp(k,"horse")) |
538 | if(ISTRUE(v)) |
539 | way.allow|=Allow_Horse; |
540 | |
541 | if(!strcmp(k,"hgv")) |
542 | if(ISTRUE(v)) |
543 | way.allow|=Allow_HGV; |
544 | |
545 | break; |
546 | |
547 | case 'j': |
548 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) |
549 | roundabout=1; |
550 | |
551 | break; |
552 | |
553 | case 'm': |
554 | if(!strcmp(k,"maxspeed")) |
555 | { |
556 | if(strstr(v,"mph")) |
557 | way.speed=kph_to_speed(1.609*atof(v)); |
558 | else |
559 | way.speed=kph_to_speed(atof(v)); |
560 | } |
561 | |
562 | if(!strcmp(k,"maxweight")) |
563 | { |
564 | if(strstr(v,"kg")) |
565 | way.weight=tonnes_to_weight(atof(v)/1000); |
566 | else |
567 | way.weight=tonnes_to_weight(atof(v)); |
568 | } |
569 | |
570 | if(!strcmp(k,"maxheight")) |
571 | { |
572 | if(strchr(v,'\'')) |
573 | { |
574 | int feet,inches; |
575 | |
576 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
577 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
578 | else if(sscanf(v,"%d'",&feet)==1) |
579 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
580 | } |
581 | else if(strstr(v,"ft") || strstr(v,"feet")) |
582 | way.height=metres_to_height(atof(v)*0.254); |
583 | else |
584 | way.height=metres_to_height(atof(v)); |
585 | } |
586 | |
587 | if(!strcmp(k,"maxwidth")) |
588 | { |
589 | if(strchr(v,'\'')) |
590 | { |
591 | int feet,inches; |
592 | |
593 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
594 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
595 | else if(sscanf(v,"%d'",&feet)==1) |
596 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
597 | } |
598 | else if(strstr(v,"ft") || strstr(v,"feet")) |
599 | way.width=metres_to_width(atof(v)*0.254); |
600 | else |
601 | way.width=metres_to_width(atof(v)); |
602 | } |
603 | |
604 | if(!strcmp(k,"maxlength")) |
605 | { |
606 | if(strchr(v,'\'')) |
607 | { |
608 | int feet,inches; |
609 | |
610 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
611 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
612 | else if(sscanf(v,"%d'",&feet)==1) |
613 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
614 | } |
615 | else if(strstr(v,"ft") || strstr(v,"feet")) |
616 | way.length=metres_to_length(atof(v)*0.254); |
617 | else |
618 | way.length=metres_to_length(atof(v)); |
619 | } |
620 | |
621 | if(!strcmp(k,"moped")) |
622 | if(ISTRUE(v)) |
623 | way.allow|=Allow_Moped; |
624 | |
625 | if(!strcmp(k,"motorbike")) |
626 | if(ISTRUE(v)) |
627 | way.allow|=Allow_Motorbike; |
628 | |
629 | if(!strcmp(k,"motorcar")) |
630 | if(ISTRUE(v)) |
631 | way.allow|=Allow_Motorcar; |
632 | |
633 | if(!strcmp(k,"multilane")) |
634 | if(ISTRUE(v)) |
635 | way.props|=Properties_Multilane; |
636 | |
637 | break; |
638 | |
639 | case 'n': |
640 | if(!strcmp(k,"name")) |
641 | name=v; |
642 | |
643 | break; |
644 | |
645 | case 'o': |
646 | if(!strcmp(k,"oneway")) |
647 | { |
648 | if(ISTRUE(v)) |
649 | oneway=1; |
650 | else if(!strcmp(v,"-1")) |
651 | oneway=-1; |
652 | } |
653 | |
654 | break; |
655 | |
656 | case 'p': |
657 | if(!strcmp(k,"paved")) |
658 | if(ISTRUE(v)) |
659 | way.props|=Properties_Paved; |
660 | |
661 | if(!strcmp(k,"psv")) |
662 | if(ISTRUE(v)) |
663 | way.allow|=Allow_PSV; |
664 | |
665 | break; |
666 | |
667 | case 'r': |
668 | if(!strcmp(k,"ref")) |
669 | ref=v; |
670 | |
671 | break; |
672 | |
673 | case 't': |
674 | if(!strcmp(k,"tunnel")) |
675 | if(ISTRUE(v)) |
676 | way.props|=Properties_Tunnel; |
677 | |
678 | break; |
679 | |
680 | case 'w': |
681 | if(!strcmp(k,"wheelchair")) |
682 | if(ISTRUE(v)) |
683 | way.allow|=Allow_Wheelchair; |
684 | |
685 | break; |
686 | |
687 | default: |
688 | ; |
689 | } |
690 | } |
691 | |
692 | /* Create the way */ |
693 | |
694 | if(way.type>0 && way.type<Way_Count) |
695 | { |
696 | if(way.allow) |
697 | { |
698 | char *refname; |
699 | |
700 | if(oneway) |
701 | way.type|=Way_OneWay; |
702 | |
703 | if(roundabout) |
704 | way.type|=Way_Roundabout; |
705 | |
706 | if(ref && name) |
707 | { |
708 | refname=(char*)malloc(strlen(ref)+strlen(name)+4); |
709 | sprintf(refname,"%s (%s)",name,ref); |
710 | } |
711 | else if(ref && !name && roundabout) |
712 | { |
713 | refname=(char*)malloc(strlen(ref)+14); |
714 | sprintf(refname,"%s (roundabout)",ref); |
715 | } |
716 | else if(ref && !name) |
717 | refname=ref; |
718 | else if(!ref && name) |
719 | refname=name; |
720 | else if(roundabout) |
721 | { |
722 | refname=(char*)malloc(strlen(highway)+14); |
723 | sprintf(refname,"%s (roundabout)",highway); |
724 | } |
725 | else /* if(!ref && !name && !roundabout) */ |
726 | refname=highway; |
727 | |
728 | AppendWay(ways,id,&way,refname); |
729 | |
730 | if(refname!=ref && refname!=name && refname!=highway) |
731 | free(refname); |
732 | |
733 | for(i=1;i<way_nnodes;i++) |
734 | { |
735 | node_t from=way_nodes[i-1]; |
736 | node_t to =way_nodes[i]; |
737 | |
738 | if(oneway>0) |
739 | { |
740 | AppendSegment(segments,id,from,to,ONEWAY_1TO2); |
741 | AppendSegment(segments,id,to,from,ONEWAY_2TO1); |
742 | } |
743 | else if(oneway<0) |
744 | { |
745 | AppendSegment(segments,id,from,to,ONEWAY_2TO1); |
746 | AppendSegment(segments,id,to,from,ONEWAY_1TO2); |
747 | } |
748 | else |
749 | { |
750 | AppendSegment(segments,id,from,to,0); |
751 | AppendSegment(segments,id,to,from,0); |
752 | } |
753 | } |
754 | } |
755 | } |
756 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |