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 69 -
(show annotations)
(download)
(as text)
Thu Jan 22 19:48:53 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 12471 byte(s)
Thu Jan 22 19:48:53 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 12471 byte(s)
Remove INVALID_DISTANCE and INVALID_DURATION.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.13 2009-01-22 19:48:53 amb Exp $ |
3 | |
4 | OSM XML file parser (either JOSM or planet) |
5 | ******************/ /****************** |
6 | Written by Andrew M. Bishop |
7 | |
8 | This file Copyright 2008,2009 Andrew M. Bishop |
9 | It may be distributed under the GNU Public License, version 2, or |
10 | any higher version. See section COPYING of the GNU Public license |
11 | for conditions under which this file may be redistributed. |
12 | ***************************************/ |
13 | |
14 | |
15 | #include <stdio.h> |
16 | #include <stdlib.h> |
17 | #include <string.h> |
18 | #include <ctype.h> |
19 | |
20 | #include "nodes.h" |
21 | #include "ways.h" |
22 | #include "segments.h" |
23 | #include "functions.h" |
24 | |
25 | |
26 | #define BUFFSIZE 64 |
27 | |
28 | static char *fgets_realloc(char *buffer,FILE *file); |
29 | |
30 | |
31 | /*++++++++++++++++++++++++++++++++++++++ |
32 | Parse an OSM XML file (from JOSM or planet download). |
33 | |
34 | int ParseXML Returns 0 if OK or something else in case of an error. |
35 | |
36 | FILE *file The file to read from. |
37 | |
38 | NodesMem *OSMNodes The array of nodes to fill in. |
39 | |
40 | SegmentsMem *OSMSegments The array of segments to fill in. |
41 | |
42 | WaysMem *OSMWays The arrray of ways to fill in. |
43 | ++++++++++++++++++++++++++++++++++++++*/ |
44 | |
45 | int ParseXML(FILE *file,NodesMem *OSMNodes,SegmentsMem *OSMSegments,WaysMem *OSMWays) |
46 | { |
47 | char *line=NULL; |
48 | long nlines=0; |
49 | long nnodes=0,nways=0,nrelations=0; |
50 | int isnode=0,isway=0,isrelation=0; |
51 | way_t way_id=0; |
52 | int way_oneway=0,way_roundabout=0; |
53 | speed_t way_maxspeed=0; |
54 | char *way_highway=NULL,*way_name=NULL,*way_ref=NULL; |
55 | wayallow_t way_allow_no=0,way_allow_yes=0; |
56 | node_t *way_nodes=NULL; |
57 | int way_nnodes=0,way_nalloc=0; |
58 | |
59 | /* Parse the file */ |
60 | |
61 | while((line=fgets_realloc(line,file))) |
62 | { |
63 | char *l=line,*m; |
64 | |
65 | nlines++; |
66 | |
67 | while(isspace(*l)) |
68 | l++; |
69 | |
70 | if(!strncmp(l,"<node",5)) /* The start of a node */ |
71 | { |
72 | node_t id; |
73 | latlong_t latitude,longitude; |
74 | |
75 | nnodes++; |
76 | |
77 | isnode=1; isway=0; isrelation=0; |
78 | |
79 | m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m); |
80 | m=strstr(l,"lat="); m+=5; if(*m=='"' || *m=='\'') m++; latitude=atof(m); |
81 | m=strstr(l,"lon="); m+=4; if(*m=='"' || *m=='\'') m++; longitude=atof(m); |
82 | |
83 | AppendNode(OSMNodes,id,latitude,longitude); |
84 | } |
85 | else if(!strncmp(l,"</node",6)) /* The end of a node */ |
86 | { |
87 | isnode=0; isway=0; isrelation=0; |
88 | } |
89 | else if(!strncmp(l,"<way",4)) /* The start of a way */ |
90 | { |
91 | nways++; |
92 | |
93 | isnode=0; isway=1; isrelation=0; |
94 | |
95 | m=strstr(l,"id="); m+=3; if(*m=='"' || *m=='\'') m++; way_id=atol(m); |
96 | |
97 | way_oneway=0; way_roundabout=0; |
98 | way_maxspeed=0; |
99 | way_highway=NULL; way_name=NULL; way_ref=NULL; |
100 | way_allow_no=0; way_allow_yes=0; |
101 | way_nnodes=0; |
102 | } |
103 | else if(!strncmp(l,"</way",5)) /* The end of a way */ |
104 | { |
105 | isnode=0; isway=0; isrelation=0; |
106 | |
107 | if(way_highway) |
108 | { |
109 | Way *way; |
110 | char *refname; |
111 | int i; |
112 | |
113 | if(way_ref && way_name) |
114 | { |
115 | refname=(char*)malloc(strlen(way_ref)+strlen(way_name)+4); |
116 | sprintf(refname,"%s (%s)",way_name,way_ref); |
117 | } |
118 | else if(way_ref && !way_name && way_roundabout) |
119 | { |
120 | refname=(char*)malloc(strlen(way_ref)+14); |
121 | sprintf(refname,"%s (roundabout)",way_ref); |
122 | } |
123 | else if(way_ref && !way_name) |
124 | refname=way_ref; |
125 | else if(!way_ref && way_name) |
126 | refname=way_name; |
127 | else if(way_roundabout) |
128 | { |
129 | refname=(char*)malloc(strlen(way_highway)+14); |
130 | sprintf(refname,"%s (roundabout)",way_highway); |
131 | } |
132 | else /* if(!way_ref && !way_name && !way_roundabout) */ |
133 | refname=way_highway; |
134 | |
135 | for(i=1;i<way_nnodes;i++) |
136 | { |
137 | node_t from=way_nodes[i-1]; |
138 | node_t to =way_nodes[i]; |
139 | Segment *segment; |
140 | |
141 | segment=AppendSegment(OSMSegments,from,to,way_id); |
142 | |
143 | segment=AppendSegment(OSMSegments,to,from,way_id); |
144 | |
145 | if(way_oneway) |
146 | segment->distance=ONEWAY_OPPOSITE; |
147 | } |
148 | |
149 | way=AppendWay(OSMWays,way_id,refname); |
150 | |
151 | way->limit=way_maxspeed; |
152 | |
153 | way->type=TypeOfWay(way_highway); |
154 | |
155 | switch(way->type) |
156 | { |
157 | case Way_Motorway: |
158 | way->allow=Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
159 | break; |
160 | case Way_Trunk: |
161 | way->allow=Allow_Bicycle|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
162 | break; |
163 | case Way_Primary: |
164 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
165 | break; |
166 | case Way_Secondary: |
167 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
168 | break; |
169 | case Way_Tertiary: |
170 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
171 | break; |
172 | case Way_Unclassfied: |
173 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
174 | break; |
175 | case Way_Residential: |
176 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
177 | break; |
178 | case Way_Service: |
179 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV; |
180 | break; |
181 | case Way_Track: |
182 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar; |
183 | break; |
184 | case Way_Bridleway: |
185 | way->allow=Allow_Foot|Allow_Bicycle|Allow_Horse; |
186 | break; |
187 | case Way_Cycleway: |
188 | way->allow=Allow_Foot|Allow_Bicycle; |
189 | break; |
190 | case Way_Footway: |
191 | way->allow=Allow_Foot; |
192 | break; |
193 | case Way_Unknown: |
194 | way->allow=0; |
195 | } |
196 | |
197 | if(way_allow_no) /* Remove the ones explicitly denied (e.g. private) */ |
198 | way->allow&=~way_allow_no; |
199 | |
200 | if(way_allow_yes) /* Add the ones explicitly allowed (e.g. footpath along private) */ |
201 | way->allow|=way_allow_yes; |
202 | |
203 | if(way_oneway) |
204 | way->type|=Way_OneWay; |
205 | |
206 | if(way_roundabout) |
207 | way->type|=Way_Roundabout; |
208 | |
209 | if(refname!=way_ref && refname!=way_name && refname!=way_highway) |
210 | free(refname); |
211 | } |
212 | |
213 | if(way_highway) free(way_highway); |
214 | if(way_name) free(way_name); |
215 | if(way_ref) free(way_ref); |
216 | } |
217 | else if(!strncmp(l,"<relation",9)) /* The start of a relation */ |
218 | { |
219 | nrelations++; |
220 | |
221 | isnode=0; isway=0; isrelation=1; |
222 | } |
223 | else if(!strncmp(l,"</relation",10)) /* The end of a relation */ |
224 | { |
225 | isnode=0; isway=0; isrelation=0; |
226 | } |
227 | else if(isnode) /* The middle of a node */ |
228 | { |
229 | } |
230 | else if(isway) /* The middle of a way */ |
231 | { |
232 | node_t id; |
233 | |
234 | if(!strncmp(l,"<nd",3)) /* The start of a node specifier */ |
235 | { |
236 | m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m); |
237 | |
238 | if(way_nnodes<=way_nalloc) |
239 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=16)*sizeof(node_t)); |
240 | |
241 | way_nodes[way_nnodes++]=id; |
242 | } |
243 | |
244 | if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */ |
245 | { |
246 | char delimiter,*k="",*v=""; |
247 | |
248 | m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m; |
249 | while(*m!=delimiter) m++; *m=0; l=m+1; |
250 | |
251 | m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m; |
252 | while(*m!=delimiter) m++; *m=0; |
253 | |
254 | switch(*k) |
255 | { |
256 | case 'a': |
257 | if(!strcmp(k,"access")) |
258 | if(!strcmp(v,"private")) |
259 | way_allow_no=~0; |
260 | break; |
261 | |
262 | case 'b': |
263 | if(!strcmp(k,"bicycle")) |
264 | { |
265 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
266 | way_allow_yes|=Allow_Bicycle; |
267 | else |
268 | way_allow_no|=Allow_Bicycle; |
269 | } |
270 | break; |
271 | |
272 | case 'f': |
273 | if(!strcmp(k,"foot")) |
274 | { |
275 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
276 | way_allow_yes|=Allow_Foot; |
277 | else |
278 | way_allow_no|=Allow_Foot; |
279 | } |
280 | break; |
281 | |
282 | case 'g': |
283 | if(!strcmp(k,"goods")) |
284 | { |
285 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
286 | way_allow_yes|=Allow_Goods; |
287 | else |
288 | way_allow_no|=Allow_Goods; |
289 | } |
290 | break; |
291 | |
292 | case 'h': |
293 | if(!strcmp(k,"highway")) |
294 | { |
295 | if(!strncmp(v,"motorway",8)) way_oneway=1; |
296 | |
297 | way_highway=strcpy((char*)malloc(strlen(v)+1),v); |
298 | } |
299 | if(!strcmp(k,"horse")) |
300 | { |
301 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
302 | way_allow_yes|=Allow_Horse; |
303 | else |
304 | way_allow_no|=Allow_Horse; |
305 | } |
306 | if(!strcmp(k,"hgv")) |
307 | { |
308 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
309 | way_allow_yes|=Allow_HGV; |
310 | else |
311 | way_allow_no|=Allow_HGV; |
312 | } |
313 | break; |
314 | |
315 | case 'j': |
316 | if(!strcmp(k,"junction")) |
317 | if(!strcmp(v,"roundabout")) |
318 | {way_oneway=1; way_roundabout=1;} |
319 | break; |
320 | |
321 | case 'm': |
322 | if(!strcmp(k,"maxspeed")) |
323 | { |
324 | way_maxspeed=atof(v); |
325 | if(strstr(v,"mph")) |
326 | way_maxspeed*=1.6; |
327 | } |
328 | if(!strcmp(k,"motorbike")) |
329 | { |
330 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
331 | way_allow_yes|=Allow_Motorbike; |
332 | else |
333 | way_allow_no|=Allow_Motorbike; |
334 | } |
335 | if(!strcmp(k,"motorcar")) |
336 | { |
337 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
338 | way_allow_yes|=Allow_Motorcar; |
339 | else |
340 | way_allow_no|=Allow_Motorcar; |
341 | } |
342 | break; |
343 | |
344 | case 'n': |
345 | if(!strcmp(k,"name")) |
346 | way_name=strcpy((char*)malloc(strlen(v)+1),v); |
347 | break; |
348 | |
349 | case 'o': |
350 | if(!strcmp(k,"oneway")) |
351 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
352 | way_oneway=1; |
353 | break; |
354 | |
355 | case 'p': |
356 | if(!strcmp(k,"psv")) |
357 | { |
358 | if(!strcmp(v,"true") || !strcmp(v,"yes")) |
359 | way_allow_yes|=Allow_PSV; |
360 | else |
361 | way_allow_no|=Allow_PSV; |
362 | } |
363 | break; |
364 | |
365 | case 'r': |
366 | if(!strcmp(k,"ref")) |
367 | way_ref=strcpy((char*)malloc(strlen(v)+1),v); |
368 | break; |
369 | |
370 | default: |
371 | ; |
372 | } |
373 | } |
374 | } |
375 | else if(isrelation) /* The middle of a relation */ |
376 | { |
377 | } |
378 | |
379 | if(!(nlines%10000)) |
380 | { |
381 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations); |
382 | fflush(stdout); |
383 | } |
384 | } |
385 | |
386 | printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",nlines,nnodes,nways,nrelations); |
387 | fflush(stdout); |
388 | |
389 | if(way_nalloc) |
390 | free(way_nodes); |
391 | |
392 | return(0); |
393 | } |
394 | |
395 | |
396 | /*++++++++++++++++++++++++++++++++++++++ |
397 | Call fgets and realloc the buffer as needed to get a whole line. |
398 | |
399 | char *fgets_realloc Returns the modified buffer (NULL at the end of the file). |
400 | |
401 | char *buffer The current buffer. |
402 | |
403 | FILE *file The file to read from. |
404 | ++++++++++++++++++++++++++++++++++++++*/ |
405 | |
406 | static char *fgets_realloc(char *buffer,FILE *file) |
407 | { |
408 | int n=0; |
409 | char *buf; |
410 | |
411 | if(!buffer) |
412 | buffer=(char*)malloc(BUFFSIZE+1); |
413 | |
414 | while((buf=fgets(&buffer[n],BUFFSIZE,file))) |
415 | { |
416 | int s=strlen(buf); |
417 | n+=s; |
418 | |
419 | if(buffer[n-1]=='\n') |
420 | break; |
421 | else |
422 | buffer=(char*)realloc(buffer,n+BUFFSIZE+1); |
423 | } |
424 | |
425 | if(!buf) |
426 | {free(buffer);buffer=NULL;} |
427 | |
428 | return(buffer); |
429 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |