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 73 - (show annotations) (download) (as text)
Fri Jan 23 16:05:38 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 12976 byte(s)
Only include ways that are not Way_Unknown type.

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

Properties

Name Value
cvs:description OSM XML file parser.