1use crate::{Point, Point3D};
2use alloc::{vec, vec::Vec};
3use core::cmp::Ordering;
4use libm::round;
5use s2json::{BBOX, BBox, BBox3D};
6
7pub trait CustomOrd {
9 fn custom_cmp(&self, other: &Self) -> Ordering;
11}
12impl CustomOrd for u64 {
13 fn custom_cmp(&self, other: &Self) -> Ordering {
14 self.partial_cmp(other).unwrap_or(Ordering::Equal)
15 }
16}
17impl CustomOrd for i64 {
18 fn custom_cmp(&self, other: &Self) -> Ordering {
19 self.partial_cmp(other).unwrap_or(Ordering::Equal)
20 }
21}
22impl CustomOrd for f32 {
23 fn custom_cmp(&self, other: &Self) -> Ordering {
24 if self.is_nan() || other.is_nan() {
25 Ordering::Equal } else {
27 self.partial_cmp(other).unwrap_or(Ordering::Equal)
28 }
29 }
30}
31impl CustomOrd for f64 {
32 fn custom_cmp(&self, other: &Self) -> Ordering {
33 if self.is_nan() || other.is_nan() {
34 Ordering::Equal } else {
36 self.partial_cmp(other).unwrap_or(Ordering::Equal)
37 }
38 }
39}
40#[derive(Debug, Default, Clone, Copy)]
42pub struct CustomOrdWrapper<T>(pub T);
43impl<T: CustomOrd> CustomOrd for CustomOrdWrapper<T> {
44 fn custom_cmp(&self, other: &Self) -> Ordering {
45 self.0.custom_cmp(&other.0)
46 }
47}
48impl<T: CustomOrd> PartialOrd for CustomOrdWrapper<T> {
49 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
50 Some(self.cmp(other))
51 }
52}
53impl<T: CustomOrd> Eq for CustomOrdWrapper<T> {}
54impl<T: CustomOrd> PartialEq for CustomOrdWrapper<T> {
55 fn eq(&self, other: &Self) -> bool {
56 self.0.custom_cmp(&other.0) == Ordering::Equal
57 }
58}
59impl<T: CustomOrd> Ord for CustomOrdWrapper<T> {
60 fn cmp(&self, other: &Self) -> Ordering {
61 self.custom_cmp(other)
62 }
63}
64
65pub fn command_encode(cmd: u8, len: u32) -> u64 {
67 ((len << 3) + ((cmd as u32) & 0x7)) as u64
68}
69
70#[derive(Debug, PartialEq)]
72pub struct Command {
73 pub cmd: u8,
75 pub len: u32,
77}
78
79pub fn command_decode(cmd: u64) -> Command {
81 Command { cmd: (cmd & 0x7) as u8, len: (cmd >> 3) as u32 }
82}
83
84pub fn zigzag(n: i32) -> u32 {
86 ((n << 1) ^ (n >> 31)) as u32
87}
88
89pub fn zagzig(n: u32) -> i32 {
91 ((n >> 1) as i32) ^ -(n as i32 & 1)
92}
93
94pub fn weave_2d(a: u16, b: u16) -> u32 {
97 let mut a = a as u32;
98 let mut b = b as u32;
99 let mut result: u32 = 0;
100 for i in 0..16 {
101 result |= (a & 1) << (i * 2); result |= (b & 1) << (i * 2 + 1); a >>= 1;
105 b >>= 1;
106 }
107
108 result
109}
110
111pub fn unweave_2d(num: u32) -> (u16, u16) {
113 let mut num = num;
114 let mut a: u16 = 0;
115 let mut b: u16 = 0;
116 for i in 0..16 {
117 let bit = 1 << i;
118 if num & 1 != 0 {
119 a |= bit;
120 }
121 if num & 2 != 0 {
122 b |= bit;
123 }
124 num >>= 2;
125 }
126
127 (a, b)
128}
129
130pub fn weave_3d(a: u16, b: u16, c: u16) -> u64 {
133 let mut result: u64 = 0;
135 let mut a: u64 = a.into();
136 let mut b: u64 = b.into();
137 let mut c: u64 = c.into();
138
139 for i in 0..16 {
140 if a & 1 != 0 {
141 result |= 1 << (i * 3);
142 } if b & 1 != 0 {
144 result |= 1 << (i * 3 + 1);
145 } if c & 1 != 0 {
147 result |= 1 << (i * 3 + 2);
148 } a >>= 1;
151 b >>= 1;
152 c >>= 1;
153 }
154
155 result
156}
157
158pub fn unweave_3d(num: u64) -> (u32, u32, u32) {
161 let mut a = 0;
162 let mut b = 0;
163 let mut c = 0;
164 let mut num = num; for i in 0..16 {
167 let bit = 1 << i;
168 if (num & 1) != 0 {
169 a |= bit;
170 }
171 if (num & 2) != 0 {
172 b |= bit;
173 }
174 if (num & 4) != 0 {
175 c |= bit;
176 }
177 num >>= 3; }
179
180 (a, b, c)
181}
182
183pub fn weave_and_delta_encode_array(array: &[Point]) -> Vec<u64> {
185 let mut res = Vec::new();
186 let mut prev_x = 0;
187 let mut prev_y = 0;
188
189 for point in array.iter() {
190 let pos_x = zigzag(point.x - prev_x);
191 let pos_y = zigzag(point.y - prev_y);
192 res.push(weave_2d(pos_x as u16, pos_y as u16).into());
193 prev_x = point.x;
194 prev_y = point.y;
195 }
196
197 res
198}
199
200pub fn unweave_and_delta_decode_array(array: &[u64]) -> Vec<Point> {
202 let mut res = Vec::new();
203 let mut prev_x = 0;
204 let mut prev_y = 0;
205
206 for &encoded_num in array {
207 let (a, b) = unweave_2d(encoded_num as u32);
208 let x = zagzig(a as u32) + prev_x;
209 let y = zagzig(b as u32) + prev_y;
210 res.push(Point::new(x, y));
211 prev_x = x;
212 prev_y = y;
213 }
214
215 res
216}
217
218pub fn weave_and_delta_encode_3d_array(array: &[Point3D]) -> Vec<u64> {
220 let mut res = Vec::new();
221 let mut offset_x = 0;
222 let mut offset_y = 0;
223 let mut offset_z = 0;
224
225 for point in array.iter() {
226 let pos_x = zigzag(point.x - offset_x);
227 let pos_y = zigzag(point.y - offset_y);
228 let pos_z = zigzag(point.z - offset_z);
229 res.push(weave_3d(pos_x as u16, pos_y as u16, pos_z as u16));
230 offset_x = point.x;
231 offset_y = point.y;
232 offset_z = point.z;
233 }
234
235 res
236}
237
238pub fn unweave_and_delta_decode_3d_array(array: &[u64]) -> Vec<Point3D> {
240 let mut res = Vec::new();
241 let mut offset_x = 0;
242 let mut offset_y = 0;
243 let mut offset_z = 0;
244
245 for &encoded_num in array {
246 let (a, b, c) = unweave_3d(encoded_num);
247 let x = zagzig(a) + offset_x;
248 let y = zagzig(b) + offset_y;
249 let z = zagzig(c) + offset_z;
250 res.push(Point3D::new(x, y, z));
251 offset_x = x;
252 offset_y = y;
253 offset_z = z;
254 }
255
256 res
257}
258
259pub fn delta_encode_array(array: &[u32]) -> Vec<u32> {
261 let mut res = Vec::new();
262 let mut offset = 0;
263
264 for &num in array {
265 let num = num as i32;
266 let encoded = zigzag(num - offset);
267 res.push(encoded);
268 offset = num;
269 }
270
271 res
272}
273
274pub fn delta_decode_array(array: &[u32]) -> Vec<u32> {
276 let mut res = Vec::new();
277 let mut offset = 0;
278
279 for &encoded_num in array {
280 let num = zagzig(encoded_num) + offset;
281 res.push(num as u32);
282 offset = num;
283 }
284
285 res
286}
287
288pub fn delta_encode_sorted_array(array: &[i32]) -> Vec<u32> {
290 let mut res = Vec::new();
291 let mut offset = 0;
292
293 for &num in array {
294 let delta = (num - offset) as u32; res.push(delta);
296 offset = num;
297 }
298
299 res
300}
301
302pub fn delta_decode_sorted_array(array: &[u32]) -> Vec<i32> {
304 let mut res = Vec::new();
305 let mut offset = 0;
306
307 for &encoded_num in array {
308 let num = encoded_num as i32 + offset; res.push(num);
310 offset = num;
311 }
312
313 res
314}
315
316pub fn quantize_lon(lon: f64) -> i32 {
320 round((lon + 180.0) * 16_777_215.0 / 360.0) as i32
321}
322
323pub fn quantize_lat(lat: f64) -> i32 {
327 ((lat + 90.0) * 16_777_215.0 / 180.0) as i32
328}
329
330pub fn dequantize_lon(q_lon: i32) -> f64 {
332 (q_lon as f64 * 360.0 / 16_777_215.0) - 180.0
333}
334
335pub fn dequantize_lat(q_lat: i32) -> f64 {
337 (q_lat as f64 * 180.0 / 16_777_215.0) - 90.0
338}
339
340pub fn pack24_bit_uint(buffer: &mut [u8], value: i32, offset: usize) {
342 buffer[offset] = ((value >> 16) & 0xff) as u8;
343 buffer[offset + 1] = ((value >> 8) & 0xff) as u8;
344 buffer[offset + 2] = (value & 0xff) as u8;
345}
346
347pub fn unpack24_bit_uint(buffer: &[u8], offset: usize) -> i32 {
349 ((buffer[offset] as i32) << 16)
350 | ((buffer[offset + 1] as i32) << 8)
351 | (buffer[offset + 2] as i32)
352}
353
354pub fn pack_float(buffer: &mut [u8], value: f32, offset: usize) {
356 let bytes: [u8; 4] = value.to_le_bytes(); buffer[offset..offset + 4].copy_from_slice(&bytes);
358}
359
360pub fn unpack_float(buffer: &[u8], offset: usize) -> f32 {
362 f32::from_le_bytes(buffer[offset..offset + 4].try_into().unwrap()) }
364
365pub trait BBoxQuantization {
386 fn quantize(&self) -> Vec<u8>;
388 fn dequantize(buf: &[u8]) -> Self;
390}
391impl BBoxQuantization for BBox {
392 fn quantize(&self) -> Vec<u8> {
393 let mut buffer = vec![0u8; 12];
394
395 let q_lon1 = quantize_lon(self.left);
396 let q_lat1 = quantize_lat(self.bottom);
397 let q_lon2 = quantize_lon(self.right);
398 let q_lat2 = quantize_lat(self.top);
399
400 pack24_bit_uint(&mut buffer, q_lon1, 0);
401 pack24_bit_uint(&mut buffer, q_lat1, 3);
402 pack24_bit_uint(&mut buffer, q_lon2, 6);
403 pack24_bit_uint(&mut buffer, q_lat2, 9);
404
405 buffer
406 }
407 fn dequantize(buf: &[u8]) -> BBox {
408 let q_lon1 = unpack24_bit_uint(buf, 0);
409 let q_lat1 = unpack24_bit_uint(buf, 3);
410 let q_lon2 = unpack24_bit_uint(buf, 6);
411 let q_lat2 = unpack24_bit_uint(buf, 9);
412
413 BBox {
414 left: dequantize_lon(q_lon1),
415 bottom: dequantize_lat(q_lat1),
416 right: dequantize_lon(q_lon2),
417 top: dequantize_lat(q_lat2),
418 }
419 }
420}
421impl BBoxQuantization for BBox3D {
422 fn quantize(&self) -> Vec<u8> {
423 let mut buffer = vec![0u8; 20];
424
425 let q_lon1 = quantize_lon(self.left);
426 let q_lat1 = quantize_lat(self.bottom);
427 let q_lon2 = quantize_lon(self.right);
428 let q_lat2 = quantize_lat(self.top);
429
430 pack24_bit_uint(&mut buffer, q_lon1, 0);
431 pack24_bit_uint(&mut buffer, q_lat1, 3);
432 pack24_bit_uint(&mut buffer, q_lon2, 6);
433 pack24_bit_uint(&mut buffer, q_lat2, 9);
434
435 pack_float(&mut buffer, self.near as f32, 12);
436 pack_float(&mut buffer, self.far as f32, 16);
437
438 buffer
439 }
440 fn dequantize(buf: &[u8]) -> Self {
441 let q_lon1 = unpack24_bit_uint(buf, 0);
442 let q_lat1 = unpack24_bit_uint(buf, 3);
443 let q_lon2 = unpack24_bit_uint(buf, 6);
444 let q_lat2 = unpack24_bit_uint(buf, 9);
445
446 let near = unpack_float(buf, 12) as f64;
447 let far = unpack_float(buf, 16) as f64;
448
449 BBox3D {
450 left: dequantize_lon(q_lon1),
451 bottom: dequantize_lat(q_lat1),
452 right: dequantize_lon(q_lon2),
453 top: dequantize_lat(q_lat2),
454 near,
455 far,
456 }
457 }
458}
459
460impl BBoxQuantization for BBOX {
461 fn quantize(&self) -> Vec<u8> {
462 match self {
463 BBOX::BBox(bbox) => bbox.quantize(),
464 BBOX::BBox3D(bbox) => bbox.quantize(),
465 }
466 }
467 fn dequantize(buf: &[u8]) -> Self {
468 if buf.len() == 12 {
469 BBOX::BBox(BBox::dequantize(buf))
470 } else {
471 BBOX::BBox3D(BBox3D::dequantize(buf))
472 }
473 }
474}