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

1 amb 2 /***************************************
2 amb 73 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.15 2009-01-23 16:05:38 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 73 waytype_t type;
111 amb 6 char *refname;
112 amb 30 int i;
113 amb 2
114 amb 73 type=TypeOfWay(way_highway);
115 amb 6
116 amb 73 if(type!=Way_Unknown)
117 amb 2 {
118 amb 73 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 amb 2
140 amb 73 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 amb 2
146 amb 73 segment=AppendSegment(OSMSegments,from,to,way_id);
147 amb 35
148 amb 73 segment=AppendSegment(OSMSegments,to,from,way_id);
149 amb 2
150 amb 73 if(way_oneway)
151     segment->distance=ONEWAY_OPPOSITE;
152     }
153 amb 6
154 amb 73 way=AppendWay(OSMWays,way_id,refname);
155 amb 68
156 amb 73 way->limit=way_maxspeed;
157 amb 30
158 amb 73 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 amb 30
198 amb 73 if(way_allow_no) /* Remove the ones explicitly denied (e.g. private) */
199     way->allow&=~way_allow_no;
200 amb 51
201 amb 73 if(way_allow_yes) /* Add the ones explicitly allowed (e.g. footpath along private) */
202     way->allow|=way_allow_yes;
203 amb 51
204 amb 73 if(way_oneway)
205     way->type|=Way_OneWay;
206 amb 30
207 amb 73 if(way_roundabout)
208     way->type|=Way_Roundabout;
209 amb 30
210 amb 73 if(refname!=way_ref && refname!=way_name && refname!=way_highway)
211     free(refname);
212     }
213 amb 2 }
214    
215 amb 51 if(way_highway) free(way_highway);
216     if(way_name) free(way_name);
217     if(way_ref) free(way_ref);
218 amb 2 }
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 amb 51 switch(*k)
257     {
258     case 'a':
259     if(!strcmp(k,"access"))
260 amb 72 if(!strcmp(v,"private") || !strcmp(v,"no"))
261 amb 51 way_allow_no=~0;
262     break;
263 amb 2
264 amb 51 case 'b':
265     if(!strcmp(k,"bicycle"))
266     {
267 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
268 amb 51 way_allow_yes|=Allow_Bicycle;
269     else
270     way_allow_no|=Allow_Bicycle;
271     }
272     break;
273 amb 2
274 amb 51 case 'f':
275     if(!strcmp(k,"foot"))
276     {
277 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
278 amb 51 way_allow_yes|=Allow_Foot;
279     else
280     way_allow_no|=Allow_Foot;
281     }
282     break;
283 amb 2
284 amb 51 case 'g':
285     if(!strcmp(k,"goods"))
286     {
287 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
288 amb 51 way_allow_yes|=Allow_Goods;
289     else
290     way_allow_no|=Allow_Goods;
291     }
292     break;
293 amb 2
294 amb 51 case 'h':
295     if(!strcmp(k,"highway"))
296     {
297     if(!strncmp(v,"motorway",8)) way_oneway=1;
298 amb 2
299 amb 51 way_highway=strcpy((char*)malloc(strlen(v)+1),v);
300     }
301     if(!strcmp(k,"horse"))
302     {
303 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
304 amb 51 way_allow_yes|=Allow_Horse;
305     else
306     way_allow_no|=Allow_Horse;
307     }
308     if(!strcmp(k,"hgv"))
309     {
310 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
311 amb 51 way_allow_yes|=Allow_HGV;
312     else
313     way_allow_no|=Allow_HGV;
314     }
315     break;
316 amb 8
317 amb 51 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 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
333 amb 51 way_allow_yes|=Allow_Motorbike;
334     else
335     way_allow_no|=Allow_Motorbike;
336     }
337     if(!strcmp(k,"motorcar"))
338     {
339 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
340 amb 51 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 amb 72 if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"permissive"))
361 amb 51 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 amb 2 }
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 amb 35 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",nlines,nnodes,nways,nrelations);
389 amb 2 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.