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 1226 -
(hide annotations)
(download)
(as text)
Mon Dec 24 11:02:10 2012 UTC (12 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 29895 byte(s)
Mon Dec 24 11:02:10 2012 UTC (12 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 29895 byte(s)
The PBF format does not support change files (the 'visible' part of the info message is only for historical data and not for changes).
1 | amb | 2 | /*************************************** |
2 | amb | 1221 | OSM file parser (either JOSM or planet) |
3 | amb | 151 | |
4 | Part of the Routino routing software. | ||
5 | amb | 2 | ******************/ /****************** |
6 | amb | 955 | This file Copyright 2008-2012 Andrew M. Bishop |
7 | amb | 2 | |
8 | amb | 151 | This program is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU Affero General Public License as published by | ||
10 | the Free Software Foundation, either version 3 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU Affero General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Affero General Public License | ||
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | amb | 2 | ***************************************/ |
21 | |||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | #include <ctype.h> | ||
26 | |||
27 | amb | 199 | #include "typesx.h" |
28 | amb | 109 | #include "nodesx.h" |
29 | #include "segmentsx.h" | ||
30 | #include "waysx.h" | ||
31 | amb | 498 | #include "relationsx.h" |
32 | |||
33 | amb | 955 | #include "osmparser.h" |
34 | amb | 394 | #include "tagging.h" |
35 | amb | 519 | #include "logging.h" |
36 | amb | 26 | |
37 | amb | 519 | |
38 | amb | 394 | /* Macros */ |
39 | amb | 2 | |
40 | amb | 680 | /*+ Checks if a value in the XML is one of the allowed values for true. +*/ |
41 | amb | 812 | #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1")) |
42 | amb | 297 | |
43 | amb | 812 | /*+ Checks if a value in the XML is one of the allowed values for false. +*/ |
44 | #define ISFALSE(xx) (!strcmp(xx,"false") || !strcmp(xx,"no") || !strcmp(xx,"0")) | ||
45 | amb | 298 | |
46 | amb | 1221 | /* Global variables */ |
47 | amb | 812 | |
48 | amb | 1221 | node_t *osmparser_way_nodes=NULL; |
49 | int osmparser_way_nnodes=0; | ||
50 | amb | 1140 | |
51 | amb | 1221 | node_t *osmparser_relation_nodes=NULL; |
52 | int osmparser_relation_nnodes=0; | ||
53 | way_t *osmparser_relation_ways=NULL; | ||
54 | int osmparser_relation_nways=0; | ||
55 | relation_t *osmparser_relation_relations=NULL; | ||
56 | int osmparser_relation_nrelations=0; | ||
57 | way_t osmparser_relation_from=NO_WAY_ID; | ||
58 | way_t osmparser_relation_to=NO_WAY_ID; | ||
59 | node_t osmparser_relation_via=NO_NODE_ID; | ||
60 | amb | 1140 | |
61 | amb | 394 | /* Local variables */ |
62 | |||
63 | amb | 498 | static NodesX *nodes; |
64 | static SegmentsX *segments; | ||
65 | static WaysX *ways; | ||
66 | static RelationsX *relations; | ||
67 | amb | 394 | |
68 | amb | 228 | /* Local functions */ |
69 | |||
70 | amb | 812 | static double parse_speed(way_t id,const char *k,const char *v); |
71 | static double parse_weight(way_t id,const char *k,const char *v); | ||
72 | static double parse_length(way_t id,const char *k,const char *v); | ||
73 | amb | 2 | |
74 | amb | 812 | |
75 | amb | 1204 | /*++++++++++++++++++++++++++++++++++++++ |
76 | amb | 1221 | Parse an OSM XML file (from JOSM or planet download). |
77 | amb | 1140 | |
78 | amb | 1221 | int ParseOSMFile Returns 0 if OK or something else in case of an error. |
79 | amb | 1140 | |
80 | amb | 1221 | int fd The file descriptor of the file to read from. |
81 | amb | 1140 | |
82 | amb | 1221 | NodesX *OSMNodes The data structure of nodes to fill in. |
83 | amb | 2 | |
84 | amb | 1221 | SegmentsX *OSMSegments The data structure of segments to fill in. |
85 | amb | 2 | |
86 | amb | 1221 | WaysX *OSMWays The data structure of ways to fill in. |
87 | amb | 2 | |
88 | amb | 1221 | RelationsX *OSMRelations The data structure of relations to fill in. |
89 | amb | 1204 | ++++++++++++++++++++++++++++++++++++++*/ |
90 | |||
91 | amb | 1221 | int ParseOSMFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations) |
92 | amb | 1204 | { |
93 | amb | 1221 | int retval; |
94 | amb | 1204 | |
95 | amb | 1221 | /* Copy the function parameters and initialise the variables */ |
96 | amb | 1204 | |
97 | amb | 1221 | nodes=OSMNodes; |
98 | segments=OSMSegments; | ||
99 | ways=OSMWays; | ||
100 | relations=OSMRelations; | ||
101 | amb | 1204 | |
102 | amb | 1221 | osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t)); |
103 | amb | 1204 | |
104 | amb | 1221 | osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t)); |
105 | osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t)); | ||
106 | osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); | ||
107 | amb | 1204 | |
108 | amb | 1221 | /* Parse the file */ |
109 | amb | 1204 | |
110 | amb | 1221 | retval=ParseXML(fd,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); |
111 | amb | 1204 | |
112 | amb | 1221 | /* Free the variables */ |
113 | amb | 1204 | |
114 | amb | 1221 | free(osmparser_way_nodes); |
115 | amb | 1204 | |
116 | amb | 1221 | free(osmparser_relation_nodes); |
117 | free(osmparser_relation_ways); | ||
118 | free(osmparser_relation_relations); | ||
119 | amb | 1204 | |
120 | amb | 1221 | return(retval); |
121 | amb | 1204 | } |
122 | |||
123 | |||
124 | /*++++++++++++++++++++++++++++++++++++++ | ||
125 | amb | 1221 | Parse an OSC XML file (from planet download). |
126 | amb | 2 | |
127 | amb | 1221 | int ParseOSCFile Returns 0 if OK or something else in case of an error. |
128 | amb | 2 | |
129 | amb | 1186 | int fd The file descriptor of the file to read from. |
130 | amb | 394 | |
131 | amb | 498 | NodesX *OSMNodes The data structure of nodes to fill in. |
132 | amb | 394 | |
133 | amb | 498 | SegmentsX *OSMSegments The data structure of segments to fill in. |
134 | amb | 394 | |
135 | amb | 498 | WaysX *OSMWays The data structure of ways to fill in. |
136 | |||
137 | RelationsX *OSMRelations The data structure of relations to fill in. | ||
138 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
139 | |||
140 | amb | 1221 | int ParseOSCFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations) |
141 | amb | 2 | { |
142 | amb | 394 | int retval; |
143 | amb | 2 | |
144 | amb | 1221 | /* Copy the function parameters and initialise the variables */ |
145 | amb | 2 | |
146 | amb | 394 | nodes=OSMNodes; |
147 | segments=OSMSegments; | ||
148 | ways=OSMWays; | ||
149 | amb | 498 | relations=OSMRelations; |
150 | amb | 394 | |
151 | amb | 1221 | osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t)); |
152 | amb | 498 | |
153 | amb | 1221 | osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t)); |
154 | osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t)); | ||
155 | osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); | ||
156 | amb | 498 | |
157 | /* Parse the file */ | ||
158 | |||
159 | amb | 1221 | retval=ParseXML(fd,xml_osc_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); |
160 | amb | 394 | |
161 | amb | 1221 | /* Free the variables */ |
162 | amb | 394 | |
163 | amb | 1221 | free(osmparser_way_nodes); |
164 | amb | 394 | |
165 | amb | 1221 | free(osmparser_relation_nodes); |
166 | free(osmparser_relation_ways); | ||
167 | free(osmparser_relation_relations); | ||
168 | amb | 394 | |
169 | return(retval); | ||
170 | } | ||
171 | |||
172 | |||
173 | /*++++++++++++++++++++++++++++++++++++++ | ||
174 | amb | 1221 | Parse a PBF format OSM file (from planet download). |
175 | amb | 1140 | |
176 | amb | 1221 | int ParsePBFFile Returns 0 if OK or something else in case of an error. |
177 | amb | 1140 | |
178 | amb | 1186 | int fd The file descriptor of the file to read from. |
179 | amb | 1140 | |
180 | NodesX *OSMNodes The data structure of nodes to fill in. | ||
181 | |||
182 | SegmentsX *OSMSegments The data structure of segments to fill in. | ||
183 | |||
184 | WaysX *OSMWays The data structure of ways to fill in. | ||
185 | |||
186 | RelationsX *OSMRelations The data structure of relations to fill in. | ||
187 | ++++++++++++++++++++++++++++++++++++++*/ | ||
188 | |||
189 | amb | 1226 | int ParsePBFFile(int fd,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations) |
190 | amb | 1140 | { |
191 | int retval; | ||
192 | |||
193 | amb | 1221 | /* Copy the function parameters and initialise the variables */ |
194 | amb | 1140 | |
195 | nodes=OSMNodes; | ||
196 | segments=OSMSegments; | ||
197 | ways=OSMWays; | ||
198 | relations=OSMRelations; | ||
199 | |||
200 | amb | 1221 | osmparser_way_nodes=(node_t*)malloc(256*sizeof(node_t)); |
201 | amb | 1140 | |
202 | amb | 1221 | osmparser_relation_nodes =(node_t *)malloc(256*sizeof(node_t)); |
203 | osmparser_relation_ways =(way_t *)malloc(256*sizeof(way_t)); | ||
204 | osmparser_relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); | ||
205 | amb | 1140 | |
206 | /* Parse the file */ | ||
207 | |||
208 | amb | 1226 | retval=ParsePBF(fd); |
209 | amb | 1140 | |
210 | amb | 1221 | /* Free the variables */ |
211 | amb | 1140 | |
212 | amb | 1221 | free(osmparser_way_nodes); |
213 | amb | 1140 | |
214 | amb | 1221 | free(osmparser_relation_nodes); |
215 | free(osmparser_relation_ways); | ||
216 | free(osmparser_relation_relations); | ||
217 | amb | 1140 | |
218 | return(retval); | ||
219 | } | ||
220 | |||
221 | |||
222 | /*++++++++++++++++++++++++++++++++++++++ | ||
223 | amb | 469 | Process the tags associated with a node. |
224 | |||
225 | TagList *tags The list of node tags. | ||
226 | |||
227 | node_t id The id of the node. | ||
228 | |||
229 | double latitude The latitude of the node. | ||
230 | |||
231 | double longitude The longitude of the node. | ||
232 | amb | 1221 | |
233 | int mode The mode of operation to take (create, modify, delete). | ||
234 | amb | 469 | ++++++++++++++++++++++++++++++++++++++*/ |
235 | |||
236 | amb | 1221 | void ProcessNodeTags(TagList *tags,node_t id,double latitude,double longitude,int mode) |
237 | amb | 469 | { |
238 | amb | 529 | transports_t allow=Transports_ALL; |
239 | amb | 1165 | nodeflags_t flags=0; |
240 | amb | 469 | int i; |
241 | |||
242 | amb | 1140 | /* Delete */ |
243 | |||
244 | if(mode==MODE_DELETE) | ||
245 | { | ||
246 | amb | 1161 | AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED); |
247 | amb | 1140 | |
248 | return; | ||
249 | } | ||
250 | |||
251 | amb | 469 | /* Parse the tags */ |
252 | |||
253 | for(i=0;i<tags->ntags;i++) | ||
254 | { | ||
255 | amb | 1025 | int recognised=0; |
256 | amb | 469 | char *k=tags->k[i]; |
257 | char *v=tags->v[i]; | ||
258 | |||
259 | switch(*k) | ||
260 | { | ||
261 | case 'b': | ||
262 | if(!strcmp(k,"bicycle")) | ||
263 | amb | 812 | { |
264 | if(ISFALSE(v)) | ||
265 | amb | 529 | allow&=~Transports_Bicycle; |
266 | amb | 812 | else if(!ISTRUE(v)) |
267 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
268 | amb | 1025 | recognised=1; break; |
269 | amb | 812 | } |
270 | amb | 469 | |
271 | break; | ||
272 | |||
273 | case 'f': | ||
274 | if(!strcmp(k,"foot")) | ||
275 | amb | 812 | { |
276 | if(ISFALSE(v)) | ||
277 | amb | 529 | allow&=~Transports_Foot; |
278 | amb | 812 | else if(!ISTRUE(v)) |
279 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
280 | amb | 1025 | recognised=1; break; |
281 | amb | 812 | } |
282 | amb | 469 | |
283 | break; | ||
284 | |||
285 | case 'g': | ||
286 | if(!strcmp(k,"goods")) | ||
287 | amb | 812 | { |
288 | if(ISFALSE(v)) | ||
289 | amb | 529 | allow&=~Transports_Goods; |
290 | amb | 812 | else if(!ISTRUE(v)) |
291 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
292 | amb | 1025 | recognised=1; break; |
293 | amb | 812 | } |
294 | amb | 469 | |
295 | break; | ||
296 | |||
297 | case 'h': | ||
298 | amb | 537 | if(!strcmp(k,"highway")) |
299 | if(!strcmp(v,"mini_roundabout")) | ||
300 | amb | 1025 | { |
301 | amb | 538 | flags|=NODE_MINIRNDBT; |
302 | amb | 1025 | recognised=1; break; |
303 | } | ||
304 | amb | 537 | |
305 | amb | 469 | if(!strcmp(k,"horse")) |
306 | amb | 812 | { |
307 | if(ISFALSE(v)) | ||
308 | amb | 529 | allow&=~Transports_Horse; |
309 | amb | 812 | else if(!ISTRUE(v)) |
310 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
311 | amb | 1025 | recognised=1; break; |
312 | amb | 812 | } |
313 | amb | 469 | |
314 | if(!strcmp(k,"hgv")) | ||
315 | amb | 812 | { |
316 | if(ISFALSE(v)) | ||
317 | amb | 529 | allow&=~Transports_HGV; |
318 | amb | 812 | else if(!ISTRUE(v)) |
319 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
320 | amb | 1025 | recognised=1; break; |
321 | amb | 812 | } |
322 | amb | 469 | |
323 | break; | ||
324 | |||
325 | case 'm': | ||
326 | if(!strcmp(k,"moped")) | ||
327 | amb | 812 | { |
328 | if(ISFALSE(v)) | ||
329 | amb | 529 | allow&=~Transports_Moped; |
330 | amb | 812 | else if(!ISTRUE(v)) |
331 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
332 | amb | 1025 | recognised=1; break; |
333 | amb | 812 | } |
334 | amb | 469 | |
335 | if(!strcmp(k,"motorbike")) | ||
336 | amb | 812 | { |
337 | if(ISFALSE(v)) | ||
338 | amb | 529 | allow&=~Transports_Motorbike; |
339 | amb | 812 | else if(!ISTRUE(v)) |
340 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
341 | amb | 1025 | recognised=1; break; |
342 | amb | 812 | } |
343 | amb | 469 | |
344 | if(!strcmp(k,"motorcar")) | ||
345 | amb | 812 | { |
346 | if(ISFALSE(v)) | ||
347 | amb | 529 | allow&=~Transports_Motorcar; |
348 | amb | 812 | else if(!ISTRUE(v)) |
349 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
350 | amb | 1025 | recognised=1; break; |
351 | amb | 812 | } |
352 | amb | 469 | |
353 | break; | ||
354 | |||
355 | case 'p': | ||
356 | if(!strcmp(k,"psv")) | ||
357 | amb | 812 | { |
358 | if(ISFALSE(v)) | ||
359 | amb | 529 | allow&=~Transports_PSV; |
360 | amb | 812 | else if(!ISTRUE(v)) |
361 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
362 | amb | 1025 | recognised=1; break; |
363 | amb | 812 | } |
364 | amb | 469 | |
365 | break; | ||
366 | |||
367 | case 'w': | ||
368 | if(!strcmp(k,"wheelchair")) | ||
369 | amb | 812 | { |
370 | if(ISFALSE(v)) | ||
371 | amb | 529 | allow&=~Transports_Wheelchair; |
372 | amb | 812 | else if(!ISTRUE(v)) |
373 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",id,v); |
374 | amb | 1025 | recognised=1; break; |
375 | amb | 812 | } |
376 | amb | 469 | |
377 | break; | ||
378 | |||
379 | default: | ||
380 | amb | 1025 | break; |
381 | } | ||
382 | |||
383 | if(!recognised) | ||
384 | amb | 813 | logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
385 | amb | 469 | } |
386 | |||
387 | /* Create the node */ | ||
388 | |||
389 | amb | 1161 | AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags); |
390 | amb | 469 | } |
391 | |||
392 | |||
393 | /*++++++++++++++++++++++++++++++++++++++ | ||
394 | amb | 394 | Process the tags associated with a way. |
395 | |||
396 | TagList *tags The list of way tags. | ||
397 | |||
398 | way_t id The id of the way. | ||
399 | amb | 1221 | |
400 | int mode The mode of operation to take (create, modify, delete). | ||
401 | amb | 394 | ++++++++++++++++++++++++++++++++++++++*/ |
402 | |||
403 | amb | 1221 | void ProcessWayTags(TagList *tags,way_t id,int mode) |
404 | amb | 394 | { |
405 | amb | 1137 | Way way={0}; |
406 | amb | 1168 | distance_t oneway=0,area=0; |
407 | amb | 1137 | int roundabout=0; |
408 | amb | 812 | char *name=NULL,*ref=NULL,*refname=NULL; |
409 | amb | 1173 | int i,j; |
410 | amb | 394 | |
411 | amb | 1140 | /* Delete */ |
412 | |||
413 | amb | 1159 | if(mode==MODE_DELETE || mode==MODE_MODIFY) |
414 | amb | 1140 | { |
415 | way.type=WAY_DELETED; | ||
416 | |||
417 | amb | 1161 | AppendWayList(ways,id,&way,""); |
418 | amb | 1140 | |
419 | amb | 1174 | way.type=Highway_None; |
420 | amb | 1154 | |
421 | amb | 1168 | AppendSegmentList(segments,id,NO_NODE_ID,NO_NODE_ID,0); |
422 | amb | 1145 | } |
423 | amb | 1140 | |
424 | amb | 1145 | if(mode==MODE_DELETE) |
425 | amb | 1140 | return; |
426 | |||
427 | amb | 1125 | /* Sanity check */ |
428 | |||
429 | amb | 1221 | if(osmparser_way_nnodes==0) |
430 | amb | 1125 | { |
431 | logerror("Way %"Pway_t" has no nodes.\n",id); | ||
432 | return; | ||
433 | } | ||
434 | |||
435 | amb | 1221 | if(osmparser_way_nnodes==1) |
436 | amb | 1125 | { |
437 | logerror("Way %"Pway_t" has only one node.\n",id); | ||
438 | return; | ||
439 | } | ||
440 | |||
441 | amb | 833 | /* Parse the tags - just look for highway */ |
442 | amb | 394 | |
443 | for(i=0;i<tags->ntags;i++) | ||
444 | amb | 2 | { |
445 | amb | 394 | char *k=tags->k[i]; |
446 | char *v=tags->v[i]; | ||
447 | amb | 2 | |
448 | amb | 833 | if(!strcmp(k,"highway")) |
449 | { | ||
450 | way.type=HighwayType(v); | ||
451 | |||
452 | amb | 1174 | if(way.type==Highway_None) |
453 | amb | 833 | logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",id,v); |
454 | amb | 1174 | |
455 | break; | ||
456 | amb | 833 | } |
457 | } | ||
458 | |||
459 | /* Don't continue if this is not a highway (bypass error logging) */ | ||
460 | |||
461 | amb | 1174 | if(way.type==Highway_None) |
462 | amb | 833 | return; |
463 | |||
464 | /* Parse the tags - look for the others */ | ||
465 | |||
466 | for(i=0;i<tags->ntags;i++) | ||
467 | { | ||
468 | amb | 1025 | int recognised=0; |
469 | amb | 833 | char *k=tags->k[i]; |
470 | char *v=tags->v[i]; | ||
471 | |||
472 | amb | 394 | switch(*k) |
473 | { | ||
474 | amb | 914 | case 'a': |
475 | if(!strcmp(k,"area")) | ||
476 | { | ||
477 | if(ISTRUE(v)) | ||
478 | amb | 1137 | area=SEGMENT_AREA; |
479 | amb | 914 | else if(!ISFALSE(v)) |
480 | logerror("Way %"Pway_t" has an unrecognised tag value 'area' = '%s' (after tagging rules); using 'no'.\n",id,v); | ||
481 | amb | 1025 | recognised=1; break; |
482 | amb | 914 | } |
483 | |||
484 | break; | ||
485 | |||
486 | amb | 394 | case 'b': |
487 | if(!strcmp(k,"bicycle")) | ||
488 | amb | 812 | { |
489 | amb | 394 | if(ISTRUE(v)) |
490 | amb | 813 | way.allow|=Transports_Bicycle; |
491 | amb | 812 | else if(!ISFALSE(v)) |
492 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'bicycle' = '%s' (after tagging rules); using 'no'.\n",id,v); |
493 | amb | 1025 | recognised=1; break; |
494 | amb | 812 | } |
495 | amb | 394 | |
496 | amb | 498 | if(!strcmp(k,"bicycleroute")) |
497 | amb | 812 | { |
498 | amb | 498 | if(ISTRUE(v)) |
499 | way.props|=Properties_BicycleRoute; | ||
500 | amb | 812 | else if(!ISFALSE(v)) |
501 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v); |
502 | amb | 1025 | recognised=1; break; |
503 | amb | 812 | } |
504 | amb | 498 | |
505 | amb | 394 | if(!strcmp(k,"bridge")) |
506 | amb | 812 | { |
507 | amb | 394 | if(ISTRUE(v)) |
508 | way.props|=Properties_Bridge; | ||
509 | amb | 812 | else if(!ISFALSE(v)) |
510 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'bridge' = '%s' (after tagging rules); using 'no'.\n",id,v); |
511 | amb | 1025 | recognised=1; break; |
512 | amb | 812 | } |
513 | amb | 394 | |
514 | amb | 2 | break; |
515 | amb | 394 | |
516 | case 'f': | ||
517 | if(!strcmp(k,"foot")) | ||
518 | amb | 812 | { |
519 | amb | 394 | if(ISTRUE(v)) |
520 | amb | 813 | way.allow|=Transports_Foot; |
521 | amb | 812 | else if(!ISFALSE(v)) |
522 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'foot' = '%s' (after tagging rules); using 'no'.\n",id,v); |
523 | amb | 1025 | recognised=1; break; |
524 | amb | 812 | } |
525 | amb | 394 | |
526 | amb | 498 | if(!strcmp(k,"footroute")) |
527 | amb | 812 | { |
528 | amb | 498 | if(ISTRUE(v)) |
529 | way.props|=Properties_FootRoute; | ||
530 | amb | 812 | else if(!ISFALSE(v)) |
531 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v); |
532 | amb | 1025 | recognised=1; break; |
533 | amb | 812 | } |
534 | amb | 498 | |
535 | amb | 394 | break; |
536 | |||
537 | case 'g': | ||
538 | if(!strcmp(k,"goods")) | ||
539 | amb | 812 | { |
540 | amb | 394 | if(ISTRUE(v)) |
541 | amb | 529 | way.allow|=Transports_Goods; |
542 | amb | 812 | else if(!ISFALSE(v)) |
543 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'goods' = '%s' (after tagging rules); using 'no'.\n",id,v); |
544 | amb | 1025 | recognised=1; break; |
545 | amb | 812 | } |
546 | amb | 394 | |
547 | break; | ||
548 | |||
549 | case 'h': | ||
550 | if(!strcmp(k,"highway")) | ||
551 | amb | 1025 | {recognised=1; break;} |
552 | amb | 394 | |
553 | if(!strcmp(k,"horse")) | ||
554 | amb | 812 | { |
555 | amb | 394 | if(ISTRUE(v)) |
556 | amb | 529 | way.allow|=Transports_Horse; |
557 | amb | 812 | else if(!ISFALSE(v)) |
558 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'horse' = '%s' (after tagging rules); using 'no'.\n",id,v); |
559 | amb | 1025 | recognised=1; break; |
560 | amb | 812 | } |
561 | amb | 394 | |
562 | if(!strcmp(k,"hgv")) | ||
563 | amb | 812 | { |
564 | amb | 394 | if(ISTRUE(v)) |
565 | amb | 529 | way.allow|=Transports_HGV; |
566 | amb | 812 | else if(!ISFALSE(v)) |
567 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'hgv' = '%s' (after tagging rules); using 'no'.\n",id,v); |
568 | amb | 1025 | recognised=1; break; |
569 | amb | 812 | } |
570 | amb | 394 | |
571 | break; | ||
572 | |||
573 | case 'm': | ||
574 | amb | 1025 | if(!strncmp(k,"max",3)) |
575 | { | ||
576 | if(!strcmp(k+3,"speed")) | ||
577 | { | ||
578 | way.speed=kph_to_speed(parse_speed(id,k,v)); | ||
579 | recognised=1; break; | ||
580 | } | ||
581 | amb | 394 | |
582 | amb | 1025 | if(!strcmp(k+3,"weight")) |
583 | { | ||
584 | way.weight=tonnes_to_weight(parse_weight(id,k,v)); | ||
585 | recognised=1; break; | ||
586 | } | ||
587 | amb | 394 | |
588 | amb | 1025 | if(!strcmp(k+3,"height")) |
589 | { | ||
590 | way.height=metres_to_height(parse_length(id,k,v)); | ||
591 | recognised=1; break; | ||
592 | } | ||
593 | amb | 394 | |
594 | amb | 1025 | if(!strcmp(k+3,"width")) |
595 | { | ||
596 | way.width=metres_to_height(parse_length(id,k,v)); | ||
597 | recognised=1; break; | ||
598 | } | ||
599 | amb | 394 | |
600 | amb | 1025 | if(!strcmp(k+3,"length")) |
601 | { | ||
602 | way.length=metres_to_height(parse_length(id,k,v)); | ||
603 | recognised=1; break; | ||
604 | } | ||
605 | } | ||
606 | amb | 394 | |
607 | if(!strcmp(k,"moped")) | ||
608 | amb | 812 | { |
609 | amb | 394 | if(ISTRUE(v)) |
610 | amb | 529 | way.allow|=Transports_Moped; |
611 | amb | 812 | else if(!ISFALSE(v)) |
612 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'moped' = '%s' (after tagging rules); using 'no'.\n",id,v); |
613 | amb | 1025 | recognised=1; break; |
614 | amb | 812 | } |
615 | amb | 394 | |
616 | if(!strcmp(k,"motorbike")) | ||
617 | amb | 812 | { |
618 | amb | 394 | if(ISTRUE(v)) |
619 | amb | 529 | way.allow|=Transports_Motorbike; |
620 | amb | 812 | else if(!ISFALSE(v)) |
621 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'motorbike' = '%s' (after tagging rules); using 'no'.\n",id,v); |
622 | amb | 1025 | recognised=1; break; |
623 | amb | 812 | } |
624 | amb | 394 | |
625 | if(!strcmp(k,"motorcar")) | ||
626 | amb | 812 | { |
627 | amb | 394 | if(ISTRUE(v)) |
628 | amb | 529 | way.allow|=Transports_Motorcar; |
629 | amb | 812 | else if(!ISFALSE(v)) |
630 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'motorcar' = '%s' (after tagging rules); using 'no'.\n",id,v); |
631 | amb | 1025 | recognised=1; break; |
632 | amb | 812 | } |
633 | amb | 394 | |
634 | if(!strcmp(k,"multilane")) | ||
635 | amb | 812 | { |
636 | amb | 394 | if(ISTRUE(v)) |
637 | way.props|=Properties_Multilane; | ||
638 | amb | 812 | else if(!ISFALSE(v)) |
639 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'multilane' = '%s' (after tagging rules); using 'no'.\n",id,v); |
640 | amb | 1025 | recognised=1; break; |
641 | amb | 812 | } |
642 | amb | 394 | |
643 | break; | ||
644 | |||
645 | case 'n': | ||
646 | if(!strcmp(k,"name")) | ||
647 | amb | 1025 | { |
648 | amb | 394 | name=v; |
649 | amb | 1025 | recognised=1; break; |
650 | } | ||
651 | amb | 394 | |
652 | break; | ||
653 | |||
654 | case 'o': | ||
655 | if(!strcmp(k,"oneway")) | ||
656 | { | ||
657 | if(ISTRUE(v)) | ||
658 | amb | 1137 | oneway=ONEWAY_1TO2; |
659 | amb | 394 | else if(!strcmp(v,"-1")) |
660 | amb | 1137 | oneway=ONEWAY_2TO1; |
661 | amb | 812 | else if(!ISFALSE(v)) |
662 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'oneway' = '%s' (after tagging rules); using 'no'.\n",id,v); |
663 | amb | 1025 | recognised=1; break; |
664 | amb | 394 | } |
665 | |||
666 | break; | ||
667 | |||
668 | case 'p': | ||
669 | if(!strcmp(k,"paved")) | ||
670 | amb | 812 | { |
671 | amb | 394 | if(ISTRUE(v)) |
672 | way.props|=Properties_Paved; | ||
673 | amb | 812 | else if(!ISFALSE(v)) |
674 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'paved' = '%s' (after tagging rules); using 'no'.\n",id,v); |
675 | amb | 1025 | recognised=1; break; |
676 | amb | 812 | } |
677 | amb | 394 | |
678 | if(!strcmp(k,"psv")) | ||
679 | amb | 812 | { |
680 | amb | 394 | if(ISTRUE(v)) |
681 | amb | 529 | way.allow|=Transports_PSV; |
682 | amb | 812 | else if(!ISFALSE(v)) |
683 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'psv' = '%s' (after tagging rules); using 'no'.\n",id,v); |
684 | amb | 1025 | recognised=1; break; |
685 | amb | 812 | } |
686 | amb | 394 | |
687 | break; | ||
688 | |||
689 | case 'r': | ||
690 | if(!strcmp(k,"ref")) | ||
691 | amb | 1025 | { |
692 | amb | 394 | ref=v; |
693 | amb | 1025 | recognised=1; break; |
694 | } | ||
695 | amb | 394 | |
696 | amb | 923 | if(!strcmp(k,"roundabout")) |
697 | { | ||
698 | if(ISTRUE(v)) | ||
699 | roundabout=1; | ||
700 | else if(!ISFALSE(v)) | ||
701 | logerror("Way %"Pway_t" has an unrecognised tag value 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v); | ||
702 | amb | 1025 | recognised=1; break; |
703 | amb | 923 | } |
704 | |||
705 | amb | 394 | break; |
706 | |||
707 | case 't': | ||
708 | if(!strcmp(k,"tunnel")) | ||
709 | amb | 812 | { |
710 | amb | 394 | if(ISTRUE(v)) |
711 | way.props|=Properties_Tunnel; | ||
712 | amb | 812 | else if(!ISFALSE(v)) |
713 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'tunnel' = '%s' (after tagging rules); using 'no'.\n",id,v); |
714 | amb | 1025 | recognised=1; break; |
715 | amb | 812 | } |
716 | amb | 394 | |
717 | break; | ||
718 | |||
719 | case 'w': | ||
720 | if(!strcmp(k,"wheelchair")) | ||
721 | amb | 812 | { |
722 | amb | 394 | if(ISTRUE(v)) |
723 | amb | 529 | way.allow|=Transports_Wheelchair; |
724 | amb | 812 | else if(!ISFALSE(v)) |
725 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",id,v); |
726 | amb | 1025 | recognised=1; break; |
727 | amb | 812 | } |
728 | amb | 394 | |
729 | break; | ||
730 | |||
731 | default: | ||
732 | amb | 1025 | break; |
733 | } | ||
734 | |||
735 | if(!recognised) | ||
736 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
737 | amb | 2 | } |
738 | |||
739 | amb | 394 | /* Create the way */ |
740 | amb | 2 | |
741 | amb | 812 | if(!way.allow) |
742 | return; | ||
743 | |||
744 | if(oneway) | ||
745 | amb | 1174 | way.type|=Highway_OneWay; |
746 | amb | 394 | |
747 | amb | 923 | if(roundabout) |
748 | amb | 1174 | way.type|=Highway_Roundabout; |
749 | amb | 923 | |
750 | amb | 812 | if(ref && name) |
751 | { | ||
752 | refname=(char*)malloc(strlen(ref)+strlen(name)+4); | ||
753 | sprintf(refname,"%s (%s)",name,ref); | ||
754 | } | ||
755 | else if(ref && !name) | ||
756 | refname=ref; | ||
757 | else if(!ref && name) | ||
758 | refname=name; | ||
759 | else /* if(!ref && !name) */ | ||
760 | refname=""; | ||
761 | amb | 394 | |
762 | amb | 1161 | AppendWayList(ways,id,&way,refname); |
763 | amb | 394 | |
764 | amb | 812 | if(ref && name) |
765 | free(refname); | ||
766 | amb | 394 | |
767 | amb | 1221 | for(i=1;i<osmparser_way_nnodes;i++) |
768 | amb | 812 | { |
769 | amb | 1221 | node_t from=osmparser_way_nodes[i-1]; |
770 | node_t to =osmparser_way_nodes[i]; | ||
771 | amb | 812 | |
772 | amb | 1173 | for(j=1;j<i;j++) |
773 | { | ||
774 | amb | 1221 | node_t n1=osmparser_way_nodes[j-1]; |
775 | node_t n2=osmparser_way_nodes[j]; | ||
776 | amb | 1173 | |
777 | if((n1==from && n2==to) || (n2==from && n1==to)) | ||
778 | logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" in way %"Pway_t" is duplicated.\n",n1,n2,id); | ||
779 | } | ||
780 | |||
781 | amb | 1168 | AppendSegmentList(segments,id,from,to,area+oneway); |
782 | amb | 394 | } |
783 | amb | 2 | } |
784 | amb | 498 | |
785 | |||
786 | /*++++++++++++++++++++++++++++++++++++++ | ||
787 | Process the tags associated with a relation. | ||
788 | |||
789 | TagList *tags The list of relation tags. | ||
790 | |||
791 | relation_t id The id of the relation. | ||
792 | amb | 1221 | |
793 | int mode The mode of operation to take (create, modify, delete). | ||
794 | amb | 498 | ++++++++++++++++++++++++++++++++++++++*/ |
795 | |||
796 | amb | 1221 | void ProcessRelationTags(TagList *tags,relation_t id,int mode) |
797 | amb | 498 | { |
798 | amb | 529 | transports_t routes=Transports_None; |
799 | amb | 540 | transports_t except=Transports_None; |
800 | int relation_turn_restriction=0; | ||
801 | amb | 541 | TurnRestriction restriction=TurnRestrict_None; |
802 | amb | 498 | int i; |
803 | |||
804 | amb | 1140 | /* Delete */ |
805 | |||
806 | amb | 1152 | if(mode==MODE_DELETE || mode==MODE_MODIFY) |
807 | amb | 1140 | { |
808 | amb | 1161 | AppendRouteRelationList(relations,id,RELATION_DELETED, |
809 | amb | 1221 | osmparser_relation_ways,osmparser_relation_nways, |
810 | osmparser_relation_relations,osmparser_relation_nrelations); | ||
811 | amb | 1140 | |
812 | amb | 1161 | AppendTurnRelationList(relations,id, |
813 | amb | 1221 | osmparser_relation_from,osmparser_relation_to,osmparser_relation_via, |
814 | amb | 1161 | restriction,RELATION_DELETED); |
815 | amb | 1152 | } |
816 | amb | 1140 | |
817 | amb | 1152 | if(mode==MODE_DELETE) |
818 | amb | 1140 | return; |
819 | |||
820 | amb | 1125 | /* Sanity check */ |
821 | |||
822 | amb | 1221 | if(osmparser_relation_nnodes==0 && osmparser_relation_nways==0 && osmparser_relation_nrelations==0) |
823 | amb | 1125 | { |
824 | logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",id); | ||
825 | return; | ||
826 | } | ||
827 | |||
828 | amb | 498 | /* Parse the tags */ |
829 | |||
830 | for(i=0;i<tags->ntags;i++) | ||
831 | { | ||
832 | amb | 1025 | int recognised=0; |
833 | amb | 498 | char *k=tags->k[i]; |
834 | char *v=tags->v[i]; | ||
835 | |||
836 | switch(*k) | ||
837 | { | ||
838 | case 'b': | ||
839 | if(!strcmp(k,"bicycleroute")) | ||
840 | amb | 812 | { |
841 | amb | 498 | if(ISTRUE(v)) |
842 | amb | 529 | routes|=Transports_Bicycle; |
843 | amb | 812 | else if(!ISFALSE(v)) |
844 | amb | 813 | logerror("Relation %"Prelation_t" has an unrecognised tag value 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",id,v); |
845 | amb | 1025 | recognised=1; break; |
846 | amb | 812 | } |
847 | amb | 498 | |
848 | break; | ||
849 | |||
850 | amb | 540 | case 'e': |
851 | if(!strcmp(k,"except")) | ||
852 | amb | 812 | { |
853 | amb | 540 | for(i=1;i<Transport_Count;i++) |
854 | amb | 876 | if(strstr(v,TransportName(i))) |
855 | amb | 540 | except|=TRANSPORTS(i); |
856 | |||
857 | amb | 812 | if(except==Transports_None) |
858 | amb | 813 | logerror("Relation %"Prelation_t" has an unrecognised tag value 'except' = '%s' (after tagging rules); ignoring it.\n",id,v); |
859 | amb | 1025 | |
860 | recognised=1; break; | ||
861 | amb | 812 | } |
862 | |||
863 | amb | 540 | break; |
864 | |||
865 | amb | 498 | case 'f': |
866 | if(!strcmp(k,"footroute")) | ||
867 | amb | 812 | { |
868 | amb | 498 | if(ISTRUE(v)) |
869 | amb | 529 | routes|=Transports_Foot; |
870 | amb | 812 | else if(!ISFALSE(v)) |
871 | amb | 813 | logerror("Relation %"Prelation_t" has an unrecognised tag value 'footroute' = '%s' (after tagging rules); using 'no'.\n",id,v); |
872 | amb | 1025 | recognised=1; break; |
873 | amb | 812 | } |
874 | amb | 498 | |
875 | break; | ||
876 | |||
877 | amb | 540 | case 'r': |
878 | if(!strcmp(k,"restriction")) | ||
879 | { | ||
880 | amb | 541 | if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn; |
881 | if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn; | ||
882 | if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn; | ||
883 | if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on; | ||
884 | if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn; | ||
885 | if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn; | ||
886 | if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on; | ||
887 | amb | 812 | |
888 | if(restriction==TurnRestrict_None) | ||
889 | amb | 813 | logerror("Relation %"Prelation_t" has an unrecognised tag value 'restriction' = '%s' (after tagging rules); ignoring it.\n",id,v); |
890 | amb | 1025 | |
891 | recognised=1; break; | ||
892 | amb | 540 | } |
893 | |||
894 | break; | ||
895 | |||
896 | case 't': | ||
897 | if(!strcmp(k,"type")) | ||
898 | amb | 1025 | { |
899 | amb | 540 | if(!strcmp(v,"restriction")) |
900 | relation_turn_restriction=1; | ||
901 | amb | 1025 | |
902 | /* Don't log an error for relations of types that we don't handle - there are so many */ | ||
903 | recognised=1; break; | ||
904 | } | ||
905 | |||
906 | amb | 540 | break; |
907 | |||
908 | amb | 498 | default: |
909 | amb | 1025 | break; |
910 | } | ||
911 | |||
912 | if(!recognised) | ||
913 | amb | 813 | logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
914 | amb | 498 | } |
915 | |||
916 | amb | 505 | /* Create the route relation (must store all relations that have ways or |
917 | relations even if they are not routes because they might be referenced by | ||
918 | other relations that are routes) */ | ||
919 | amb | 498 | |
920 | amb | 1221 | if((osmparser_relation_nways || osmparser_relation_nrelations) && !relation_turn_restriction) |
921 | amb | 1161 | AppendRouteRelationList(relations,id,routes, |
922 | amb | 1221 | osmparser_relation_ways,osmparser_relation_nways, |
923 | osmparser_relation_relations,osmparser_relation_nrelations); | ||
924 | amb | 540 | |
925 | /* Create the turn restriction relation. */ | ||
926 | |||
927 | amb | 812 | if(relation_turn_restriction && restriction!=TurnRestrict_None) |
928 | { | ||
929 | amb | 1221 | if(osmparser_relation_from==NO_WAY_ID) |
930 | amb | 813 | logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",id); |
931 | amb | 1221 | else if(osmparser_relation_to==NO_WAY_ID) |
932 | amb | 813 | logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",id); |
933 | amb | 1221 | else if(osmparser_relation_via==NO_NODE_ID) |
934 | amb | 813 | logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",id); |
935 | amb | 812 | else |
936 | amb | 1161 | AppendTurnRelationList(relations,id, |
937 | amb | 1221 | osmparser_relation_from,osmparser_relation_to,osmparser_relation_via, |
938 | amb | 1161 | restriction,except); |
939 | amb | 812 | } |
940 | amb | 498 | } |
941 | amb | 812 | |
942 | |||
943 | /*++++++++++++++++++++++++++++++++++++++ | ||
944 | Convert a string containing a speed into a double precision. | ||
945 | |||
946 | double parse_speed Returns the speed in km/h if it can be parsed. | ||
947 | |||
948 | way_t id The way being processed. | ||
949 | |||
950 | const char *k The tag key. | ||
951 | |||
952 | const char *v The tag value. | ||
953 | ++++++++++++++++++++++++++++++++++++++*/ | ||
954 | |||
955 | static double parse_speed(way_t id,const char *k,const char *v) | ||
956 | { | ||
957 | char *ev; | ||
958 | double value=strtod(v,&ev); | ||
959 | |||
960 | if(v==ev) | ||
961 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
962 | amb | 812 | else |
963 | { | ||
964 | while(isspace(*ev)) ev++; | ||
965 | |||
966 | if(!strcmp(ev,"mph")) | ||
967 | return(1.609*value); | ||
968 | amb | 813 | |
969 | if(*ev==0 || !strcmp(ev,"kph")) | ||
970 | amb | 812 | return(value); |
971 | amb | 813 | |
972 | logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); | ||
973 | amb | 812 | } |
974 | |||
975 | return(0); | ||
976 | } | ||
977 | |||
978 | |||
979 | /*++++++++++++++++++++++++++++++++++++++ | ||
980 | Convert a string containing a weight into a double precision. | ||
981 | |||
982 | double parse_weight Returns the weight in tonnes if it can be parsed. | ||
983 | |||
984 | way_t id The way being processed. | ||
985 | |||
986 | const char *k The tag key. | ||
987 | |||
988 | const char *v The tag value. | ||
989 | ++++++++++++++++++++++++++++++++++++++*/ | ||
990 | |||
991 | static double parse_weight(way_t id,const char *k,const char *v) | ||
992 | { | ||
993 | char *ev; | ||
994 | double value=strtod(v,&ev); | ||
995 | |||
996 | if(v==ev) | ||
997 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
998 | amb | 812 | else |
999 | { | ||
1000 | while(isspace(*ev)) ev++; | ||
1001 | |||
1002 | if(!strcmp(ev,"kg")) | ||
1003 | return(value/1000.0); | ||
1004 | amb | 813 | |
1005 | amb | 825 | if(*ev==0 || !strcmp(ev,"T") || !strcmp(ev,"t") |
1006 | || !strcmp(ev,"ton") || !strcmp(ev,"tons") | ||
1007 | || !strcmp(ev,"tonne") || !strcmp(ev,"tonnes")) | ||
1008 | amb | 812 | return(value); |
1009 | amb | 813 | |
1010 | logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); | ||
1011 | amb | 812 | } |
1012 | |||
1013 | return(0); | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | /*++++++++++++++++++++++++++++++++++++++ | ||
1018 | Convert a string containing a length into a double precision. | ||
1019 | |||
1020 | double parse_length Returns the length in metres if it can be parsed. | ||
1021 | |||
1022 | way_t id The way being processed. | ||
1023 | |||
1024 | const char *k The tag key. | ||
1025 | |||
1026 | const char *v The tag value. | ||
1027 | ++++++++++++++++++++++++++++++++++++++*/ | ||
1028 | |||
1029 | static double parse_length(way_t id,const char *k,const char *v) | ||
1030 | { | ||
1031 | char *ev; | ||
1032 | double value=strtod(v,&ev); | ||
1033 | |||
1034 | if(v==ev) | ||
1035 | amb | 813 | logerror("Way %"Pway_t" has an unrecognised tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); |
1036 | amb | 812 | else |
1037 | { | ||
1038 | amb | 813 | int en=0; |
1039 | int feet=0,inches=0; | ||
1040 | amb | 812 | |
1041 | amb | 813 | if(sscanf(v,"%d' %d\"%n",&feet,&inches,&en)==2 && en && !v[en]) |
1042 | amb | 812 | return((feet+(double)inches/12.0)*0.254); |
1043 | amb | 813 | |
1044 | amb | 1127 | if(sscanf(v,"%d'%d\"%n",&feet,&inches,&en)==2 && en && !v[en]) |
1045 | return((feet+(double)inches/12.0)*0.254); | ||
1046 | |||
1047 | if(sscanf(v,"%d'-%d\"%n",&feet,&inches,&en)==2 && en && !v[en]) | ||
1048 | return((feet+(double)inches/12.0)*0.254); | ||
1049 | |||
1050 | amb | 813 | if(sscanf(v,"%d - %d%n",&feet,&inches,&en)==2 && en && !v[en]) |
1051 | return((feet+(double)inches/12.0)*0.254); | ||
1052 | |||
1053 | if(sscanf(v,"%d ft %d in%n",&feet,&inches,&en)==2 && en && !v[en]) | ||
1054 | return((feet+(double)inches/12.0)*0.254); | ||
1055 | |||
1056 | amb | 825 | if(sscanf(v,"%d feet %d inches%n",&feet,&inches,&en)==2 && en && !v[en]) |
1057 | return((feet+(double)inches/12.0)*0.254); | ||
1058 | |||
1059 | if(!strcmp(ev,"'")) | ||
1060 | amb | 812 | return(feet*0.254); |
1061 | amb | 813 | |
1062 | while(isspace(*ev)) ev++; | ||
1063 | |||
1064 | if(!strcmp(ev,"ft") || !strcmp(ev,"feet")) | ||
1065 | amb | 812 | return(value*0.254); |
1066 | amb | 813 | |
1067 | amb | 825 | if(*ev==0 || !strcmp(ev,"m") || !strcmp(ev,"metre") || !strcmp(ev,"metres")) |
1068 | amb | 812 | return(value); |
1069 | amb | 813 | |
1070 | logerror("Way %"Pway_t" has an un-parseable tag value '%s' = '%s' (after tagging rules); ignoring it.\n",id,k,v); | ||
1071 | amb | 812 | } |
1072 | |||
1073 | return(0); | ||
1074 | } |
Properties
Name | Value |
---|---|
cvs:description | OSM XML file parser. |