1use crate::proto;
2use crate::proto::osmformat::{HeaderBlock,PrimitiveBlock};
3use quick_protobuf::{MessageRead,Reader};
4use flate2::read::ZlibDecoder;
5use std::io::Read;
6use crate::{element,Blob};
7
8type Error = Box<dyn std::error::Error+Send+Sync+'static>;
9
10impl Blob {
11 pub fn decode_header(&self) -> Result<HeaderBlock,Error> {
12 let data = self.get_data()?;
13 let header_block = Reader::from_bytes(data)
14 .read(HeaderBlock::from_reader)?;
15 Ok(header_block)
16 }
17 pub fn decode_primitive(&self) -> Result<PrimitiveBlock,Error> {
18 let data = self.get_data()?;
19 let primitive_block = Reader::from_bytes(data)
20 .read(PrimitiveBlock::from_reader)?;
21 Ok(primitive_block)
22 }
23 pub fn get_data(&self) -> Result<Vec<u8>,Error> {
24 if let Some(data) = &self.raw {
25 Ok(data.clone())
26 } else if let Some(input) = &self.zlib_data {
27 let mut z = ZlibDecoder::new(&input[..]);
28 let mut data = vec![];
29 z.read_to_end(&mut data)?;
30 Ok(data)
31 } else {
32 panic!["unsupported compression type"];
33 }
34 }
35}
36
37impl PrimitiveBlock {
38 pub fn decode(&self) -> Vec<element::Element> {
39 let mut elements = vec![];
40 for g in self.primitivegroup.iter() {
41 for node in g.nodes.iter() {
42 elements.push(element::Element::Node(element::Node {
43 id: node.id,
44 tags: self.tags(&node.keys, &node.vals),
45 info: node.info.as_ref().map(|info| self.info(info)),
46 lon: (self.lon_offset + (self.granularity as i64 * node.lon)) as f64 * 1e-9,
47 lat: (self.lat_offset + (self.granularity as i64 * node.lat)) as f64 * 1e-9,
48 }));
49 }
50 if let Some(dense) = &g.dense {
51 let mut prev_id = 0;
52 let mut prev_lon = 0;
53 let mut prev_lat = 0;
54 let mut prev_timestamp = 0;
55 let mut prev_changeset = 0;
56 let mut prev_uid = 0;
57 let mut prev_user_sid = 0;
58 let mut tag_i = 0;
59 let mut info_i = 0;
60 let z = dense.id.iter().zip(dense.lon.iter().zip(dense.lat.iter()));
61 for (d_id,(d_lon,d_lat)) in z {
62 let id = *d_id + prev_id;
63 let lon = *d_lon + prev_lon;
64 let lat = *d_lat + prev_lat;
65
66 let mut tags = vec![];
67 while tag_i+1 < dense.keys_vals.len() && dense.keys_vals[tag_i] != 0 {
68 tags.push((
69 self.get_string(dense.keys_vals[tag_i+0] as usize),
70 self.get_string(dense.keys_vals[tag_i+1] as usize),
71 ));
72 tag_i += 2;
73 }
74 tag_i += 1;
75 let info = dense.denseinfo.as_ref().map(|info| {
76 let timestamp = info.timestamp.get(info_i).map(|x| prev_timestamp+*x);
77 let changeset = info.changeset.get(info_i).map(|x| prev_changeset+*x);
78 let uid = info.uid.get(info_i).map(|x| prev_uid+*x);
79 let user_sid = info.user_sid.get(info_i).map(|x| prev_user_sid+*x);
80 let einfo = element::Info {
81 version: info.version.get(info_i).cloned().unwrap_or(0),
82 timestamp,
83 changeset,
84 uid,
85 user: user_sid.map(|i| self.get_string(i as usize)),
86 visible: info.visible.get(info_i).cloned(),
87 };
88 info_i += 1;
89 prev_timestamp = timestamp.unwrap_or(0);
90 prev_changeset = changeset.unwrap_or(0);
91 prev_uid = uid.unwrap_or(0);
92 prev_user_sid = user_sid.unwrap_or(0);
93 einfo
94 });
95 elements.push(element::Element::Node(element::Node {
96 id: id,
97 tags,
98 info,
99 lon: (self.lon_offset + (self.granularity as i64 * lon)) as f64 * 1e-9,
100 lat: (self.lat_offset + (self.granularity as i64 * lat)) as f64 * 1e-9,
101 }));
102 prev_id = id;
103 prev_lon = lon;
104 prev_lat = lat;
105 }
106 }
107 for way in g.ways.iter() {
108 let mut refs = vec![];
109 let mut prev_ref = 0;
110 for r in way.refs.iter() {
111 refs.push(prev_ref + *r);
113 prev_ref += r;
114 }
115 elements.push(element::Element::Way(element::Way {
116 id: way.id,
117 tags: self.tags(&way.keys, &way.vals),
118 info: way.info.as_ref().map(|info| self.info(info)),
119 refs,
120 }));
121 }
122 for relation in g.relations.iter() {
123 let mut members = vec![];
124 let mut prev_mem_id = 0;
125 let z = relation.memids.iter().zip(relation.roles_sid.iter()).zip(relation.types.iter());
126 for ((mem_id,role_sid),mem_type) in z {
127 members.push(element::Member {
128 id: mem_id + prev_mem_id,
129 role: self.get_string(*role_sid as usize),
130 member_type: match mem_type {
131 proto::osmformat::mod_Relation::MemberType::NODE => element::MemberType::Node,
132 proto::osmformat::mod_Relation::MemberType::WAY => element::MemberType::Way,
133 proto::osmformat::mod_Relation::MemberType::RELATION => element::MemberType::Relation,
134 },
135 });
136 prev_mem_id = mem_id + prev_mem_id;
137 }
138 elements.push(element::Element::Relation(element::Relation {
139 id: relation.id,
140 tags: self.tags(&relation.keys, &relation.vals),
141 info: relation.info.as_ref().map(|info| self.info(info)),
142 members,
143 }));
144 }
145 }
146 elements
147 }
148 fn tags<'a>(&self, keys: &[u32], values: &[u32]) -> element::Tags {
149 keys.iter().zip(values.iter()).map(|(ki,vi)| {
150 let key = self.get_string(*ki as usize);
151 let value = self.get_string(*vi as usize);
152 (key, value)
153 }).collect()
154 }
155 fn info(&self, info: &proto::osmformat::Info) -> element::Info {
156 element::Info {
157 version: info.version,
158 timestamp: info.timestamp,
159 changeset: info.changeset,
160 uid: info.uid,
161 user: info.user_sid.map(|i| self.get_string(i as usize)),
162 visible: info.visible,
163 }
164 }
165 pub fn get_string(&self, i: usize) -> String {
166 let s = &self.stringtable.s[i];
167 String::from_utf8(s.to_vec()).unwrap()
168 }
169}