DenseNodes.java (3807B) download
1package osm.message;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.List;
6import java.util.function.Supplier;
7
8import protobuf.Message;
9import protobuf.ProtobufReader;
10
11// repeated sint64 id = 1 [packed = true]; // DELTA coded
12// optional DenseInfo denseinfo = 5;
13// repeated sint64 lat = 8 [packed = true]; // DELTA coded
14// repeated sint64 lon = 9 [packed = true]; // DELTA coded
15// repeated int32 keys_vals = 10 [packed = true];
16public class DenseNodes implements Message<List<Node>> {
17 public final PrimitiveBlock block;
18
19 public DenseNodes(PrimitiveBlock block) {
20 this.block = block;
21 }
22
23 private <T> void expandList(List<T> list, int index, Supplier<T> with) {
24 while (list.size() <= index)
25 list.add(with.get());
26 }
27
28 @Override
29 public List<Node> parse(Iterator<ProtobufReader> iter) {
30 boolean isKey = true;
31
32 int indexID = 0,
33 indexLatiude = 0,
34 indexLongitude = 0,
35 indexTags = 0;
36
37 List<Node> nodes = new ArrayList<>();
38
39 while (iter.hasNext()) {
40 ProtobufReader stream = iter.next();
41
42 switch (stream.tag()) {
43 case 1:
44 Iterator<Long> ids = stream.packed(stream::svarint64, 0l, Long::sum);
45 while (ids.hasNext()) {
46 expandList(nodes, indexID, () -> new Node(block));
47
48 nodes.get(indexID).id = ids.next();
49 indexID++;
50 }
51 break;
52 case 5:
53 stream.skip();
54 break;
55 case 8:
56 Iterator<Double> lats = stream.packed(stream::svarint64,
57 n -> block.latitudeOffset + block.granularity * n,
58 0.0d, Double::sum);
59 while (lats.hasNext()) {
60 expandList(nodes, indexLatiude, () -> new Node(block));
61
62 nodes.get(indexLatiude).latitude = lats.next();
63
64 indexLatiude++;
65 }
66 break;
67 case 9:
68 Iterator<Double> lons = stream.packed(stream::svarint64,
69 n -> block.longitudeOffset + block.granularity * n,
70 0.0d, Double::sum);
71 while (lons.hasNext()) {
72 expandList(nodes, indexLongitude, () -> new Node(block));
73 nodes.get(indexLongitude).longitude = lons.next();
74
75 indexLongitude++;
76 }
77 break;
78 case 10:
79 Iterator<Integer> tags = stream.packed(stream::varint32);
80 while (tags.hasNext()) {
81 int strIndex = tags.next();
82 if (isKey) {
83 expandList(nodes, indexTags, () -> new Node(block));
84 if (strIndex == 0) {
85 indexTags++;
86 continue;
87 }
88 String key = block.stringtable.get(strIndex);
89 nodes.get(indexTags).keys.add(key);
90
91 isKey = false;
92 } else {
93 String value = block.stringtable.get(strIndex);
94 nodes.get(indexTags).values.add(value);
95
96 isKey = true;
97 }
98 }
99 break;
100 default:
101 stream.throwUnexpected();
102 break;
103 }
104 }
105
106 return nodes;
107 }
108}