copc-rust
Pure-Rust COPC reader, writer, and shared core primitives for cloud-optimized point clouds. No C libraries, no build scripts; internal unsafe is limited to read-only memory mapping of writer spill files.
Crates
| Crate | Description |
|---|---|
copc-core |
Shared COPC metadata, hierarchy entries, voxel keys, bounds, LAS-native column batches, streaming LAS records, and errors |
copc-reader |
Strict COPC header/info parsing, iterative hierarchy access, chunked-LAZ row iteration, and materialized column reads |
copc-writer |
COPC writer with source-trait point access, column-batch source support, native LOD distribution, mmap spill support, and streaming LAS/LAZ intake |
Usage
use CopcFile;
let file = open?;
for entry in file.hierarchy_walk
use ;
let mut reader = from_path?;
for point in reader.points?
use ;
use ;
let mut reader = from_path?;
let batch = reader.read_columns?;
if let Some = batch.column
use ;
convert_las_to_copc_streaming?;
For GeoTIFF-only CRS inputs, resolve CRS externally and call
convert_las_to_copc_streaming_with_crs_wkt_override with Some(wkt); the
writer emits the supplied WKT CRS VLR without depending on a geodesy library.
Generated files carry caller metadata through CopcWriteMetadata (WKT CRS,
GUID, identifiers, creation date, GPS time type, scale/offset overrides):
use ;
let mut metadata = default;
metadata.wkt_crs = Some;
write_source?;
Remote and partial reads go through CopcRangeReader, which fetches only the
header and VLRs at open, loads hierarchy pages lazily as queries reach them,
and coalesces adjacent chunk fetches into single range requests:
use ;
// Requires the `http` feature (plus `http-tls` for HTTPS URLs).
let source = new;
let mut reader = open?;
let batch = reader.read_columns?;
Any byte-range source works by implementing the RangeRead trait;
std::fs::File implements it out of the box.
Feature Flags
All features are off by default, keeping the crates dependency-light.
| Crate | Feature | Effect |
|---|---|---|
copc-writer |
parallel |
rayon-parallel LAZ chunk compression (one octree node per chunk, written in order with a standard chunk table) |
copc-reader |
parallel |
rayon-parallel chunk decoding for read_columns |
copc-reader |
http |
HttpRangeReader over HTTP Range requests (plain HTTP) |
copc-reader |
http-tls |
enables ureq/rustls so HttpRangeReader can fetch HTTPS URLs |
Column Ownership Model
copc-core owns the LAS/COPC-native column model: LasDimension,
ColumnSpec, ColumnData, ColumnView, ColumnSelection, and
LasColumnBatch. These types are dependency-light and do not depend on Arrow,
DataFusion, or engine-specific point-cloud crates.
copc-reader exposes materialized column batches with
CopcReader::read_columns and CopcReader::read_columns_with_cancel.
Existing row iteration with points, points_for_query, and
points_with_cancel remains supported.
The column API is materialized. COPC point data is still read from compressed LAZ chunks, decoded, filtered, transformed, and appended into owned column buffers. It is not a zero-copy view into compressed COPC files.
Downstream engines should adapt LasColumnBatch into their own canonical
memory model. For example, roteiro-engine maps these native batches into its
PointCloud struct-of-arrays representation. Arrow conversion is intentionally
out of scope for copc-rust today; it belongs in downstream engine code or
behind a future optional feature.
Supported Now
- Public COPC hierarchy types for availability, indexing, and tile serving
- COPC info VLR and stack-safe iterative hierarchy page parsing
- Chunked-LAZ point iteration in
copc-reader - All-points, LOD-selected, and bounds-selected reader point iteration
- Materialized LAS/COPC-native column batches in
copc-reader - Source-trait writer API for caller-owned point storage
- COPC writing from neutral
LasColumnBatchvalues viaColumnBatchSource - Streaming LAS/LAZ-to-COPC conversion through a disk-backed mmap spill
- Streaming conversion preserves WKT CRS records, LAS Extra Bytes payloads and descriptors, and source non-CRS VLRs/EVLRs
- Streaming conversion can accept caller-resolved WKT for GeoTIFF-only CRS
inputs without adding a geodesy dependency to
copc-writer - Reading LAS 1.4 point formats 6, 7, and 8 with LAZ variable-size chunks
- Writing LAS 1.4 point formats 6 and 7 with LAZ variable-size chunks
- Interior-node representative points for native LOD reads
- Lazy remote reads over byte-range sources (
CopcRangeReader,RangeRead, optional HTTP source) with on-demand hierarchy loading and coalesced chunk fetches - Optional rayon parallelism for writer chunk compression and reader column decoding
- Caller-supplied output metadata (WKT CRS, GUID, identifiers, creation date) for generated COPC files, which always carry the LAS 1.4 WKT global-encoding bit and a WKT CRS VLR
Not Yet Supported
- Zero-copy column views directly over compressed COPC/LAZ point data
- Built-in Arrow or DataFusion conversion
- Built-in GeoTIFF-only CRS conversion to WKT during LAS/LAZ-to-COPC conversion
Testing
Checked-in external COPC fixtures from PDAL and QGIS are exercised by:
License
MIT OR Apache-2.0