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 213 - (hide annotations) (download) (as text)
Thu Jul 2 16:33:31 2009 UTC (15 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 18556 byte(s)
Removed unused header files, change assert statements, tidy some code.

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

Properties

Name Value
cvs:description OSM XML file parser.