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