persolijn

an efficient router for busses
Log | Files | Refs

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 }