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 121 - (hide annotations) (download) (as text)
Sun Feb 15 14:30:11 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 13498 byte(s)
Store radians rather than degrees.

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

Properties

Name Value
cvs:description OSM XML file parser.