1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
//! Write las files. use std::path::Path; use Result; use file::File; use header::Header; use point::Point; /// A las writer. /// /// This wrapper conforms to the more standard structure of requiring a filename on create, not on /// close. /// /// I recognize that it's pretty messy to have both this and `File`, and TODO I need to clean /// things up. #[derive(Debug)] pub struct Writer<P: AsRef<Path>> { auto_offsets: bool, file: File, header: Header, path: P, } impl<P: AsRef<Path>> Writer<P> { /// Creates a new writer that will write las data to the given path. /// /// This won't actually write anything until the writer is closed. /// /// # Examples /// /// ``` /// use las::writer::Writer; /// let writer = Writer::from_path("temp.las"); /// ``` pub fn from_path(path: P) -> Writer<P> { Writer { auto_offsets: false, file: File::new(), header: Header::new(), path: path, } } /// Sets the scale factors on a writer. /// /// # Examples /// /// ``` /// use las::writer::Writer; /// let writer = Writer::from_path("temp.las").scale_factors(0.01, 0.01, 0.01); /// ``` pub fn scale_factors(mut self, x_scale_factor: f64, y_scale_factor: f64, z_scale_factor: f64) -> Writer<P> { self.header.x_scale_factor = x_scale_factor; self.header.y_scale_factor = y_scale_factor; self.header.z_scale_factor = z_scale_factor; self } /// Sets the offset values for a file. /// /// # Examples /// /// ``` /// use las::writer::Writer; /// let writer = Writer::from_path("temp.las").offsets(1000.0, 2000.0, 100.0); /// ``` pub fn offsets(mut self, x_offset: f64, y_offset: f64, z_offset: f64) -> Writer<P> { self.header.x_offset = x_offset; self.header.y_offset = y_offset; self.header.z_offset = z_offset; self } /// Enables auto-offsetting. /// /// If auto-offsetting is enabled, this file will set the header offset values to sensible /// values before writing anything. This is usually easier than calculating the offsets /// yourself. /// /// # Examples /// /// ``` /// use las::writer::Writer; /// let writer = Writer::from_path("temp.las").auto_offsets(true); /// ``` pub fn auto_offsets(mut self, enable: bool) -> Writer<P> { self.auto_offsets = enable; self } /// Writes a point to this writer. /// /// Note that this point won't actually be written until the writer is closed. /// /// # Examples /// /// ``` /// use las::writer::Writer; /// use las::point::Point; /// let mut writer = Writer::from_path("temp.las"); /// writer.write_point(Point::new()); /// ``` pub fn write_point(&mut self, point: Point) { self.file.add_point(point) } /// Closes this writer and actually writes data out to disc. /// /// Since we need to calculate some stats on the points for the header, we delay writing until /// the very last minute. If you don't want to hold all those points in memory, we'll need to /// come up with some other way to do that. /// /// This function consumes the writer. /// /// # Examples /// /// ``` /// use std::fs::remove_file; /// use las::writer::Writer; /// use las::point::Point; /// let mut writer = Writer::from_path("temp.las"); /// writer.write_point(Point::new()); /// writer.close().unwrap(); /// remove_file("temp.las").unwrap(); /// ``` pub fn close(&mut self) -> Result<()> { self.file.set_header(self.header); self.file.to_path(&self.path, self.auto_offsets) } }