gistools/readers/las/laz/
mod.rs

1/// Arithmetic Decoder tools
2pub mod arithmetic_decoder;
3/// LAZ Constants
4mod constants;
5/// Integer Compressor
6pub mod integer_compressor;
7/// LAZ Reader
8mod reader;
9/// LAZ Version 1 Reader
10pub mod v1;
11/// LAZ Version 2 Reader
12pub mod v2;
13/// LAZ Version 3 Reader
14pub mod v3;
15
16use super::{
17    LASPoint,
18    util::{i8_clamp, i16_quantize},
19};
20use crate::parsers::{BufferReader, Reader};
21use alloc::boxed::Box;
22pub use reader::*;
23
24/// LAZ Item Reader
25#[derive(Debug, Clone)]
26pub enum ItemReaders<T: Reader> {
27    /// LAZ Version 10.1 Point10
28    V1Point10(Box<v1::LAZPoint10v1Reader<T>>),
29    /// LAZ Version 10.2 Point10
30    V2Point10(Box<v2::LAZPoint10v2Reader<T>>),
31    /// LAZ Version 11.1 GpsTime
32    V1GpsTime11(Box<v1::LAZGpsTime11v1Reader<T>>),
33    /// LAZ Version 11.2 GpsTime
34    V2GpsTime11(Box<v2::LAZGpsTime11v2Reader<T>>),
35    /// LAZ Version 12.1 Rgb
36    V1Rgb12(Box<v1::LAZrgb12v1Reader<T>>),
37    /// LAZ Version 12.2 Rgb
38    V2Rgb12(Box<v2::LAZrgb12v2Reader<T>>),
39    /// LAZ Version 13.1 Wavepacket
40    V1Wavepacket13(Box<v1::LAZwavepacket13v1Reader<T>>),
41    /// LAZ Version 10.1 Byte
42    V1Byte10(Box<v1::LAZbyte10v1Reader<T>>),
43    /// LAZ Version 10.2 Byte
44    V2Byte10(Box<v2::LAZbyte10v2Reader<T>>),
45    /// LAZ Version 14.3 Point
46    V3Point14(Box<v3::LAZPoint14v3Reader<T>>),
47    /// LAZ Version 14.3 Rgb
48    V3Rgb14(Box<v3::LAZrgb14v3Reader<T>>),
49    /// LAZ Version 14.3 Rgb Nir
50    V3RgbNir14(Box<v3::LAZrgbNir14v3Reader<T>>),
51    /// LAZ Version 14.3 Wavepacket
52    V3Wavepacket14(Box<v3::LAZwavepacket14v3Reader<T>>),
53    /// LAZ Version 14.3 Byte
54    V3Byte14(Box<v3::LAZbyte14v3Reader<T>>),
55}
56impl<T: Reader> ItemReader for ItemReaders<T> {
57    fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, context: &mut u32) {
58        match self {
59            ItemReaders::V1Point10(v1) => v1.init(item, point, context),
60            ItemReaders::V2Point10(v2) => v2.init(item, point, context),
61            ItemReaders::V1GpsTime11(v1) => v1.init(item, point, context),
62            ItemReaders::V2GpsTime11(v2) => v2.init(item, point, context),
63            ItemReaders::V1Rgb12(v1) => v1.init(item, point, context),
64            ItemReaders::V2Rgb12(v2) => v2.init(item, point, context),
65            ItemReaders::V1Wavepacket13(v1) => v1.init(item, point, context),
66            ItemReaders::V1Byte10(v1) => v1.init(item, point, context),
67            ItemReaders::V2Byte10(v2) => v2.init(item, point, context),
68            ItemReaders::V3Point14(v3) => v3.init(item, point, context),
69            ItemReaders::V3Rgb14(v3) => v3.init(item, point, context),
70            ItemReaders::V3RgbNir14(v3) => v3.init(item, point, context),
71            ItemReaders::V3Wavepacket14(v3) => v3.init(item, point, context),
72            ItemReaders::V3Byte14(v3) => v3.init(item, point, context),
73        }
74    }
75    fn read(&mut self, item: &mut LASPoint, context: &mut u32) {
76        match self {
77            ItemReaders::V1Point10(v1) => v1.read(item, context),
78            ItemReaders::V2Point10(v2) => v2.read(item, context),
79            ItemReaders::V1GpsTime11(v1) => v1.read(item, context),
80            ItemReaders::V2GpsTime11(v2) => v2.read(item, context),
81            ItemReaders::V1Rgb12(v1) => v1.read(item, context),
82            ItemReaders::V2Rgb12(v2) => v2.read(item, context),
83            ItemReaders::V1Wavepacket13(v1) => v1.read(item, context),
84            ItemReaders::V1Byte10(v1) => v1.read(item, context),
85            ItemReaders::V2Byte10(v2) => v2.read(item, context),
86            ItemReaders::V3Point14(v3) => v3.read(item, context),
87            ItemReaders::V3Rgb14(v3) => v3.read(item, context),
88            ItemReaders::V3RgbNir14(v3) => v3.read(item, context),
89            ItemReaders::V3Wavepacket14(v3) => v3.read(item, context),
90            ItemReaders::V3Byte14(v3) => v3.read(item, context),
91        }
92    }
93    fn chunk_sizes<R: Reader>(&mut self, reader: &R) {
94        match self {
95            ItemReaders::V1Point10(v1) => v1.chunk_sizes(reader),
96            ItemReaders::V2Point10(v2) => v2.chunk_sizes(reader),
97            ItemReaders::V1GpsTime11(v1) => v1.chunk_sizes(reader),
98            ItemReaders::V2GpsTime11(v2) => v2.chunk_sizes(reader),
99            ItemReaders::V1Rgb12(v1) => v1.chunk_sizes(reader),
100            ItemReaders::V2Rgb12(v2) => v2.chunk_sizes(reader),
101            ItemReaders::V1Wavepacket13(v1) => v1.chunk_sizes(reader),
102            ItemReaders::V1Byte10(v1) => v1.chunk_sizes(reader),
103            ItemReaders::V2Byte10(v2) => v2.chunk_sizes(reader),
104            ItemReaders::V3Point14(v3) => v3.chunk_sizes(reader),
105            ItemReaders::V3Rgb14(v3) => v3.chunk_sizes(reader),
106            ItemReaders::V3RgbNir14(v3) => v3.chunk_sizes(reader),
107            ItemReaders::V3Wavepacket14(v3) => v3.chunk_sizes(reader),
108            ItemReaders::V3Byte14(v3) => v3.chunk_sizes(reader),
109        }
110    }
111}
112impl<T: Reader> From<v1::LAZPoint10v1Reader<T>> for ItemReaders<T> {
113    fn from(reader: v1::LAZPoint10v1Reader<T>) -> Self {
114        ItemReaders::V1Point10(reader.into())
115    }
116}
117impl<T: Reader> From<v2::LAZPoint10v2Reader<T>> for ItemReaders<T> {
118    fn from(reader: v2::LAZPoint10v2Reader<T>) -> Self {
119        ItemReaders::V2Point10(reader.into())
120    }
121}
122impl<T: Reader> From<v1::LAZGpsTime11v1Reader<T>> for ItemReaders<T> {
123    fn from(reader: v1::LAZGpsTime11v1Reader<T>) -> Self {
124        ItemReaders::V1GpsTime11(reader.into())
125    }
126}
127impl<T: Reader> From<v2::LAZGpsTime11v2Reader<T>> for ItemReaders<T> {
128    fn from(reader: v2::LAZGpsTime11v2Reader<T>) -> Self {
129        ItemReaders::V2GpsTime11(reader.into())
130    }
131}
132impl<T: Reader> From<v1::LAZrgb12v1Reader<T>> for ItemReaders<T> {
133    fn from(reader: v1::LAZrgb12v1Reader<T>) -> Self {
134        ItemReaders::V1Rgb12(reader.into())
135    }
136}
137impl<T: Reader> From<v2::LAZrgb12v2Reader<T>> for ItemReaders<T> {
138    fn from(reader: v2::LAZrgb12v2Reader<T>) -> Self {
139        ItemReaders::V2Rgb12(reader.into())
140    }
141}
142impl<T: Reader> From<v1::LAZwavepacket13v1Reader<T>> for ItemReaders<T> {
143    fn from(reader: v1::LAZwavepacket13v1Reader<T>) -> Self {
144        ItemReaders::V1Wavepacket13(reader.into())
145    }
146}
147impl<T: Reader> From<v1::LAZbyte10v1Reader<T>> for ItemReaders<T> {
148    fn from(reader: v1::LAZbyte10v1Reader<T>) -> Self {
149        ItemReaders::V1Byte10(reader.into())
150    }
151}
152impl<T: Reader> From<v2::LAZbyte10v2Reader<T>> for ItemReaders<T> {
153    fn from(reader: v2::LAZbyte10v2Reader<T>) -> Self {
154        ItemReaders::V2Byte10(reader.into())
155    }
156}
157impl<T: Reader> From<v3::LAZPoint14v3Reader<T>> for ItemReaders<T> {
158    fn from(reader: v3::LAZPoint14v3Reader<T>) -> Self {
159        ItemReaders::V3Point14(reader.into())
160    }
161}
162impl<T: Reader> From<v3::LAZrgb14v3Reader<T>> for ItemReaders<T> {
163    fn from(reader: v3::LAZrgb14v3Reader<T>) -> Self {
164        ItemReaders::V3Rgb14(reader.into())
165    }
166}
167impl<T: Reader> From<v3::LAZrgbNir14v3Reader<T>> for ItemReaders<T> {
168    fn from(reader: v3::LAZrgbNir14v3Reader<T>) -> Self {
169        ItemReaders::V3RgbNir14(reader.into())
170    }
171}
172impl<T: Reader> From<v3::LAZwavepacket14v3Reader<T>> for ItemReaders<T> {
173    fn from(reader: v3::LAZwavepacket14v3Reader<T>) -> Self {
174        ItemReaders::V3Wavepacket14(reader.into())
175    }
176}
177impl<T: Reader> From<v3::LAZbyte14v3Reader<T>> for ItemReaders<T> {
178    fn from(reader: v3::LAZbyte14v3Reader<T>) -> Self {
179        ItemReaders::V3Byte14(reader.into())
180    }
181}
182
183/// Template for reading data
184pub trait ItemReader {
185    /// Initialize the reader
186    fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, context: &mut u32);
187    /// Read the next item
188    fn read(&mut self, item: &mut LASPoint, context: &mut u32);
189    /// Read in chunk sizes
190    fn chunk_sizes<R: Reader>(&mut self, reader: &R);
191}
192
193/// Compression leaves the raw input for point14 a bit messy. This fixes the problem
194pub fn modify_point14_raw_input(reader: &BufferReader) -> BufferReader {
195    let mut tmp = LASPoint::default();
196    tmp.inject_point14_temp(reader, 0);
197    let LASPoint { x, y, z, intensity, flags, scan_direction_flag, edge_of_flight_line, .. } = tmp;
198    let mut res = LASPoint {
199        x,
200        y,
201        z,
202        intensity,
203        flags,
204        scan_direction_flag,
205        edge_of_flight_line,
206        ..Default::default()
207    };
208
209    if tmp.number_of_returns > 7 {
210        if tmp.return_number > 6 {
211            if tmp.return_number >= tmp.number_of_returns {
212                res.legacy_return_number = 7;
213            } else {
214                res.legacy_return_number = 6;
215            }
216        } else {
217            res.legacy_return_number = tmp.return_number;
218        }
219        res.legacy_number_of_returns = 7;
220    } else {
221        res.legacy_return_number = tmp.return_number;
222        res.legacy_number_of_returns = tmp.number_of_returns;
223    }
224    // res.legacy_flags = (tmp.classification << 5) & 0xe0;
225    if tmp.classification < 32 {
226        res.legacy_classification |= tmp.classification;
227    }
228    res.legacy_scan_angle_rank = i8_clamp(i16_quantize(0.006 * tmp.scan_angle as f64) as i32);
229    res.user_data = tmp.user_data;
230    res.point_source_id = tmp.point_source_id;
231    res.scanner_channel = tmp.scanner_channel;
232    res.class_flag = tmp.class_flag;
233    res.classification = tmp.classification;
234    res.return_number = tmp.return_number;
235    res.number_of_returns = tmp.number_of_returns;
236    res.scan_angle = tmp.scan_angle;
237    res.gps_time = Some(reader.f64_le(Some(22)));
238
239    res.to_buffer_14(true).into()
240}