gistools/readers/osm/
info.rs

1use super::primitive::PrimitiveBlock;
2use alloc::{
3    string::{String, ToString},
4    vec,
5    vec::Vec,
6};
7use pbf::{ProtoRead, Protobuf};
8use serde::{Deserialize, Serialize};
9
10/// Info Block - decoded into an object
11#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
12pub struct InfoBlock {
13    /// The version of the object. Default is -1
14    pub version: i32,
15    /// (millisec_stamp = time_stamp*dateGranularity.)
16    pub time_stamp: Option<i64>,
17    /// The changeset id
18    pub changeset: Option<i64>,
19    /// The uid
20    pub uid: Option<i32>,
21    /// String IDs for usernames. Pull string from local Primitive Block
22    pub user_sid: Option<String>,
23    /// The visible flag is used to store history information. It indicates that
24    /// the current object version has been created by a delete operation on the
25    /// OSM API.
26    /// When a writer sets this flag, it MUST add a required_features tag with
27    /// value "HistoricalInformation" to the HeaderBlock.
28    /// If this flag is not available for some object it MUST be assumed to be
29    /// true if the file has the required_features tag "HistoricalInformation"
30    /// set.
31    pub visible: bool, // default true
32}
33
34/// Optional metadata that may be included into each primitive.
35#[derive(Debug, Clone, PartialEq)]
36pub struct Info {
37    /// The version of the object. Default is -1
38    pub version: i32,
39    /// (millisec_stamp = time_stamp*dateGranularity.)
40    pub time_stamp: Option<i64>,
41    /// The changeset id
42    pub changeset: Option<i64>,
43    /// The uid
44    pub uid: Option<i32>,
45    /// String IDs for usernames. Pull string from local Primitive Block
46    pub user_sid: Option<u32>,
47    /// The visible flag is used to store history information. It indicates that
48    /// the current object version has been created by a delete operation on the
49    /// OSM API.
50    /// When a writer sets this flag, it MUST add a required_features tag with
51    /// value "HistoricalInformation" to the HeaderBlock.
52    /// If this flag is not available for some object it MUST be assumed to be
53    /// true if the file has the required_features tag "HistoricalInformation"
54    /// set.
55    pub visible: bool, // default true
56}
57impl Default for Info {
58    fn default() -> Self {
59        Self {
60            version: -1,
61            time_stamp: None,
62            changeset: None,
63            uid: None,
64            user_sid: None,
65            visible: true,
66        }
67    }
68}
69impl Info {
70    /// Converts the Info object to an InfoBlock with the injected correct time stamp and user name
71    pub fn to_block(&self, pb: &PrimitiveBlock) -> InfoBlock {
72        InfoBlock {
73            version: self.version,
74            time_stamp: self.time_stamp.map(|ts| ts * pb.date_granularity as i64),
75            changeset: self.changeset,
76            uid: self.uid,
77            user_sid: self.user_sid.map(|sid| pb.get_string(sid as usize).to_string()),
78            visible: self.visible,
79        }
80    }
81}
82/// Read in the contents of the Info block
83impl ProtoRead for Info {
84    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
85        match tag {
86            1 => self.version = pb.read_s_varint(),
87            2 => self.time_stamp = Some(pb.read_s_varint()),
88            3 => self.changeset = Some(pb.read_s_varint()),
89            4 => self.uid = Some(pb.read_s_varint()),
90            5 => self.user_sid = Some(pb.read_varint()),
91            6 => self.visible = pb.read_varint(),
92            _ => panic!("unknown tag {}", tag),
93        }
94    }
95}
96
97/// DenseInfo
98#[derive(Debug, Default, Clone, PartialEq)]
99pub struct DenseInfo {
100    version: Vec<i32>,
101    time_stamp: Vec<i64>, // DELTA coded (millisec_stamp = time_stamp*dateGranularity.)
102    changeset: Vec<i64>,
103    uid: Vec<i32>,      // DELTA coded
104    user_sid: Vec<u32>, // String IDs for usernames. DELTA coded
105    // The visible flag is used to store history information. It indicates that
106    // the current object version has been created by a delete operation on the
107    // OSM API.
108    // When a writer sets this flag, it MUST add a required_features tag with
109    // value "HistoricalInformation" to the HeaderBlock.
110    // If this flag is not available for some object it MUST be assumed to be
111    // true if the file has the required_features tag "HistoricalInformation"
112    // set.
113    visible: Vec<bool>,
114}
115/// Read in the contents of the Dense Info block
116impl ProtoRead for DenseInfo {
117    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
118        match tag {
119            1 => self.version = pb.read_s_packed(),
120            2 => self.time_stamp = pb.read_s_packed(),
121            3 => self.changeset = pb.read_s_packed(),
122            4 => self.uid = pb.read_s_packed(),
123            5 => self.user_sid = pb.read_packed(),
124            6 => self.visible = pb.read_packed(),
125            _ => panic!("unknown tag {}", tag),
126        }
127    }
128}
129impl DenseInfo {
130    /// Get the info objects
131    pub fn infos(&self) -> Vec<Info> {
132        let mut res: Vec<Info> = vec![];
133        let mut cur_time_stamp = 0;
134        let mut cur_uid = 0;
135        for i in 0..self.version.len() {
136            cur_time_stamp += self.time_stamp[i];
137            cur_uid += self.uid[i];
138            res.push(Info {
139                version: self.version[i],
140                time_stamp: Some(cur_time_stamp),
141                changeset: Some(self.changeset[i]),
142                uid: Some(cur_uid),
143                user_sid: self.user_sid.get(i).copied(),
144                visible: self.visible.get(i).copied().unwrap_or(true),
145            });
146        }
147        res
148    }
149}