Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/osmparser.c

Parent Directory Parent Directory | Revision Log 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)
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.