pbf_parser 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/pbf_parser/pbf_parser.c +124 -2
- metadata +14 -16
- data/lib/pbf_parser.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5341b491bdc9e0695a864bb7b190d226dc8ad2ca
|
4
|
+
data.tar.gz: 988771cfcd757689ceb0c4875722d9653b345720
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eebbaf35074633ae16866fa1d59b888159aa9f53425fc3ebb61ffa46bf501c6c4a7d6e1c1fbb0f4b7cd41b184bd563d2b4ab9a77f2f53b8c66694a4121c95ee
|
7
|
+
data.tar.gz: b036b89bbaaa41f986a79686d61fe116eeb838be457cad07041c936dcabeba0de1e2a48f1e7b1fd4736bc6971c3eb64bf99c51445e60e1b10e7d9c0043838985
|
data/ext/pbf_parser/pbf_parser.c
CHANGED
@@ -590,9 +590,70 @@ static VALUE parse_osm_data(VALUE obj)
|
|
590
590
|
|
591
591
|
primitive_block__free_unpacked(primitive_block, NULL);
|
592
592
|
|
593
|
+
// Increment position
|
594
|
+
rb_iv_set(obj, "@pos", INT2NUM(NUM2INT(rb_iv_get(obj, "@pos")) + 1));
|
595
|
+
|
593
596
|
return Qtrue;
|
594
597
|
}
|
595
598
|
|
599
|
+
// Find position and size of all data blobs in the file
|
600
|
+
static VALUE find_all_blobs(VALUE obj)
|
601
|
+
{
|
602
|
+
FILE *input = DATA_PTR(obj);
|
603
|
+
long old_pos = ftell(input);
|
604
|
+
|
605
|
+
if (0 != fseek(input, 0, SEEK_SET)) {
|
606
|
+
rb_raise(rb_eIOError, "Unable to seek to beginning of file");
|
607
|
+
}
|
608
|
+
|
609
|
+
BlobHeader *header;
|
610
|
+
|
611
|
+
VALUE blobs = rb_ary_new();
|
612
|
+
rb_iv_set(obj, "@blobs", blobs);
|
613
|
+
|
614
|
+
long pos = 0, data_pos = 0;
|
615
|
+
int32_t datasize;
|
616
|
+
|
617
|
+
while ((header = read_blob_header(input)) != NULL) {
|
618
|
+
|
619
|
+
datasize = header->datasize;
|
620
|
+
|
621
|
+
if (0 == strcmp(header->type, "OSMData")) {
|
622
|
+
VALUE blob_info = rb_hash_new();
|
623
|
+
data_pos = ftell(input);
|
624
|
+
|
625
|
+
// This is designed to be user-friendly, so I have chosen
|
626
|
+
// to make header_pos the position of the protobuf stream
|
627
|
+
// itself, in line with data_pos. However, internally, we
|
628
|
+
// subtract 4 when calling parse_osm_data().
|
629
|
+
rb_hash_aset(blob_info, STR2SYM("header_pos"),
|
630
|
+
LONG2NUM(pos + 4));
|
631
|
+
rb_hash_aset(blob_info, STR2SYM("header_size"),
|
632
|
+
LONG2NUM(data_pos - pos - 4));
|
633
|
+
rb_hash_aset(blob_info, STR2SYM("data_pos"),
|
634
|
+
LONG2NUM(data_pos));
|
635
|
+
rb_hash_aset(blob_info, STR2SYM("data_size"),
|
636
|
+
UINT2NUM(datasize));
|
637
|
+
|
638
|
+
rb_ary_push(blobs, blob_info);
|
639
|
+
}
|
640
|
+
|
641
|
+
blob_header__free_unpacked(header, NULL);
|
642
|
+
|
643
|
+
if (0 != fseek(input, datasize, SEEK_CUR)) {
|
644
|
+
break; // cut losses
|
645
|
+
}
|
646
|
+
pos = ftell(input);
|
647
|
+
}
|
648
|
+
|
649
|
+
// restore old position
|
650
|
+
if (0 != fseek(input, old_pos, SEEK_SET)) {
|
651
|
+
rb_raise(rb_eIOError, "Unable to restore old file position");
|
652
|
+
}
|
653
|
+
|
654
|
+
return blobs;
|
655
|
+
}
|
656
|
+
|
596
657
|
static VALUE header_getter(VALUE obj)
|
597
658
|
{
|
598
659
|
return rb_iv_get(obj, "@header");
|
@@ -624,10 +685,63 @@ static VALUE relations_getter(VALUE obj)
|
|
624
685
|
return rb_hash_aref(data, STR2SYM("relations"));
|
625
686
|
}
|
626
687
|
|
688
|
+
static VALUE blobs_getter(VALUE obj)
|
689
|
+
{
|
690
|
+
VALUE blobs = rb_iv_get(obj, "@blobs");
|
691
|
+
if (blobs == Qnil) {
|
692
|
+
blobs = find_all_blobs(obj);
|
693
|
+
}
|
694
|
+
return blobs;
|
695
|
+
}
|
696
|
+
|
697
|
+
static VALUE size_getter(VALUE obj)
|
698
|
+
{
|
699
|
+
VALUE blobs = blobs_getter(obj);
|
700
|
+
return rb_funcall(blobs, rb_intern("size"), 0);
|
701
|
+
}
|
702
|
+
|
703
|
+
static VALUE pos_getter(VALUE obj)
|
704
|
+
{
|
705
|
+
return rb_iv_get(obj, "@pos");
|
706
|
+
}
|
707
|
+
|
708
|
+
static VALUE seek_to_osm_data(VALUE obj, VALUE index)
|
709
|
+
{
|
710
|
+
FILE *input = DATA_PTR(obj);
|
711
|
+
VALUE blobs = blobs_getter(obj);
|
712
|
+
int index_raw = NUM2INT(index);
|
713
|
+
|
714
|
+
// Normalise the index, otherwise #pos returns the wrong value
|
715
|
+
if (index_raw < 0) {
|
716
|
+
int size = NUM2INT(size_getter(obj));
|
717
|
+
// Only normalise if valid; otherwise, allow rb_ary_entry() to fail.
|
718
|
+
if (index_raw + size >= 0) {
|
719
|
+
index_raw += size;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
|
723
|
+
if (NUM2INT(rb_iv_get(obj, "@pos")) == index_raw) {
|
724
|
+
return Qtrue; // already there
|
725
|
+
}
|
726
|
+
VALUE blob_info = rb_ary_entry(blobs, index_raw);
|
727
|
+
if (!RTEST(blob_info)) {
|
728
|
+
return Qfalse; // no such blob entry
|
729
|
+
}
|
730
|
+
long pos = NUM2LONG(rb_hash_aref(blob_info, STR2SYM("header_pos"))) - 4;
|
731
|
+
if (0 != fseek(input, pos, SEEK_SET)) {
|
732
|
+
rb_raise(rb_eIOError, "Unable to seek to file position");
|
733
|
+
}
|
734
|
+
|
735
|
+
// Set position - incremented by parse_osm_data
|
736
|
+
rb_iv_set(obj, "@pos", INT2NUM(index_raw - 1));
|
737
|
+
|
738
|
+
return parse_osm_data(obj);
|
739
|
+
}
|
740
|
+
|
627
741
|
static VALUE iterate(VALUE obj)
|
628
742
|
{
|
629
743
|
if (!rb_block_given_p())
|
630
|
-
|
744
|
+
return rb_funcall(obj, rb_intern("to_enum"), 0);
|
631
745
|
|
632
746
|
do
|
633
747
|
{
|
@@ -637,7 +751,7 @@ static VALUE iterate(VALUE obj)
|
|
637
751
|
|
638
752
|
rb_yield_values(3, nodes, ways, relations);
|
639
753
|
|
640
|
-
} while(parse_osm_data(obj)
|
754
|
+
} while(RTEST(parse_osm_data(obj)));
|
641
755
|
|
642
756
|
return Qnil;
|
643
757
|
}
|
@@ -658,6 +772,9 @@ static VALUE initialize(VALUE obj, VALUE filename)
|
|
658
772
|
// Store the filename
|
659
773
|
rb_iv_set(obj, "@filename", filename);
|
660
774
|
|
775
|
+
// Set initial position - incremented by parse_osm_data
|
776
|
+
rb_iv_set(obj, "@pos", INT2NUM(-1));
|
777
|
+
|
661
778
|
// Every osm.pbf file must have an OSMHeader at the beginning.
|
662
779
|
// Failing to find it means that the file is corrupt or invalid.
|
663
780
|
parse_osm_header(obj, DATA_PTR(obj));
|
@@ -689,6 +806,8 @@ void Init_pbf_parser(void)
|
|
689
806
|
rb_define_method(klass, "initialize", initialize, 1);
|
690
807
|
rb_define_method(klass, "inspect", inspect, 0);
|
691
808
|
rb_define_method(klass, "next", parse_osm_data, 0);
|
809
|
+
rb_define_method(klass, "seek", seek_to_osm_data, 1);
|
810
|
+
rb_define_method(klass, "pos=", seek_to_osm_data, 1);
|
692
811
|
rb_define_method(klass, "each", iterate, 0);
|
693
812
|
|
694
813
|
// Getters
|
@@ -697,4 +816,7 @@ void Init_pbf_parser(void)
|
|
697
816
|
rb_define_method(klass, "nodes", nodes_getter, 0);
|
698
817
|
rb_define_method(klass, "ways", ways_getter, 0);
|
699
818
|
rb_define_method(klass, "relations", relations_getter, 0);
|
819
|
+
rb_define_method(klass, "blobs", blobs_getter, 0);
|
820
|
+
rb_define_method(klass, "size", size_getter, 0);
|
821
|
+
rb_define_method(klass, "pos", pos_getter, 0);
|
700
822
|
}
|
metadata
CHANGED
@@ -1,45 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pbf_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrià Planas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description:
|
42
|
-
on GitHub for installation instructions.
|
41
|
+
description:
|
43
42
|
email:
|
44
43
|
- adriaplanas@liquidcodeworks.com
|
45
44
|
executables: []
|
@@ -47,14 +46,13 @@ extensions:
|
|
47
46
|
- ext/pbf_parser/extconf.rb
|
48
47
|
extra_rdoc_files: []
|
49
48
|
files:
|
50
|
-
-
|
49
|
+
- ext/pbf_parser/extconf.rb
|
51
50
|
- ext/pbf_parser/fileformat.pb-c.c
|
52
|
-
- ext/pbf_parser/osmformat.pb-c.c
|
53
|
-
- ext/pbf_parser/pbf_parser.c
|
54
51
|
- ext/pbf_parser/fileformat.pb-c.h
|
52
|
+
- ext/pbf_parser/osmformat.pb-c.c
|
55
53
|
- ext/pbf_parser/osmformat.pb-c.h
|
54
|
+
- ext/pbf_parser/pbf_parser.c
|
56
55
|
- ext/pbf_parser/pbf_parser.h
|
57
|
-
- ext/pbf_parser/extconf.rb
|
58
56
|
homepage: https://github.com/planas/pbf_parser
|
59
57
|
licenses:
|
60
58
|
- MIT
|
@@ -65,18 +63,18 @@ require_paths:
|
|
65
63
|
- lib
|
66
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
65
|
requirements:
|
68
|
-
- -
|
66
|
+
- - ">="
|
69
67
|
- !ruby/object:Gem::Version
|
70
68
|
version: '0'
|
71
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
70
|
requirements:
|
73
|
-
- -
|
71
|
+
- - ">="
|
74
72
|
- !ruby/object:Gem::Version
|
75
73
|
version: '0'
|
76
74
|
requirements: []
|
77
75
|
rubyforge_project:
|
78
|
-
rubygems_version: 2.
|
76
|
+
rubygems_version: 2.2.2
|
79
77
|
signing_key:
|
80
78
|
specification_version: 4
|
81
|
-
summary:
|
79
|
+
summary: Parse Open Street Map PBF files with ease
|
82
80
|
test_files: []
|
data/lib/pbf_parser.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'pbf_parser/pbf_parser'
|