Working with Lidar
This chapter documents lidar workflows in WbW-R, including file-backed processing, metadata checks, and output control patterns.
Lidar workflows are strongly shaped by dataset size and I/O cost. The guiding pattern here is to use file-backed objects and vectorized matrix operations for normal workloads, then switch to chunked processing when point counts exceed comfortable memory limits.
Baseline Workflow
Use this as a first-run validation before introducing matrix edits or chunked processing.
library(whiteboxworkflows)
l <- wbw_read_lidar('survey.las')
print(l$metadata())
copy <- l$deep_copy('survey_copy.las', overwrite = TRUE)
print(copy$metadata())
Memory-Backed Lidar for Pipeline Efficiency
For workflows that chain multiple lidar operations, memory-backed lidar objects eliminate disk I/O between steps. This is valuable when processing large point clouds through sequential filtering or classification steps.
Load a point cloud into memory with file_mode = "m":
library(whiteboxworkflows)
# Read directly into memory
survey <- wbw_read_lidar('survey.las', file_mode = "m")
print(survey$file_path()) # prints: memory://lidar/...
Memory-backed lidar objects support the full matrix/data-frame API and all downstream operations:
library(whiteboxworkflows)
# Read into memory
survey <- wbw_read_lidar('survey.las', file_mode = "m")
# Inspect and process
meta <- survey$metadata()
cat('Points:', meta$point_count, '\n')
# Extract and edit points
pts <- survey$to_matrix(fields = c('x', 'y', 'z', 'classification'))
high <- pts[, 3] > 250
pts[high, 4] <- 6
# Write edits back to disk
edited <- survey$from_matrix(
pts,
output_path = 'survey_filtered.laz',
overwrite = TRUE,
fields = c('x', 'y', 'z', 'classification')
)
Lidar Memory Lifecycle
Memory-backed lidar objects persist until explicitly removed or cleared. For long-running lidar pipelines, manage memory explicitly:
library(whiteboxworkflows)
# Check current memory
cat('Lidar objects in memory:', wbw_lidar_memory_count(), '\n')
# Read point clouds
survey1 <- wbw_read_lidar('large1.las', file_mode = "m")
survey2 <- wbw_read_lidar('large2.las', file_mode = "m")
cat('After reads:', wbw_lidar_memory_count(), '\n')
# Remove when done
wbw_remove_lidar_from_memory(survey1)
cat('After remove:', wbw_lidar_memory_count(), '\n')
# Or clear all
wbw_clear_lidar_memory()
cat('After clear:', wbw_lidar_memory_count(), '\n')
Implicit Memory Output from Tools
All lidar-output tools store their result in memory automatically when the
output argument is omitted (NULL). You do not need to pass file_mode = "m"
or choose a temporary path — simply leave output out and the returned
wbw_lidar object is already memory-backed:
library(whiteboxworkflows)
wbe <- wbw_make_session()
survey <- wbw_read_lidar('survey.laz')
# No output path — result is stored in memory automatically
filtered <- wbe$filter_lidar_classes(input = survey$path, excluded_classes = list(7L))
cat(filtered$path, '\n') # prints: memory://lidar/...
# Chain operations without any intermediate files
thinned <- wbe$lidar_thin(input = filtered$path, resolution = 0.5)
cat(thinned$path, '\n') # also memory://lidar/...
# Persist the final result only
wbw_write_lidar(thinned, 'survey_clean.copc.laz')
This applies to all lidar tools. Providing an explicit output argument writes
to disk as before.
Best practices:
- Use
file_mode = "m"for intermediate point cloud processing. - Export memory-backed lidar to disk with
write()when persisting final outputs. - Call
remove_lidar_from_memory()after a point cloud is no longer needed. - Use
clear_lidar_memory()between independent analysis phases. - Use
wbw_clear_memory()when resetting all in-process raster/vector/lidar stores together. - Monitor
lidar_memory_count()for large processing jobs.
Iterating Through Lidar Points
Stable WbW-R lidar objects are file-backed and tool-oriented, with explicit columnar point access through matrix/data-frame APIs. Direct point-by-point iteration is still not the primary API path.
Recommended point-level workflow:
- Use
to_matrix()orto_data_frame()with selected point fields. - Apply vectorized edits in base R/tidy workflows.
- Write updates with
from_matrix(...)orfrom_data_frame(...).
The example below uses a simple reclassification rule to illustrate the matrix roundtrip pattern.
library(whiteboxworkflows)
l <- wbw_read_lidar('survey.las')
pts <- l$to_matrix(fields = c('x', 'y', 'z', 'classification'))
ground <- pts[, 4] == 2
pts[ground, 4] <- 6
edited <- l$from_matrix(
pts,
output_path = 'survey_reclassified.laz',
overwrite = TRUE,
fields = c('x', 'y', 'z', 'classification')
)
print(edited$point_count())
Tool-Driven Lidar Processing
Use tool-driven processing when extracting QA outputs and diagnostics from lidar datasets.
For complete lidar write-option keys and allowed values, see Output Controls.
library(whiteboxworkflows)
s <- wbw_session()
wbw_lidar_info(input = 'survey.las', output = 'survey_info.html')
Chunked Matrix Streaming
For very large point clouds, use chunked matrix streaming to avoid keeping the full point matrix in memory.
Recommended chunked workflow:
- Read chunks with
to_matrix_chunks(...). - Apply vectorized edits in each chunk.
- Write edited chunks with
from_matrix_chunks(...).
Use this when full-matrix operations would exceed available memory.
library(whiteboxworkflows)
l <- wbw_read_lidar('survey.las')
fields <- c('x', 'y', 'z', 'classification')
chunks <- l$to_matrix_chunks(chunk_size = 200000, fields = fields)
for (i in seq_along(chunks)) {
high <- chunks[[i]][, 3] > 250
chunks[[i]][high, 4] <- 6
}
edited <- l$from_matrix_chunks(
chunks,
output_path = 'survey_chunked_reclassified.laz',
overwrite = TRUE,
fields = fields
)
print(edited$point_count())
Notes:
- LAS/LAZ chunk outputs use shared core streaming rewrite.
- Other output formats currently fall back to non-streaming assembly in this API path.
Best Practices
- Validate CRS before and after reprojection.
- Keep source lidar immutable; write derived products to new files.
- Prefer COPC/LAZ outputs for large cloud workflows.
Lidar Object Method Reference
Metadata and Access
| Method | Description |
|---|---|
metadata | Return lidar metadata (bounds, point format, CRS, counts). |
point_count | Return total number of points. |
file_path, path | Return backing lidar path. |
get_short_filename | Return basename of lidar file. |
Matrix and Data-Frame Conversion
| Method | Description |
|---|---|
to_matrix | Read selected lidar fields as numeric matrix. |
to_data_frame | Read selected lidar fields as data frame. |
to_matrix_chunks | Read selected lidar fields in chunked matrix blocks. |
Writing Edited Point Data
| Method | Description |
|---|---|
from_matrix | Write edited matrix data to lidar output. |
from_data_frame | Write edited data frame fields to lidar output. |
from_matrix_chunks | Write chunked matrix edits to lidar output. |
Persistence
| Method | Description |
|---|---|
deep_copy | Copy lidar to a new path with optional write options. |
write | Write lidar to a new output path. |