Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/osmparser.c
Parent Directory
|
Revision Log
Revision 401 -
(hide annotations)
(download)
(as text)
Sun May 23 10:18:59 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20795 byte(s)
Sun May 23 10:18:59 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20795 byte(s)
Fix some memory leaks.
1 | amb | 2 | /*************************************** |
2 | amb | 401 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.68 2010-05-23 10:18:58 amb Exp $ |
3 | amb | 2 | |
4 | OSM XML file parser (either JOSM or planet) | ||
5 | amb | 151 | |
6 | Part of the Routino routing software. | ||
7 | amb | 2 | ******************/ /****************** |
8 | amb | 347 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | amb | 2 | |
10 | amb | 151 | 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 | amb | 2 | ***************************************/ |
23 | |||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <ctype.h> | ||
29 | |||
30 | amb | 199 | #include "typesx.h" |
31 | #include "functionsx.h" | ||
32 | amb | 109 | #include "nodesx.h" |
33 | #include "segmentsx.h" | ||
34 | #include "waysx.h" | ||
35 | amb | 394 | #include "xmlparse.h" |
36 | #include "tagging.h" | ||
37 | amb | 2 | |
38 | amb | 26 | |
39 | amb | 394 | /* Macros */ |
40 | amb | 2 | |
41 | amb | 394 | #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1")) |
42 | amb | 297 | |
43 | amb | 298 | |
44 | amb | 394 | /* Local variables */ |
45 | |||
46 | static long nnodes=0,nways=0,nrelations=0; | ||
47 | amb | 401 | static TagList *current_tags=NULL; |
48 | amb | 394 | |
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 | amb | 228 | /* Local functions */ |
58 | |||
59 | amb | 394 | static void process_way_tags(TagList *tags,way_t id); |
60 | amb | 2 | |
61 | |||
62 | amb | 394 | /* The XML tag processing function prototypes */ |
63 | amb | 2 | |
64 | amb | 394 | //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 | amb | 399 | //static int boundType_function(const char *_tag_,int _type_); |
73 | amb | 394 | //static int boundsType_function(const char *_tag_,int _type_); |
74 | amb | 2 | |
75 | amb | 26 | |
76 | amb | 394 | /* The XML tag definitions */ |
77 | amb | 26 | |
78 | amb | 394 | /*+ The boundsType type tag. +*/ |
79 | static xmltag boundsType_tag= | ||
80 | {"bounds", | ||
81 | 0, {NULL}, | ||
82 | NULL, | ||
83 | {NULL}}; | ||
84 | amb | 26 | |
85 | amb | 399 | /*+ The boundType type tag. +*/ |
86 | static xmltag boundType_tag= | ||
87 | {"bound", | ||
88 | 0, {NULL}, | ||
89 | NULL, | ||
90 | {NULL}}; | ||
91 | |||
92 | amb | 394 | /*+ The tagType type tag. +*/ |
93 | static xmltag tagType_tag= | ||
94 | {"tag", | ||
95 | 2, {"k","v"}, | ||
96 | tagType_function, | ||
97 | {NULL}}; | ||
98 | amb | 75 | |
99 | amb | 394 | /*+ The nodeType type tag. +*/ |
100 | static xmltag nodeType_tag= | ||
101 | {"node", | ||
102 | 3, {"id","lat","lon"}, | ||
103 | nodeType_function, | ||
104 | {&tagType_tag,NULL}}; | ||
105 | amb | 2 | |
106 | amb | 394 | /*+ The ndType type tag. +*/ |
107 | static xmltag ndType_tag= | ||
108 | {"nd", | ||
109 | 1, {"ref"}, | ||
110 | ndType_function, | ||
111 | {NULL}}; | ||
112 | amb | 2 | |
113 | amb | 394 | /*+ The memberType type tag. +*/ |
114 | static xmltag memberType_tag= | ||
115 | {"member", | ||
116 | 3, {"type","ref","role"}, | ||
117 | NULL, | ||
118 | {NULL}}; | ||
119 | amb | 227 | |
120 | amb | 394 | /*+ The wayType type tag. +*/ |
121 | static xmltag wayType_tag= | ||
122 | {"way", | ||
123 | 1, {"id"}, | ||
124 | wayType_function, | ||
125 | {&ndType_tag,&tagType_tag,NULL}}; | ||
126 | amb | 2 | |
127 | amb | 394 | /*+ The relationType type tag. +*/ |
128 | static xmltag relationType_tag= | ||
129 | {"relation", | ||
130 | 1, {"id"}, | ||
131 | relationType_function, | ||
132 | {&memberType_tag,&tagType_tag,NULL}}; | ||
133 | amb | 2 | |
134 | amb | 394 | /*+ The osmType type tag. +*/ |
135 | static xmltag osmType_tag= | ||
136 | {"osm", | ||
137 | 0, {NULL}, | ||
138 | NULL, | ||
139 | amb | 399 | {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; |
140 | amb | 2 | |
141 | amb | 394 | /*+ The xmlDeclaration type tag. +*/ |
142 | static xmltag xmlDeclaration_tag= | ||
143 | {"xml", | ||
144 | 2, {"version","encoding"}, | ||
145 | NULL, | ||
146 | {NULL}}; | ||
147 | amb | 2 | |
148 | |||
149 | amb | 394 | /*+ The complete set of tags at the top level. +*/ |
150 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL}; | ||
151 | amb | 2 | |
152 | |||
153 | amb | 394 | /* The XML tag processing functions */ |
154 | amb | 2 | |
155 | amb | 159 | |
156 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
157 | The function that is called when the boundsType XSD type is seen | ||
158 | amb | 2 | |
159 | amb | 394 | int boundsType_function Returns 0 if no error occured or something else otherwise. |
160 | amb | 2 | |
161 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
162 | amb | 203 | |
163 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
164 | ++++++++++++++++++++++++++++++++++++++*/ | ||
165 | amb | 2 | |
166 | amb | 394 | //static int boundsType_function(const char *_tag_,int _type_) |
167 | //{ | ||
168 | // return(0); | ||
169 | //} | ||
170 | amb | 2 | |
171 | amb | 6 | |
172 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
173 | amb | 399 | 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 | amb | 394 | The function that is called when the tagType XSD type is seen |
190 | amb | 2 | |
191 | amb | 394 | int tagType_function Returns 0 if no error occured or something else otherwise. |
192 | amb | 314 | |
193 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
194 | amb | 2 | |
195 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
196 | amb | 30 | |
197 | amb | 394 | const char *k The contents of the 'k' attribute (or NULL if not defined). |
198 | amb | 30 | |
199 | amb | 394 | const char *v The contents of the 'v' attribute (or NULL if not defined). |
200 | ++++++++++++++++++++++++++++++++++++++*/ | ||
201 | amb | 30 | |
202 | amb | 394 | static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v) |
203 | { | ||
204 | amb | 401 | if(_type_&XMLPARSE_TAG_START && current_tags) |
205 | amb | 394 | { |
206 | XMLPARSE_ASSERT_STRING(_tag_,k); | ||
207 | XMLPARSE_ASSERT_STRING(_tag_,v); | ||
208 | amb | 30 | |
209 | amb | 401 | AppendTag(current_tags,k,v); |
210 | amb | 394 | } |
211 | amb | 262 | |
212 | amb | 394 | return(0); |
213 | } | ||
214 | amb | 308 | |
215 | amb | 313 | |
216 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
217 | The function that is called when the nodeType XSD type is seen | ||
218 | amb | 313 | |
219 | amb | 394 | int nodeType_function Returns 0 if no error occured or something else otherwise. |
220 | amb | 298 | |
221 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
222 | amb | 298 | |
223 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
224 | amb | 298 | |
225 | amb | 394 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
226 | amb | 298 | |
227 | amb | 394 | const char *lat The contents of the 'lat' attribute (or NULL if not defined). |
228 | amb | 298 | |
229 | amb | 394 | const char *lon The contents of the 'lon' attribute (or NULL if not defined). |
230 | ++++++++++++++++++++++++++++++++++++++*/ | ||
231 | amb | 2 | |
232 | amb | 394 | 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 | amb | 2 | |
239 | amb | 394 | nnodes++; |
240 | |||
241 | if(!(nnodes%1000)) | ||
242 | amb | 2 | { |
243 | amb | 394 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
244 | fflush(stdout); | ||
245 | amb | 2 | } |
246 | |||
247 | amb | 394 | /* Handle the node information */ |
248 | amb | 2 | |
249 | amb | 394 | 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 | amb | 2 | |
253 | amb | 394 | AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude)); |
254 | amb | 2 | |
255 | amb | 401 | // current_tags=NewTagList(); |
256 | current_tags=NULL; | ||
257 | amb | 394 | } |
258 | amb | 2 | |
259 | amb | 394 | // if(_type_&XMLPARSE_TAG_END) |
260 | // { | ||
261 | amb | 401 | // TagList *result=ApplyTaggingRules(&NodeRules,current_tags); |
262 | amb | 394 | // |
263 | amb | 401 | // DeleteTagList(current_tags); |
264 | amb | 394 | // DeleteTagList(result); |
265 | // } | ||
266 | amb | 2 | |
267 | amb | 394 | return(0); |
268 | } | ||
269 | amb | 2 | |
270 | |||
271 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
272 | The function that is called when the ndType XSD type is seen | ||
273 | amb | 313 | |
274 | amb | 394 | int ndType_function Returns 0 if no error occured or something else otherwise. |
275 | amb | 2 | |
276 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
277 | amb | 297 | |
278 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
279 | amb | 2 | |
280 | amb | 394 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
281 | ++++++++++++++++++++++++++++++++++++++*/ | ||
282 | amb | 2 | |
283 | amb | 394 | 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 | amb | 2 | |
289 | amb | 394 | XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */ |
290 | amb | 298 | |
291 | amb | 394 | if((way_nnodes%256)==0) |
292 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); | ||
293 | amb | 8 | |
294 | amb | 394 | way_nodes[way_nnodes++]=node_id; |
295 | } | ||
296 | amb | 51 | |
297 | amb | 394 | return(0); |
298 | } | ||
299 | amb | 308 | |
300 | amb | 298 | |
301 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
302 | The function that is called when the memberType XSD type is seen | ||
303 | amb | 298 | |
304 | amb | 394 | int memberType_function Returns 0 if no error occured or something else otherwise. |
305 | amb | 298 | |
306 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
307 | amb | 183 | |
308 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
309 | amb | 298 | |
310 | amb | 394 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
311 | amb | 183 | |
312 | amb | 394 | const char *ref The contents of the 'ref' attribute (or NULL if not defined). |
313 | amb | 298 | |
314 | amb | 394 | const char *role The contents of the 'role' attribute (or NULL if not defined). |
315 | ++++++++++++++++++++++++++++++++++++++*/ | ||
316 | amb | 183 | |
317 | amb | 394 | //static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) |
318 | //{ | ||
319 | // return(0); | ||
320 | //} | ||
321 | amb | 298 | |
322 | |||
323 | amb | 394 | /*++++++++++++++++++++++++++++++++++++++ |
324 | The function that is called when the wayType XSD type is seen | ||
325 | amb | 298 | |
326 | amb | 394 | int wayType_function Returns 0 if no error occured or something else otherwise. |
327 | amb | 298 | |
328 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
329 | amb | 51 | |
330 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
331 | amb | 51 | |
332 | amb | 394 | const char *id The contents of the 'id' attribute (or NULL if not defined). |
333 | ++++++++++++++++++++++++++++++++++++++*/ | ||
334 | amb | 51 | |
335 | amb | 394 | static int wayType_function(const char *_tag_,int _type_,const char *id) |
336 | { | ||
337 | static way_t way_id; | ||
338 | amb | 299 | |
339 | amb | 394 | if(_type_&XMLPARSE_TAG_START) |
340 | { | ||
341 | nways++; | ||
342 | amb | 51 | |
343 | amb | 394 | 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 | amb | 51 | |
349 | amb | 401 | current_tags=NewTagList(); |
350 | amb | 394 | way_nnodes=0; |
351 | amb | 298 | |
352 | amb | 394 | /* Handle the way information */ |
353 | amb | 313 | |
354 | amb | 394 | XMLPARSE_ASSERT_STRING(_tag_,id); way_id=atoll(id); /* need long long conversion */ |
355 | } | ||
356 | amb | 196 | |
357 | amb | 394 | if(_type_&XMLPARSE_TAG_END) |
358 | { | ||
359 | amb | 401 | TagList *result=ApplyTaggingRules(&WayRules,current_tags); |
360 | amb | 314 | |
361 | amb | 394 | process_way_tags(result,way_id); |
362 | amb | 2 | |
363 | amb | 401 | DeleteTagList(current_tags); |
364 | amb | 394 | 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 | amb | 2 | { |
391 | amb | 394 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations); |
392 | amb | 2 | fflush(stdout); |
393 | } | ||
394 | amb | 394 | |
395 | amb | 401 | // current_tags=NewTagList(); |
396 | current_tags=NULL; | ||
397 | amb | 2 | } |
398 | |||
399 | amb | 401 | // if(_type_&XMLPARSE_TAG_END) |
400 | // { | ||
401 | // TagList *result=ApplyTaggingRules(&RelationRules,current_tags); | ||
402 | // | ||
403 | // DeleteTagList(current_tags); | ||
404 | // DeleteTagList(result); | ||
405 | // } | ||
406 | amb | 2 | |
407 | return(0); | ||
408 | } | ||
409 | |||
410 | |||
411 | /*++++++++++++++++++++++++++++++++++++++ | ||
412 | amb | 394 | The function that is called when the osmType XSD type is seen |
413 | amb | 2 | |
414 | amb | 394 | int osmType_function Returns 0 if no error occured or something else otherwise. |
415 | amb | 2 | |
416 | amb | 394 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
417 | amb | 2 | |
418 | amb | 394 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
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 | amb | 2 | FILE *file The file to read from. |
453 | amb | 394 | |
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 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
460 | |||
461 | amb | 398 | int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays) |
462 | amb | 2 | { |
463 | amb | 394 | int retval; |
464 | amb | 2 | |
465 | amb | 394 | /* Parse the file */ |
466 | amb | 2 | |
467 | amb | 394 | 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 *highway=NULL,*name=NULL,*ref=NULL; | ||
498 | |||
499 | int i; | ||
500 | |||
501 | /* Parse the tags */ | ||
502 | |||
503 | for(i=0;i<tags->ntags;i++) | ||
504 | amb | 2 | { |
505 | amb | 394 | char *k=tags->k[i]; |
506 | char *v=tags->v[i]; | ||
507 | amb | 2 | |
508 | amb | 394 | 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 | amb | 2 | break; |
520 | amb | 394 | |
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 | { | ||
538 | highway=v; | ||
539 | way.type=HighwayType(v); | ||
540 | } | ||
541 | |||
542 | if(!strcmp(k,"horse")) | ||
543 | if(ISTRUE(v)) | ||
544 | way.allow|=Allow_Horse; | ||
545 | |||
546 | if(!strcmp(k,"hgv")) | ||
547 | if(ISTRUE(v)) | ||
548 | way.allow|=Allow_HGV; | ||
549 | |||
550 | break; | ||
551 | |||
552 | case 'j': | ||
553 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) | ||
554 | roundabout=1; | ||
555 | |||
556 | break; | ||
557 | |||
558 | case 'm': | ||
559 | if(!strcmp(k,"maxspeed")) | ||
560 | { | ||
561 | if(strstr(v,"mph")) | ||
562 | way.speed=kph_to_speed(1.609*atof(v)); | ||
563 | else | ||
564 | way.speed=kph_to_speed(atof(v)); | ||
565 | } | ||
566 | |||
567 | if(!strcmp(k,"maxweight")) | ||
568 | { | ||
569 | if(strstr(v,"kg")) | ||
570 | way.weight=tonnes_to_weight(atof(v)/1000); | ||
571 | else | ||
572 | way.weight=tonnes_to_weight(atof(v)); | ||
573 | } | ||
574 | |||
575 | if(!strcmp(k,"maxheight")) | ||
576 | { | ||
577 | if(strchr(v,'\'')) | ||
578 | { | ||
579 | int feet,inches; | ||
580 | |||
581 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) | ||
582 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
583 | else if(sscanf(v,"%d'",&feet)==1) | ||
584 | way.height=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
585 | } | ||
586 | else if(strstr(v,"ft") || strstr(v,"feet")) | ||
587 | way.height=metres_to_height(atof(v)*0.254); | ||
588 | else | ||
589 | way.height=metres_to_height(atof(v)); | ||
590 | } | ||
591 | |||
592 | if(!strcmp(k,"maxwidth")) | ||
593 | { | ||
594 | if(strchr(v,'\'')) | ||
595 | { | ||
596 | int feet,inches; | ||
597 | |||
598 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) | ||
599 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
600 | else if(sscanf(v,"%d'",&feet)==1) | ||
601 | way.width=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
602 | } | ||
603 | else if(strstr(v,"ft") || strstr(v,"feet")) | ||
604 | way.width=metres_to_width(atof(v)*0.254); | ||
605 | else | ||
606 | way.width=metres_to_width(atof(v)); | ||
607 | } | ||
608 | |||
609 | if(!strcmp(k,"maxlength")) | ||
610 | { | ||
611 | if(strchr(v,'\'')) | ||
612 | { | ||
613 | int feet,inches; | ||
614 | |||
615 | if(sscanf(v,"%d'%d\"",&feet,&inches)==2) | ||
616 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
617 | else if(sscanf(v,"%d'",&feet)==1) | ||
618 | way.length=metres_to_height((feet+(double)inches/12.0)*0.254); | ||
619 | } | ||
620 | else if(strstr(v,"ft") || strstr(v,"feet")) | ||
621 | way.length=metres_to_length(atof(v)*0.254); | ||
622 | else | ||
623 | way.length=metres_to_length(atof(v)); | ||
624 | } | ||
625 | |||
626 | if(!strcmp(k,"moped")) | ||
627 | if(ISTRUE(v)) | ||
628 | way.allow|=Allow_Moped; | ||
629 | |||
630 | if(!strcmp(k,"motorbike")) | ||
631 | if(ISTRUE(v)) | ||
632 | way.allow|=Allow_Motorbike; | ||
633 | |||
634 | if(!strcmp(k,"motorcar")) | ||
635 | if(ISTRUE(v)) | ||
636 | way.allow|=Allow_Motorcar; | ||
637 | |||
638 | if(!strcmp(k,"multilane")) | ||
639 | if(ISTRUE(v)) | ||
640 | way.props|=Properties_Multilane; | ||
641 | |||
642 | break; | ||
643 | |||
644 | case 'n': | ||
645 | if(!strcmp(k,"name")) | ||
646 | name=v; | ||
647 | |||
648 | break; | ||
649 | |||
650 | case 'o': | ||
651 | if(!strcmp(k,"oneway")) | ||
652 | { | ||
653 | if(ISTRUE(v)) | ||
654 | oneway=1; | ||
655 | else if(!strcmp(v,"-1")) | ||
656 | oneway=-1; | ||
657 | } | ||
658 | |||
659 | break; | ||
660 | |||
661 | case 'p': | ||
662 | if(!strcmp(k,"paved")) | ||
663 | if(ISTRUE(v)) | ||
664 | way.props|=Properties_Paved; | ||
665 | |||
666 | if(!strcmp(k,"psv")) | ||
667 | if(ISTRUE(v)) | ||
668 | way.allow|=Allow_PSV; | ||
669 | |||
670 | break; | ||
671 | |||
672 | case 'r': | ||
673 | if(!strcmp(k,"ref")) | ||
674 | ref=v; | ||
675 | |||
676 | break; | ||
677 | |||
678 | case 't': | ||
679 | if(!strcmp(k,"tunnel")) | ||
680 | if(ISTRUE(v)) | ||
681 | way.props|=Properties_Tunnel; | ||
682 | |||
683 | break; | ||
684 | |||
685 | case 'w': | ||
686 | if(!strcmp(k,"wheelchair")) | ||
687 | if(ISTRUE(v)) | ||
688 | way.allow|=Allow_Wheelchair; | ||
689 | |||
690 | break; | ||
691 | |||
692 | default: | ||
693 | ; | ||
694 | } | ||
695 | amb | 2 | } |
696 | |||
697 | amb | 394 | /* Create the way */ |
698 | amb | 2 | |
699 | amb | 398 | if(way.type>0 && way.type<Way_Count) |
700 | amb | 394 | { |
701 | amb | 398 | if(way.allow) |
702 | amb | 394 | { |
703 | char *refname; | ||
704 | |||
705 | if(oneway) | ||
706 | way.type|=Way_OneWay; | ||
707 | |||
708 | if(roundabout) | ||
709 | way.type|=Way_Roundabout; | ||
710 | |||
711 | if(ref && name) | ||
712 | { | ||
713 | refname=(char*)malloc(strlen(ref)+strlen(name)+4); | ||
714 | sprintf(refname,"%s (%s)",name,ref); | ||
715 | } | ||
716 | else if(ref && !name && roundabout) | ||
717 | { | ||
718 | refname=(char*)malloc(strlen(ref)+14); | ||
719 | sprintf(refname,"%s (roundabout)",ref); | ||
720 | } | ||
721 | else if(ref && !name) | ||
722 | refname=ref; | ||
723 | else if(!ref && name) | ||
724 | refname=name; | ||
725 | else if(roundabout) | ||
726 | { | ||
727 | refname=(char*)malloc(strlen(highway)+14); | ||
728 | sprintf(refname,"%s (roundabout)",highway); | ||
729 | } | ||
730 | else /* if(!ref && !name && !roundabout) */ | ||
731 | refname=highway; | ||
732 | |||
733 | AppendWay(ways,id,&way,refname); | ||
734 | |||
735 | if(refname!=ref && refname!=name && refname!=highway) | ||
736 | free(refname); | ||
737 | |||
738 | for(i=1;i<way_nnodes;i++) | ||
739 | { | ||
740 | node_t from=way_nodes[i-1]; | ||
741 | node_t to =way_nodes[i]; | ||
742 | |||
743 | if(oneway>0) | ||
744 | { | ||
745 | AppendSegment(segments,id,from,to,ONEWAY_1TO2); | ||
746 | AppendSegment(segments,id,to,from,ONEWAY_2TO1); | ||
747 | } | ||
748 | else if(oneway<0) | ||
749 | { | ||
750 | AppendSegment(segments,id,from,to,ONEWAY_2TO1); | ||
751 | AppendSegment(segments,id,to,from,ONEWAY_1TO2); | ||
752 | } | ||
753 | else | ||
754 | { | ||
755 | AppendSegment(segments,id,from,to,0); | ||
756 | AppendSegment(segments,id,to,from,0); | ||
757 | } | ||
758 | } | ||
759 | } | ||
760 | } | ||
761 | amb | 2 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |