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 297 - (hide annotations) (download) (as text)
Tue Oct 27 18:48:53 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 18652 byte(s)
Handle the "designation=..." tag for bridleway, byway and footpath.  (Also
change to using a macro for testing if access is allowed and now allow
"destination").

1 amb 2 /***************************************
2 amb 297 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.55 2009-10-27 18:48:53 amb Exp $
3 amb 2
4     OSM XML file parser (either JOSM or planet)
5 amb 151
6     Part of the Routino routing software.
7 amb 2 ******************/ /******************
8 amb 151 This file Copyright 2008,2009 Andrew M. Bishop
9 amb 2
10 amb 151 This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU Affero General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU Affero General Public License for more details.
19    
20     You should have received a copy of the GNU Affero General Public License
21     along with this program. If not, see <http://www.gnu.org/licenses/>.
22 amb 2 ***************************************/
23    
24    
25     #include <stdio.h>
26     #include <stdlib.h>
27     #include <string.h>
28     #include <ctype.h>
29    
30 amb 199 #include "typesx.h"
31     #include "functionsx.h"
32 amb 109 #include "nodesx.h"
33     #include "segmentsx.h"
34     #include "waysx.h"
35 amb 228 #include "ways.h"
36 amb 2
37 amb 26
38 amb 228 /*+ The length of the buffer and the size increment for reading lines from the file. +*/
39 amb 244 #define BUFFSIZE 256
40 amb 2
41 amb 297 #define ISALLOWED(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1") || !strcmp(xx,"permissive") || !strcmp(xx,"designated") || !strcmp(xx,"destination"))
42    
43 amb 228 /* Local functions */
44    
45 amb 2 static char *fgets_realloc(char *buffer,FILE *file);
46    
47    
48     /*++++++++++++++++++++++++++++++++++++++
49     Parse an OSM XML file (from JOSM or planet download).
50    
51     int ParseXML Returns 0 if OK or something else in case of an error.
52    
53     FILE *file The file to read from.
54 amb 26
55 amb 97 NodesX *OSMNodes The array of nodes to fill in.
56 amb 26
57 amb 97 SegmentsX *OSMSegments The array of segments to fill in.
58 amb 26
59 amb 97 WaysX *OSMWays The arrray of ways to fill in.
60 amb 75
61 amb 228 Profile *profile A profile of the allowed transport types and included/excluded highway types.
62 amb 2 ++++++++++++++++++++++++++++++++++++++*/
63    
64 amb 97 int ParseXML(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,Profile *profile)
65 amb 2 {
66     char *line=NULL;
67     long nlines=0;
68     long nnodes=0,nways=0,nrelations=0;
69     int isnode=0,isway=0,isrelation=0;
70 amb 203 way_t way_id=0;
71 amb 6 int way_oneway=0,way_roundabout=0;
72 amb 51 speed_t way_maxspeed=0;
73 amb 136 weight_t way_maxweight=0;
74     height_t way_maxheight=0;
75     width_t way_maxwidth=0;
76     length_t way_maxlength=0;
77 amb 51 char *way_highway=NULL,*way_name=NULL,*way_ref=NULL;
78     wayallow_t way_allow_no=0,way_allow_yes=0;
79 amb 2 node_t *way_nodes=NULL;
80     int way_nnodes=0,way_nalloc=0;
81    
82 amb 227 printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
83     fflush(stdout);
84    
85 amb 2 /* Parse the file */
86    
87     while((line=fgets_realloc(line,file)))
88     {
89     char *l=line,*m;
90    
91     nlines++;
92    
93     while(isspace(*l))
94     l++;
95    
96     if(!strncmp(l,"<node",5)) /* The start of a node */
97     {
98     node_t id;
99 amb 219 double latitude,longitude;
100 amb 2
101     nnodes++;
102    
103     isnode=1; isway=0; isrelation=0;
104    
105     m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
106 amb 198 m=strstr(l,"lat="); m+=5; if(*m=='"' || *m=='\'') m++; latitude=degrees_to_radians(atof(m));
107     m=strstr(l,"lon="); m+=4; if(*m=='"' || *m=='\'') m++; longitude=degrees_to_radians(atof(m));
108 amb 2
109 amb 26 AppendNode(OSMNodes,id,latitude,longitude);
110 amb 159
111     if(strstr(l,"/>")) /* The end of a node */
112     {
113     isnode=0; isway=0; isrelation=0;
114     }
115 amb 2 }
116     else if(!strncmp(l,"</node",6)) /* The end of a node */
117     {
118     isnode=0; isway=0; isrelation=0;
119     }
120     else if(!strncmp(l,"<way",4)) /* The start of a way */
121     {
122     nways++;
123    
124     isnode=0; isway=1; isrelation=0;
125    
126 amb 203 m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; way_id=atoll(m);
127    
128 amb 51 way_oneway=0; way_roundabout=0;
129 amb 136 way_maxspeed=0; way_maxweight=0; way_maxheight=0; way_maxwidth=0;
130     way_maxlength=0;
131 amb 51 way_highway=NULL; way_name=NULL; way_ref=NULL;
132     way_allow_no=0; way_allow_yes=0;
133 amb 2 way_nnodes=0;
134     }
135     else if(!strncmp(l,"</way",5)) /* The end of a way */
136     {
137     isnode=0; isway=0; isrelation=0;
138    
139 amb 30 if(way_highway)
140 amb 2 {
141 amb 73 waytype_t type;
142 amb 75 wayallow_t allow;
143 amb 2
144 amb 74 type=HighwayType(way_highway);
145 amb 6
146 amb 75 switch(type)
147 amb 2 {
148 amb 75 case Way_Motorway:
149     allow=Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
150     break;
151     case Way_Trunk:
152 amb 296 allow=Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
153 amb 75 break;
154     case Way_Primary:
155 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
156 amb 75 break;
157     case Way_Secondary:
158 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
159 amb 75 break;
160     case Way_Tertiary:
161 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
162 amb 75 break;
163 amb 85 case Way_Unclassified:
164 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
165 amb 75 break;
166     case Way_Residential:
167 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
168 amb 75 break;
169     case Way_Service:
170 amb 296 allow=Allow_Foot|Allow_Horse|Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_PSV|Allow_Goods|Allow_HGV;
171 amb 75 break;
172     case Way_Track:
173 amb 294 allow=Allow_Foot|Allow_Horse|Allow_Bicycle;
174 amb 75 break;
175     case Way_Cycleway:
176     allow=Allow_Foot|Allow_Bicycle;
177     break;
178 amb 293 case Way_Path:
179     if(!strcmp(way_highway,"bridleway"))
180 amb 294 allow=Allow_Foot|Allow_Horse|Allow_Bicycle; /* Special case for UK "bridleway". */
181 amb 293 else
182     allow=Allow_Foot; /* Only allow bicycle and horse if so indicated. */
183 amb 75 break;
184 amb 92 default:
185     allow=0;
186     break;
187 amb 75 }
188    
189     if(way_allow_no) /* Remove the ones explicitly denied (e.g. private) */
190     allow&=~way_allow_no;
191    
192     if(way_allow_yes) /* Add the ones explicitly allowed (e.g. footpath along private) */
193     allow|=way_allow_yes;
194    
195 amb 166 if(allow&profile->allow && profile->highway[HIGHWAY(type)])
196 amb 75 {
197 amb 283 Way way={0};
198 amb 87 char *refname;
199     int i;
200    
201 amb 73 if(way_ref && way_name)
202     {
203     refname=(char*)malloc(strlen(way_ref)+strlen(way_name)+4);
204     sprintf(refname,"%s (%s)",way_name,way_ref);
205     }
206     else if(way_ref && !way_name && way_roundabout)
207     {
208     refname=(char*)malloc(strlen(way_ref)+14);
209     sprintf(refname,"%s (roundabout)",way_ref);
210     }
211     else if(way_ref && !way_name)
212     refname=way_ref;
213     else if(!way_ref && way_name)
214     refname=way_name;
215     else if(way_roundabout)
216     {
217     refname=(char*)malloc(strlen(way_highway)+14);
218     sprintf(refname,"%s (roundabout)",way_highway);
219     }
220     else /* if(!way_ref && !way_name && !way_roundabout) */
221     refname=way_highway;
222 amb 2
223 amb 262 way.speed=way_maxspeed;
224     way.weight=way_maxweight;
225     way.height=way_maxheight;
226     way.width=way_maxwidth;
227     way.length=way_maxlength;
228 amb 2
229 amb 262 way.type=type;
230 amb 30
231 amb 262 way.allow=allow;
232 amb 30
233 amb 73 if(way_oneway)
234 amb 262 way.type|=Way_OneWay;
235 amb 30
236 amb 73 if(way_roundabout)
237 amb 262 way.type|=Way_Roundabout;
238 amb 30
239 amb 262 AppendWay(OSMWays,way_id,&way,refname);
240    
241 amb 73 if(refname!=way_ref && refname!=way_name && refname!=way_highway)
242     free(refname);
243 amb 87
244     for(i=1;i<way_nnodes;i++)
245     {
246     node_t from=way_nodes[i-1];
247     node_t to =way_nodes[i];
248    
249 amb 117 if(way_oneway>0)
250 amb 277 {
251 amb 209 AppendSegment(OSMSegments,way_id,from,to,ONEWAY_1TO2);
252 amb 277 AppendSegment(OSMSegments,way_id,to,from,ONEWAY_2TO1);
253     }
254 amb 117 else if(way_oneway<0)
255 amb 277 {
256 amb 209 AppendSegment(OSMSegments,way_id,from,to,ONEWAY_2TO1);
257 amb 277 AppendSegment(OSMSegments,way_id,to,from,ONEWAY_1TO2);
258     }
259 amb 209 else
260 amb 277 {
261 amb 209 AppendSegment(OSMSegments,way_id,from,to,0);
262 amb 277 AppendSegment(OSMSegments,way_id,to,from,0);
263     }
264 amb 87 }
265 amb 73 }
266 amb 2 }
267    
268 amb 51 if(way_highway) free(way_highway);
269     if(way_name) free(way_name);
270     if(way_ref) free(way_ref);
271 amb 2 }
272     else if(!strncmp(l,"<relation",9)) /* The start of a relation */
273     {
274     nrelations++;
275    
276     isnode=0; isway=0; isrelation=1;
277     }
278     else if(!strncmp(l,"</relation",10)) /* The end of a relation */
279     {
280     isnode=0; isway=0; isrelation=0;
281     }
282     else if(isnode) /* The middle of a node */
283     {
284     }
285     else if(isway) /* The middle of a way */
286     {
287     node_t id;
288    
289     if(!strncmp(l,"<nd",3)) /* The start of a node specifier */
290     {
291     m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
292    
293 amb 244 if(way_nnodes==way_nalloc)
294     way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=256)*sizeof(node_t));
295 amb 2
296     way_nodes[way_nnodes++]=id;
297     }
298    
299     if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */
300     {
301     char delimiter,*k="",*v="";
302    
303     m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m;
304     while(*m!=delimiter) m++; *m=0; l=m+1;
305    
306     m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m;
307     while(*m!=delimiter) m++; *m=0;
308    
309 amb 51 switch(*k)
310     {
311     case 'a':
312     if(!strcmp(k,"access"))
313 amb 136 {
314 amb 297 if(ISALLOWED(v))
315 amb 136 ;
316     else
317 amb 51 way_allow_no=~0;
318 amb 136 }
319 amb 51 break;
320 amb 2
321 amb 51 case 'b':
322     if(!strcmp(k,"bicycle"))
323     {
324 amb 297 if(ISALLOWED(v))
325 amb 51 way_allow_yes|=Allow_Bicycle;
326     else
327 amb 297 way_allow_no |=Allow_Bicycle;
328 amb 51 }
329     break;
330 amb 2
331 amb 297 case 'd':
332     if(!strcmp(k,"designation"))
333     {
334     if(!strcmp(v,"bridleway"))
335     way_allow_yes|=Allow_Foot|Allow_Horse|Allow_Bicycle;
336     else if(!strcmp(v,"byway"))
337     way_allow_yes|=Allow_Foot|Allow_Horse|Allow_Bicycle;
338     else if(!strcmp(v,"footpath"))
339     way_allow_yes|=Allow_Foot;
340     }
341     break;
342    
343 amb 51 case 'f':
344     if(!strcmp(k,"foot"))
345     {
346 amb 297 if(ISALLOWED(v))
347 amb 51 way_allow_yes|=Allow_Foot;
348     else
349 amb 297 way_allow_no |=Allow_Foot;
350 amb 51 }
351     break;
352 amb 2
353 amb 51 case 'g':
354     if(!strcmp(k,"goods"))
355     {
356 amb 297 if(ISALLOWED(v))
357 amb 51 way_allow_yes|=Allow_Goods;
358     else
359 amb 297 way_allow_no |=Allow_Goods;
360 amb 51 }
361     break;
362 amb 2
363 amb 51 case 'h':
364     if(!strcmp(k,"highway"))
365     {
366     if(!strncmp(v,"motorway",8)) way_oneway=1;
367 amb 2
368 amb 51 way_highway=strcpy((char*)malloc(strlen(v)+1),v);
369     }
370     if(!strcmp(k,"horse"))
371     {
372 amb 297 if(ISALLOWED(v))
373 amb 51 way_allow_yes|=Allow_Horse;
374     else
375 amb 297 way_allow_no |=Allow_Horse;
376 amb 51 }
377     if(!strcmp(k,"hgv"))
378     {
379 amb 297 if(ISALLOWED(v))
380 amb 51 way_allow_yes|=Allow_HGV;
381     else
382 amb 297 way_allow_no |=Allow_HGV;
383 amb 51 }
384     break;
385 amb 8
386 amb 51 case 'j':
387     if(!strcmp(k,"junction"))
388     if(!strcmp(v,"roundabout"))
389     {way_oneway=1; way_roundabout=1;}
390     break;
391    
392     case 'm':
393     if(!strcmp(k,"maxspeed"))
394     {
395     if(strstr(v,"mph"))
396 amb 183 way_maxspeed=kph_to_speed(1.609*atof(v));
397 amb 136 else
398     way_maxspeed=kph_to_speed(atof(v));
399 amb 51 }
400 amb 183 if(!strcmp(k,"maxspeed:mph"))
401     way_maxspeed=kph_to_speed(1.609*atof(v));
402 amb 136 if(!strcmp(k,"maxweight"))
403     {
404     if(strstr(v,"kg"))
405     way_maxweight=tonnes_to_weight(atof(v)/1000);
406     else
407     way_maxweight=tonnes_to_weight(atof(v));
408     }
409     if(!strcmp(k,"maxheight"))
410     {
411 amb 183 if(strchr(v,'\''))
412     {
413     int feet,inches;
414    
415     if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
416 amb 219 way_maxheight=metres_to_height((feet+(double)inches/12.0)*0.254);
417 amb 183 else if(sscanf(v,"%d'",&feet)==1)
418 amb 219 way_maxheight=metres_to_height((feet+(double)inches/12.0)*0.254);
419 amb 183 }
420     else if(strstr(v,"ft") || strstr(v,"feet"))
421 amb 136 way_maxheight=metres_to_height(atof(v)*0.254);
422     else
423     way_maxheight=metres_to_height(atof(v));
424     }
425     if(!strcmp(k,"maxwidth"))
426     {
427 amb 183 if(strchr(v,'\''))
428     {
429     int feet,inches;
430    
431     if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
432 amb 219 way_maxwidth=metres_to_height((feet+(double)inches/12.0)*0.254);
433 amb 183 else if(sscanf(v,"%d'",&feet)==1)
434 amb 219 way_maxwidth=metres_to_height((feet+(double)inches/12.0)*0.254);
435 amb 183 }
436     else if(strstr(v,"ft") || strstr(v,"feet"))
437 amb 136 way_maxwidth=metres_to_width(atof(v)*0.254);
438     else
439     way_maxwidth=metres_to_width(atof(v));
440     }
441     if(!strcmp(k,"maxlength"))
442     {
443 amb 183 if(strchr(v,'\''))
444     {
445     int feet,inches;
446    
447     if(sscanf(v,"%d'%d\"",&feet,&inches)==2)
448 amb 219 way_maxlength=metres_to_height((feet+(double)inches/12.0)*0.254);
449 amb 183 else if(sscanf(v,"%d'",&feet)==1)
450 amb 219 way_maxlength=metres_to_height((feet+(double)inches/12.0)*0.254);
451 amb 183 }
452     else if(strstr(v,"ft") || strstr(v,"feet"))
453 amb 136 way_maxlength=metres_to_length(atof(v)*0.254);
454     else
455     way_maxlength=metres_to_length(atof(v));
456     }
457 amb 296 if(!strcmp(k,"moped"))
458     {
459 amb 297 if(ISALLOWED(v))
460 amb 296 way_allow_yes|=Allow_Moped;
461     else
462 amb 297 way_allow_no |=Allow_Moped;
463 amb 296 }
464 amb 51 if(!strcmp(k,"motorbike"))
465     {
466 amb 297 if(ISALLOWED(v))
467 amb 51 way_allow_yes|=Allow_Motorbike;
468     else
469 amb 297 way_allow_no |=Allow_Motorbike;
470 amb 51 }
471     if(!strcmp(k,"motorcar"))
472     {
473 amb 297 if(ISALLOWED(v))
474 amb 51 way_allow_yes|=Allow_Motorcar;
475     else
476 amb 297 way_allow_no |=Allow_Motorcar;
477 amb 51 }
478 amb 196 if(!strcmp(k,"motor_vehicle"))
479     {
480 amb 297 if(ISALLOWED(v))
481 amb 296 way_allow_yes|=Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_Goods|Allow_HGV|Allow_PSV;
482 amb 196 else
483 amb 297 way_allow_no |=Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_Goods|Allow_HGV|Allow_PSV;
484 amb 196 }
485 amb 51 break;
486    
487     case 'n':
488     if(!strcmp(k,"name"))
489     way_name=strcpy((char*)malloc(strlen(v)+1),v);
490     break;
491    
492     case 'o':
493     if(!strcmp(k,"oneway"))
494 amb 117 {
495     if(!strcmp(v,"true") || !strcmp(v,"yes") || !strcmp(v,"1"))
496 amb 51 way_oneway=1;
497 amb 117 else if(!strcmp(v,"-1"))
498     way_oneway=-1;
499     }
500 amb 51 break;
501    
502     case 'p':
503     if(!strcmp(k,"psv"))
504     {
505 amb 297 if(ISALLOWED(v))
506 amb 51 way_allow_yes|=Allow_PSV;
507     else
508 amb 297 way_allow_no |=Allow_PSV;
509 amb 51 }
510     break;
511    
512     case 'r':
513     if(!strcmp(k,"ref"))
514     way_ref=strcpy((char*)malloc(strlen(v)+1),v);
515     break;
516    
517 amb 196 case 'v':
518     if(!strcmp(k,"vehicle"))
519     {
520 amb 297 if(ISALLOWED(v))
521 amb 296 way_allow_yes|=Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_Goods|Allow_HGV|Allow_PSV;
522 amb 196 else
523 amb 297 way_allow_no |=Allow_Bicycle|Allow_Moped|Allow_Motorbike|Allow_Motorcar|Allow_Goods|Allow_HGV|Allow_PSV;
524 amb 196 }
525     break;
526    
527 amb 51 default:
528     ;
529 amb 2 }
530     }
531     }
532     else if(isrelation) /* The middle of a relation */
533     {
534     }
535    
536     if(!(nlines%10000))
537     {
538     printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations);
539     fflush(stdout);
540     }
541     }
542    
543 amb 35 printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",nlines,nnodes,nways,nrelations);
544 amb 2 fflush(stdout);
545    
546 amb 97 if(line)
547     free(line);
548    
549 amb 2 if(way_nalloc)
550     free(way_nodes);
551    
552     return(0);
553     }
554    
555    
556     /*++++++++++++++++++++++++++++++++++++++
557     Call fgets and realloc the buffer as needed to get a whole line.
558    
559     char *fgets_realloc Returns the modified buffer (NULL at the end of the file).
560    
561     char *buffer The current buffer.
562    
563     FILE *file The file to read from.
564     ++++++++++++++++++++++++++++++++++++++*/
565    
566     static char *fgets_realloc(char *buffer,FILE *file)
567     {
568     int n=0;
569     char *buf;
570    
571     if(!buffer)
572     buffer=(char*)malloc(BUFFSIZE+1);
573    
574     while((buf=fgets(&buffer[n],BUFFSIZE,file)))
575     {
576     int s=strlen(buf);
577     n+=s;
578    
579     if(buffer[n-1]=='\n')
580     break;
581     else
582     buffer=(char*)realloc(buffer,n+BUFFSIZE+1);
583     }
584    
585     if(!buf)
586     {free(buffer);buffer=NULL;}
587    
588     return(buffer);
589     }

Properties

Name Value
cvs:description OSM XML file parser.