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 411 -
(show annotations)
(download)
(as text)
Sat May 29 13:54:43 2010 UTC (14 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20360 byte(s)
Sat May 29 13:54:43 2010 UTC (14 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20360 byte(s)
Translate the names given to unnamed roads (the highway type).
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.69 2010-05-29 13:54:23 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=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 && current_tags) |
205 | { |
206 | XMLPARSE_ASSERT_STRING(_tag_,k); |
207 | XMLPARSE_ASSERT_STRING(_tag_,v); |
208 | |
209 | AppendTag(current_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=NewTagList(); |
256 | current_tags=NULL; |
257 | } |
258 | |
259 | // if(_type_&XMLPARSE_TAG_END) |
260 | // { |
261 | // TagList *result=ApplyTaggingRules(&NodeRules,current_tags); |
262 | // |
263 | // DeleteTagList(current_tags); |
264 | // DeleteTagList(result); |
265 | // } |
266 | |
267 | return(0); |
268 | } |
269 | |
270 | |
271 | /*++++++++++++++++++++++++++++++++++++++ |
272 | The function that is called when the ndType XSD type is seen |
273 | |
274 | int ndType_function Returns 0 if no error occured or something else otherwise. |
275 | |
276 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
277 | |
278 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
279 | |
280 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
281 | ++++++++++++++++++++++++++++++++++++++*/ |
282 | |
283 | static int ndType_function(const char *_tag_,int _type_,const char *ref) |
284 | { |
285 | if(_type_&XMLPARSE_TAG_START) |
286 | { |
287 | node_t node_id; |
288 | |
289 | XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */ |
290 | |
291 | if((way_nnodes%256)==0) |
292 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); |
293 | |
294 | way_nodes[way_nnodes++]=node_id; |
295 | } |
296 | |
297 | return(0); |
298 | } |
299 | |
300 | |
301 | /*++++++++++++++++++++++++++++++++++++++ |
302 | The function that is called when the memberType XSD type is seen |
303 | |
304 | int memberType_function Returns 0 if no error occured or something else otherwise. |
305 | |
306 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
307 | |
308 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
309 | |
310 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
311 | |
312 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
313 | |
314 | const char *role The contents of the 'role' attribute (or NULL if not defined). |
315 | ++++++++++++++++++++++++++++++++++++++*/ |
316 | |
317 | //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) |
318 | //{ |
319 | // return(0); |
320 | //} |
321 | |
322 | |
323 | /*++++++++++++++++++++++++++++++++++++++ |
324 | The function that is called when the wayType XSD type is seen |
325 | |
326 | int wayType_function Returns 0 if no error occured or something else otherwise. |
327 | |
328 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
329 | |
330 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
331 | |
332 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
333 | ++++++++++++++++++++++++++++++++++++++*/ |
334 | |
335 | static int wayType_function(const char *_tag_,int _type_,const char *id) |
336 | { |
337 | static way_t way_id; |
338 | |
339 | if(_type_&XMLPARSE_TAG_START) |
340 | { |
341 | nways++; |
342 | |
343 | if(!(nways%1000)) |
344 | { |
345 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
346 | fflush(stdout); |
347 | } |
348 | |
349 | current_tags=NewTagList(); |
350 | way_nnodes=0; |
351 | |
352 | /* Handle the way information */ |
353 | |
354 | XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */ |
355 | } |
356 | |
357 | if(_type_&XMLPARSE_TAG_END) |
358 | { |
359 | TagList *result=ApplyTaggingRules(&WayRules,current_tags); |
360 | |
361 | process_way_tags(result,way_id); |
362 | |
363 | DeleteTagList(current_tags); |
364 | DeleteTagList(result); |
365 | } |
366 | |
367 | return(0); |
368 | } |
369 | |
370 | |
371 | /*++++++++++++++++++++++++++++++++++++++ |
372 | The function that is called when the relationType XSD type is seen |
373 | |
374 | int relationType_function Returns 0 if no error occured or something else otherwise. |
375 | |
376 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
377 | |
378 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
379 | |
380 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
381 | ++++++++++++++++++++++++++++++++++++++*/ |
382 | |
383 | static int relationType_function(const char *_tag_,int _type_,const char *id) |
384 | { |
385 | if(_type_&XMLPARSE_TAG_START) |
386 | { |
387 | nrelations++; |
388 | |
389 | if(!(nrelations%1000)) |
390 | { |
391 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
392 | fflush(stdout); |
393 | } |
394 | |
395 | // current_tags=NewTagList(); |
396 | current_tags=NULL; |
397 | } |
398 | |
399 | // if(_type_&XMLPARSE_TAG_END) |
400 | // { |
401 | // TagList *result=ApplyTaggingRules(&RelationRules,current_tags); |
402 | // |
403 | // DeleteTagList(current_tags); |
404 | // DeleteTagList(result); |
405 | // } |
406 | |
407 | return(0); |
408 | } |
409 | |
410 | |
411 | /*++++++++++++++++++++++++++++++++++++++ |
412 | The function that is called when the osmType XSD type is seen |
413 | |
414 | int osmType_function Returns 0 if no error occured or something else otherwise. |
415 | |
416 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
417 | |
418 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
419 | ++++++++++++++++++++++++++++++++++++++*/ |
420 | |
421 | //static int osmType_function(const char *_tag_,int _type_) |
422 | //{ |
423 | // return(0); |
424 | //} |
425 | |
426 | |
427 | /*++++++++++++++++++++++++++++++++++++++ |
428 | The function that is called when the XML declaration is seen |
429 | |
430 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. |
431 | |
432 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
433 | |
434 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
435 | |
436 | const char *version The contents of the 'version' attribute (or NULL if not defined). |
437 | |
438 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). |
439 | ++++++++++++++++++++++++++++++++++++++*/ |
440 | |
441 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) |
442 | //{ |
443 | // return(0); |
444 | //} |
445 | |
446 | |
447 | /*++++++++++++++++++++++++++++++++++++++ |
448 | Parse an OSM XML file (from JOSM or planet download). |
449 | |
450 | int ParseOSM Returns 0 if OK or something else in case of an error. |
451 | |
452 | FILE *file The file to read from. |
453 | |
454 | NodesX *OSMNodes The array of nodes to fill in. |
455 | |
456 | SegmentsX *OSMSegments The array of segments to fill in. |
457 | |
458 | WaysX *OSMWays The arrray of ways to fill in. |
459 | ++++++++++++++++++++++++++++++++++++++*/ |
460 | |
461 | int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays) |
462 | { |
463 | int retval; |
464 | |
465 | /* Parse the file */ |
466 | |
467 | nodes=OSMNodes; |
468 | segments=OSMSegments; |
469 | ways=OSMWays; |
470 | |
471 | nnodes=0,nways=0,nrelations=0; |
472 | |
473 | printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0"); |
474 | fflush(stdout); |
475 | |
476 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); |
477 | |
478 | printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations); |
479 | fflush(stdout); |
480 | |
481 | return(retval); |
482 | } |
483 | |
484 | |
485 | /*++++++++++++++++++++++++++++++++++++++ |
486 | Process the tags associated with a way. |
487 | |
488 | TagList *tags The list of way tags. |
489 | |
490 | way_t id The id of the way. |
491 | ++++++++++++++++++++++++++++++++++++++*/ |
492 | |
493 | static void process_way_tags(TagList *tags,way_t id) |
494 | { |
495 | Way way={0}; |
496 | int oneway=0,roundabout=0; |
497 | char *name=NULL,*ref=NULL; |
498 | |
499 | int i; |
500 | |
501 | /* Parse the tags */ |
502 | |
503 | for(i=0;i<tags->ntags;i++) |
504 | { |
505 | char *k=tags->k[i]; |
506 | char *v=tags->v[i]; |
507 | |
508 | switch(*k) |
509 | { |
510 | case 'b': |
511 | if(!strcmp(k,"bicycle")) |
512 | if(ISTRUE(v)) |
513 | way.allow|= Allow_Bicycle; |
514 | |
515 | if(!strcmp(k,"bridge")) |
516 | if(ISTRUE(v)) |
517 | way.props|=Properties_Bridge; |
518 | |
519 | break; |
520 | |
521 | case 'f': |
522 | if(!strcmp(k,"foot")) |
523 | if(ISTRUE(v)) |
524 | way.allow|= Allow_Foot; |
525 | |
526 | break; |
527 | |
528 | case 'g': |
529 | if(!strcmp(k,"goods")) |
530 | if(ISTRUE(v)) |
531 | way.allow|=Allow_Goods; |
532 | |
533 | break; |
534 | |
535 | case 'h': |
536 | if(!strcmp(k,"highway")) |
537 | way.type=HighwayType(v); |
538 | |
539 | if(!strcmp(k,"horse")) |
540 | if(ISTRUE(v)) |
541 | way.allow|=Allow_Horse; |
542 | |
543 | if(!strcmp(k,"hgv")) |
544 | if(ISTRUE(v)) |
545 | way.allow|=Allow_HGV; |
546 | |
547 | break; |
548 | |
549 | case 'j': |
550 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) |
551 | roundabout=1; |
552 | |
553 | break; |
554 | |
555 | case 'm': |
556 | if(!strcmp(k,"maxspeed")) |
557 | { |
558 | if(strstr(v,"mph")) |
559 | way.speed=kph_to_speed(1.609*atof(v)); |
560 | else |
561 | way.speed=kph_to_speed(atof(v)); |
562 | } |
563 | |
564 | if(!strcmp(k,"maxweight")) |
565 | { |
566 | if(strstr(v,"kg")) |
567 | way.weight=tonnes_to_weight(atof(v)/1000); |
568 | else |
569 | way.weight=tonnes_to_weight(atof(v)); |
570 | } |
571 | |
572 | if(!strcmp(k,"maxheight")) |
573 | { |
574 | if(strchr(v,'\'')) |
575 | { |
576 | int feet,inches; |
577 | |
578 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
579 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
580 | else if(sscanf(v,"%d'",&feet)==1) |
581 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); |
582 | } |
583 | else if(strstr(v,"ft") || strstr(v,"feet")) |
584 | way.height=metres_to_height(atof(v)*0.254); |
585 | else |
586 | way.height=metres_to_height(atof(v)); |
587 | } |
588 | |
589 | if(!strcmp(k,"maxwidth")) |
590 | { |
591 | if(strchr(v,'\'')) |
592 | { |
593 | int feet,inches; |
594 | |
595 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
596 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
597 | else if(sscanf(v,"%d'",&feet)==1) |
598 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); |
599 | } |
600 | else if(strstr(v,"ft") || strstr(v,"feet")) |
601 | way.width=metres_to_width(atof(v)*0.254); |
602 | else |
603 | way.width=metres_to_width(atof(v)); |
604 | } |
605 | |
606 | if(!strcmp(k,"maxlength")) |
607 | { |
608 | if(strchr(v,'\'')) |
609 | { |
610 | int feet,inches; |
611 | |
612 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) |
613 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
614 | else if(sscanf(v,"%d'",&feet)==1) |
615 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); |
616 | } |
617 | else if(strstr(v,"ft") || strstr(v,"feet")) |
618 | way.length=metres_to_length(atof(v)*0.254); |
619 | else |
620 | way.length=metres_to_length(atof(v)); |
621 | } |
622 | |
623 | if(!strcmp(k,"moped")) |
624 | if(ISTRUE(v)) |
625 | way.allow|=Allow_Moped; |
626 | |
627 | if(!strcmp(k,"motorbike")) |
628 | if(ISTRUE(v)) |
629 | way.allow|=Allow_Motorbike; |
630 | |
631 | if(!strcmp(k,"motorcar")) |
632 | if(ISTRUE(v)) |
633 | way.allow|=Allow_Motorcar; |
634 | |
635 | if(!strcmp(k,"multilane")) |
636 | if(ISTRUE(v)) |
637 | way.props|=Properties_Multilane; |
638 | |
639 | break; |
640 | |
641 | case 'n': |
642 | if(!strcmp(k,"name")) |
643 | name=v; |
644 | |
645 | break; |
646 | |
647 | case 'o': |
648 | if(!strcmp(k,"oneway")) |
649 | { |
650 | if(ISTRUE(v)) |
651 | oneway=1; |
652 | else if(!strcmp(v,"-1")) |
653 | oneway=-1; |
654 | } |
655 | |
656 | break; |
657 | |
658 | case 'p': |
659 | if(!strcmp(k,"paved")) |
660 | if(ISTRUE(v)) |
661 | way.props|=Properties_Paved; |
662 | |
663 | if(!strcmp(k,"psv")) |
664 | if(ISTRUE(v)) |
665 | way.allow|=Allow_PSV; |
666 | |
667 | break; |
668 | |
669 | case 'r': |
670 | if(!strcmp(k,"ref")) |
671 | ref=v; |
672 | |
673 | break; |
674 | |
675 | case 't': |
676 | if(!strcmp(k,"tunnel")) |
677 | if(ISTRUE(v)) |
678 | way.props|=Properties_Tunnel; |
679 | |
680 | break; |
681 | |
682 | case 'w': |
683 | if(!strcmp(k,"wheelchair")) |
684 | if(ISTRUE(v)) |
685 | way.allow|=Allow_Wheelchair; |
686 | |
687 | break; |
688 | |
689 | default: |
690 | ; |
691 | } |
692 | } |
693 | |
694 | /* Create the way */ |
695 | |
696 | if(way.type>0 && way.type<Way_Count) |
697 | { |
698 | if(way.allow) |
699 | { |
700 | char *refname; |
701 | |
702 | if(oneway) |
703 | way.type|=Way_OneWay; |
704 | |
705 | if(roundabout) |
706 | way.type|=Way_Roundabout; |
707 | |
708 | if(ref && name) |
709 | { |
710 | refname=(char*)malloc(strlen(ref)+strlen(name)+4); |
711 | sprintf(refname,"%s (%s)",name,ref); |
712 | } |
713 | else if(ref && !name) |
714 | refname=ref; |
715 | else if(!ref && name) |
716 | refname=name; |
717 | else /* if(!ref && !name) */ |
718 | refname=""; |
719 | |
720 | AppendWay(ways,id,&way,refname); |
721 | |
722 | if(ref && name) |
723 | free(refname); |
724 | |
725 | for(i=1;i<way_nnodes;i++) |
726 | { |
727 | node_t from=way_nodes[i-1]; |
728 | node_t to =way_nodes[i]; |
729 | |
730 | if(oneway>0) |
731 | { |
732 | AppendSegment(segments,id,from,to,ONEWAY_1TO2); |
733 | AppendSegment(segments,id,to,from,ONEWAY_2TO1); |
734 | } |
735 | else if(oneway<0) |
736 | { |
737 | AppendSegment(segments,id,from,to,ONEWAY_2TO1); |
738 | AppendSegment(segments,id,to,from,ONEWAY_1TO2); |
739 | } |
740 | else |
741 | { |
742 | AppendSegment(segments,id,from,to,0); |
743 | AppendSegment(segments,id,to,from,0); |
744 | } |
745 | } |
746 | } |
747 | } |
748 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |