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 5 -
(hide annotations)
(download)
(as text)
Fri Jan 2 11:33:47 2009 UTC (16 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 7811 byte(s)
Fri Jan 2 11:33:47 2009 UTC (16 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 7811 byte(s)
Added macros to convert between distance/km and duration/hours/minutes. Shortened the Segment data type with shorter distances and durations.
1 | amb | 2 | /*************************************** |
2 | amb | 5 | $Header: /home/amb/CVS/routino/src/osmparser.c,v 1.2 2009-01-02 11:33:47 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 | int way_oneway=0; | ||
44 | float way_maxspeed=0; | ||
45 | char *way_highway=NULL,*way_name=NULL,*way_ref=NULL,*way_access=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_maxspeed=0; | ||
89 | way_name=NULL; way_ref=NULL; | ||
90 | way_nnodes=0; | ||
91 | } | ||
92 | else if(!strncmp(l,"</way",5)) /* The end of a way */ | ||
93 | { | ||
94 | double speed=0; | ||
95 | int i; | ||
96 | |||
97 | isnode=0; isway=0; isrelation=0; | ||
98 | |||
99 | if(!way_highway) speed=0; | ||
100 | else if(way_access && !strcmp(way_access,"private")) speed=0; | ||
101 | else if(way_maxspeed) speed=way_maxspeed; | ||
102 | else if(!strncmp(way_highway,"motorway",8)) speed=80*1.6; | ||
103 | else if(!strncmp(way_highway,"trunk",5) && way_oneway) speed=75*1.6; | ||
104 | else if(!strncmp(way_highway,"primary",7) && way_oneway) speed=70*1.6; | ||
105 | else if(!strncmp(way_highway,"trunk",5)) speed=65*1.6; | ||
106 | else if(!strncmp(way_highway,"primary",7)) speed=60*1.6; | ||
107 | else if(!strncmp(way_highway,"secondary",9)) speed=55*1.6; | ||
108 | else if(!strcmp(way_highway,"tertiary")) speed=50*1.6; | ||
109 | else if(!strcmp(way_highway,"unclassified") || !strcmp(way_highway,"road") || !strcmp(way_highway,"minor")) speed=40*1.6; | ||
110 | else if(!strcmp(way_highway,"residential")) speed=30*1.6; | ||
111 | else if(!strcmp(way_highway,"service")) speed=20*1.6; | ||
112 | // else if(!strcmp(way_highway =~ m%(track|byway|unsurfaced|unpaved)%) { $speed = 10*1.6; } | ||
113 | // else if(!strcmp(way_highway =~ m%(steps|path|walkway|footway|pedestrian|bridleway|cycleway|living_street)%) { $speed = 5*1.6; } | ||
114 | // else if(!strcmp(way_highway =~ m%(raceway)%) { next; } | ||
115 | // else { print STDERR "\nhighway=$highway\n"; next; } | ||
116 | |||
117 | if(speed) | ||
118 | { | ||
119 | // if($ref && $name) | ||
120 | // {$refname="$name ($ref)";} | ||
121 | // if($ref && !$name) | ||
122 | // {$refname=$ref;} | ||
123 | // if(!$ref && $name) | ||
124 | // {$refname=$name;} | ||
125 | // if(!$ref && !$name) | ||
126 | // {$refname="unamed $highway road";} | ||
127 | // | ||
128 | // print WAYS "$id\t$refname\n"; | ||
129 | |||
130 | for(i=1;i<way_nnodes;i++) | ||
131 | { | ||
132 | node_t from=way_nodes[i-1]; | ||
133 | node_t to =way_nodes[i]; | ||
134 | |||
135 | distance_t distance=SegmentLength(FindNode(from),FindNode(to)); | ||
136 | amb | 5 | duration_t duration=hours_to_duration(distance_to_km(distance)/speed); |
137 | amb | 2 | |
138 | AppendSegment(from,to,way_id,distance,duration); | ||
139 | |||
140 | if(!way_oneway) | ||
141 | AppendSegment(to,from,way_id,distance,duration); | ||
142 | |||
143 | // $junctions{$from}++; | ||
144 | // $junctions{$to}++; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if(way_highway) {free(way_highway); way_highway=NULL;} | ||
149 | if(way_name) {free(way_name); way_name=NULL;} | ||
150 | if(way_ref) {free(way_ref); way_ref=NULL;} | ||
151 | if(way_access) {free(way_access); way_access=NULL;} | ||
152 | } | ||
153 | else if(!strncmp(l,"<relation",9)) /* The start of a relation */ | ||
154 | { | ||
155 | nrelations++; | ||
156 | |||
157 | isnode=0; isway=0; isrelation=1; | ||
158 | } | ||
159 | else if(!strncmp(l,"</relation",10)) /* The end of a relation */ | ||
160 | { | ||
161 | isnode=0; isway=0; isrelation=0; | ||
162 | } | ||
163 | else if(isnode) /* The middle of a node */ | ||
164 | { | ||
165 | } | ||
166 | else if(isway) /* The middle of a way */ | ||
167 | { | ||
168 | node_t id; | ||
169 | |||
170 | if(!strncmp(l,"<nd",3)) /* The start of a node specifier */ | ||
171 | { | ||
172 | m=strstr(l,"ref="); m+=4; if(*m=='"' || *m=='\'') m++; id=atoll(m); | ||
173 | |||
174 | if(way_nnodes<=way_nalloc) | ||
175 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nalloc+=16)*sizeof(node_t)); | ||
176 | |||
177 | way_nodes[way_nnodes++]=id; | ||
178 | } | ||
179 | |||
180 | if(!strncmp(l,"<tag",4)) /* The start of a tag specifier */ | ||
181 | { | ||
182 | char delimiter,*k="",*v=""; | ||
183 | |||
184 | m=strstr(l,"k="); m+=2; delimiter=*m; m++; k=m; | ||
185 | while(*m!=delimiter) m++; *m=0; l=m+1; | ||
186 | |||
187 | m=strstr(l,"v="); m+=2; delimiter=*m; m++; v=m; | ||
188 | while(*m!=delimiter) m++; *m=0; | ||
189 | |||
190 | if(!strcmp(k,"oneway") && (!strcmp(v,"true") || !strcmp(v,"yes"))) way_oneway=1; | ||
191 | if(!strcmp(k,"junction") && !strcmp(v,"roundabout")) way_oneway=1; | ||
192 | if(!strcmp(k,"highway") && !strncmp(v,"motorway",8)) way_oneway=1; | ||
193 | |||
194 | if(!strcmp(k,"highway")) | ||
195 | way_highway=strcpy((char*)malloc(strlen(v)+1),v); | ||
196 | |||
197 | if(!strcmp(k,"name")) | ||
198 | way_name=strcpy((char*)malloc(strlen(v)+1),v); | ||
199 | |||
200 | if(!strcmp(k,"ref")) | ||
201 | way_ref=strcpy((char*)malloc(strlen(v)+1),v); | ||
202 | |||
203 | if(!strcmp(k,"access")) | ||
204 | way_access=strcpy((char*)malloc(strlen(v)+1),v); | ||
205 | |||
206 | if(!strcmp(k,"maxspeed")) | ||
207 | { | ||
208 | way_maxspeed=atof(v); | ||
209 | if(strstr(v,"mph")) | ||
210 | way_maxspeed*=1.6; | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | else if(isrelation) /* The middle of a relation */ | ||
215 | { | ||
216 | } | ||
217 | |||
218 | if(!(nlines%10000)) | ||
219 | { | ||
220 | printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",nlines,nnodes,nways,nrelations); | ||
221 | fflush(stdout); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | printf("\rRead : Lines=%ld Nodes=%ld Ways=%ld Relations=%ld\n",nlines,nnodes,nways,nrelations); | ||
226 | fflush(stdout); | ||
227 | |||
228 | if(way_nalloc) | ||
229 | free(way_nodes); | ||
230 | |||
231 | return(0); | ||
232 | } | ||
233 | |||
234 | |||
235 | /*++++++++++++++++++++++++++++++++++++++ | ||
236 | Call fgets and realloc the buffer as needed to get a whole line. | ||
237 | |||
238 | char *fgets_realloc Returns the modified buffer (NULL at the end of the file). | ||
239 | |||
240 | char *buffer The current buffer. | ||
241 | |||
242 | FILE *file The file to read from. | ||
243 | ++++++++++++++++++++++++++++++++++++++*/ | ||
244 | |||
245 | static char *fgets_realloc(char *buffer,FILE *file) | ||
246 | { | ||
247 | int n=0; | ||
248 | char *buf; | ||
249 | |||
250 | if(!buffer) | ||
251 | buffer=(char*)malloc(BUFFSIZE+1); | ||
252 | |||
253 | while((buf=fgets(&buffer[n],BUFFSIZE,file))) | ||
254 | { | ||
255 | int s=strlen(buf); | ||
256 | n+=s; | ||
257 | |||
258 | if(buffer[n-1]=='\n') | ||
259 | break; | ||
260 | else | ||
261 | buffer=(char*)realloc(buffer,n+BUFFSIZE+1); | ||
262 | } | ||
263 | |||
264 | if(!buf) | ||
265 | {free(buffer);buffer=NULL;} | ||
266 | |||
267 | return(buffer); | ||
268 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |