Skip to content

Commit

Permalink
Spatial indexing and TLS tools
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Romain committed Oct 24, 2024
1 parent 9301d09 commit a2a2cc8
Show file tree
Hide file tree
Showing 23 changed files with 965 additions and 123 deletions.
114 changes: 114 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,117 @@ LinkingTo: BH (>= 1.72.0),Rcpp,RcppArmadillo
Encoding: UTF-8
ByteCompile: true
VignetteBuilder: knitr
Collate:
'Class-LAS.R'
'Class-LAScatalog.R'
'Class-LAScluster.R'
'RcppExports.R'
'add_attribute.R'
'algorithm-dec.R'
'algorithm-dsm.R'
'algorithm-dtm.R'
'algorithm-gnd.R'
'algorithm-itd.R'
'algorithm-its.R'
'algorithm-noi.R'
'algorithm-out.R'
'algorithm-shp.R'
'algorithm-snag.R'
'algorithm-trk.R'
'backward_compatibility.R'
'catalog_apply.R'
'catalog_boundaries.R'
'catalog_fakerun.R'
'catalog_intersect.R'
'catalog_laxindex.R'
'catalog_overlaps.R'
'catalog_retile.R'
'catalog_select.R'
'classify.R'
'classify_ground.R'
'classify_noise.R'
'classify_poi.R'
'clip_roi.R'
'connected_components.R'
'decimate_points.R'
'io_readLAScatalog.R'
'io_readXLAS.R'
'deprecated.R'
'doc-drivers.R'
'doc-lidR.R'
'doc-parallelism.R'
'doc-spatialindex.R'
'engine.R'
'engine_apply.R'
'engine_chunks.R'
'engine_crop.R'
'engine_index.R'
'engine_merge.R'
'engine_options.R'
'engine_write.R'
'fasterize.R'
'filters.R'
'fullwaveform.R'
'generate_las.R'
'io_readLAS.R'
'io_writeLAS.R'
'las_check.R'
'las_compression.R'
'las_tools.R'
'locate_localmaxima.R'
'locate_trees.R'
'merge_spatial.R'
'methods-LAS.R'
'methods-LAScatalog.R'
'methods-LAScluster.R'
'methods-LASheader.R'
'metrics_cloud.R'
'metrics_crowns.R'
'metrics_hexagons.R'
'metrics_pixels.R'
'metrics_plot.R'
'metrics_point.R'
'metrics_polygon.R'
'metrics_stdmetrics.R'
'metrics_template.R'
'metrics_voxels.R'
'normalize.R'
'normalize_height.R'
'normalize_intensity.R'
'plot.R'
'plot.s3.R'
'plugins.R'
'print.R'
'rasterize.R'
'rasterize_canopy.R'
'rasterize_density.R'
'rasterize_terrain.R'
'retrieve_info.R'
'segment.R'
'segment_shapes.R'
'segment_snags.R'
'segment_trees.R'
'smooth_height.R'
'st_area.R'
'st_as_sf.R'
'st_bbox.R'
'st_coordinates.R'
'st_crs.R'
'st_hull.R'
'st_misc.R'
'st_transform.R'
'track_sensor.R'
'utils_assertive.R'
'utils_base.R'
'utils_chm.R'
'utils_colors.R'
'utils_constant.R'
'utils_delaunay.R'
'utils_geometry.R'
'utils_is.R'
'utils_misc.R'
'utils_raster.R'
'utils_spatial_index.R'
'utils_threads.R'
'voxelize_points.R'
'zzz.R'
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ export(clip_roi)
export(clip_transect)
export(cloud_metrics)
export(concaveman)
export(connected_components)
export(count_not_quantized)
export(crown_metrics)
export(csf)
Expand Down Expand Up @@ -247,6 +248,7 @@ export(is.overlapping)
export(is.parallelised)
export(is.quantized)
export(ivf)
export(knn_distance)
export(knnidw)
export(kriging)
export(las_check)
Expand Down Expand Up @@ -350,16 +352,20 @@ export(range_correction)
export(rasterize_canopy)
export(rasterize_density)
export(rasterize_terrain)
export(readALS)
export(readALSLAS)
export(readALSLAScatalog)
export(readALScatalog)
export(readDAPLAS)
export(readDAPLAScatalog)
export(readLAS)
export(readLAScatalog)
export(readLASheader)
export(readMSLAS)
export(readTLS)
export(readTLSLAS)
export(readTLSLAScatalog)
export(readTLScatalog)
export(readUAVLAS)
export(readUAVLAScatalog)
export(remove_lasattribute)
Expand Down
9 changes: 8 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
If you are viewing this file on CRAN, please check [the latest news on GitHub](https://github.com/r-lidar/lidR/blob/master/NEWS.md) where the formatting is also better

## lidR v4.1.3 (Release date: )
## lidR v4.2.0 (Release date: )

v4.2.0 bring new tools for terrestrial data (TLS, MLS)

- New: new function `connected_components()` to perform clustering
- New: new function `knn_distance()` to measure average distance between a point and its neighborhood
- New: new C++ spatial indexing class `SparsePartition3D` for TLS data which is memory optimized
- New: new functions `readALS` and `readTLS` that replace overly complex and unused `readALSLAS`, `readTLSLAS`, `readUAVLAS` and co.
- New: new functions `readALScatalog` and `readTLScatalog` that replace overly complex and unused `readALSLAScatalog`, `readTLSLAScatalog`, `readUAVLAScatalog` and co.
- Fix: #771 read VPC files with absolute path
- Enhance: `crs()` `is.empty()` and `area()` are now inherits from `terra` and no longer clash with `terra`.
- Enhance: #776 `readLAScatalog` can skip corrupted files
Expand Down
12 changes: 10 additions & 2 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ is_disable_point_metrics <- function() {
.Call(`_lidR_is_disable_point_metrics`)
}

C_fast_knn_metrics <- function(las, k, metrics, cpu) {
.Call(`_lidR_C_fast_knn_metrics`, las, k, metrics, cpu)
C_knn_distance <- function(las, k, cpu) {
.Call(`_lidR_C_knn_distance`, las, k, cpu)
}

C_lasrangecorrection <- function(las, flightlines, Rs, f) {
Expand All @@ -113,6 +113,14 @@ C_eigen_metrics <- function(las, k, r, coeffs, filter, ncpu) {
.Call(`_lidR_C_eigen_metrics`, las, k, r, coeffs, filter, ncpu)
}

C_connected_component <- function(las, res) {
.Call(`_lidR_C_connected_component`, las, res)
}

C_voxel_id <- function(las, res) {
.Call(`_lidR_C_voxel_id`, las, res)
}

fast_table <- function(x, size = 5L) {
.Call(`_lidR_fast_table`, x, size)
}
Expand Down
2 changes: 1 addition & 1 deletion R/algorithm-out.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ sor = function(k = 10, m = 3, quantile = FALSE)
f = function(las)
{
assert_is_valid_context(LIDRCONTEXTOUT, "sor")
dmean <- C_fast_knn_metrics(las, k, 1, getThreads())
dmean <- C_knn_distance(las, k, getThreads())
if (quantile) {
th <- quantile(dmean, probs = m)
} else {
Expand Down
53 changes: 53 additions & 0 deletions R/connected_components.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#' Connected-Component Labeling
#'
#' Assigns an ID to each cluster of connected components in a point cloud. The point cloud is subdivided
#' into a 3D grid, and a classical [Connected-Component Labeling](https://en.wikipedia.org/wiki/Connected-component_labeling)
#' algorithm is applied in 3D.
#'
#' @param las A LAS object representing the point cloud data.
#' @param res Grid resolution. If two non-empty voxels are contiguous, they are considered part of
#' the same component.
#' @param min_pts Minimum number of points in a cluster. If a cluster contains fewer than `min_pts`
#' points, it is assigned an ID of 0, indicating that it does not belong to any group.
#' @param name A string specifying the name of the new attribute used to store the ID of each cluster.
#'
#' @return A LAS object with an additional attribute named as specified by `name`.
#' @md
#' @export
connected_components = function(las, res, min_pts, name = "clusterID")
{
.N <- N <- cluster <- gpstime <- NULL

u = C_connected_component(las, res)
las = add_lasattribute(las, u, name, "connected component ID")
grp = las@data[, .N, by = cluster]
grp = grp[N < min_pts]
las@data[cluster %in% grp$cluster, cluster := 0][]
return(las)
}



#' Computes the Distance to k-Nearest Neighbors
#'
#' Computes the average distance between each point and its k-nearest neighbors in a point cloud.
#' The results are stored in a new attribute.
#'
#' @param las A LAS object representing the point cloud data.
#' @param k The number of nearest neighbors.
#' @param name A string specifying the name of the new attribute used to store the computed distances.
#'
#' @return A LAS object with an additional attribute named as specified by `name`.
#' @export
#' @examples
#' LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
#' las <- readLAS(LASfile, select = "xyz", filter = "-inside 481250 3812980 481300 3813030")
#' las = knn_distance(las)
#' #plot(las, color = "distance", breaks = "quantile", legend = TRUE)
knn_distance = function(las, k = 10, name = "distance")
{
d = C_knn_distance(las, k, getThreads())
las = add_lasattribute(las, d, name, "knn average distance")
return(las)
}

36 changes: 36 additions & 0 deletions R/deprecated.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,49 @@
#' @param uniqueness See the new functions that replace the old ones
#' @param interval,pmin,extra_check,thin_pulse_with_time See the new functions that replace the old ones
#' @param concavity,length_threshold,func See the new functions that replace the old ones
#' @param files,select,sort See the new functions that replace the old ones
#'
#' @rdname deprecated
#' @name deprecated
#'
#' @include io_readXLAS.R
#' @include io_readLAScatalog.R
NULL

# nocov start

#' @export
#' @rdname deprecated
readALSLAS = readALS

#' @export
#' @rdname deprecated
readTLSLAS = readTLS

#' @export
#' @rdname deprecated
readUAVLAS = readTLS

#' @export
#' @rdname readLAS
readDAPLAS = readTLS

#' @export
#' @rdname readLAScatalog
readALSLAScatalog = readALScatalog

#' @export
#' @rdname readLAScatalog
readTLSLAScatalog = readTLScatalog

#' @export
#' @rdname readLAScatalog
readUAVLAScatalog = readTLScatalog

#' @export
#' @rdname readLAScatalog
readDAPLAScatalog = readTLScatalog

#' @export
#' @rdname deprecated
lascheck <- function(las) {
Expand Down
9 changes: 4 additions & 5 deletions R/io_readLAS.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
#' once the returned LAS object is considered as one LAS file. The optional parameters enable the user
#' to save a substantial amount of memory by choosing to load only the attributes or points of interest.
#' LAS formats 1.0 to 1.4 are supported. Point Data Record Format 0 to 10 are supported.\cr\cr
#' `readLAS` is the original function and always works. Using one of the `read*LAS` functions
#' `readLAS` is the original function and always works. Using one of the `readALS` or `readTLS` functions
#' adds information to the returned object to register a point-cloud type. Registering the correct point
#' type **may** improve the performance of some functions by enabling users to select an appropriate spatial index.
#' type improves the performance of some functions by enabling users to select an appropriate spatial index.
#' See \link[=lidR-spatial-index]{spatial indexing}. Notice that by legacy and for backwards-compatibility reasons,
#' `readLAS()` and `readALSLAS()` are equivalent because lidR was originally designed for ALS and thus the
#' `readLAS()` and `readALS()` are equivalent because lidR was originally designed for ALS and thus the
#' original function `readLAS()` was (supposedly) used for ALS. Reading a TLS dataset with `readLAS()` instead
#' of `readTLSLAS()` is perfectly valid and performs similarly to versions `<= 3.0.0`, with neither
#' performance degradation nor improvements.
#' of `readTLS()` is perfectly valid but less powerful.
#'
#'
#' **Select:** the 'select' argument specifies the data that will actually be loaded. For example,
Expand Down
22 changes: 2 additions & 20 deletions R/io_readLAScatalog.R
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ readLAScatalog <- function(folder, progress = TRUE, select = "*", filter = "", c

#' @export
#' @rdname readLAScatalog
readALSLAScatalog = function(folder, ...)
readALScatalog = function(folder, ...)
{
ctg <- readLAScatalog(folder, ...)
ctg@index <- LIDRALSINDEX
Expand All @@ -193,31 +193,13 @@ readALSLAScatalog = function(folder, ...)

#' @export
#' @rdname readLAScatalog
readTLSLAScatalog = function(folder, ...)
readTLScatalog = function(folder, ...)
{
ctg <- readLAScatalog(folder, ...)
ctg@index <- LIDRTLSINDEX
return(ctg)
}

#' @export
#' @rdname readLAScatalog
readUAVLAScatalog = function(folder, ...)
{
ctg <- readLAScatalog(folder, ...)
ctg@index <- LIDRUAVINDEX
return(ctg)
}

#' @export
#' @rdname readLAScatalog
readDAPLAScatalog = function(folder, ...)
{
ctg <- readLAScatalog(folder, ...)
ctg@index <- LIDRDAPINDEX
return(ctg)
}

#' @export
#' @name readLAScatalog
catalog <- function(folder, ...) { readLAScatalog(folder, FALSE, ...) }
Expand Down
Loading

0 comments on commit a2a2cc8

Please sign in to comment.