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 78 - (hide annotations) (download) (as text)
Fri Jan 23 19:31:48 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 13131 byte(s)
Fix bug with not specifying a method of transport.

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

Properties

Name Value
cvs:description OSM XML file parser.