osm_io/osm/pbf/
element_iterator.rs

1use std::vec::IntoIter;
2
3use crate::osm::model::element::Element;
4use crate::osm::pbf::file_block::FileBlock;
5use crate::osm::pbf::file_block_iterator::FileBlockIterator;
6
7/// Iterate over elements in *.osm.pbf file
8pub struct ElementIterator {
9    file_block_iterator: FileBlockIterator,
10    element_iterator: Option<IntoIter<Element>>,
11}
12
13impl ElementIterator {
14    pub(crate) fn new(mut file_block_iterator: FileBlockIterator) -> ElementIterator {
15        // skip the header
16        file_block_iterator.next();
17        let element_iterator = Self::create_element_iterator(&mut file_block_iterator);
18        ElementIterator {
19            file_block_iterator,
20            element_iterator,
21        }
22    }
23
24    #[allow(clippy::collapsible_match)]
25    fn create_element_iterator(file_block_iterator: &mut FileBlockIterator) -> Option<IntoIter<Element>> {
26        if let Some(current_block) = file_block_iterator.next() {
27            if let FileBlock::Data { metadata: _, mut data } = current_block {
28                Some(data.take_elements().into_iter())
29            } else {
30                None
31            }
32        } else {
33            None
34        }
35    }
36}
37
38impl Iterator for ElementIterator {
39    type Item = Element;
40
41    fn next(&mut self) -> Option<Self::Item> {
42        match &mut self.element_iterator {
43            None => {
44                None
45            }
46            Some(element_iterator) => {
47                let element = element_iterator.next();
48                match &element {
49                    None => {
50                        self.element_iterator = ElementIterator::create_element_iterator(&mut self.file_block_iterator);
51                        self.next()
52                    }
53                    Some(_) => {
54                        element
55                    }
56                }
57            }
58        }
59    }
60}