Since my actual goal was quite specific, my code is probably a bit non-generic, but I solved my issue. I got the voxels containing points, then I altered the voxel values and then I attatched the voxel metric to the point cloud by creating rasters for each vertical layer of voxels and merging them to the point vloud with merge_spatial()
. I used 10 cm pixels and did not change the bottom 5 voxel rows because I wanted them to remain unchanged. I will be honest: This code takes quite some time to execute, but it does what I want it to do. I guess it could be improved a lot.
# voxel metrics: is there a point in the voxel or not?
voxels <- voxel_metrics(las, length(X), res=0.1, all_voxels=TRUE)
voxels$V1 <- ifelse(voxels$V1 > 0, 1, 0)
voxels$V1[is.na(voxels$V1)] <- 0
# here I filter / change my voxels
# add empty voxel attributes to the points
las <- add_lasattribute(las, 1, "V1", "keep voxels with 1")
# save points which should remain the same
z_loop_vals <- sort(unique(voxels$Z))[6:length(unique(voxels$Z))]
unchanged_las <- filter_poi(las, Z <= min(z_loop_vals-5)/100)
# for each (filtered) vertical voxel layer, create a raster
for (z_val in z_loop_vals) {
# create raster
z_subset <- voxels[voxels$Z==z_val,]
z_subset <- as.data.frame(z_subset)[,c(1,2,4)]
new_raster <- rasterFromXYZ(z_subset)
crs(new_raster) <- CRS("+init=EPSG:25832")
# add raster values to point cloud
las_z <- filter_poi(las, Z > (z_val-0.05) & Z <= (z_val+0.05))
las_z <- merge_spatial(las_z, new_raster, "V1")
# remove points with V1 == 0
las_z <- filter_poi(las_z, V1 == 1)
unchanged_las <- rbind(unchanged_las, las_z)
}
# overwrite old point cloud
las <- unchanged_las