gistools/readers/osm/
header_block.rs

1use alloc::{string::String, vec::Vec};
2use pbf::{ProtoRead, Protobuf};
3use s2json::BBox;
4
5/// OSM Header Block
6#[derive(Debug, PartialEq, Default)]
7pub struct OSMHeader {
8    /// The bounding box field in the OSM header
9    pub bbox: BBox,
10    /// The required features field in the OSM header
11    pub required_features: Vec<String>,
12    /// The optional features field in the OSM header
13    pub optional_features: Vec<String>,
14    /// The writingprogram field in the OSM header
15    pub writingprogram: Option<String>,
16    /// The source field in the OSM header
17    pub source: Option<String>,
18    /// Tags that allow continuing an Osmosis replication
19    /// Replication timestamp, expressed in seconds since the epoch,
20    /// otherwise the same value as in the "timestamp=..." field
21    /// in the state.txt file used by Osmosis.
22    pub osmosis_replication_timestamp: i64,
23    /// Replication sequence number (sequenceNumber in state.txt).
24    pub osmosis_replication_sequence_number: i64,
25    /// Replication base URL (from Osmosis' configuration.txt file).
26    pub osmosis_replication_base_url: Option<String>,
27}
28impl From<&HeaderBlock> for OSMHeader {
29    fn from(block: &HeaderBlock) -> Self {
30        OSMHeader {
31            bbox: block.bbox.to_bbox(),
32            required_features: block.required_features.clone(),
33            optional_features: block.optional_features.clone(),
34            writingprogram: block.writingprogram.clone(),
35            source: block.source.clone(),
36            osmosis_replication_timestamp: block.osmosis_replication_timestamp,
37            osmosis_replication_sequence_number: block.osmosis_replication_sequence_number,
38            osmosis_replication_base_url: block.osmosis_replication_base_url.clone(),
39        }
40    }
41}
42
43/// The OSM Header Block
44/// A block containing OSM header information that helps guide the parser
45/// of the OSM data how to interpret the data.
46#[derive(Debug, Default, PartialEq)]
47pub struct HeaderBlock {
48    bbox: HeaderBBox,
49    // Additional tags to aid in parsing this dataset
50    required_features: Vec<String>,
51    optional_features: Vec<String>,
52    writingprogram: Option<String>,
53    source: Option<String>,
54    // Tags that allow continuing an Osmosis replication
55    // Replication timestamp, expressed in seconds since the epoch,
56    // otherwise the same value as in the "timestamp=..." field
57    // in the state.txt file used by Osmosis.
58    osmosis_replication_timestamp: i64,
59    // Replication sequence number (sequenceNumber in state.txt).
60    osmosis_replication_sequence_number: i64,
61    // Replication base URL (from Osmosis' configuration.txt file).
62    osmosis_replication_base_url: Option<String>,
63}
64impl HeaderBlock {
65    /// Read the header block's contents into an object
66    pub fn to_header(&self) -> OSMHeader {
67        self.into()
68    }
69}
70/// Read in the contents of the header block
71impl ProtoRead for HeaderBlock {
72    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
73        match tag {
74            1 => pb.read_message(&mut self.bbox),
75            4 => self.required_features.push(pb.read_string()),
76            5 => self.optional_features.push(pb.read_string()),
77            16 => self.writingprogram = Some(pb.read_string()),
78            17 => self.source = Some(pb.read_string()),
79            32 => self.osmosis_replication_timestamp = pb.read_varint(),
80            33 => self.osmosis_replication_sequence_number = pb.read_varint(),
81            34 => self.osmosis_replication_base_url = Some(pb.read_string()),
82            _ => panic!("unknown tag {}", tag),
83        }
84    }
85}
86
87/// The bounding box field in the OSM header. BBOX, as used in the OSM
88/// header. Units are always in nanodegrees -- they do not obey
89/// granularity rules.
90#[derive(Debug, Default, PartialEq)]
91pub struct HeaderBBox {
92    left: i64,
93    right: i64,
94    top: i64,
95    bottom: i64,
96}
97impl HeaderBBox {
98    /// Returns the bounding box as a [left, bottom, right, top] array
99    fn to_bbox(&self) -> BBox {
100        BBox::new(
101            self.left as f64 / 1_000_000_000.0,
102            self.bottom as f64 / 1_000_000_000.0,
103            self.right as f64 / 1_000_000_000.0,
104            self.top as f64 / 1_000_000_000.0,
105        )
106    }
107}
108/// Read in the contents of the bounding box
109impl ProtoRead for HeaderBBox {
110    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
111        match tag {
112            1 => self.left = pb.read_s_varint(),
113            2 => self.right = pb.read_s_varint(),
114            3 => self.top = pb.read_s_varint(),
115            4 => self.bottom = pb.read_s_varint(),
116            _ => panic!("unknown tag {}", tag),
117        }
118    }
119}