misc/persolijn

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

Relation.java (3208B) 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.ProtobufReader;
  9
 10// enum MemberType {
 11// NODE = 0;
 12// WAY = 1;
 13// RELATION = 2;
 14// } 
 15// required int64 id = 1;
 16// repeated uint32 keys = 2 [packed = true];
 17// repeated uint32 vals = 3 [packed = true];
 18// optional Info info = 4;
 19// repeated int32 roles_sid = 8 [packed = true]; // This should have been defined as uint32 for consistency, but it is now too late to change it
 20// repeated sint64 memids = 9 [packed = true]; // DELTA encoded
 21// repeated MemberType types = 10 [packed = true];
 22public class Relation extends AbstractEntity<Relation> {
 23    public static enum RelationMemberType {
 24        NODE, WAY, RELATION
 25    }
 26
 27    public static class RelationMember {
 28        private RelationMemberType type;
 29        private long id;
 30        private String role;
 31
 32        public RelationMemberType getType() {
 33            return type;
 34        }
 35
 36        public long getID() {
 37            return id;
 38        }
 39
 40        public String getRole() {
 41            return role;
 42        }
 43    }
 44
 45    private List<RelationMember> members = new ArrayList<>();
 46
 47    public Relation(PrimitiveBlock block) {
 48        super(block);
 49    }
 50
 51    private <T> void expandList(List<T> list, int index, Supplier<T> with) {
 52        while (list.size() <= index)
 53            list.add(with.get());
 54    }
 55
 56    @Override
 57    public Relation parseRemaining(Iterator<ProtobufReader> tags) {
 58        int indexRole = 0,
 59                indexID = 0,
 60                indexType = 0;
 61
 62        while (tags.hasNext()) {
 63            ProtobufReader message = tags.next();
 64            switch (message.tag()) {
 65                case 4:
 66                    message.skip();
 67                    break;
 68                case 8:
 69                    Iterator<Integer> roles = message.packed(message::varint32);
 70                    while (roles.hasNext()) {
 71                        expandList(members, indexRole, RelationMember::new);
 72
 73                        members.get(indexRole).role = block.stringtable.get(roles.next());
 74                        indexRole++;
 75                    }
 76                    break;
 77                case 9:
 78                    Iterator<Long> ids = message.packed(message::svarint64, 0L, Long::sum);
 79                    while (ids.hasNext()) {
 80                        expandList(members, indexID, RelationMember::new);
 81
 82                        members.get(indexID).id = ids.next();
 83                        indexID++;
 84                    }
 85                    break;
 86                case 10:
 87                    Iterator<Integer> types = message.packed(message::varint32);
 88                    while (types.hasNext()) {
 89                        expandList(members, indexType, RelationMember::new);
 90
 91                        members.get(indexType).type = RelationMemberType.values()[types.next()];
 92                        indexType++;
 93                    }
 94                    break;
 95                default:
 96                    message.throwUnexpected();
 97            }
 98        }
 99        return this;
100    }
101
102    public List<RelationMember> getMembers() {
103        return members;
104    }
105}