Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/osmparser.c
Parent Directory
|
Revision Log
Revision 8 -
(hide annotations)
(download)
(as text)
Sun Jan 4 17:51:24 2009 UTC (16 years, 3 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, 3 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 | amb | 2 | /*************************************** |
2 | amb | 8 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.4 2009-01-04 17:51:23 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 | #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 | amb | 6 | int way_oneway=0,way_roundabout=0; |
44 | amb | 2 | float way_maxspeed=0; |
45 | amb | 8 | char *way_highway=NULL,*way_name=NULL,*way_ref=NULL,*way_access=NULL,*way_car=NULL; |
46 | amb | 2 | 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 | amb | 6 | way_roundabout=0; |
89 | amb | 2 | 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 | amb | 8 | else if(way_car && !strcmp(way_car,"no")) speed=0; |
103 | amb | 2 | 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 | amb | 8 | else if(!strcmp(way_highway,"track") || !strcmp(way_highway,"byway") || !strcmp(way_highway,"unsurfaced") || !strcmp(way_highway,"unpaved")) speed=10*1.6; |
115 | amb | 2 | // 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 | amb | 6 | char *refname; |
120 | amb | 2 | |
121 | amb | 6 | 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 | amb | 8 | refname=(char*)malloc(strlen(way_highway)+14); |
133 | sprintf(refname,"%s (roundabout)",way_highway); | ||
134 | amb | 6 | } |
135 | else /* if(!way_ref && !way_name && !way_roundabout) */ | ||
136 | refname=way_highway; | ||
137 | |||
138 | amb | 2 | 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 | amb | 8 | AppendSegment(from,to,way_id); |
144 | amb | 2 | |
145 | if(!way_oneway) | ||
146 | amb | 8 | AppendSegment(to,from,way_id); |
147 | amb | 6 | } |
148 | amb | 2 | |
149 | amb | 8 | AppendWay(way_id,refname,speed); |
150 | amb | 6 | |
151 | if(refname!=way_ref && refname!=way_name && refname!=way_highway) | ||
152 | free(refname); | ||
153 | amb | 2 | } |
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 | amb | 8 | if(way_car) {free(way_car); way_car=NULL;} |
160 | amb | 2 | } |
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 | amb | 6 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) {way_oneway=1; way_roundabout=1;} |
200 | amb | 2 | 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 | amb | 8 | if(!strcmp(k,"car")) |
215 | way_car=strcpy((char*)malloc(strlen(v)+1),v); | ||
216 | |||
217 | amb | 2 | 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. |