1pub mod blob;
3pub mod filter;
5pub mod header_block;
7pub mod info;
9pub mod node;
11pub mod primitive;
13pub mod relation;
15pub mod way;
17
18#[cfg(feature = "std")]
19use crate::data_store::kv::file::FileKV;
20use crate::{
21 data_store::{KV, KVStore},
22 parsers::{FeatureReader, Reader},
23};
24use alloc::{boxed::Box, vec::Vec};
25use blob::{Blob, BlobHeader};
26use core::fmt::Debug;
27use filter::*;
28use header_block::{HeaderBlock, OSMHeader};
29use node::IntermediateNode;
30use pbf::{Field, Protobuf, Type};
31use primitive::{OSMMetadata, PrimitiveBlock};
32use relation::IntermediateRelation;
33use s2json::{MValue, Properties, VectorFeature, VectorPoint};
34use way::{IntermediateWay, WayNodes};
35
36#[derive(Debug, Clone)]
40pub struct OSMReaderOptions {
41 pub remove_empty_nodes: bool,
43 pub tag_filter: Option<OSMTagFilter>,
45 pub skip_nodes: bool,
47 pub skip_ways: bool,
49 pub skip_relations: bool,
51 pub upgrade_ways_to_areas: bool,
55 pub add_bbox: bool,
57}
58impl Default for OSMReaderOptions {
59 fn default() -> Self {
60 OSMReaderOptions {
61 remove_empty_nodes: false,
62 tag_filter: None,
63 skip_nodes: false,
64 skip_ways: false,
65 skip_relations: false,
66 upgrade_ways_to_areas: false,
67 add_bbox: true,
68 }
69 }
70}
71
72#[cfg(feature = "std")]
76pub type OSMFileReader<T> = OSMReader<
77 T,
78 FileKV<u64, VectorPoint<MValue>>,
79 FileKV<u64, IntermediateNode>,
80 FileKV<u64, WayNodes>,
81 FileKV<u64, IntermediateWay>,
82 FileKV<u64, IntermediateRelation>,
83>;
84#[cfg(feature = "std")]
86pub type OSMFileReaderIter<'a, T> = OsmReaderIter<
87 'a,
88 T,
89 FileKV<u64, VectorPoint<MValue>>,
90 FileKV<u64, IntermediateNode>,
91 FileKV<u64, WayNodes>,
92 FileKV<u64, IntermediateWay>,
93 FileKV<u64, IntermediateRelation>,
94>;
95
96pub type OSMLocalReader<T> = OSMReader<
100 T,
101 KV<u64, VectorPoint<MValue>>,
102 KV<u64, IntermediateNode>,
103 KV<u64, WayNodes>,
104 KV<u64, IntermediateWay>,
105 KV<u64, IntermediateRelation>,
106>;
107pub type OSMLocalReaderIter<'a, T> = OsmReaderIter<
109 'a,
110 T,
111 KV<u64, VectorPoint<MValue>>,
112 KV<u64, IntermediateNode>,
113 KV<u64, WayNodes>,
114 KV<u64, IntermediateWay>,
115 KV<u64, IntermediateRelation>,
116>;
117
118#[derive(Debug, Clone)]
158pub struct OSMReader<
159 T: Reader,
160 _N: KVStore<u64, VectorPoint<MValue>> = KV<u64, VectorPoint<MValue>>,
161 N: KVStore<u64, IntermediateNode> = KV<u64, IntermediateNode>,
162 _W: KVStore<u64, WayNodes> = KV<u64, WayNodes>,
163 W: KVStore<u64, IntermediateWay> = KV<u64, IntermediateWay>,
164 R: KVStore<u64, IntermediateRelation> = KV<u64, IntermediateRelation>,
165> {
166 reader: T,
168 skip_empty_nodes: bool,
170 tag_filter: Option<OSMTagFilter>,
172 skip_nodes: bool,
174 skip_ways: bool,
176 skip_relations: bool,
178 upgrade_ways_to_areas: bool,
182 add_bbox: bool,
184 _offset: u64,
186 _parsed: bool,
188 node_geometry: _N,
190 nodes: N,
192 way_geometry: _W,
194 ways: W,
196 relations: R,
198}
199impl<
200 T: Reader,
201 _N: KVStore<u64, VectorPoint<MValue>>,
202 N: KVStore<u64, IntermediateNode>,
203 _W: KVStore<u64, WayNodes>,
204 W: KVStore<u64, IntermediateWay>,
205 R: KVStore<u64, IntermediateRelation>,
206> OSMReader<T, _N, N, _W, W, R>
207{
208 pub fn new(reader: T, options: Option<OSMReaderOptions>) -> Self {
210 let options = options.unwrap_or_default();
211 OSMReader {
212 reader,
213 skip_empty_nodes: options.remove_empty_nodes,
214 tag_filter: options.tag_filter,
215 skip_nodes: options.skip_nodes,
216 skip_ways: options.skip_ways,
217 skip_relations: options.skip_relations,
218 upgrade_ways_to_areas: options.upgrade_ways_to_areas,
219 add_bbox: options.add_bbox,
220 _offset: 0,
221 _parsed: false,
222 node_geometry: _N::new(None),
223 nodes: N::new(None),
224 way_geometry: _W::new(None),
225 ways: W::new(None),
226 relations: R::new(None),
227 }
228 }
229
230 pub fn cleanup(&mut self) {
232 self.node_geometry.cleanup();
233 self.nodes.cleanup();
234 self.way_geometry.cleanup();
235 self.ways.cleanup();
236 self.relations.cleanup();
237 }
238
239 pub fn get_header(&mut self) -> OSMHeader {
241 self._offset = 0;
242 let blob_header = self.next();
243 if blob_header.is_none() {
244 panic!("OSM header not found");
245 }
246 let bytes = blob_header.unwrap();
247 let mut pbf = Protobuf::from(bytes.clone());
248 let mut header_block = HeaderBlock::default();
249 let Field { tag, r#type } = pbf.read_field();
250 if tag != 1 || r#type != Type::Bytes {
251 return OSMHeader::default();
252 }
253 pbf.read_message(&mut header_block);
254
255 header_block.to_header()
256 }
257
258 fn next_blob(&mut self) -> Option<BlobHeader> {
259 if self._offset >= self.reader.len() {
261 return None;
262 }
263 let length = self.reader.int32_be(Some(self._offset)) as u64;
266 self._offset += 4;
267 let blob_header_data = self.reader.slice(Some(self._offset), Some(self._offset + length));
268 self._offset += length;
269 let mut pbf: Protobuf = blob_header_data.into();
271 let mut blob_header = BlobHeader::default();
272 pbf.read_fields(&mut blob_header, None);
273 Some(blob_header)
274 }
275
276 fn next(&mut self) -> Option<Vec<u8>> {
281 if let Some(blob_header) = self.next_blob() {
282 let compressed_blob_data =
284 self.reader.slice(Some(self._offset), Some(self._offset + blob_header.datasize));
285 self._offset += blob_header.datasize;
286 Some(compressed_blob_data)
287 } else {
288 None
289 }
290 }
291
292 fn skip(&mut self) {
294 if let Some(blob_header) = self.next_blob() {
295 self._offset += blob_header.datasize;
296 }
297 }
298
299 pub fn parse_blocks(&mut self) {
301 if self._parsed {
302 return;
303 }
304 self._offset = 0;
305 self.skip();
307 while let Some(b) = self.next() {
308 self.parse_block(OSMReader::<T, _N, N, _W, W, R>::next_block(b));
309 }
310 self._parsed = true;
311 }
312
313 pub fn next_block(data: Vec<u8>) -> PrimitiveBlock {
315 let mut pbf: Protobuf = data.into();
317 let mut blob = Blob::default();
318 pbf.read_fields(&mut blob, None);
319 let mut pbf: Protobuf = blob.data.into();
320 let mut pb = PrimitiveBlock::default();
323 pbf.read_fields(&mut pb, None);
324 pb
325 }
326
327 fn parse_block(&mut self, block: PrimitiveBlock) {
328 let skip_wr = self.skip_ways && self.skip_relations;
329 for group in &block.primitive_groups {
330 for node in &group.nodes {
331 if !node.is_filterable(&block, self) {
332 self.nodes.set(node.id, node.to_intermediate_feature(&block));
333 }
334 if !skip_wr {
335 self.node_geometry.set(node.id, node.to_vector_geometry(&block));
336 }
337 }
338 if !skip_wr {
339 for way in &group.ways {
340 if !way.is_filterable(&block, self)
341 && let Some(i_way) = way.to_intermediate_feature(&block, self)
342 {
343 self.ways.set(way.id, i_way);
344 }
345 if !self.skip_ways {
346 self.way_geometry.set(way.id, way.node_refs());
347 }
348 }
349 for relation in &group.relations {
350 if !relation.is_filterable(&block, self)
351 && let Some(i_relation) = relation.to_intermediate_feature(&block)
352 {
353 self.relations.set(relation.id, i_relation);
354 }
355 }
356 }
357 }
358 }
359
360 pub fn par_parse_node_blocks(
363 &mut self,
364 pool_size: usize,
365 thread_id: usize,
366 cb: &mut dyn FnMut(VectorFeature<OSMMetadata, Properties, MValue>),
367 ) {
368 if pool_size == 0 || thread_id > pool_size {
369 panic!("pool_size must be > 0 and thread_id must be <= pool_size");
370 }
371 self._offset = 0;
373 self.skip();
374 for _ in 0..thread_id {
375 self.skip();
376 }
377 while let Some(b) = self.next() {
379 self.parse_node_block(OSMReader::<T, _N, N, _W, W, R>::next_block(b), cb);
380 for _ in 0..pool_size {
381 self.skip();
382 }
383 }
384 }
385
386 pub fn parse_node_blocks(
389 &mut self,
390 cb: &mut dyn FnMut(VectorFeature<OSMMetadata, Properties, MValue>),
391 ) {
392 self._offset = 0;
393 self.skip();
395 while let Some(b) = self.next() {
396 self.parse_node_block(OSMReader::<T, _N, N, _W, W, R>::next_block(b), cb);
397 }
398 }
399
400 fn parse_node_block(
401 &mut self,
402 block: PrimitiveBlock,
403 cb: &mut dyn FnMut(VectorFeature<OSMMetadata, Properties, MValue>),
404 ) {
405 for group in &block.primitive_groups {
406 for node in &group.nodes {
407 if !node.is_filterable(&block, self) {
408 cb(node.to_intermediate_feature(&block).to_vector_feature(self.add_bbox));
409 }
410 }
411 }
412 }
413}
414
415pub struct OsmReaderIter<
417 'a,
418 T: Reader,
419 _N: KVStore<u64, VectorPoint<MValue>>,
420 N: KVStore<u64, IntermediateNode>,
421 _W: KVStore<u64, WayNodes>,
422 W: KVStore<u64, IntermediateWay>,
423 R: KVStore<u64, IntermediateRelation>,
424> {
425 reader: &'a OSMReader<T, _N, N, _W, W, R>,
426 node_iter: Box<dyn Iterator<Item = (&'a u64, &'a IntermediateNode)> + 'a>,
427 way_iter: Box<dyn Iterator<Item = (&'a u64, &'a IntermediateWay)> + 'a>,
428 relation_iter: Box<dyn Iterator<Item = (&'a u64, &'a IntermediateRelation)> + 'a>,
429}
430impl<
431 'a,
432 T: Reader,
433 _N: KVStore<u64, VectorPoint<MValue>>,
434 N: KVStore<u64, IntermediateNode>,
435 _W: KVStore<u64, WayNodes>,
436 W: KVStore<u64, IntermediateWay>,
437 R: KVStore<u64, IntermediateRelation>,
438> Debug for OsmReaderIter<'a, T, _N, N, _W, W, R>
439{
440 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
441 write!(f, "OsmReaderIter")
442 }
443}
444
445impl<
446 T: Reader,
447 _N: KVStore<u64, VectorPoint<MValue>>,
448 N: KVStore<u64, IntermediateNode>,
449 _W: KVStore<u64, WayNodes>,
450 W: KVStore<u64, IntermediateWay>,
451 R: KVStore<u64, IntermediateRelation>,
452> Iterator for OsmReaderIter<'_, T, _N, N, _W, W, R>
453{
454 type Item = VectorFeature<OSMMetadata, Properties, MValue>;
455
456 fn next(&mut self) -> Option<Self::Item> {
457 let node_geometry = &self.reader.node_geometry;
458 let way_geometry = &self.reader.way_geometry;
459 let add_bbox = self.reader.add_bbox;
460 if let Some((_, node)) = self.node_iter.next() {
461 Some(node.to_vector_feature(add_bbox))
462 } else if let Some((_, way)) = self.way_iter.next() {
463 Some(way.to_vector_feature(node_geometry, add_bbox))
464 } else if let Some((_, relation)) = self.relation_iter.next() {
465 relation.to_vector_feature(node_geometry, way_geometry, add_bbox)
466 } else {
467 None
468 }
469 }
470}
471impl<
472 T: Reader,
473 _N: KVStore<u64, VectorPoint<MValue>>,
474 N: KVStore<u64, IntermediateNode>,
475 _W: KVStore<u64, WayNodes>,
476 W: KVStore<u64, IntermediateWay>,
477 R: KVStore<u64, IntermediateRelation>,
478> FeatureReader<OSMMetadata, Properties, MValue> for OSMReader<T, _N, N, _W, W, R>
479{
480 type FeatureIterator<'a>
481 = OsmReaderIter<'a, T, _N, N, _W, W, R>
482 where
483 T: 'a,
484 _N: 'a,
485 N: 'a,
486 _W: 'a,
487 W: 'a,
488 R: 'a;
489
490 fn iter(&self) -> Self::FeatureIterator<'_> {
491 OsmReaderIter {
492 reader: self,
493 node_iter: Box::new(self.nodes.iter()),
494 way_iter: Box::new(self.ways.iter()),
495 relation_iter: Box::new(self.relations.iter()),
496 }
497 }
498
499 fn par_iter(&self, _pool_size: usize, _thread_id: usize) -> Self::FeatureIterator<'_> {
500 self.iter()
502 }
503}