Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/osmparser.c
Parent Directory
|
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)
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. |