Call a user-defined function on the point cloud. The function receives a data.frame
with the
point cloud. Its first input must be the point cloud. If the function returns anything other than
a data.frame
with the same number of points, the output is stored and returned at the end. However,
if the output is a data.frame
with the same number of points, it updates the point cloud. This
function can, therefore, be used to modify the point cloud using a user-defined function. The function
is versatile but complex. A more comprehensive set of examples can be found in the
online tutorial.
Arguments
- fun
function. A user-defined function that takes as first argument a
data.frame
with the exposed point cloud attributes (see examples).- expose
character. Expose only attributes of interest to save memory (see details).
- ...
parameters of function
fun
- drop_buffer
bool. If false, does not expose the point from the buffer.
- no_las_update
bool. If the user-defined function returns a data.frame, this is supposed to update the point cloud. Can be disabled.
Details
In lasR
, the point cloud is not exposed to R in a data.frame
like in lidR. It is stored internally
in a C++ structure and cannot be seen or modified directly by users using R code. The callback
function
is the only stage that allows direct interaction with the point cloud by copying it
temporarily into a data.frame
to apply a user-defined function.
expose: the 'expose' argument specifies the data that will actually be exposed to R. For example,
'xyzia' means that the x, y, and z coordinates, the intensity, and the scan angle will be exposed.
The supported entries are t - gpstime, a - scan angle, i - intensity, n - number of returns,
r - return number, c - classification, s - synthetic flag, k - keypoint flag, w - withheld flag,
o - overlap flag (format 6+), u - user data, p - point source ID, e - edge of flight line flag,
d - direction of scan flag, R - red channel of RGB color, G - green channel of RGB color,
B - blue channel of RGB color, N - near-infrared channel, C - scanner channel (format 6+)
Also numbers from 1 to 9 for the extra bytes data numbers 1 to 9. 'E' enables all extra bytes to be
loaded. '*' is the wildcard that enables everything to be exposed from the LAS file.
Examples
f <- system.file("extdata", "Topography.las", package = "lasR")
# There is no function in lasR to read the data in R. Let's create one
read_las <- function(f)
{
load <- function(data) { return(data) }
read <- reader_las()
call <- callback(load, expose = "xyzi", no_las_update = TRUE)
return (exec(read + call, on = f))
}
las <- read_las(f)
head(las)
#> X Y Z Intensity
#> 1 273357.1 5274360 806.5340 1340
#> 2 273357.2 5274359 806.5635 728
#> 3 273357.2 5274358 806.0248 1369
#> 4 273357.2 5274510 809.6303 589
#> 5 273357.2 5274509 809.3880 1302
#> 6 273357.2 5274508 809.4847 123
convert_intensity_in_range <- function(data, min, max)
{
i <- data$Intensity
i <- ((i - min(i)) / (max(i) - min(i))) * (max - min) + min
i[i < min] <- min
i[i > max] <- max
data$Intensity <- as.integer(i)
return(data)
}
read <- reader_las()
call <- callback(convert_intensity_in_range, expose = "i", min = 0, max = 255)
write <- write_las()
pipeline <- read + call + write
ans <- exec(pipeline, on = f)
las <- read_las(ans)
head(las)
#> X Y Z Intensity
#> 1 273357.1 5274360 806.5340 137
#> 2 273357.2 5274359 806.5635 72
#> 3 273357.2 5274358 806.0248 140
#> 4 273357.2 5274510 809.6303 57
#> 5 273357.2 5274509 809.3880 133
#> 6 273357.2 5274508 809.4847 7