misc/persolijn

osm-protobuf/src/main/java/osm/message/DenseNodes.java in master
Repositories | Summary | Log | Files

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}