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