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 26 -
(hide 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 | amb | 2 | /*************************************** |
2 | amb | 26 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.5 2009-01-10 11:53:48 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 | 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 | amb | 8 | else if(way_car && !strcmp(way_car,"no")) speed=0; |
112 | amb | 2 | 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 | amb | 8 | else if(!strcmp(way_highway,"track") || !strcmp(way_highway,"byway") || !strcmp(way_highway,"unsurfaced") || !strcmp(way_highway,"unpaved")) speed=10*1.6; |
124 | amb | 2 | // 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 | amb | 6 | char *refname; |
129 | amb | 2 | |
130 | amb | 6 | 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 | amb | 8 | refname=(char*)malloc(strlen(way_highway)+14); |
142 | sprintf(refname,"%s (roundabout)",way_highway); | ||
143 | amb | 6 | } |
144 | else /* if(!way_ref && !way_name && !way_roundabout) */ | ||
145 | refname=way_highway; | ||
146 | |||
147 | amb | 2 | 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 | amb | 26 | AppendSegment(OSMSegments,from,to,way_id); |
153 | amb | 2 | |
154 | if(!way_oneway) | ||
155 | amb | 26 | AppendSegment(OSMSegments,to,from,way_id); |
156 | amb | 6 | } |
157 | amb | 2 | |
158 | amb | 26 | AppendWay(OSMWays,way_id,refname,speed); |
159 | amb | 6 | |
160 | if(refname!=way_ref && refname!=way_name && refname!=way_highway) | ||
161 | free(refname); | ||
162 | amb | 2 | } |
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 | amb | 8 | if(way_car) {free(way_car); way_car=NULL;} |
169 | amb | 2 | } |
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 | amb | 6 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) {way_oneway=1; way_roundabout=1;} |
209 | amb | 2 | 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 | amb | 8 | if(!strcmp(k,"car")) |
224 | way_car=strcpy((char*)malloc(strlen(v)+1),v); | ||
225 | |||
226 | amb | 2 | 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. |