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 75 - (show annotations) (download) (as text)
Fri Jan 23 17:09:41 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 13100 byte(s)
Add command line options to planetsplitter and router.
Select transport type (must be allowed on way for parsing).
Select highway types (ignore when parsing or routing).

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.17 2009-01-23 17:09:41 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 Transport transport The method of transport that must be allowed on the way.
45
46 int highways[] An array of flags indicating the highway type.
47 ++++++++++++++++++++++++++++++++++++++*/
48
49 int ParseXML(FILE *file,NodesMem *OSMNodes,SegmentsMem *OSMSegments,WaysMem *OSMWays,Transport transport,int highways[])
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 way_t way_id=0;
56 int way_oneway=0,way_roundabout=0;
57 speed_t way_maxspeed=0;
58 char *way_highway=NULL,*way_name=NULL,*way_ref=NULL;
59 wayallow_t way_allow_no=0,way_allow_yes=0;
60 node_t *way_nodes=NULL;
61 int way_nnodes=0,way_nalloc=0;
62 wayallow_t mustallow=1<<(transport-1);
63
64 /* Parse the file */
65
66 while((line=fgets_realloc(line,file)))
67 {
68 char *l=line,*m;
69
70 nlines++;
71
72 while(isspace(*l))
73 l++;
74
75 if(!strncmp(l,"<node",5)) /* The start of a node */
76 {
77 node_t id;
78 latlong_t latitude,longitude;
79
80 nnodes++;
81
82 isnode=1; isway=0; isrelation=0;
83
84 m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
85 m=strstr(l,"lat="); m+=5; if(*m=='"' || *m=='\'') m++; latitude=atof(m);
86 m=strstr(l,"lon="); m+=4; if(*m=='"' || *m=='\'') m++; longitude=atof(m);
87
88 AppendNode(OSMNodes,id,latitude,longitude);
89 }
90 else if(!strncmp(l,"</node",6)) /* The end of a node */
91 {
92 isnode=0; isway=0; isrelation=0;
93 }
94 else if(!strncmp(l,"<way",4)) /* The start of a way */
95 {
96 nways++;
97
98 isnode=0; isway=1; isrelation=0;
99
100 m=strstr(l,"id="); m+=3; if(*m=='"' || *m=='\'') m++; way_id=atol(m);
101
102 way_oneway=0; way_roundabout=0;
103 way_maxspeed=0;
104 way_highway=NULL; way_name=NULL; way_ref=NULL;
105 way_allow_no=0; way_allow_yes=0;
106 way_nnodes=0;
107 }
108 else if(!strncmp(l,"</way",5)) /* The end of a way */
109 {
110 isnode=0; isway=0; isrelation=0;
111
112 if(way_highway)
113 {
114 Way *way;
115 waytype_t type;
116 wayallow_t allow;
117 char *refname;
118 int i;
119
120 type=HighwayType(way_highway);
121
122 switch(type)
123 {
124 case Way_Motorway:
125 allow=Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
126 break;
127 case Way_Trunk:
128 allow=Allow_Bicycle|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
129 break;
130 case Way_Primary:
131 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
132 break;
133 case Way_Secondary:
134 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
135 break;
136 case Way_Tertiary:
137 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
138 break;
139 case Way_Unclassfied:
140 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
141 break;
142 case Way_Residential:
143 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
144 break;
145 case Way_Service:
146 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
147 break;
148 case Way_Track:
149 allow=Allow_Foot|Allow_Bicycle|Allow_Horse|Allow_Motorbike|Allow_Motorcar;
150 break;
151 case Way_Bridleway:
152 allow=Allow_Foot|Allow_Bicycle|Allow_Horse;
153 break;
154 case Way_Cycleway:
155 allow=Allow_Foot|Allow_Bicycle;
156 break;
157 case Way_Footway:
158 allow=Allow_Foot;
159 break;
160 }
161
162 if(way_allow_no) /* Remove the ones explicitly denied (e.g. private) */
163 allow&=~way_allow_no;
164
165 if(way_allow_yes) /* Add the ones explicitly allowed (e.g. footpath along private) */
166 allow|=way_allow_yes;
167
168 if(allow&mustallow && highways[type])
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 for(i=1;i<way_nnodes;i++)
193 {
194 node_t from=way_nodes[i-1];
195 node_t to =way_nodes[i];
196 Segment *segment;
197
198 segment=AppendSegment(OSMSegments,from,to,way_id);
199
200 segment=AppendSegment(OSMSegments,to,from,way_id);
201
202 if(way_oneway)
203 segment->distance=ONEWAY_OPPOSITE;
204 }
205
206 way=AppendWay(OSMWays,way_id,refname);
207
208 way->limit=way_maxspeed;
209
210 way->type=type;
211
212 way->allow=allow;
213
214 if(way_oneway)
215 way->type|=Way_OneWay;
216
217 if(way_roundabout)
218 way->type|=Way_Roundabout;
219
220 if(refname!=way_ref && refname!=way_name && refname!=way_highway)
221 free(refname);
222 }
223 }
224
225 if(way_highway) free(way_highway);
226 if(way_name) free(way_name);
227 if(way_ref) free(way_ref);
228 }
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 switch(*k)
267 {
268 case 'a':
269 if(!strcmp(k,"access"))
270 if(!strcmp(v,"private") || !strcmp(v,"no"))
271 way_allow_no=~0;
272 break;
273
274 case 'b':
275 if(!strcmp(k,"bicycle"))
276 {
277 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
278 way_allow_yes|=Allow_Bicycle;
279 else
280 way_allow_no|=Allow_Bicycle;
281 }
282 break;
283
284 case 'f':
285 if(!strcmp(k,"foot"))
286 {
287 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
288 way_allow_yes|=Allow_Foot;
289 else
290 way_allow_no|=Allow_Foot;
291 }
292 break;
293
294 case 'g':
295 if(!strcmp(k,"goods"))
296 {
297 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
298 way_allow_yes|=Allow_Goods;
299 else
300 way_allow_no|=Allow_Goods;
301 }
302 break;
303
304 case 'h':
305 if(!strcmp(k,"highway"))
306 {
307 if(!strncmp(v,"motorway",8)) way_oneway=1;
308
309 way_highway=strcpy((char*)malloc(strlen(v)+1),v);
310 }
311 if(!strcmp(k,"horse"))
312 {
313 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
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") || !strcmp(v,"permissive"))
321 way_allow_yes|=Allow_HGV;
322 else
323 way_allow_no|=Allow_HGV;
324 }
325 break;
326
327 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") || !strcmp(v,"permissive"))
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") || !strcmp(v,"permissive"))
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") || !strcmp(v,"permissive"))
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 }
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 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",nlines,nnodes,nways,nrelations);
399 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.