1use crate::{Error, Header, Result, Vlr};
4use laz::{LazItemRecordBuilder, LazItemType, LazVlr};
5use std::io::Cursor;
6
7pub fn is_laszip_vlr(vlr: &Vlr) -> bool {
24 vlr.user_id == LazVlr::USER_ID && vlr.record_id == LazVlr::RECORD_ID
25}
26
27impl Header {
28 pub fn add_laz_vlr(&mut self) -> Result<()> {
42 let point_format = self.point_format();
43 let mut laz_items = LazItemRecordBuilder::new();
44 if !point_format.is_extended {
45 let _ = laz_items.add_item(LazItemType::Point10);
46
47 if point_format.has_gps_time {
48 let _ = laz_items.add_item(LazItemType::GpsTime);
49 }
50
51 if point_format.has_color {
52 let _ = laz_items.add_item(LazItemType::RGB12);
53 }
54
55 if point_format.has_waveform {
56 let _ = laz_items.add_item(LazItemType::WavePacket13);
57 }
58
59 if point_format.extra_bytes > 0 {
60 let _ = laz_items.add_item(LazItemType::Byte(point_format.extra_bytes));
61 }
62 } else {
63 let _ = laz_items.add_item(LazItemType::Point14);
64
65 if point_format.has_color {
66 if point_format.has_nir {
68 let _ = laz_items.add_item(LazItemType::RGBNIR14);
69 } else {
70 let _ = laz_items.add_item(LazItemType::RGB14);
71 }
72 }
73
74 if point_format.has_waveform {
75 let _ = laz_items.add_item(LazItemType::WavePacket14);
76 }
77
78 if point_format.extra_bytes > 0 {
79 let _ = laz_items.add_item(LazItemType::Byte14(point_format.extra_bytes));
80 }
81 }
82 let laz_vlr = LazVlr::from_laz_items(laz_items.build());
83 let mut cursor = Cursor::new(Vec::<u8>::new());
84 laz_vlr.write_to(&mut cursor)?;
85 let vlr = Vlr {
86 user_id: LazVlr::USER_ID.to_owned(),
87 record_id: LazVlr::RECORD_ID,
88 description: LazVlr::DESCRIPTION.to_owned(),
89 data: cursor.into_inner(),
90 };
91 self.vlrs.push(vlr);
92 Ok(())
93 }
94
95 pub fn laz_vlr(&self) -> Result<LazVlr> {
112 self.vlrs
113 .iter()
114 .find(|vlr| is_laszip_vlr(vlr))
115 .map_or(Err(Error::LasZipVlrNotFound), |vlr| vlr.try_into())
116 }
117}
118
119impl TryFrom<&Vlr> for LazVlr {
120 type Error = Error;
121
122 fn try_from(vlr: &Vlr) -> Result<LazVlr> {
123 LazVlr::from_buffer(&vlr.data).map_err(Error::from)
124 }
125}