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 { 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}