Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/osmparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 125 - (show annotations) (download) (as text)
Sun Feb 15 19:12:25 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 13642 byte(s)
Add in tests for motorcar=1 etc.

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

Properties

Name Value
cvs:description OSM XML file parser.