Relation.java (3208B)
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.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]; 22 public 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 }