Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/osmparser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations) (download) (as text)
Sat Jan 10 11:53:49 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 8578 byte(s)
About to add the super-segment functionality using Segments data type to hold
them.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.5 2009-01-10 11:53:48 amb Exp $
3
4 OSM XML file parser (either JOSM or planet)
5 ******************/ /******************
6 Written by Andrew M. Bishop
7
8 This file Copyright 2008,2009 Andrew M. Bishop
9 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 #include "nodes.h"
21 #include "ways.h"
22 #include "segments.h"
23 #include "functions.h"
24
25
26 #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
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 ++++++++++++++++++++++++++++++++++++++*/
44
45 int ParseXML(FILE *file,NodesMem *OSMNodes,SegmentsMem *OSMSegments,WaysMem *OSMWays)
46 {
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 int way_oneway=0,way_roundabout=0;
53 float way_maxspeed=0;
54 char *way_highway=NULL,*way_name=NULL,*way_ref=NULL,*way_access=NULL,*way_car=NULL;
55 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 AppendNode(OSMNodes,id,latitude,longitude);
83 }
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 way_roundabout=0;
98 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 double speed=0;
105 int i;
106
107 isnode=0; isway=0; isrelation=0;
108
109 if(!way_highway) speed=0;
110 else if(way_access && !strcmp(way_access,"private")) speed=0;
111 else if(way_car && !strcmp(way_car,"no")) speed=0;
112 else if(way_maxspeed) speed=way_maxspeed;
113 else if(!strncmp(way_highway,"motorway",8)) speed=80*1.6;
114 else if(!strncmp(way_highway,"trunk",5) && way_oneway) speed=75*1.6;
115 else if(!strncmp(way_highway,"primary",7) && way_oneway) speed=70*1.6;
116 else if(!strncmp(way_highway,"trunk",5)) speed=65*1.6;
117 else if(!strncmp(way_highway,"primary",7)) speed=60*1.6;
118 else if(!strncmp(way_highway,"secondary",9)) speed=55*1.6;
119 else if(!strcmp(way_highway,"tertiary")) speed=50*1.6;
120 else if(!strcmp(way_highway,"unclassified") || !strcmp(way_highway,"road") || !strcmp(way_highway,"minor")) speed=40*1.6;
121 else if(!strcmp(way_highway,"residential")) speed=30*1.6;
122 else if(!strcmp(way_highway,"service")) speed=20*1.6;
123 else if(!strcmp(way_highway,"track") || !strcmp(way_highway,"byway") || !strcmp(way_highway,"unsurfaced") || !strcmp(way_highway,"unpaved")) speed=10*1.6;
124 // else if(!strcmp(way_highway =~ m%(steps|path|walkway|footway|pedestrian|bridleway|cycleway|living_street)%) { $speed = 5*1.6; }
125
126 if(speed)
127 {
128 char *refname;
129
130 if(way_ref && way_name)
131 {
132 refname=(char*)malloc(strlen(way_ref)+strlen(way_name)+4);
133 sprintf(refname,"%s (%s)",way_name,way_ref);
134 }
135 else if(way_ref && !way_name)
136 refname=way_ref;
137 else if(!way_ref && way_name)
138 refname=way_name;
139 else if(way_roundabout)
140 {
141 refname=(char*)malloc(strlen(way_highway)+14);
142 sprintf(refname,"%s (roundabout)",way_highway);
143 }
144 else /* if(!way_ref && !way_name && !way_roundabout) */
145 refname=way_highway;
146
147 for(i=1;i<way_nnodes;i++)
148 {
149 node_t from=way_nodes[i-1];
150 node_t to =way_nodes[i];
151
152 AppendSegment(OSMSegments,from,to,way_id);
153
154 if(!way_oneway)
155 AppendSegment(OSMSegments,to,from,way_id);
156 }
157
158 AppendWay(OSMWays,way_id,refname,speed);
159
160 if(refname!=way_ref && refname!=way_name && refname!=way_highway)
161 free(refname);
162 }
163
164 if(way_highway) {free(way_highway); way_highway=NULL;}
165 if(way_name) {free(way_name); way_name=NULL;}
166 if(way_ref) {free(way_ref); way_ref=NULL;}
167 if(way_access) {free(way_access); way_access=NULL;}
168 if(way_car) {free(way_car); way_car=NULL;}
169 }
170 else if(!strncmp(l,"<relation",9)) /* The start of a relation */
171 {
172 nrelations++;
173
174 isnode=0; isway=0; isrelation=1;
175 }
176 else if(!strncmp(l,"</relation",10)) /* The end of a relation */
177 {
178 isnode=0; isway=0; isrelation=0;
179 }
180 else if(isnode) /* The middle of a node */
181 {
182 }
183 else if(isway) /* The middle of a way */
184 {
185 node_t id;
186
187 if(!strncmp(l,"<nd",3)) /* The start of a node specifier */
188 {
189 m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m);
190
191 if(way_nnodes<=way_nalloc)
192 way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=16)*sizeof(node_t));
193
194 way_nodes[way_nnodes++]=id;
195 }
196
197 if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */
198 {
199 char delimiter,*k="",*v="";
200
201 m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m;
202 while(*m!=delimiter) m++; *m=0; l=m+1;
203
204 m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m;
205 while(*m!=delimiter) m++; *m=0;
206
207 if(!strcmp(k,"oneway") && (!strcmp(v,"true") || !strcmp(v,"yes"))) way_oneway=1;
208 if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) {way_oneway=1; way_roundabout=1;}
209 if(!strcmp(k,"highway") && !strncmp(v,"motorway",8)) way_oneway=1;
210
211 if(!strcmp(k,"highway"))
212 way_highway=strcpy((char*)malloc(strlen(v)+1),v);
213
214 if(!strcmp(k,"name"))
215 way_name=strcpy((char*)malloc(strlen(v)+1),v);
216
217 if(!strcmp(k,"ref"))
218 way_ref=strcpy((char*)malloc(strlen(v)+1),v);
219
220 if(!strcmp(k,"access"))
221 way_access=strcpy((char*)malloc(strlen(v)+1),v);
222
223 if(!strcmp(k,"car"))
224 way_car=strcpy((char*)malloc(strlen(v)+1),v);
225
226 if(!strcmp(k,"maxspeed"))
227 {
228 way_maxspeed=atof(v);
229 if(strstr(v,"mph"))
230 way_maxspeed*=1.6;
231 }
232 }
233 }
234 else if(isrelation) /* The middle of a relation */
235 {
236 }
237
238 if(!(nlines%10000))
239 {
240 printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations);
241 fflush(stdout);
242 }
243 }
244
245 printf("\rRead : Lines=%ld Nodes=%ld Ways=%ld Relations=%ld\n",nlines,nnodes,nways,nrelations);
246 fflush(stdout);
247
248 if(way_nalloc)
249 free(way_nodes);
250
251 return(0);
252 }
253
254
255 /*++++++++++++++++++++++++++++++++++++++
256 Call fgets and realloc the buffer as needed to get a whole line.
257
258 char *fgets_realloc Returns the modified buffer (NULL at the end of the file).
259
260 char *buffer The current buffer.
261
262 FILE *file The file to read from.
263 ++++++++++++++++++++++++++++++++++++++*/
264
265 static char *fgets_realloc(char *buffer,FILE *file)
266 {
267 int n=0;
268 char *buf;
269
270 if(!buffer)
271 buffer=(char*)malloc(BUFFSIZE+1);
272
273 while((buf=fgets(&buffer[n],BUFFSIZE,file)))
274 {
275 int s=strlen(buf);
276 n+=s;
277
278 if(buffer[n-1]=='\n')
279 break;
280 else
281 buffer=(char*)realloc(buffer,n+BUFFSIZE+1);
282 }
283
284 if(!buf)
285 {free(buffer);buffer=NULL;}
286
287 return(buffer);
288 }

Properties

Name Value
cvs:description OSM XML file parser.