Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /branches/libroutino/src/osmo5mparse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1727 - (show annotations) (download) (as text)
Wed Jul 1 18:20:13 2015 UTC (9 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 18842 byte(s)
Merge changes from MS-Windows branch.

1 /***************************************
2 A simple o5m/o5c parser.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2012-2015 Andrew M. Bishop
7
8 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 ***************************************/
21
22
23 #include <stdio.h>
24
25 #if defined(_MSC_VER)
26 #include <io.h>
27 #include <basetsd.h>
28 #define read(fd,address,length) _read(fd,address,(unsigned int)(length))
29 #define ssize_t SSIZE_T
30 #else
31 #include <unistd.h>
32 #endif
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <inttypes.h>
37 #include <stdint.h>
38
39 #include "osmparser.h"
40 #include "tagging.h"
41 #include "logging.h"
42
43
44 /* At the top level */
45
46 #define O5M_FILE_NODE 0x10
47 #define O5M_FILE_WAY 0x11
48 #define O5M_FILE_RELATION 0x12
49 #define O5M_FILE_BOUNDING_BOX 0xdb
50 #define O5M_FILE_TIMESTAMP 0xdc
51 #define O5M_FILE_HEADER 0xe0
52 #define O5M_FILE_SYNC 0xee
53 #define O5M_FILE_JUMP 0xef
54 #define O5M_FILE_END 0xfe
55 #define O5M_FILE_RESET 0xff
56
57 /* Errors */
58
59 #define O5M_EOF 0
60
61 #define O5M_ERROR_UNEXP_EOF 100
62 #define O5M_ERROR_RESET_NOT_FIRST 101
63 #define O5M_ERROR_HEADER_NOT_FIRST 102
64 #define O5M_ERROR_EXPECTED_O5M 103
65 #define O5M_ERROR_EXPECTED_O5C 104
66 #define O5M_ERROR_FILE_LEVEL 105
67
68 /* Local parsing variables (re-initialised for each file) */
69
70 static uint64_t byteno=0;
71 static uint64_t nnodes=0,nways=0,nrelations=0;
72
73 static int64_t id=0;
74 static int32_t lat=0;
75 static int32_t lon=0;
76 static int64_t timestamp=0;
77 static int64_t node_refid=0,way_refid=0,relation_refid=0;
78
79 static int mode_change=MODE_NORMAL;
80
81 static uint32_t buffer_allocated;
82 static unsigned char *buffer=NULL;
83 static unsigned char *buffer_ptr,*buffer_end;
84
85 static int string_table_start=0;
86 static unsigned char **string_table=NULL;
87
88 #define STRING_TABLE_ALLOCATED 15000
89
90
91 /*++++++++++++++++++++++++++++++++++++++
92 Refill the data buffer and set the pointers.
93
94 int buffer_refill Return 0 if everything is OK or 1 for EOF.
95
96 int fd The file descriptor to read from.
97
98 uint32_t bytes The number of bytes to read.
99 ++++++++++++++++++++++++++++++++++++++*/
100
101 static inline int buffer_refill(int fd,uint32_t bytes)
102 {
103 ssize_t n,m;
104 uint32_t totalbytes;
105
106 m=buffer_end-buffer_ptr;
107
108 if(m)
109 memmove(buffer,buffer_ptr,m);
110
111 totalbytes=bytes+m;
112
113 if(totalbytes>buffer_allocated)
114 buffer=(unsigned char *)realloc(buffer,buffer_allocated=totalbytes);
115
116 byteno+=bytes;
117
118 buffer_ptr=buffer;
119 buffer_end=buffer+m;
120
121 do
122 {
123 n=read(fd,buffer_end,bytes);
124
125 if(n<=0)
126 return(1);
127
128 buffer_end+=n;
129 bytes-=n;
130 }
131 while(bytes>0);
132
133 return(0);
134 }
135
136 static void process_node(void);
137 static void process_way(void);
138 static void process_relation(void);
139 static void process_info(void);
140 static unsigned char *process_string(int pair,unsigned char **buf_ptr,unsigned char **string1,unsigned char **string2);
141
142
143 /* Macros to simplify the parser (and make it look more like the XML parser) */
144
145 #define BEGIN(xx) do{ state=(xx); goto finish_parsing; } while(0)
146
147 #define BUFFER_CHARS(xx) do{ if(buffer_refill(fd,(xx))) BEGIN(O5M_ERROR_UNEXP_EOF); } while(0)
148
149
150 /* O5M decoding */
151
152 #define O5M_LATITUDE(xx) (double)(1E-7*(xx))
153 #define O5M_LONGITUDE(xx) (double)(1E-7*(xx))
154
155
156 /*++++++++++++++++++++++++++++++++++++++
157 Parse an O5M int32 data value.
158
159 uint32_t o5m_int32 Returns the integer value.
160
161 unsigned char **ptr The pointer to read the data from.
162 ++++++++++++++++++++++++++++++++++++++*/
163
164 static inline uint32_t o5m_int32(unsigned char **ptr)
165 {
166 uint32_t result=(**ptr)&0x7F;
167
168 if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<7;
169 if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<14;
170 if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<21;
171 if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<28;
172
173 (*ptr)++;
174
175 return(result);
176 }
177
178
179 /*++++++++++++++++++++++++++++++++++++++
180 Parse an O5M int32 data value.
181
182 int32_t o5m_sint32 Returns the integer value.
183
184 unsigned char **ptr The pointer to read the data from.
185 ++++++++++++++++++++++++++++++++++++++*/
186
187 static inline int32_t o5m_sint32(unsigned char **ptr)
188 {
189 int64_t result=((**ptr)&0x7E)>>1;
190 int sign=(**ptr)&0x01;
191
192 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<6;
193 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<13;
194 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<20;
195 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<27;
196
197 (*ptr)++;
198
199 if(sign)
200 result=-result-1;
201
202 return(result);
203 }
204
205
206 /*++++++++++++++++++++++++++++++++++++++
207 Parse an O5M int64 data value.
208
209 int64_t o5m_int64 Returns the integer value.
210
211 unsigned char **ptr The pointer to read the data from.
212 ++++++++++++++++++++++++++++++++++++++*/
213
214 static inline int64_t o5m_int64(unsigned char **ptr)
215 {
216 uint64_t result=(**ptr)&0x7F;
217
218 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<7;
219 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<14;
220 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<21;
221 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<28;
222 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<35;
223 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<42;
224 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<49;
225 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<56;
226 if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<63;
227
228 (*ptr)++;
229
230 return(result);
231 }
232
233
234 /*++++++++++++++++++++++++++++++++++++++
235 Parse an O5M sint64 data value.
236
237 int64_t o5m_sint64 Returns the integer value.
238
239 unsigned char **ptr The pointer to read the data from.
240 ++++++++++++++++++++++++++++++++++++++*/
241
242 static inline int64_t o5m_sint64(unsigned char **ptr)
243 {
244 int64_t result=((**ptr)&0x7E)>>1;
245 int sign=(**ptr)&0x01;
246
247 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<6;
248 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<13;
249 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<20;
250 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<27;
251 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<34;
252 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<41;
253 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<48;
254 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<55;
255 if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<62;
256
257 (*ptr)++;
258
259 if(sign)
260 result=-result-1;
261
262 return(result);
263 }
264
265
266 /*++++++++++++++++++++++++++++++++++++++
267 Parse the O5M and call the functions for each OSM item as seen.
268
269 int ParseO5M Returns 0 if OK or something else in case of an error.
270
271 int fd The file descriptor of the file to parse.
272
273 int changes Set to 1 if this is expected to be a changes file, otherwise zero.
274 ++++++++++++++++++++++++++++++++++++++*/
275
276 static int ParseO5M(int fd,int changes)
277 {
278 int i;
279 int state;
280 int number_reset=0;
281 int error;
282
283 /* Print the initial message */
284
285 printf_first("Reading: Bytes=0 Nodes=0 Ways=0 Relations=0");
286
287 /* The actual parser. */
288
289 nnodes=0,nways=0,nrelations=0;
290
291 if(changes)
292 mode_change=MODE_MODIFY;
293
294 string_table_start=0;
295 string_table=(unsigned char **)malloc(STRING_TABLE_ALLOCATED*sizeof(unsigned char *));
296 for(i=0;i<STRING_TABLE_ALLOCATED;i++)
297 string_table[i]=(unsigned char*)malloc(252);
298
299 buffer_allocated=4096;
300 buffer=(unsigned char*)malloc(buffer_allocated);
301
302 buffer_ptr=buffer_end=buffer;
303
304 while(1)
305 {
306 uint32_t dataset_length=0;
307
308 /* ================ Parsing states ================ */
309
310 BUFFER_CHARS(1);
311
312 state=*buffer_ptr++;
313
314 if(state!=O5M_FILE_END && state!=O5M_FILE_RESET)
315 {
316 uint32_t length;
317 unsigned char *ptr;
318
319 if(number_reset==0)
320 BEGIN(O5M_ERROR_RESET_NOT_FIRST);
321
322 BUFFER_CHARS(4);
323
324 ptr=buffer_ptr;
325 dataset_length=o5m_int32(&buffer_ptr);
326
327 length=dataset_length-4+(buffer_ptr-ptr);
328
329 BUFFER_CHARS(length);
330 }
331 else if(state==O5M_FILE_END)
332 ;
333 else if(state==O5M_FILE_RESET)
334 number_reset++;
335
336 switch(state)
337 {
338 case O5M_FILE_NODE:
339
340 process_node();
341
342 break;
343
344 case O5M_FILE_WAY:
345
346 process_way();
347
348 break;
349
350 case O5M_FILE_RELATION:
351
352 process_relation();
353
354 break;
355
356 case O5M_FILE_BOUNDING_BOX:
357
358 buffer_ptr+=dataset_length;
359
360 break;
361
362 case O5M_FILE_TIMESTAMP:
363
364 buffer_ptr+=dataset_length;
365
366 break;
367
368 case O5M_FILE_HEADER:
369
370 if(number_reset!=1)
371 BEGIN(O5M_ERROR_HEADER_NOT_FIRST);
372
373 if(!changes && strncmp((char*)buffer_ptr,"o5m2",4))
374 BEGIN(O5M_ERROR_EXPECTED_O5M);
375
376 if( changes && strncmp((char*)buffer_ptr,"o5c2",4))
377 BEGIN(O5M_ERROR_EXPECTED_O5C);
378
379 buffer_ptr+=dataset_length;
380
381 break;
382
383 case O5M_FILE_SYNC:
384
385 buffer_ptr+=dataset_length;
386
387 break;
388
389 case O5M_FILE_JUMP:
390
391 buffer_ptr+=dataset_length;
392
393 break;
394
395 case O5M_FILE_END:
396
397 BEGIN(O5M_EOF);
398
399 break;
400
401 case O5M_FILE_RESET:
402
403 string_table_start=0;
404 id=0;
405 lat=0;
406 lon=0;
407 timestamp=0;
408 node_refid=0,way_refid=0,relation_refid=0;
409
410 break;
411
412 default:
413
414 error=state;
415 BEGIN(O5M_ERROR_FILE_LEVEL);
416 }
417 }
418
419
420 finish_parsing:
421
422 switch(state)
423 {
424 /* End of file */
425
426 case O5M_EOF:
427 break;
428
429
430 /* ================ Error states ================ */
431
432
433 case O5M_ERROR_UNEXP_EOF:
434 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": unexpected end of file seen.\n",byteno);
435 break;
436
437 case O5M_ERROR_RESET_NOT_FIRST:
438 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": Reset was not the first byte.\n",byteno);
439 break;
440
441 case O5M_ERROR_HEADER_NOT_FIRST:
442 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": Header was not the first section.\n",byteno);
443 break;
444
445 case O5M_ERROR_EXPECTED_O5M:
446 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": Expected O5M format but header disagrees.\n",byteno);
447 break;
448
449 case O5M_ERROR_EXPECTED_O5C:
450 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": Expected O5C format but header disagrees.\n",byteno);
451 break;
452
453 case O5M_ERROR_FILE_LEVEL:
454 fprintf(stderr,"O5M Parser: Error at byte %"PRIu64": Unexpected dataset type %02x.\n",byteno,error);
455 break;
456 }
457
458 /* Free the parser variables */
459
460 for(i=0;i<STRING_TABLE_ALLOCATED;i++)
461 free(string_table[i]);
462 free(string_table);
463
464 free(buffer);
465
466 /* Print the final message */
467
468 printf_last("Read: Bytes=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,byteno,nnodes,nways,nrelations);
469
470 return(state);
471 }
472
473
474 /*++++++++++++++++++++++++++++++++++++++
475 Process an O5M Node dataset.
476 ++++++++++++++++++++++++++++++++++++++*/
477
478 static void process_node(void)
479 {
480 int64_t delta_id;
481 int32_t delta_lat;
482 int32_t delta_lon;
483 TagList *tags=NULL,*result=NULL;
484 int mode=mode_change;
485
486 delta_id=o5m_sint64(&buffer_ptr);
487 id+=delta_id;
488
489 if(buffer_ptr<buffer_end)
490 {
491 if(*buffer_ptr!=0)
492 process_info();
493 else
494 buffer_ptr++;
495 }
496
497 if(buffer_ptr<buffer_end)
498 {
499 delta_lon=o5m_sint32(&buffer_ptr);
500 lon+=delta_lon;
501
502 delta_lat=o5m_sint32(&buffer_ptr);
503 lat+=delta_lat;
504 }
505 else
506 mode=MODE_DELETE;
507
508 /* Mangle the data and send it to the OSM parser */
509
510 nnodes++;
511
512 if(!(nnodes%10000))
513 printf_middle("Reading: Bytes=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,byteno,nnodes,nways,nrelations);
514
515 tags=NewTagList();
516
517 while(buffer_ptr<buffer_end)
518 {
519 unsigned char *key,*val;
520
521 process_string(2,&buffer_ptr,&key,&val);
522
523 AppendTag(tags,(char*)key,(char*)val);
524 }
525
526 result=ApplyNodeTaggingRules(tags,id);
527
528 ProcessNodeTags(result,id,O5M_LATITUDE(lat),O5M_LONGITUDE(lon),mode);
529
530 DeleteTagList(tags);
531 DeleteTagList(result);
532 }
533
534
535 /*++++++++++++++++++++++++++++++++++++++
536 Process an O5M Way dataset.
537 ++++++++++++++++++++++++++++++++++++++*/
538
539 static void process_way(void)
540 {
541 int64_t delta_id;
542 TagList *tags=NULL,*result=NULL;
543 int mode=mode_change;
544 unsigned char *refs=NULL,*refs_end;
545
546 delta_id=o5m_sint64(&buffer_ptr);
547 id+=delta_id;
548
549 if(buffer_ptr<buffer_end)
550 {
551 if(*buffer_ptr!=0)
552 process_info();
553 else
554 buffer_ptr++;
555 }
556
557 if(buffer_ptr<buffer_end)
558 {
559 uint32_t length;
560
561 length=o5m_int32(&buffer_ptr);
562
563 if(length)
564 {
565 refs=buffer_ptr;
566 refs_end=buffer_ptr+length;
567
568 buffer_ptr=refs_end;
569 }
570 }
571 else
572 mode=MODE_DELETE;
573
574 /* Mangle the data and send it to the OSM parser */
575
576 nways++;
577
578 if(!(nways%1000))
579 printf_middle("Reading: Bytes=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,byteno,nnodes,nways,nrelations);
580
581 AddWayRefs(0);
582
583 if(refs)
584 while(refs<refs_end)
585 {
586 int64_t delta_ref;
587
588 delta_ref=o5m_sint64(&refs);
589 node_refid+=delta_ref;
590
591 AddWayRefs(node_refid);
592 }
593
594 tags=NewTagList();
595
596 while(buffer_ptr<buffer_end)
597 {
598 unsigned char *key,*val;
599
600 process_string(2,&buffer_ptr,&key,&val);
601
602 AppendTag(tags,(char*)key,(char*)val);
603 }
604
605 result=ApplyWayTaggingRules(tags,id);
606
607 ProcessWayTags(result,id,mode);
608
609 DeleteTagList(tags);
610 DeleteTagList(result);
611 }
612
613
614 /*++++++++++++++++++++++++++++++++++++++
615 Process an O5M Relation dataset.
616 ++++++++++++++++++++++++++++++++++++++*/
617
618 static void process_relation()
619 {
620 int64_t delta_id;
621 TagList *tags=NULL,*result=NULL;
622 int mode=mode_change;
623 unsigned char *refs=NULL,*refs_end;
624
625 delta_id=o5m_sint64(&buffer_ptr);
626 id+=delta_id;
627
628 if(buffer_ptr<buffer_end)
629 {
630 if(*buffer_ptr!=0)
631 process_info();
632 else
633 buffer_ptr++;
634 }
635
636 if(buffer_ptr<buffer_end)
637 {
638 uint32_t length;
639
640 length=o5m_int32(&buffer_ptr);
641
642 if(length)
643 {
644 refs=buffer_ptr;
645 refs_end=buffer_ptr+length;
646
647 buffer_ptr=refs_end;
648 }
649 }
650 else
651 mode=MODE_DELETE;
652
653 /* Mangle the data and send it to the OSM parser */
654
655 nrelations++;
656
657 if(!(nrelations%1000))
658 printf_middle("Reading: Bytes=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,byteno,nnodes,nways,nrelations);
659
660 AddRelationRefs(0,0,0,NULL);
661
662 if(refs)
663 while(refs<refs_end)
664 {
665 int64_t delta_ref;
666 unsigned char *typerole=NULL;
667
668 delta_ref=o5m_sint64(&refs);
669
670 typerole=process_string(1,&refs,NULL,NULL);
671
672 if(*typerole=='0')
673 {
674 node_refid+=delta_ref;
675
676 AddRelationRefs(node_refid,0,0,(char*)(typerole+1));
677 }
678 else if(*typerole=='1')
679 {
680 way_refid+=delta_ref;
681
682 AddRelationRefs(0,way_refid,0,(char*)(typerole+1));
683 }
684 else if(*typerole=='2')
685 {
686 relation_refid+=delta_ref;
687
688 AddRelationRefs(0,0,relation_refid,(char*)(typerole+1));
689 }
690 }
691
692 tags=NewTagList();
693
694 while(buffer_ptr<buffer_end)
695 {
696 unsigned char *key,*val;
697
698 process_string(2,&buffer_ptr,&key,&val);
699
700 AppendTag(tags,(char*)key,(char*)val);
701 }
702
703 result=ApplyRelationTaggingRules(tags,id);
704
705 ProcessRelationTags(result,id,mode);
706
707 DeleteTagList(tags);
708 DeleteTagList(result);
709 }
710
711
712 /*++++++++++++++++++++++++++++++++++++++
713 Process an O5M info message.
714 ++++++++++++++++++++++++++++++++++++++*/
715
716 static void process_info(void)
717 {
718 int64_t timestamp_delta;
719
720 o5m_int32(&buffer_ptr); /* version */
721
722 timestamp_delta=o5m_sint64(&buffer_ptr);
723 timestamp+=timestamp_delta;
724
725 if(timestamp!=0)
726 {
727 o5m_sint32(&buffer_ptr); /* changeset */
728
729 process_string(2,&buffer_ptr,NULL,NULL); /* user */
730 }
731 }
732
733
734 /*++++++++++++++++++++++++++++++++++++++
735 Process an O5M string and take care of maintaining the string table.
736
737 unsigned char *process_string_pair Return a pointer to the concatenation of the two strings.
738
739 int pair Set to 2 for a pair or 1 for a single string.
740
741 unsigned char **buf_ptr The pointer to the buffer that is to be updated.
742
743 unsigned char **string1 Returns a pointer to the first of the strings in the pair.
744
745 unsigned char **string2 Returns a pointer to the second of the strings in the pair.
746 ++++++++++++++++++++++++++++++++++++++*/
747
748 static unsigned char *process_string(int pair,unsigned char **buf_ptr,unsigned char **string1,unsigned char **string2)
749 {
750 int lookup=0;
751 unsigned char *string;
752 unsigned char *p;
753
754 if(**buf_ptr==0)
755 string=*buf_ptr+1;
756 else
757 {
758 uint32_t position=o5m_int32(buf_ptr);
759
760 string=string_table[(string_table_start-position+STRING_TABLE_ALLOCATED)%STRING_TABLE_ALLOCATED];
761
762 lookup=1;
763 }
764
765 p=string;
766
767 if(pair==2)
768 {
769 if(string1)
770 *string1=p;
771
772 while(*p) p++;
773
774 p++;
775
776 if(string2)
777 *string2=p;
778 }
779
780 while(*p) p++;
781
782 if(!lookup)
783 {
784 if((p-string)<252)
785 {
786 memcpy(string_table[string_table_start],string,p-string+1);
787
788 string_table_start=(string_table_start+1)%STRING_TABLE_ALLOCATED;
789 }
790
791 *buf_ptr=p+1;
792 }
793
794 return(string);
795 }
796
797
798 /*++++++++++++++++++++++++++++++++++++++
799 Parse an O5M format OSM file (from planet download).
800
801 int ParseO5MFile Returns 0 if OK or something else in case of an error.
802
803 int fd The file descriptor of the file to read from.
804
805 NodesX *OSMNodes The data structure of nodes to fill in.
806
807 WaysX *OSMWays The data structure of ways to fill in.
808
809 RelationsX *OSMRelations The data structure of relations to fill in.
810 ++++++++++++++++++++++++++++++++++++++*/
811
812 int ParseO5MFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations)
813 {
814 int retval;
815
816 /* Initialise the parser */
817
818 InitialiseParser(OSMNodes,OSMWays,OSMRelations);
819
820 /* Parse the file */
821
822 retval=ParseO5M(fd,0);
823
824 /* Cleanup the parser */
825
826 CleanupParser();
827
828 return(retval);
829 }
830
831
832 /*++++++++++++++++++++++++++++++++++++++
833 Parse an O5C format OSM file (from planet download).
834
835 int ParseO5CFile Returns 0 if OK or something else in case of an error.
836
837 int fd The file descriptor of the file to read from.
838
839 NodesX *OSMNodes The data structure of nodes to fill in.
840
841 WaysX *OSMWays The data structure of ways to fill in.
842
843 RelationsX *OSMRelations The data structure of relations to fill in.
844 ++++++++++++++++++++++++++++++++++++++*/
845
846 int ParseO5CFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations)
847 {
848 int retval;
849
850 /* Initialise the parser */
851
852 InitialiseParser(OSMNodes,OSMWays,OSMRelations);
853
854 /* Parse the file */
855
856 retval=ParseO5M(fd,1);
857
858 /* Cleanup the parser */
859
860 CleanupParser();
861
862 return(retval);
863 }