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