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
//! Async streaming reader for [COPC](https://copc.io/) (Cloud-Optimized Point Cloud) files.
//!
//! COPC organises LAS/LAZ point cloud data in a spatial octree so that clients can
//! fetch only the regions they need. This crate reads COPC files incrementally through
//! the [`ByteSource`] trait — any random-access backend (local files, HTTP range
//! requests, in-memory buffers) works out of the box.
//!
//! # Quick start
//!
//! ```rust,ignore
//! use copc_streaming::{Aabb, CopcStreamingReader, FileSource};
//!
//! let mut reader = CopcStreamingReader::open(
//! FileSource::open("points.copc.laz")?,
//! ).await?;
//!
//! // One call: loads hierarchy, fetches chunks, filters points by bounds.
//! let points = reader.query_points(&my_query_box).await?;
//! // each `point` has .x, .y, .z, .gps_time, .color, etc.
//! ```
//!
//! # With LOD control
//!
//! ```rust,ignore
//! // Load points with at most 0.5 m between samples.
//! let level = reader.copc_info().level_for_resolution(0.5);
//! let points = reader.query_points_to_level(&my_query_box, level).await?;
//! ```
//!
//! # Low-level access
//!
//! For full control over hierarchy loading and chunk processing:
//!
//! ```rust,ignore
//! let mut reader = CopcStreamingReader::open(
//! FileSource::open("points.copc.laz")?,
//! ).await?;
//!
//! let root_bounds = reader.copc_info().root_bounds();
//! reader.load_hierarchy_for_bounds(&my_query_box).await?;
//!
//! for (key, entry) in reader.entries() {
//! if entry.point_count == 0 { continue; }
//! if !key.bounds(&root_bounds).intersects(&my_query_box) { continue; }
//!
//! let chunk = reader.fetch_chunk(key).await?;
//! let points = reader.read_points_in_bounds(&chunk, &my_query_box)?;
//! }
//! ```
//!
//! # Hierarchy loading
//!
//! The COPC hierarchy is stored as a tree of *pages*. Each page contains metadata
//! for a group of octree nodes (typically several levels deep) plus pointers to
//! child pages covering deeper subtrees.
//!
//! [`CopcStreamingReader::open`] reads the LAS header, COPC info, and the **root
//! hierarchy page**. This gives you the coarse octree nodes immediately (often
//! levels 0–3, depending on the file). Any subtrees stored in separate pages
//! are tracked as *pending pages* — they haven't been fetched yet.
//!
//! You then control when and which deeper pages are loaded:
//!
//! - [`load_hierarchy_for_bounds`](CopcStreamingReader::load_hierarchy_for_bounds) —
//! load only pages whose subtree intersects a bounding box. Call this when the
//! camera moves or a spatial query arrives.
//! - [`load_hierarchy_for_bounds_to_level`](CopcStreamingReader::load_hierarchy_for_bounds_to_level) —
//! same, but stops at a maximum octree level. Use with
//! [`CopcInfo::level_for_resolution`] for LOD control.
//! - [`load_pending_pages`](CopcStreamingReader::load_pending_pages) — fetch the
//! next batch of pending pages (all of them). Useful when you don't need spatial
//! filtering and just want to go one level deeper.
//! - [`load_all_hierarchy`](CopcStreamingReader::load_all_hierarchy) — convenience
//! to pull every remaining page in one go.
//! - [`children`](CopcStreamingReader::children) — list loaded children of a node.
//! Returns only children already in the cache; if deeper pages haven't been
//! loaded yet this may return fewer than exist in the file.
//! - [`has_pending_pages`](CopcStreamingReader::has_pending_pages) — check if there
//! are still unloaded pages.
//!
//! # Custom byte sources
//!
//! Implement [`ByteSource`] to read from any backend. The trait requires only
//! `read_range(offset, length)` and `size()`. A default `read_ranges` implementation
//! issues sequential reads — override it for backends that support parallel fetches
//! (e.g. HTTP/2 multiplexing).
//!
//! Built-in implementations: [`FileSource`] (local files), `Vec<u8>` and `&[u8]`
//! (in-memory).
//!
//! Futures returned by `ByteSource` are *not* required to be `Send`, so the crate
//! works in single-threaded runtimes and WASM environments.
pub use ByteSource;
pub use ;
pub use CopcError;
pub use FileSource;
pub use ;
pub use ;
pub use ;
pub use ;
/// Re-export `las::Point` — the point type returned by all read methods.
pub use Point;