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 92 - (hide annotations) (download) (as text)
Fri Jan 30 19:57:09 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 13034 byte(s)
Remove gcc warning.

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

Properties

Name Value
cvs:description OSM XML file parser.