epoint_io/las/
write.rs

1use crate::las::write_impl::write_las_format;
2use crate::{Error, FILE_EXTENSION_LAS_FORMAT, FILE_EXTENSION_LAZ_FORMAT};
3use epoint_core::PointCloud;
4
5use crate::Error::{InvalidFileExtension, NoFileExtension};
6use ecoord::FrameId;
7use std::fmt::Debug;
8use std::fs::File;
9use std::io::{BufWriter, Seek, Write};
10use std::path::Path;
11
12/// `EpointWriter` sets up a writer for the custom reader data structure.
13///
14#[derive(Debug, Clone)]
15pub struct LasWriter<W: 'static + std::io::Write + Seek + Debug + Send> {
16    writer: W,
17    frame_id: Option<FrameId>,
18}
19
20impl<W: Write + Seek + Debug + Send> LasWriter<W> {
21    pub fn new(writer: W) -> Self {
22        Self {
23            writer,
24            frame_id: None,
25        }
26    }
27
28    pub fn with_frame_id(mut self, frame_id: FrameId) -> Self {
29        self.frame_id = Some(frame_id);
30        self
31    }
32
33    pub fn finish(self, point_cloud: &PointCloud) -> Result<(), Error> {
34        let mut exported_point_cloud = point_cloud.clone();
35        let resulting_point_cloud: PointCloud =
36            self.frame_id.map_or(point_cloud.to_owned(), |f: FrameId| {
37                exported_point_cloud
38                    .resolve_to_frame(f)
39                    .expect("Resolving should work");
40                exported_point_cloud
41            });
42
43        write_las_format(BufWriter::new(self.writer), &resulting_point_cloud)?;
44
45        Ok(())
46    }
47}
48
49impl LasWriter<File> {
50    pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
51        let extension = path.as_ref().extension().ok_or(NoFileExtension())?;
52        if extension != FILE_EXTENSION_LAS_FORMAT && extension != FILE_EXTENSION_LAZ_FORMAT {
53            return Err(InvalidFileExtension(
54                extension.to_str().unwrap_or_default().to_string(),
55            ));
56        }
57
58        let file = File::create(path)?;
59        Ok(Self::new(file))
60    }
61}