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 30 - (hide annotations) (download) (as text)
Sat Jan 10 15:59:59 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 8881 byte(s)
Store more information about ways.

1 amb 2 /***************************************
2 amb 30 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.6 2009-01-10 15:59:58 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 26 #include "nodes.h"
21     #include "ways.h"
22     #include "segments.h"
23 amb 2 #include "functions.h"
24    
25 amb 26
26 amb 2 #define BUFFSIZE 64
27    
28     static char *fgets_realloc(char *buffer,FILE *file);
29    
30    
31     /*++++++++++++++++++++++++++++++++++++++
32     Parse an OSM XML file (from JOSM or planet download).
33    
34     int ParseXML Returns 0 if OK or something else in case of an error.
35    
36     FILE *file The file to read from.
37 amb 26
38     NodesMem *OSMNodes The array of nodes to fill in.
39    
40     SegmentsMem *OSMSegments The array of segments to fill in.
41    
42     WaysMem *OSMWays The arrray of ways to fill in.
43 amb 2 ++++++++++++++++++++++++++++++++++++++*/
44    
45 amb 26 int ParseXML(FILE *file,NodesMem *OSMNodes,SegmentsMem *OSMSegments,WaysMem *OSMWays)
46 amb 2 {
47     char *line=NULL;
48     long nlines=0;
49     long nnodes=0,nways=0,nrelations=0;
50     int isnode=0,isway=0,isrelation=0;
51     way_t way_id=0;
52 amb 6 int way_oneway=0,way_roundabout=0;
53 amb 2 float way_maxspeed=0;
54 amb 8 char *way_highway=NULL,*way_name=NULL,*way_ref=NULL,*way_access=NULL,*way_car=NULL;
55 amb 2 node_t *way_nodes=NULL;
56     int way_nnodes=0,way_nalloc=0;
57    
58     /* Parse the file */
59    
60     while((line=fgets_realloc(line,file)))
61     {
62     char *l=line,*m;
63    
64     nlines++;
65    
66     while(isspace(*l))
67     l++;
68    
69     if(!strncmp(l,"<node",5)) /* The start of a node */
70     {
71     node_t id;
72     latlong_t latitude,longitude;
73    
74     nnodes++;
75    
76     isnode=1; isway=0; isrelation=0;
77    
78     m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
79     m=strstr(l,"lat="); m+=5; if(*m=='"' || *m=='\'') m++; latitude=atof(m);
80     m=strstr(l,"lon="); m+=4; if(*m=='"' || *m=='\'') m++; longitude=atof(m);
81    
82 amb 26 AppendNode(OSMNodes,id,latitude,longitude);
83 amb 2 }
84     else if(!strncmp(l,"</node",6)) /* The end of a node */
85     {
86     isnode=0; isway=0; isrelation=0;
87     }
88     else if(!strncmp(l,"<way",4)) /* The start of a way */
89     {
90     nways++;
91    
92     isnode=0; isway=1; isrelation=0;
93    
94     m=strstr(l,"id="); m+=3; if(*m=='"' || *m=='\'') m++; way_id=atol(m);
95    
96     way_oneway=0;
97 amb 6 way_roundabout=0;
98 amb 2 way_maxspeed=0;
99     way_name=NULL; way_ref=NULL;
100     way_nnodes=0;
101     }
102     else if(!strncmp(l,"</way",5)) /* The end of a way */
103     {
104     isnode=0; isway=0; isrelation=0;
105    
106 amb 30 if(way_highway)
107 amb 2 {
108 amb 30 Way *way;
109 amb 6 char *refname;
110 amb 30 int i;
111 amb 2
112 amb 6 if(way_ref && way_name)
113     {
114     refname=(char*)malloc(strlen(way_ref)+strlen(way_name)+4);
115     sprintf(refname,"%s (%s)",way_name,way_ref);
116     }
117 amb 30 else if(way_ref && !way_name && way_roundabout)
118     {
119     refname=(char*)malloc(strlen(way_ref)+14);
120     sprintf(refname,"%s (roundabout)",way_ref);
121     }
122 amb 6 else if(way_ref && !way_name)
123     refname=way_ref;
124     else if(!way_ref && way_name)
125     refname=way_name;
126     else if(way_roundabout)
127     {
128 amb 8 refname=(char*)malloc(strlen(way_highway)+14);
129     sprintf(refname,"%s (roundabout)",way_highway);
130 amb 6 }
131     else /* if(!way_ref && !way_name && !way_roundabout) */
132     refname=way_highway;
133    
134 amb 2 for(i=1;i<way_nnodes;i++)
135     {
136     node_t from=way_nodes[i-1];
137     node_t to =way_nodes[i];
138    
139 amb 26 AppendSegment(OSMSegments,from,to,way_id);
140 amb 2
141     if(!way_oneway)
142 amb 26 AppendSegment(OSMSegments,to,from,way_id);
143 amb 6 }
144 amb 2
145 amb 30 way=AppendWay(OSMWays,way_id,refname);
146 amb 6
147 amb 30 way->limit=way_maxspeed;
148     way->type=TypeOfWay(way_highway);
149    
150     switch(way->type)
151     {
152     case Way_Motorway:
153     way->speed=1.6*80; break;
154     case Way_Trunk:
155     way->speed=1.6*((way_oneway&&!way_roundabout)?75:65); break;
156     case Way_Primary:
157     way->speed=1.6*((way_oneway&&!way_roundabout)?70:60); break;
158     case Way_Secondary:
159     way->speed=1.6*55; break;
160     case Way_Tertiary:
161     way->speed=1.6*50; break;
162     case Way_Unclassfied:
163     way->speed=1.6*40; break;
164     case Way_Residential:
165     way->speed=1.6*30; break;
166     case Way_Service:
167     way->speed=1.6*20; break;
168     case Way_Track:
169     way->speed=1.6*10; break;
170     case Way_Bridleway:
171     case Way_Cycleway:
172     case Way_Footway:
173     case Way_Unknown:
174     way->speed=0;
175     }
176    
177     if(way_oneway)
178     way->type|=Way_ONEWAY;
179    
180     if(way_roundabout)
181     way->type|=Way_ROUNDABOUT;
182    
183     if(way_access && (!strcmp(way_access,"private") || !strcmp(way_access,"no")))
184     way->type|=Way_NOTROUTABLE;
185    
186     if(way_car && !strcmp(way_car,"no"))
187     way->type|=Way_NOTROUTABLE;
188    
189 amb 6 if(refname!=way_ref && refname!=way_name && refname!=way_highway)
190     free(refname);
191 amb 2 }
192    
193     if(way_highway) {free(way_highway); way_highway=NULL;}
194     if(way_name) {free(way_name); way_name=NULL;}
195     if(way_ref) {free(way_ref); way_ref=NULL;}
196     if(way_access) {free(way_access); way_access=NULL;}
197 amb 8 if(way_car) {free(way_car); way_car=NULL;}
198 amb 2 }
199     else if(!strncmp(l,"<relation",9)) /* The start of a relation */
200     {
201     nrelations++;
202    
203     isnode=0; isway=0; isrelation=1;
204     }
205     else if(!strncmp(l,"</relation",10)) /* The end of a relation */
206     {
207     isnode=0; isway=0; isrelation=0;
208     }
209     else if(isnode) /* The middle of a node */
210     {
211     }
212     else if(isway) /* The middle of a way */
213     {
214     node_t id;
215    
216     if(!strncmp(l,"<nd",3)) /* The start of a node specifier */
217     {
218     m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
219    
220     if(way_nnodes<=way_nalloc)
221     way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=16)*sizeof(node_t));
222    
223     way_nodes[way_nnodes++]=id;
224     }
225    
226     if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */
227     {
228     char delimiter,*k="",*v="";
229    
230     m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m;
231     while(*m!=delimiter) m++; *m=0; l=m+1;
232    
233     m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m;
234     while(*m!=delimiter) m++; *m=0;
235    
236     if(!strcmp(k,"oneway") && (!strcmp(v,"true") || !strcmp(v,"yes"))) way_oneway=1;
237 amb 6 if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) {way_oneway=1; way_roundabout=1;}
238 amb 2 if(!strcmp(k,"highway") && !strncmp(v,"motorway",8)) way_oneway=1;
239    
240     if(!strcmp(k,"highway"))
241     way_highway=strcpy((char*)malloc(strlen(v)+1),v);
242    
243     if(!strcmp(k,"name"))
244     way_name=strcpy((char*)malloc(strlen(v)+1),v);
245    
246     if(!strcmp(k,"ref"))
247     way_ref=strcpy((char*)malloc(strlen(v)+1),v);
248    
249     if(!strcmp(k,"access"))
250     way_access=strcpy((char*)malloc(strlen(v)+1),v);
251    
252 amb 8 if(!strcmp(k,"car"))
253     way_car=strcpy((char*)malloc(strlen(v)+1),v);
254    
255 amb 2 if(!strcmp(k,"maxspeed"))
256     {
257     way_maxspeed=atof(v);
258     if(strstr(v,"mph"))
259     way_maxspeed*=1.6;
260     }
261     }
262     }
263     else if(isrelation) /* The middle of a relation */
264     {
265     }
266    
267     if(!(nlines%10000))
268     {
269     printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations);
270     fflush(stdout);
271     }
272     }
273    
274     printf("\rRead : Lines=%ld Nodes=%ld Ways=%ld Relations=%ld\n",nlines,nnodes,nways,nrelations);
275     fflush(stdout);
276    
277     if(way_nalloc)
278     free(way_nodes);
279    
280     return(0);
281     }
282    
283    
284     /*++++++++++++++++++++++++++++++++++++++
285     Call fgets and realloc the buffer as needed to get a whole line.
286    
287     char *fgets_realloc Returns the modified buffer (NULL at the end of the file).
288    
289     char *buffer The current buffer.
290    
291     FILE *file The file to read from.
292     ++++++++++++++++++++++++++++++++++++++*/
293    
294     static char *fgets_realloc(char *buffer,FILE *file)
295     {
296     int n=0;
297     char *buf;
298    
299     if(!buffer)
300     buffer=(char*)malloc(BUFFSIZE+1);
301    
302     while((buf=fgets(&buffer[n],BUFFSIZE,file)))
303     {
304     int s=strlen(buf);
305     n+=s;
306    
307     if(buffer[n-1]=='\n')
308     break;
309     else
310     buffer=(char*)realloc(buffer,n+BUFFSIZE+1);
311     }
312    
313     if(!buf)
314     {free(buffer);buffer=NULL;}
315    
316     return(buffer);
317     }

Properties

Name Value
cvs:description OSM XML file parser.