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 8 -
(show annotations)
(download)
(as text)
Sun Jan 4 17:51:24 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 8269 byte(s)
Sun Jan 4 17:51:24 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 8269 byte(s)
Changed the node, way and segment functions and data types. Removed 'alloced', shortened the prototype array. Remove the automatic sorting of the data. Added assert statements.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.4 2009-01-04 17:51:23 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 "types.h" |
21 | #include "functions.h" |
22 | |
23 | #define BUFFSIZE 64 |
24 | |
25 | static char *fgets_realloc(char *buffer,FILE *file); |
26 | |
27 | |
28 | /*++++++++++++++++++++++++++++++++++++++ |
29 | Parse an OSM XML file (from JOSM or planet download). |
30 | |
31 | int ParseXML Returns 0 if OK or something else in case of an error. |
32 | |
33 | FILE *file The file to read from. |
34 | ++++++++++++++++++++++++++++++++++++++*/ |
35 | |
36 | int ParseXML(FILE *file) |
37 | { |
38 | char *line=NULL; |
39 | long nlines=0; |
40 | long nnodes=0,nways=0,nrelations=0; |
41 | int isnode=0,isway=0,isrelation=0; |
42 | way_t way_id=0; |
43 | int way_oneway=0,way_roundabout=0; |
44 | float way_maxspeed=0; |
45 | char *way_highway=NULL,*way_name=NULL,*way_ref=NULL,*way_access=NULL,*way_car=NULL; |
46 | node_t *way_nodes=NULL; |
47 | int way_nnodes=0,way_nalloc=0; |
48 | |
49 | /* Parse the file */ |
50 | |
51 | while((line=fgets_realloc(line,file))) |
52 | { |
53 | char *l=line,*m; |
54 | |
55 | nlines++; |
56 | |
57 | while(isspace(*l)) |
58 | l++; |
59 | |
60 | if(!strncmp(l,"<node",5)) /* The start of a node */ |
61 | { |
62 | node_t id; |
63 | latlong_t latitude,longitude; |
64 | |
65 | nnodes++; |
66 | |
67 | isnode=1; isway=0; isrelation=0; |
68 | |
69 | m=strstr(l,"id="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m); |
70 | m=strstr(l,"lat="); m+=5; if(*m=='"' || *m=='\'') m++; latitude=atof(m); |
71 | m=strstr(l,"lon="); m+=4; if(*m=='"' || *m=='\'') m++; longitude=atof(m); |
72 | |
73 | AppendNode(id,latitude,longitude); |
74 | } |
75 | else if(!strncmp(l,"</node",6)) /* The end of a node */ |
76 | { |
77 | isnode=0; isway=0; isrelation=0; |
78 | } |
79 | else if(!strncmp(l,"<way",4)) /* The start of a way */ |
80 | { |
81 | nways++; |
82 | |
83 | isnode=0; isway=1; isrelation=0; |
84 | |
85 | m=strstr(l,"id="); m+=3; if(*m=='"' || *m=='\'') m++; way_id=atol(m); |
86 | |
87 | way_oneway=0; |
88 | way_roundabout=0; |
89 | way_maxspeed=0; |
90 | way_name=NULL; way_ref=NULL; |
91 | way_nnodes=0; |
92 | } |
93 | else if(!strncmp(l,"</way",5)) /* The end of a way */ |
94 | { |
95 | double speed=0; |
96 | int i; |
97 | |
98 | isnode=0; isway=0; isrelation=0; |
99 | |
100 | if(!way_highway) speed=0; |
101 | else if(way_access && !strcmp(way_access,"private")) speed=0; |
102 | else if(way_car && !strcmp(way_car,"no")) speed=0; |
103 | else if(way_maxspeed) speed=way_maxspeed; |
104 | else if(!strncmp(way_highway,"motorway",8)) speed=80*1.6; |
105 | else if(!strncmp(way_highway,"trunk",5) && way_oneway) speed=75*1.6; |
106 | else if(!strncmp(way_highway,"primary",7) && way_oneway) speed=70*1.6; |
107 | else if(!strncmp(way_highway,"trunk",5)) speed=65*1.6; |
108 | else if(!strncmp(way_highway,"primary",7)) speed=60*1.6; |
109 | else if(!strncmp(way_highway,"secondary",9)) speed=55*1.6; |
110 | else if(!strcmp(way_highway,"tertiary")) speed=50*1.6; |
111 | else if(!strcmp(way_highway,"unclassified") || !strcmp(way_highway,"road") || !strcmp(way_highway,"minor")) speed=40*1.6; |
112 | else if(!strcmp(way_highway,"residential")) speed=30*1.6; |
113 | else if(!strcmp(way_highway,"service")) speed=20*1.6; |
114 | else if(!strcmp(way_highway,"track") || !strcmp(way_highway,"byway") || !strcmp(way_highway,"unsurfaced") || !strcmp(way_highway,"unpaved")) speed=10*1.6; |
115 | // else if(!strcmp(way_highway =~ m%(steps|path|walkway|footway|pedestrian|bridleway|cycleway|living_street)%) { $speed = 5*1.6; } |
116 | |
117 | if(speed) |
118 | { |
119 | char *refname; |
120 | |
121 | if(way_ref && way_name) |
122 | { |
123 | refname=(char*)malloc(strlen(way_ref)+strlen(way_name)+4); |
124 | sprintf(refname,"%s (%s)",way_name,way_ref); |
125 | } |
126 | else if(way_ref && !way_name) |
127 | refname=way_ref; |
128 | else if(!way_ref && way_name) |
129 | refname=way_name; |
130 | else if(way_roundabout) |
131 | { |
132 | refname=(char*)malloc(strlen(way_highway)+14); |
133 | sprintf(refname,"%s (roundabout)",way_highway); |
134 | } |
135 | else /* if(!way_ref && !way_name && !way_roundabout) */ |
136 | refname=way_highway; |
137 | |
138 | for(i=1;i<way_nnodes;i++) |
139 | { |
140 | node_t from=way_nodes[i-1]; |
141 | node_t to =way_nodes[i]; |
142 | |
143 | AppendSegment(from,to,way_id); |
144 | |
145 | if(!way_oneway) |
146 | AppendSegment(to,from,way_id); |
147 | } |
148 | |
149 | AppendWay(way_id,refname,speed); |
150 | |
151 | if(refname!=way_ref && refname!=way_name && refname!=way_highway) |
152 | free(refname); |
153 | } |
154 | |
155 | if(way_highway) {free(way_highway); way_highway=NULL;} |
156 | if(way_name) {free(way_name); way_name=NULL;} |
157 | if(way_ref) {free(way_ref); way_ref=NULL;} |
158 | if(way_access) {free(way_access); way_access=NULL;} |
159 | if(way_car) {free(way_car); way_car=NULL;} |
160 | } |
161 | else if(!strncmp(l,"<relation",9)) /* The start of a relation */ |
162 | { |
163 | nrelations++; |
164 | |
165 | isnode=0; isway=0; isrelation=1; |
166 | } |
167 | else if(!strncmp(l,"</relation",10)) /* The end of a relation */ |
168 | { |
169 | isnode=0; isway=0; isrelation=0; |
170 | } |
171 | else if(isnode) /* The middle of a node */ |
172 | { |
173 | } |
174 | else if(isway) /* The middle of a way */ |
175 | { |
176 | node_t id; |
177 | |
178 | if(!strncmp(l,"<nd",3)) /* The start of a node specifier */ |
179 | { |
180 | m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m); |
181 | |
182 | if(way_nnodes<=way_nalloc) |
183 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=16)*sizeof(node_t)); |
184 | |
185 | way_nodes[way_nnodes++]=id; |
186 | } |
187 | |
188 | if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */ |
189 | { |
190 | char delimiter,*k="",*v=""; |
191 | |
192 | m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m; |
193 | while(*m!=delimiter) m++; *m=0; l=m+1; |
194 | |
195 | m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m; |
196 | while(*m!=delimiter) m++; *m=0; |
197 | |
198 | if(!strcmp(k,"oneway") && (!strcmp(v,"true") || !strcmp(v,"yes"))) way_oneway=1; |
199 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) {way_oneway=1; way_roundabout=1;} |
200 | if(!strcmp(k,"highway") && !strncmp(v,"motorway",8)) way_oneway=1; |
201 | |
202 | if(!strcmp(k,"highway")) |
203 | way_highway=strcpy((char*)malloc(strlen(v)+1),v); |
204 | |
205 | if(!strcmp(k,"name")) |
206 | way_name=strcpy((char*)malloc(strlen(v)+1),v); |
207 | |
208 | if(!strcmp(k,"ref")) |
209 | way_ref=strcpy((char*)malloc(strlen(v)+1),v); |
210 | |
211 | if(!strcmp(k,"access")) |
212 | way_access=strcpy((char*)malloc(strlen(v)+1),v); |
213 | |
214 | if(!strcmp(k,"car")) |
215 | way_car=strcpy((char*)malloc(strlen(v)+1),v); |
216 | |
217 | if(!strcmp(k,"maxspeed")) |
218 | { |
219 | way_maxspeed=atof(v); |
220 | if(strstr(v,"mph")) |
221 | way_maxspeed*=1.6; |
222 | } |
223 | } |
224 | } |
225 | else if(isrelation) /* The middle of a relation */ |
226 | { |
227 | } |
228 | |
229 | if(!(nlines%10000)) |
230 | { |
231 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations); |
232 | fflush(stdout); |
233 | } |
234 | } |
235 | |
236 | printf("\rRead : Lines=%ld Nodes=%ld Ways=%ld Relations=%ld\n",nlines,nnodes,nways,nrelations); |
237 | fflush(stdout); |
238 | |
239 | if(way_nalloc) |
240 | free(way_nodes); |
241 | |
242 | return(0); |
243 | } |
244 | |
245 | |
246 | /*++++++++++++++++++++++++++++++++++++++ |
247 | Call fgets and realloc the buffer as needed to get a whole line. |
248 | |
249 | char *fgets_realloc Returns the modified buffer (NULL at the end of the file). |
250 | |
251 | char *buffer The current buffer. |
252 | |
253 | FILE *file The file to read from. |
254 | ++++++++++++++++++++++++++++++++++++++*/ |
255 | |
256 | static char *fgets_realloc(char *buffer,FILE *file) |
257 | { |
258 | int n=0; |
259 | char *buf; |
260 | |
261 | if(!buffer) |
262 | buffer=(char*)malloc(BUFFSIZE+1); |
263 | |
264 | while((buf=fgets(&buffer[n],BUFFSIZE,file))) |
265 | { |
266 | int s=strlen(buf); |
267 | n+=s; |
268 | |
269 | if(buffer[n-1]=='\n') |
270 | break; |
271 | else |
272 | buffer=(char*)realloc(buffer,n+BUFFSIZE+1); |
273 | } |
274 | |
275 | if(!buf) |
276 | {free(buffer);buffer=NULL;} |
277 | |
278 | return(buffer); |
279 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |