parallax wraps point cloud workflows in platform-aware R
classes and uses a Rust backend for the operations that are likely to
become expensive on real data. The installed demo files are
intentionally tiny, but they mirror the same flow you would use for
LAS/LAZ data.
Demo files
aerial_path <- system.file("extdata", "aerial-demo.csv", package = "parallax")
terrestrial_path <- system.file("extdata", "terrestrial-demo.csv", package = "parallax")
aerial <- px_read(aerial_path, platform = "aerial")
terrestrial <- px_read(terrestrial_path, platform = "terrestrial")
class(aerial)
#> [1] "px_aerial" "px_cloud"
class(terrestrial)
#> [1] "px_terrestrial" "px_cloud"Aerial workflow
Start with filtering and ground classification.
filtered <- px_filter_statistical(aerial, k = 6, std_ratio = 1.5)
ground <- px_classify_ground(filtered)
c(
n_points = nrow(filtered$xyz),
n_ground = ground$n_ground,
n_nonground = ground$n_nonground
)
#> n_points n_ground n_nonground
#> 18 8 10The same cloud can feed tree segmentation and summary metrics.
trees <- px_segment_trees(filtered, min_height = 2.0, crown_threshold = 0.75)
metrics <- px_metrics(filtered)
trees$n_segments
#> [1] 3
metrics
#> # A tibble: 1 × 18
#> n_points x_min x_max y_min y_max z_min z_max x_mean y_mean z_mean z_sd z_q05
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 18 0 3 0 2 0.02 5.1 1.61 1.02 2.16 2.04 0.0285
#> # ℹ 6 more variables: z_q25 <dbl>, z_q50 <dbl>, z_q75 <dbl>, z_q95 <dbl>,
#> # point_density <dbl>, intensity_mean <dbl>If you want gridded outputs, assign a simple ground/non-ground classification and build canopy products.
filtered$classification <- ifelse(ground$ground_mask, 2L, 1L)
chm <- px_canopy_height_model(filtered, resolution = 1.0)
density <- px_density_map(filtered, resolution = 1.0)
dim(chm$chm)
#> [1] 3 4
dim(density$density)
#> [1] 3 4Terrestrial workflow
Terrestrial data often leads with local geometry. Here the small demo scan has a dominant plane and enough points for local normal estimation.
scan_with_normals <- px_estimate_normals(terrestrial, k_neighbors = 4L)
planes <- px_detect_planes(
scan_with_normals,
distance_threshold = 0.08,
min_points = 6L,
num_iterations = 100L
)
length(planes)
#> [1] 1
if (length(planes) > 0) planes[[1]]$equation
#> [1] 0.010000458 -0.005000229 0.999937492 -0.008333354Where to go next
- Use
px_read()on LAS/LAZ files for real data. - Use
px_icp()andpx_align_scans()for scan registration. - Use
px_poisson_reconstruct()afterpx_estimate_normals()for mesh-style outputs. - Convert to and from
lidRobjects withto_lidr()andfrom_lidr().
