Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1526 - (show annotations) (download) (as text)
Mon Mar 17 19:14:32 2014 UTC (11 years ago) by amb
Original Path: trunk/src/osmo5mparse.c
File MIME type: text/x-csrc
File size: 18650 byte(s)
Make two global functions local to the files that contain them.

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