DenseNodes.java (3807B)
1 package osm.message; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 import java.util.List; 6 import java.util.function.Supplier; 7 8 import protobuf.Message; 9 import 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]; 16 public 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 }