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 82 - (hide annotations) (download) (as text)
Sun Jan 25 10:58:52 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 12986 byte(s)
Added profiles to define speed and allowed highways.
Added new options to planetsplitter and router to use the profiles.

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

Properties

Name Value
cvs:description OSM XML file parser.