osmpbf_parser/
scan.rs

1use hashbrown::HashMap;
2use crate::{Parser,element,Element,Error};
3use unbounded_interval_tree::IntervalTree;
4use std::ops::{Bound::Included,Bound};
5use std::io::{Read,Seek};
6
7pub struct Scan<F: Read+Seek> {
8  pub parser: Parser<F>,
9  pub table: ScanTable,
10}
11
12#[derive(Debug,Clone)]
13pub struct ScanTable {
14  pub nodes: IntervalTree<i64>,
15  pub ways: IntervalTree<i64>,
16  pub relations: IntervalTree<i64>,
17  pub node_interval_offsets: HashMap<(Bound<i64>,Bound<i64>),(u64,usize,usize)>,
18  pub way_interval_offsets: HashMap<(Bound<i64>,Bound<i64>),(u64,usize,usize)>,
19  pub relation_interval_offsets: HashMap<(Bound<i64>,Bound<i64>),(u64,usize,usize)>,
20}
21impl Default for ScanTable {
22  fn default() -> Self {
23    Self {
24      nodes: IntervalTree::default(),
25      ways: IntervalTree::default(),
26      relations: IntervalTree::default(),
27      node_interval_offsets: HashMap::new(),
28      way_interval_offsets: HashMap::new(),
29      relation_interval_offsets: HashMap::new(),
30    }
31  }
32}
33
34impl ScanTable {
35  pub fn extend(&mut self, other: &ScanTable) {
36    for range in other.nodes.iter() {
37      self.nodes.insert(range.clone());
38    }
39    for range in other.ways.iter() {
40      self.ways.insert(range.clone());
41    }
42    for range in other.relations.iter() {
43      self.relations.insert(range.clone());
44    }
45    self.node_interval_offsets.extend(other.node_interval_offsets.iter());
46    self.way_interval_offsets.extend(other.way_interval_offsets.iter());
47    self.relation_interval_offsets.extend(other.relation_interval_offsets.iter());
48  }
49  pub fn get_node_blob_offsets(&self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
50    self.node_interval_offsets.values().cloned()
51  }
52  pub fn get_node_blob_offsets_for_id(&self, id: i64) -> Vec<(u64,usize,usize)> {
53    let q = (Included(id),Included(id));
54    self.nodes.get_interval_overlaps(&q).iter()
55      .map(|iv| self.node_interval_offsets.get(iv))
56      .filter(|o_pair| o_pair.is_some())
57      .map(|o_pair| o_pair.unwrap())
58      .cloned()
59      .collect()
60  }
61  pub fn get_way_blob_offsets(&self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
62    self.way_interval_offsets.values().cloned()
63  }
64  pub fn get_way_blob_offsets_for_id(&self, id: i64) -> Vec<(u64,usize,usize)> {
65    let q = (Included(id),Included(id));
66    self.ways.get_interval_overlaps(&q).iter()
67      .map(|iv| self.way_interval_offsets.get(iv))
68      .filter(|o_pair| o_pair.is_some())
69      .map(|o_pair| o_pair.unwrap())
70      .cloned()
71      .collect()
72  }
73  pub fn get_relation_blob_offsets(&self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
74    self.relation_interval_offsets.values().cloned()
75  }
76  pub fn get_relation_blob_offsets_for_id(&self, id: i64) -> Vec<(u64,usize,usize)> {
77    let q = (Included(id),Included(id));
78    self.relations.get_interval_overlaps(&q).iter()
79      .map(|iv| self.relation_interval_offsets.get(iv))
80      .filter(|o_pair| o_pair.is_some())
81      .map(|o_pair| o_pair.unwrap())
82      .cloned()
83      .collect()
84  }
85}
86
87impl<F> Scan<F> where F: Read+Seek {
88  pub fn new(parser: Parser<F>) -> Self {
89    Self {
90      parser,
91      table: ScanTable::default(),
92    }
93  }
94  pub fn from_table(parser: Parser<F>, table: ScanTable) -> Self {
95    Self { parser, table }
96  }
97  pub fn scan(&mut self, start: u64, end: u64) -> Result<(),Error> {
98    let mut offset = start;
99    while offset < end {
100      let (blob_header_len,blob_header) = self.parser.read_blob_header(offset)?;
101      let blob_offset = offset + blob_header_len;
102      let blob_len = blob_header.datasize as usize;
103      let blob = self.parser.read_blob(blob_offset, blob_len)?;
104      let len = blob_header_len + blob_len as u64;
105      if offset == 0 { // skip header
106        offset += len;
107        continue;
108      }
109      let items = blob.decode_primitive()?.decode();
110
111      let mut etype = element::MemberType::Node;
112      let mut min_id = i64::MAX;
113      let mut max_id = i64::MIN;
114      for item in items.iter() {
115        match item {
116          Element::Node(node) => {
117            min_id = node.id.min(min_id);
118            max_id = node.id.max(max_id);
119          },
120          Element::Way(way) => {
121            etype = element::MemberType::Way;
122            min_id = way.id.min(min_id);
123            max_id = way.id.max(max_id);
124          },
125          Element::Relation(relation) => {
126            etype = element::MemberType::Relation;
127            min_id = relation.id.min(min_id);
128            max_id = relation.id.max(max_id);
129          },
130        }
131      }
132      if !items.is_empty() {
133        let iv = (Included(min_id),Included(max_id));
134        match etype {
135          element::MemberType::Node => {
136            self.table.node_interval_offsets.insert(
137              iv.clone(),
138              (blob_offset,blob_len,items.len())
139            );
140            self.table.nodes.insert(iv);
141          },
142          element::MemberType::Way => {
143            self.table.way_interval_offsets.insert(
144              iv.clone(),
145              (blob_offset,blob_len,items.len())
146            );
147            self.table.ways.insert(iv);
148          },
149          element::MemberType::Relation => {
150            self.table.relation_interval_offsets.insert(
151              iv.clone(),
152              (blob_offset,blob_len,items.len())
153            );
154            self.table.relations.insert(iv);
155          },
156        }
157      }
158      offset += len;
159    }
160    Ok(())
161  }
162  pub fn get_node_blob_offsets(&self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
163    self.table.get_node_blob_offsets()
164  }
165  pub fn get_node_blob_offsets_for_id(&mut self, id: i64) -> Vec<(u64,usize,usize)> {
166    self.table.get_node_blob_offsets_for_id(id)
167  }
168  pub fn get_node(&mut self, id: i64) -> Result<Option<element::Node>,Error> {
169    for (offset,byte_len,_len) in self.get_node_blob_offsets_for_id(id) {
170      let blob = self.parser.read_blob(offset,byte_len)?;
171      let items = blob.decode_primitive()?.decode();
172      for item in items {
173        match item {
174          Element::Node(node) => {
175            if node.id == id { return Ok(Some(node)) }
176          },
177          _ => { break }
178        }
179      }
180    }
181    Ok(None)
182  }
183  pub fn get_way_blob_offsets(&mut self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
184    self.table.get_way_blob_offsets()
185  }
186  pub fn get_way_blob_offsets_for_id(&mut self, id: i64) -> Vec<(u64,usize,usize)> {
187    self.table.get_way_blob_offsets_for_id(id)
188  }
189  pub fn get_way(&mut self, id: i64) -> Result<Option<element::Way>,Error> {
190    for (offset,byte_len,_len) in self.get_way_blob_offsets_for_id(id) {
191      let blob = self.parser.read_blob(offset,byte_len)?;
192      let items = blob.decode_primitive()?.decode();
193      for item in items {
194        match item {
195          Element::Way(way) => {
196            if way.id == id { return Ok(Some(way)) }
197          },
198          _ => { break }
199        }
200      }
201    }
202    Ok(None)
203  }
204  pub fn get_relation_blob_offsets(&mut self) -> impl Iterator<Item=(u64,usize,usize)>+'_ {
205    self.table.get_relation_blob_offsets()
206  }
207  pub fn get_relation_blob_offsets_for_id(&mut self, id: i64) -> Vec<(u64,usize,usize)> {
208    self.table.get_relation_blob_offsets_for_id(id)
209  }
210  pub fn get_relation(&mut self, id: i64) -> Result<Option<element::Relation>,Error> {
211    for (offset,byte_len,_len) in self.get_relation_blob_offsets_for_id(id) {
212      let blob = self.parser.read_blob(offset,byte_len)?;
213      let items = blob.decode_primitive()?.decode();
214      for item in items {
215        match item {
216          Element::Relation(relation) => {
217            if relation.id == id { return Ok(Some(relation)) }
218          },
219          _ => { break }
220        }
221      }
222    }
223    Ok(None)
224  }
225}