las/
lib.rs

1//! Read and write [ASPRS LAS](https://www.asprs.org/committee-general/laser-las-file-format-exchange-activities.html)
2//! point cloud data.
3//!
4//! # Reading
5//!
6//! Create a [Reader] from a [Path](std::path::Path):
7//!
8//! ```
9//! use las::Reader;
10//! let reader = Reader::from_path("tests/data/autzen.las").unwrap();
11//! ```
12//!
13//! Or anything that implements [Read](std::io::Read):
14//!
15//! ```
16//! use std::io::BufReader;
17//! use std::fs::File;
18//! use las::Reader;
19//! let read = BufReader::new(File::open("tests/data/autzen.las").unwrap());
20//! let reader = Reader::new(read).unwrap();
21//! ```
22//!
23//! ## Prefer [BufRead](std::io::BufRead)
24//!
25//! Your performance will be better if your [Read](std::io::Read) is actually a
26//! [BufRead](std::io::BufRead). [Reader::from_path] takes care of this for you,
27//! but [Reader::new] doesn't.
28//!
29//! ## Read points
30//!
31//! Read points one-by-one with [Reader::read]:
32//!
33//! ```
34//! use las::Reader;
35//! let mut reader = Reader::from_path("tests/data/autzen.las").unwrap();
36//! let point = reader.read().unwrap().unwrap();
37//! ```
38//!
39//! Or iterate over all points with [Reader::points]:
40//!
41//! ```
42//! use las::Reader;
43//! let mut reader = Reader::from_path("tests/data/autzen.las").unwrap();
44//! for wrapped_point in reader.points() {
45//!     let point = wrapped_point.unwrap();
46//!     println!("Point coordinates: ({}, {}, {})", point.x, point.y, point.z);
47//!     if let Some(color) = point.color {
48//!         println!("Point color: red={}, green={}, blue={}",
49//!             color.red,
50//!             color.green,
51//!             color.blue,
52//!         );
53//!     }
54//! }
55//! ```
56//!
57//! # Writing
58//!
59//! Create a [Writer] from a [Write](std::io::Write) and a [Header]:
60//!
61//! ```
62//! use std::io::Cursor;
63//! use las::{Writer, Header};
64//! let write = Cursor::new(Vec::new());
65//! let header = Header::default();
66//! let writer = Writer::new(write, header).unwrap();
67//! ```
68//!
69//! You can also write out to a path (automatically buffered with [BufWriter](std::io::BufWriter)):
70//!
71//! ```
72//! use las::Writer;
73//! let writer = Writer::from_path("/dev/null", Default::default());
74//! ```
75//!
76//! Use a [Builder] to customize the las data:
77//!
78//! ```
79//! use std::io::Cursor;
80//! use las::{Writer, Builder};
81//! use las::point::Format;
82//!
83//! let mut builder = Builder::from((1, 4));
84//! builder.point_format = Format::new(2).unwrap();
85//! let header = builder.into_header().unwrap();
86//!
87//! let write = Cursor::new(Vec::new());
88//! let writer = Writer::new(write, header).unwrap();
89//! ```
90//!
91//! ## Prefer [BufWriter](std::io::BufWriter)
92//!
93//! Just like the [Reader], your performance will improve greatly if you use a
94//! [BufWriter](std::io::BufWriter) instead of just a [Write](std::io::Write).
95//!
96//! ## Write points
97//!
98//! Write points one at a time:
99//!
100//! ```
101//! use std::io::Cursor;
102//! use las::{Write, Writer, Point};
103//! let mut writer = Writer::default();
104//! let point = Point { x: 1., y: 2., z: 3., ..Default::default() };
105//! writer.write(point).unwrap();
106//! ```
107//!
108//! # Compression
109//!
110//! The [laz](https://laszip.org/) compression format is the de-facto standard for compression las data.
111//! To enable laz support, enable the `laz` or `laz-parallel` feature:
112//!
113//! ```toml
114//! [dependencies]
115//! las = { version = "0.9", features = ["laz"] }  # or laz-parallel
116//! ```
117//!
118//! Then, you can compress the data when writing:
119//!
120//! ```
121//! use std::io::Cursor;
122//! use las::{Writer, Builder};
123//! use las::point::Format;
124//!
125//! let mut builder = Builder::from((1, 4));
126//! builder.point_format = Format::new(2).unwrap();
127//! builder.point_format.is_compressed = true;
128//! let header = builder.into_header().unwrap();
129//! let write = Cursor::new(Vec::new());
130//! let result =  Writer::new(write, header);
131//! if cfg!(feature = "laz") {
132//!     assert!(result.is_ok());
133//! } else {
134//!     assert!(result.is_err());
135//! }
136//! ```
137//!
138//! [Writer::from_path] will use the extension of the output file to determine
139//! wether the data should be compressed or not:
140//!
141//! - `.laz`: compressed
142//! - `.las`: not compressed
143
144#![deny(
145    elided_lifetimes_in_paths,
146    explicit_outlives_requirements,
147    keyword_idents,
148    macro_use_extern_crate,
149    meta_variable_misuse,
150    missing_abi,
151    missing_debug_implementations,
152    missing_docs,
153    non_ascii_idents,
154    noop_method_call,
155    rust_2021_incompatible_closure_captures,
156    rust_2021_incompatible_or_patterns,
157    rust_2021_prefixes_incompatible_syntax,
158    rust_2021_prelude_collisions,
159    single_use_lifetimes,
160    trivial_casts,
161    trivial_numeric_casts,
162    unreachable_pub,
163    unsafe_code,
164    unsafe_op_in_unsafe_fn,
165    unused_crate_dependencies,
166    unused_extern_crates,
167    unused_import_braces,
168    unused_lifetimes,
169    unused_qualifications,
170    unused_results,
171    warnings
172)]
173
174#[cfg(feature = "laz")]
175pub mod copc;
176#[cfg(feature = "laz")]
177pub mod laz;
178
179pub mod crs;
180pub mod feature;
181pub mod header;
182pub mod point;
183pub mod raw;
184pub mod reader;
185pub mod vlr;
186pub mod writer;
187
188mod bounds;
189mod color;
190mod error;
191mod gps_time_type;
192mod transform;
193mod utils;
194mod vector;
195mod version;
196
197#[cfg(feature = "laz")]
198pub use crate::copc::CopcEntryReader;
199pub use crate::{
200    bounds::Bounds,
201    color::Color,
202    error::Error,
203    feature::Feature,
204    gps_time_type::GpsTimeType,
205    header::{Builder, Header},
206    point::Point,
207    reader::{Reader, ReaderOptions},
208    transform::Transform,
209    vector::Vector,
210    version::Version,
211    vlr::Vlr,
212    writer::Writer,
213};
214#[cfg(feature = "laz")]
215pub use reader::LazParallelism;
216#[allow(deprecated)]
217pub use {reader::Read, writer::Write};
218
219/// Crate-specific result type.
220pub type Result<T> = std::result::Result<T, Error>;
221
222#[cfg(test)]
223use criterion as _;