mlt_core/frames/v01/geometry/
decode.rs1use crate::enc_dec::Decode;
2use crate::utils::{AsUsize as _, SetOptionOnce as _};
3use crate::v01::{
4 DictionaryType, GeometryType, GeometryValues, LengthType, OffsetType, RawGeometry, RawStream,
5 StreamType,
6};
7use crate::{Decoder, MltError, MltResult};
8
9pub fn decode_geometry_types(
10 meta: RawStream<'_>,
11 dec: &mut Decoder,
12) -> Result<Vec<GeometryType>, MltError> {
13 let vector_types: Vec<u32> = meta.decode_u32s(dec)?;
15 let vector_types: Vec<GeometryType> = vector_types
16 .into_iter()
17 .map::<MltResult<GeometryType>, _>(|v| Ok(u8::try_from(v)?.try_into()?))
18 .collect::<Result<_, _>>()?;
19 Ok(vector_types)
20}
21
22pub fn decode_root_length_stream(
25 geometry_types: &[GeometryType],
26 root_length_stream: &[u32],
27 buffer_id: GeometryType,
28 dec: &mut Decoder,
29) -> Result<Vec<u32>, MltError> {
30 let alloc_size = geometry_types.len() + 1;
31 let mut root_buffer_offsets = dec.alloc(alloc_size)?;
32
33 root_buffer_offsets.push(0);
34 let mut previous_offset = 0_u32;
35 let mut root_length_counter = 0_usize;
36 for &geom_type in geometry_types {
37 let offset = previous_offset
38 + if geom_type > buffer_id {
39 let val = root_length_stream[root_length_counter];
40 root_length_counter += 1;
41 val
42 } else {
43 1
44 };
45 root_buffer_offsets.push(offset);
46 previous_offset = offset;
47 }
48
49 dec.adjust_alloc(&root_buffer_offsets, alloc_size);
50 Ok(root_buffer_offsets)
51}
52
53pub fn decode_level1_without_ring_buffer_length_stream(
55 geometry_types: &[GeometryType],
56 root_offset_buffer: &[u32],
57 level1_length_buffer: &[u32],
58 dec: &mut Decoder,
59) -> Result<Vec<u32>, MltError> {
60 let alloc_size = root_offset_buffer[root_offset_buffer.len() - 1].as_usize() + 1;
61 let mut level1_buffer_offsets = dec.alloc(alloc_size)?;
62 level1_buffer_offsets.push(0);
63 let mut previous_offset = 0_u32;
64 let mut level1_length_counter = 0_usize;
65
66 for (i, &geometry_type) in geometry_types.iter().enumerate() {
67 let num_geometries = (root_offset_buffer[i + 1] - root_offset_buffer[i]).as_usize();
68
69 if geometry_type.is_linestring() {
70 for _j in 0..num_geometries {
72 previous_offset += level1_length_buffer[level1_length_counter];
73 level1_length_counter += 1;
74 level1_buffer_offsets.push(previous_offset);
75 }
76 } else {
77 for _j in 0..num_geometries {
79 previous_offset += 1;
80 level1_buffer_offsets.push(previous_offset);
81 }
82 }
83 }
84
85 dec.adjust_alloc(&level1_buffer_offsets, alloc_size);
86 Ok(level1_buffer_offsets)
87}
88
89pub fn decode_level1_length_stream(
90 geometry_types: &[GeometryType],
91 root_offset_buffer: &[u32],
92 level1_length_buffer: &[u32],
93 is_line_string_present: bool,
94 dec: &mut Decoder,
95) -> Result<Vec<u32>, MltError> {
96 let alloc_size = root_offset_buffer[root_offset_buffer.len() - 1].as_usize() + 1;
97 let mut level1_buffer_offsets = dec.alloc(alloc_size)?;
98 level1_buffer_offsets.push(0);
99 let mut previous_offset = 0_u32;
100 let mut level1_length_buffer_counter = 0_usize;
101
102 for (i, &geometry_type) in geometry_types.iter().enumerate() {
103 let num_geometries = (root_offset_buffer[i + 1] - root_offset_buffer[i]).as_usize();
104
105 if geometry_type.is_polygon() || (is_line_string_present && geometry_type.is_linestring()) {
106 for _j in 0..num_geometries {
109 previous_offset += level1_length_buffer[level1_length_buffer_counter];
110 level1_length_buffer_counter += 1;
111 level1_buffer_offsets.push(previous_offset);
112 }
113 } else {
114 for _j in 0..num_geometries {
117 previous_offset += 1;
118 level1_buffer_offsets.push(previous_offset);
119 }
120 }
121 }
122
123 dec.adjust_alloc(&level1_buffer_offsets, alloc_size);
124 Ok(level1_buffer_offsets)
125}
126
127pub fn decode_level2_length_stream(
128 geometry_types: &[GeometryType],
129 root_offset_buffer: &[u32],
130 level1_offset_buffer: &[u32],
131 level2_length_buffer: &[u32],
132 dec: &mut Decoder,
133) -> Result<Vec<u32>, MltError> {
134 let alloc_size = level1_offset_buffer[level1_offset_buffer.len() - 1].as_usize() + 1;
135 let mut level2_buffer_offsets = dec.alloc(alloc_size)?;
136 level2_buffer_offsets.push(0);
137 let mut previous_offset = 0_u32;
138 let mut level1_offset_buffer_counter = 1_usize;
139 let mut level2_length_buffer_counter = 0_usize;
140
141 for (i, &geometry_type) in geometry_types.iter().enumerate() {
142 let num_geometries = (root_offset_buffer[i + 1] - root_offset_buffer[i]).as_usize();
143
144 if geometry_type != GeometryType::Point && geometry_type != GeometryType::MultiPoint {
145 for _j in 0..num_geometries {
148 let num_parts = (level1_offset_buffer[level1_offset_buffer_counter]
149 - level1_offset_buffer[level1_offset_buffer_counter - 1])
150 .as_usize();
151 level1_offset_buffer_counter += 1;
152 for _k in 0..num_parts {
153 previous_offset += level2_length_buffer[level2_length_buffer_counter];
154 level2_length_buffer_counter += 1;
155 level2_buffer_offsets.push(previous_offset);
156 }
157 }
158 } else {
159 for _j in 0..num_geometries {
161 previous_offset += 1;
162 level2_buffer_offsets.push(previous_offset);
163 level1_offset_buffer_counter += 1;
164 }
165 }
166 }
167
168 dec.adjust_alloc(&level2_buffer_offsets, alloc_size);
169 Ok(level2_buffer_offsets)
170}
171
172impl Decode<GeometryValues> for RawGeometry<'_> {
173 fn decode(self, decoder: &mut Decoder) -> MltResult<GeometryValues> {
174 RawGeometry::decode(self, decoder)
175 }
176}
177
178impl RawGeometry<'_> {
179 pub fn decode(self, dec: &mut Decoder) -> MltResult<GeometryValues> {
183 let RawGeometry { meta, items } = self;
184 let vector_types = decode_geometry_types(meta, dec)?;
185 let mut geometry_offsets: Option<Vec<u32>> = None;
186 let mut part_offsets: Option<Vec<u32>> = None;
187 let mut ring_offsets: Option<Vec<u32>> = None;
188 let mut vertex_offsets: Option<Vec<u32>> = None;
189 let mut index_buffer: Option<Vec<u32>> = None;
190 let mut triangles: Option<Vec<u32>> = None;
191 let mut vertices: Option<Vec<i32>> = None;
192
193 for stream in items {
194 match stream.meta.stream_type {
195 StreamType::Present => {}
196 StreamType::Data(v) => match v {
197 DictionaryType::Vertex | DictionaryType::Morton => {
198 vertices.set_once(stream.decode_i32s(dec)?)?;
199 }
200 _ => Err(MltError::UnexpectedStreamType(stream.meta.stream_type))?,
201 },
202 StreamType::Offset(v) => {
203 let target = match v {
204 OffsetType::Vertex => &mut vertex_offsets,
205 OffsetType::Index => &mut index_buffer,
206 _ => Err(MltError::UnexpectedStreamType(stream.meta.stream_type))?,
207 };
208 target.set_once(stream.decode_u32s(dec)?)?;
209 }
210 StreamType::Length(v) => {
211 let target = match v {
212 LengthType::Geometries => &mut geometry_offsets,
213 LengthType::Parts => &mut part_offsets,
214 LengthType::Rings => &mut ring_offsets,
215 LengthType::Triangles => &mut triangles,
216 _ => Err(MltError::UnexpectedStreamType(stream.meta.stream_type))?,
217 };
218 target.set_once(stream.decode_u32s(dec)?)?;
219 }
220 }
221 }
222
223 if index_buffer.is_some() && part_offsets.is_none() {
224 return Err(MltError::NotImplemented(
229 "index_buffer.is_some() && part_offsets.is_none() case",
230 ));
231 }
232
233 if let Some(offsets) = geometry_offsets.take() {
235 geometry_offsets = Some(decode_root_length_stream(
236 &vector_types,
237 &offsets,
238 GeometryType::Polygon,
239 dec,
240 )?);
241 if let Some(part_offsets_copy) = part_offsets.take() {
242 if let Some(ring_offsets_copy) = ring_offsets.take() {
243 part_offsets = Some(decode_level1_length_stream(
244 &vector_types,
245 geometry_offsets.as_ref().unwrap(),
246 &part_offsets_copy,
247 false, dec,
249 )?);
250 ring_offsets = Some(decode_level2_length_stream(
251 &vector_types,
252 geometry_offsets.as_ref().unwrap(),
253 part_offsets.as_ref().unwrap(),
254 &ring_offsets_copy,
255 dec,
256 )?);
257 } else {
258 part_offsets = Some(decode_level1_without_ring_buffer_length_stream(
259 &vector_types,
260 geometry_offsets.as_ref().unwrap(),
261 &part_offsets_copy,
262 dec,
263 )?);
264 }
265 }
266 } else if let Some(offsets) = part_offsets.take() {
267 if let Some(ring_offsets_copy) = ring_offsets.take() {
268 let is_line_string_present = vector_types.iter().any(|t| t.is_linestring());
269 part_offsets = Some(decode_root_length_stream(
270 &vector_types,
271 &offsets,
272 GeometryType::LineString,
273 dec,
274 )?);
275 ring_offsets = Some(decode_level1_length_stream(
276 &vector_types,
277 part_offsets.as_ref().unwrap(),
278 &ring_offsets_copy,
279 is_line_string_present,
280 dec,
281 )?);
282 } else {
283 part_offsets = Some(decode_root_length_stream(
284 &vector_types,
285 &offsets,
286 GeometryType::Point,
287 dec,
288 )?);
289 }
290 }
291
292 if let Some(offsets) = vertex_offsets.take()
303 && let Some(dict) = vertices.as_deref()
304 {
305 dec.consume_items::<[i32; 2]>(offsets.len())?;
306 vertices = Some(
307 offsets
308 .iter()
309 .flat_map(|&i| {
310 let i = i.as_usize();
311 [dict[i * 2], dict[i * 2 + 1]]
312 })
313 .collect(),
314 );
315 }
316
317 Ok(GeometryValues {
318 vector_types,
319 geometry_offsets,
320 part_offsets,
321 ring_offsets,
322 index_buffer,
323 triangles,
324 vertices,
325 })
326 }
327}