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 117 - (show annotations) (download) (as text)
Sun Feb 15 13:45:28 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 13458 byte(s)
Handle oneway=1 and oneway=-1.

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

Properties

Name Value
cvs:description OSM XML file parser.