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 98 - (hide annotations) (download) (as text)
Mon Feb 2 18:53:13 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 13070 byte(s)
More variable and function name changes.

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

Properties

Name Value
cvs:description OSM XML file parser.