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 136 - (hide annotations) (download) (as text)
Sun Mar 1 17:24:44 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 15236 byte(s)
Added more limits (weight, height, width, length).
Added highway=living_street and highway=services.

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

Properties

Name Value
cvs:description OSM XML file parser.