1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
use protobuf_iter::*; use delta::DeltaEncodedIter; use delimited::DelimitedIter; use dense_info::DenseInfoParser; use super::*; pub struct DenseNodesParser<'a> { primitive_block: &'a PrimitiveBlock<'a>, ids: DeltaEncodedIter<'a, PackedVarint, i64>, lats: DeltaEncodedIter<'a, PackedVarint, i64>, lons: DeltaEncodedIter<'a, PackedVarint, i64>, infos: Option<DenseInfoParser<'a>>, keys_vals: DelimitedIter<'a, PackedVarint, u32>, } impl<'a> DenseNodesParser<'a> { pub fn new(primitive_block: &'a PrimitiveBlock<'a>, data: &'a [u8]) -> Option<Self> { let iter = MessageIter::new(data); Some(DenseNodesParser { primitive_block: primitive_block, ids: DeltaEncodedIter::new( iter.clone() .tag::<ParseValue<'a>>(1) .nth(0)? ), lats: DeltaEncodedIter::new( iter.clone() .tag::<ParseValue<'a>>(8) .nth(0)? ), lons: DeltaEncodedIter::new( iter.clone() .tag::<ParseValue<'a>>(9) .nth(0)? ), infos: iter.clone() .tag::<ParseValue<'a>>(5) .nth(0) .and_then(|value| DenseInfoParser::new(&primitive_block, *value) ), keys_vals: DelimitedIter::new( iter.clone() .tag::<ParseValue<'a>>(10) .nth(0)? ), }) } } impl<'a> Iterator for DenseNodesParser<'a> { type Item = Node<'a>; fn next(&mut self) -> Option<Self::Item> { let mut keys_vals = self.keys_vals.next()?.into_iter(); let tag_hint = keys_vals.size_hint().1 .unwrap_or(keys_vals.size_hint().0); let mut tags = Vec::with_capacity(tag_hint); loop { let k = match keys_vals.next() { Some(k) => self.primitive_block.stringtable[k as usize], None => break, }; let v = match keys_vals.next() { Some(v) => self.primitive_block.stringtable[v as usize], None => break, }; tags.push((k, v)); } let info = self.infos.as_mut() .and_then(|infos| infos.next()); Some(Node { id: self.ids.next()? as u64, lat: self.primitive_block.convert_lat( self.lats.next()? ), lon: self.primitive_block.convert_lon( self.lons.next()? ), info: info, tags: tags, }) } }