v3.1.0
lidR v3.1.0 (Release date: 2021-01-15)
MAJOR NEW FEATURES
The release of lidR
3.1.0 comes with major internal modifications enabling users to chose different kinds of spatial indexes to process the point-clouds, including Quadtrees and Octrees, plus others. Previous releases were optimized to process ALS data but were suboptimal for TLS data (for example) because the spatial index in use was specialized for ALS. With 3 new spatial indexes, version 3.1.0 brings the capability to process TLS (but not only) data more efficiently. For the time being, however, lidR
is still mainly focused on ALS and does not include many functions for TLS processing, but the existing functions that be used on all kinds of point-cloud, such as point_metrics()
, detect_shape()
, and classify_noise()
are already much faster for TLS data.
- The class
LAS
has a new slot@index
that registers the source of the point cloud (e.g. ALS, TLS, UAV, DAP) and the spatial index that must be used (e.g. grid partition, voxel partition, quadtree, octree). Seehelp("lidR-spatial-index")
. - This comes with several new
read*LAS()
functions, such asreadTLSLAS()
, which registers the point-cloud type and a default spatial index. Registering the correct point type improves the performance of some functions. This is particularly visible in functions that perform 3D knn searches, such aspoint_metrics()
. Computingpoint_metrics()
on a TLS point-cloud tagged as TLS is much faster than if it is not tagged. If performance is not improved in this release the future versions of the package may bring enhancements transparently. - New functions
index()
andsensor()
to manually modify the spatial indexing-related information.help("lidR-spatial-index")
. - New C++ API: the C++ classes for spatial indexing are header-only and stored in
inst/include
, meaning that other packages can link tolidR
to uses the spatial index at C++ level. The classes are not documented yet but the source code is simple and commented, and the lidR book contains (or will contain) a chapter on spatial indexing.
CHANGES
- The use of old deprecated namespaces (such as
lassomething()
) now triggers a message inviting users to move on the new namespace. - The construction of a
LAS
object withLAS()
now triggers warnings with incorrectly quantized coordinates according to the information in the header. grid_terrain()
now has a parameter...
afteralgorithm
that invalidates code that uses too many parameters without naming them. This no longer works:
grid_terrain(las, 1, tin(), TRUE, TRUE, 8)
# Use instead
grid_terrain(las, 1, tin(), keep_lowest = TRUE, full_raster = TRUE, use_class = 8)
opt_cores()
andopt_cores<-()
are now defunct. These functions did not have any effect because they only throw a warning to alert about deprecation since v2.1.0 (July 2019).- The
LAS*
classes have a new slot@index
(see above). This should not break anything expect when aLAS*
object is saved in anRds
file and loaded as an R object instead of being read withreadLAS
.
NEW FEATURES
-
classify_noise()
- New function
classify_noise()
to classify the outliers of a point-cloud according to ASPRS standard - New algorithm
sor()
(statistical outlier removal) for noise classification - New algorithm
ivf()
(isolated voxel filter) for noise classification
- New function
-
Quantization of the coordinates.
LAS
objects inlidR
closely respect the ASPRS standard. When modified manually by users, some inadequate practices may generate invalid LAS objects. We thus decided to export some internal functions to help in creating valid LAS objects and we modified the behavior of the[[<-
and$<-
operators to ensure that it is more difficult to createLAS
objects that are not ASPRS compliant.- New functions
las_quantize()
,quantize()
,is.quantized()
,count_not_quantized()
to ensure that coordinates are quantized according to the metadata in the header. - New function
las_update()
to update the header (bounding box, number of points, return count and so on) if a LAS object was modified outside alidR
functions. - Enhanced behaviour of
[[<-
and$<-
operators. Values are quantized on-the-fly and the header is updated automatically when attributing new values toX
,Y
orZ
.
las$X # Original values #> [1] 0.755 0.286 0.100 0.954 0.416 0.455 0.971 0.584 0.962 0.762 las$X + 5/3 # Many decimals because 5/3 = 1.666666... #> [1] 2.421667 1.952667 1.766667 2.620667 2.082667 2.121667 2.637667 2.250667 2.628667 2.428667 las$X <- las$X + 5/3 # Updates X with these numbers las$X # Values were quantized (and header updated) #> [1] 2.422 1.953 1.767 2.621 2.083 2.122 2.638 2.251 2.629 2.429
- New manual page can be found in
help("las_utilities")
.
- New functions
-
metrics
voxel_metrics()
gained a parameterall_voxels
to include "empty" voxels (i.e. those with 0 points) in the output #375.
-
grid_terrain()
- new parameter
...
afteralgorithm
that invalidates code that uses too many parameters without naming them. This no longer works:
grid_terrain(las, 1, tin(), TRUE, TRUE, 8) # Use instead grid_terrain(las, 1, tin(), keep_lowest = TRUE, full_raster = TRUE, use_class = 8)
- new parameter
is_concave
to compute a nicer DTM if the point-cloud boundaries are not convex #374
- new parameter
FIXES
- In
clip_transect()
the polygon generated to extract the transect defined by pointsp1
,p2
was created by buffering the linep1-p2
with aSQUARE
cap style meaning that the transect was extended beyond pointsp1
,p2
. It now uses aFLAT
cap style meaning that the transect is no longer extended beyond the limits of the user input. - In
segment_trees()
when using a raster-based algorithm, some points may have been misclassified as NAs at the edges of the point cloud instead of getting the correct tree ID found in the raster because of some edge effects. Now, all points are correctly classified and there are no longer false positive NAs. normalize_intensity()
was previously not working with aLAScatalog
. Now fixed. See #388- In
grid_*()
functions when aRasterLayer
is given as layout, the computation was performed for all the cells no matter if the extent of the loaded point-cloud was much smaller than the raster. For large rasters this dramatically increased the workload with redundant computation and saturated the RAM to a point that the computation was no longer possible. - In
track_sensor()
pulse IDs could be wrongly attributed for multi-beam sensors if the number of points is very low. See #392 - In
track_sensor()
, ifthin_pulses_with_time = 0
a single pulse was loaded with aLAScatalog
. However it worked as expected with aLAS
object. This behavior has been fixed. - Fixed some new warnings coming from
future
and related to RNG. clip_*()
in a region with no points from aLAScatalog
+ an output file no longer fails. See #400.
ENHANCEMENTS
- Doc: The documentation of
point_metrics()
clarifies how the user-defined function is fed and in which order the points are sorted. - Doc: The argument
Wdegenerated
ingrid_terrain()
andnormalize_height()
was misleading. A wrong interpretation was that degenerated ground points were discarded from the dataset. The documentation now clarifies the text to avoid misinterpretation. - Doc: minor fixes and clarifications in the
LAScatalog-class
page of the manual. - Enhance:
plot_dtm3d()
now enables pan by default, likeplot()
forLAS
objects. - Enhance:
track_sensor()
throws a new warning if a swath in the point cloud does not produce any sensor location. This addresses #391. - Misc: switch to C++14 (see #402)