Recent Releases of lidR
lidR - v4.0.3
lidR v4.0.3 (Release date: 2023-03-11)
- Add a function
add_lasnir()
. - Replace
rg::rgl.*
byrgl::*3d
functions #651 - Fix:
readLAS
no longer checks for attribute names validity as they are necessarily correct #659 - Fix:
plot_metrics()
no longer fails with a single plot #664
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 2 years ago

lidR - v4.0.2
lidR v4.0.2 (Release date: 2022-11-28)
- Fix: #638.
unormalize_height()
removes extra_bytes in VLR. - Fix: #637.
print(las)
works even when the CRS is not recognized bysf
. - New:
dsmtin
andpitfree
gain an argumenthighest
. This option was enabled by default in previous releases. There is now an option to disable it. - Fix: #580 and #622
normalize_height()
andsegment_trees
work in parallel withSpatRaster
. - Fix: #586.
- Fix: #587.
crown_metrics()
now triggers a warning when invalid geometries are created anddelineate_crowns()
remove these geometries before to convert tosp
. - Fix: #594.
crown_metrics()
now works withfunc = NULL
and aLAScatalog
. - Fix: #608. The C++ function used to compute the range between a point and the sensor from the sensor positions was re-based to resolve a bug when a single sensor position was found for a given flightline. New warnings were added.
- Fix: #609.
*_metrics()
functions always returnedNA
s forlastofmany
. - Fix: #614. Manual tree detection preserves the CRS.
- Doc:
dalponte2016
doc updated to useterra
.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 2 years ago

lidR - v4.0.1
lidR v4.0.1 (Release date: 2022-05-03)
- Fix:
plot(ctg, chunk = TRUE)
does not fail if an invalid output file template is registered #537 - Enhance:
locate_trees()
throws an informative error if called with an on-disk raster. The former error was cryptic. If the raster is small enough it is loaded on-the-fly. - Fix:
merge_spatial()
with RGB andSpatRaster
was not working properly #545 - Enhance:
st_area()
better estimates the area of small point-clouds and is faster - Fix: #548
- Enhance: Scale factors are better estimated in
interpret_waveform
#549. - Fix:
plot_metrics()
returns NA if 0 points available #551. - Fix: floating point accuracy error with
rasterize_canopy
may generate error or messed-up CHM #552. - Fix:
print()
andst_area()
were not working for point cloud with no CRS - Fix:
track_sensor()
does not fail with aLAScatalog
when no sensor position is found. It also triggers a warning. #556. - Fix: The LAScatalog processing engine works with a single file #558.
- Fix:
rasterize_terrain()
now works with aLAScatalog
andshape = sfc_object
#558. - Fix:
catalog_retile()
now works when some tiles are empty #563. - Fix:
crown_metrics()
messed up tree IDs with a hull geometry #554. - Fix:
merge_spatial()
crops large vectors to the extent of the point cloud before to perform the merge. This has for consequences to sometime transform polygons into multipolygons. When polygons and multipolygons were mixed the functions stopped with an error. It now works. - Fix:
normalize_height()
now sets the Z offset to 0 #571. - Fix: smaller rasters stored on-disk are better handled and loaded if needed
Changes related to rlas 1.6.0
We are currently developing rlas 1.6.0 that uses the ALTREP framework to load compact representation of non populated attributes. For example UserData
is usually populated with zeros (not populated). Yet it takes 32 bits per point to store each 0. With rlas 1.6.0 it will only uses 644 bits no matter the number of points loaded for non populated attributes. This applies to each attribute populated with a single repeated value. This allows for saving approximately 30% of memory usage depending on the number of non-populated attributes that are present in the file. rlas 1.6.0 is compatible will all versions of lidR but lidR 4.0.1 introduced some internal optimization, internal fixes and new functions to fully take advantage of rlas 1.6.0. lidR v<= 4.0.0 will work with rlas 1.6.0 but won't take advantage of the new compression feature.
-
the function
LAS()
no longer calldata.table::setDT()
if the input is already adata.table
. Indeeddata.table::setDT()
materializes the compressed ALTREP vectors and this is not what we want. One consequence of this change is thatreadLAS()
now preserve the ALTREPness (i.e. the compression) of the output ofrlas::read.las()
. -
Subsetting a
LAS
object no longer calldata.table
native subset. We previously used something likelas@data[indx]
to subset the point cloud. Sadlydata.table
tries to materialized the ALTREPed vector whenever it can. We implemented internally asmart_subset()
function that subset and preserves the compression of the vectors. One consequence of such change is that allfilter_*()
andclip_*()
functions preserve the compression of the point-cloud if any. -
las_check()
has been slightly modified to ensure it does not materialize ALTREPed object. One side effect oflas_check()
was to decompress the point cloud unexpectedly. Such a pity! We also changelas_check()
to print information about the compression. -
We changed the way
*_metrics()
functions evaluates the user defined expression because we found that it had the side effect of materializing all the attributes instead of materializing only those needed. For examplepixel_metrics(las, mean(Z))
only needs the attribute Z. No need to allocate and copy memory forIntensity
,ScanAngle
and so on. In previous version all attributes where inspected with the side effect to materialize all compressed vectors. The*_metrics()
functions now properly detect which attributes are actually necessary for the evaluation offunc
. Two consequences: (1)*_metrics()
functions are 20 to 40% faster, (2) the compression is preserved if no compressed attribute is used in the evaluation and e.g.pixel_metrics(las, mean(UserData))
uncompresses onlyUserData
. -
New functions
las_is_compressed()
that tells which attributes are compressed andlas_size()
that returns the true size of aLAS
objects taking into account the compression.las_size()
should returns something similar topryr::object_size()
but different toobject.size()
that is not ALTREP aware. We also changed theprint
function so it useslas_size()
instead ofobject.size()
.
On overall lidR's functions are expected to almost never decompress a LAS object. However other R packages and R functions may do it. For example data.table::print
do materializes the ALTREP vectors. base::range()
too but not base::mean()
or base::var()
.
las@data # Full decompression (print data.table)
range(las$Userdata) # Decompression of UserData
las@data[2, UserData := 1] # Decompression of UserData
las@data[1:10] # Full decompression
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 3 years ago

lidR - v4.0.0
lidR v4.0.0 (Release date: 2022-02-17)
rgdal
and rgeos
will be retired on Jan 1st 2024. see twitter, youtube, or see the respective package descriptions on CRAN. Packages raster
and sp
are based on rgdal
/rgeos
and lidR
was based on raster
and sp
because it was created before sf
, terra
and stars
. This means that sooner or later lidR
will run into trouble (actually it is more or less already the case). Consequently, we modernized lidR
by moving to sf
, terra
/stars
and we are no longer depending on sp
and raster
(see also Older R Spatial Package for more insight). It is time for everybody to stop using sp
and raster
and to embrace sf
and stars/terra
.
In version 4 lidR
now no longer uses sp
, it uses sf
and it no longer uses raster
. It is now raster agnostic and works transparently with rasters from raster
, terra
and stars
. These two changes meant we had to rewrite a large portion of the code base, which implies few backward incompatibilities. The backward incompatibilities are very small compared to the huge internal changes we implemented in the foundations of the code and should not even be visible for most users.
Backward inconpatibilites
-
lidR
no longer loadsraster
andsp
. To manipulateRaster*
andSpatial*
objects returned by lidR users need to loadsp
andraster
with:library(sp) library(raster) library(lidR)
-
The formal class
LAS
no longer inherits the classSpatial
fromsp
. It means, among other things, that aLAS
object no longer has a slot@proj4string
with aCRS
fromsp
, or a slot@bbox
. The CRS is now stored in the slot@crs
in acrs
object fromsf
. Former functionscrs()
andprojection()
inherited fromraster
are backward compatible and return aCRS
or aproj4string
fromsp
. However code that accesses these slots manually are no longer valid (but nobody was supposed to do that anyway because it was the purpose of the functionprojection()
):las@proj4string # No longer works las@bbox # No longer works inherits(las, "Spatial") # Now returns FALSE
-
The formal class
LAScatalog
no longer inherits the classSpatialPolygonDataFrame
fromsp
. It means, among other things, that aLAScatalog
object no longer has a slot@proj4string
, or@bbox
, or@polygons
. The slot@data
is preserved and contains ansf,data.frame
instead of adata.frame
allowing backward compatibility of data access to be maintained. The syntaxctg$attribute
is the way to access data, but statement likectg@data$attribute
are backward compatible. However, code that accesses other slots manually is no longer valid, like for theLAS
class:ctg@proj4string # No longer works ctg@bbox # No longer works ctg@polygons # No longer works inherits(ctg, "Spatial") # Now returns FALSE
-
sp::spplot()
no longer works on aLAScatalog
because aLAScatalog
is no longer aSpatialPolygonDataFrame
spplot(ctg, "Max.Z") # becomes plot(ctg["Max.Z"])
-
raster::projection()
no longer works onLAS*
objects because they no longer inheritSpatial
. Moreover,lidR
no longerDepends
onraster
which means thatraster::projection()
andlidR::projection
can mask each other. Users should usest_crs()
preferentially. To useprojection
users can either loadraster
beforelidR
or calllidR::projection()
with the explicit namespace.library(lidR) projection(las) # works library(raster) projection(las) # no longer works
-
Serialized
LAS/LAScatalog
objects (i.e. stored in.rds
or.Rdata
files) saved withlidR v3.x.y
are no longer compatible withlidR v4.x.y
. Indeed, the structure of aLAS/LAScatalog
object is now different mainly because the slot@crs
replaces the slot@proj4string
. Users may get errors when using e.g.readRDS(las.rds)
to load back an R object. However we put safeguards in place so, in practice, it should be backward compatible transparently, and even repaired automatically in some circumstances. Consequently we are not sure it is a backward incompatibility because we handled and fixed all warnings and errors we found. In the worst case it is possible to repair aLAS
object v3 with:las <- LAS(las)
-
track_sensor()
is not backward compatible because it is a very specific function used by probably just 10 people in the world. We chose not to rename it. It now returns ansf
object instead of aSpatialPointsDataFrame
.
New modern functions
Former functions that return Spatial*
objects from package sp
should no longer be used. It is time for everybody to embrace sf
. However, these functions are still in lidR
for backward compatibility. They won't be removed except if package sp
is removed from CRAN. It might happen on Jan 1st 2024, it might happen later. We do not know. New functions return sf
or sfc
objects. Old functions are not documented so new users won't be able to use them.
tree_metrics()
anddelineate_crowns()
are replaced by a single functioncrown_metrics()
that has the same functionality, and more.find_trees()
is replaced bylocate_trees()
.
Older functions that return Raster*
objects from the raster
package should no longer be used. It is time for everybody to embrace terra/stars
. However, these functions are still in lidR
for backward compatibility. They won't be removed except if package raster
is removed from CRAN. New functions return either a Raster*
, a SpatRaster
, or a stars
object, according to user preference.
grid_metrics()
is replaced bypixel_metrics()
grid_terrain()
,grid_canopy()
,grid_density()
are replaced byrasterize_terrain()
,rasterize_canopy()
,rasterize_density()
New features
New functions are mostly convenient features that simplify some workflow aspects without introducing a lot of brand new functionality that did not already exist in lidR
v3.
-
New geometry functions
st_convex_hull()
andst_concave_hull()
that returnsfc
-
New modern functions
st_area()
,st_bbox()
,st_transform()
andst_crs()
inherited fromsf
forLAS*
objects. -
New convenient functions
nrow()
,ncol()
,dim()
,names()
inherited frombase
forLAS*
objects -
New operators
$
,[[
,$<-
and[[<-
onLASheader
. The following are now valid statements:header[["Version Major"]] header[["Z scale factor"]] <- 0.001
-
Operators
$
,[[
,$<-
and[[<-
onLAS
can now access theLASheader
metadata. The following are now valid statements:las[["Version Major"]] las[["Z scale factor"]] <- 0.001
-
RStudio now supports auto completion for operator
$
inLAS
objects. Yay! -
New functions
template_metrics()
,hexagon_metrics()
,polygon_metrics()
that extend the concept of metrics further to any kind of template. -
Functions that used to accept spatial vector or spatial raster as input now consistently accept any of
Spatial*
,sf
,sfc
,Raster*
,SpatRaster
andstars
objects. This includemerge_spatial()
,normalize_intensity()
,normalize_height()
,rasterize_*()
,segment_trees()
,plot_dtm3d()
and several others. We plan to supportSpatVector
in future releases. -
Every function that supports a raster as input now accept an "on-disk" raster from
raster
,terra
andstars
i.e. a raster not loaded in memory. This includes rasterization functions, individual tree segmentation functions,merge_spatial
and others, in particularplot_dtm3d()
andadd_dtm3d()
that now downsample on-disk rasters on-the-fly to display very large DTMs. On-disk rasters were already generally supported in previous versions but not every function was properly optimized to handle such objects. -
All the functions that return a raster (
pixel_metrics()
andrasterize_*()
) are raster agnostic and can return rasters fromraster
,terra
orstars
. They have an argumentpkg = "raster|terra|stars"
to choose. The default isterra
but this can be changed globally using:options(lidR.raster.default = "stars")
-
New function
catalog_map()
that simplifiescatalog_apply()
to a large degree. Yet it is not as versatile ascatalog_apply()
but well suits around 80% of use cases. Applying a user-defined function to a collection of LAS files is now as simple as:my_fun <- function(las, ...) { # do something with the point cloud return(something) } res <- catalog_map(ctg, my_fun, param1 = 2, param2 = 5)
-
Operator
[
onLAS
object has been overloaded to clip a point-cloud using abbox
or asfc
sub <- las[sfc]
-
rasterize_terrain()
accepts ansfc
as argument to force interpolation within a defined area. -
normalize_height()
now always interpolates all points. It is no longer possible to get an error that some points cannot be interpolated. The problem of interpolating the DTM where there is no data is still present but we opted for a nearest neighbour approach with a warning instead of a failure. This prevents the method from failing after hours of computation for special cases somewhere in the file collection. This also means we removed thena.rm
option that is no longer relevant. -
New functions
header()
,payload()
,phb()
,vlr()
,evlr()
to get the corresponding data from aLAS
object. -
New algorithm
shp_hline
andshp_vline
forsegment_shapes()
#499 -
New algorithm
mcc
for ground classification.
Enhancement
-
The bounding box of the CHM computed with
rastertize_canopy()
orgrid_canopy()
is no longer affected by thesubcircle
tweak. See #518. -
readLAS()
can now read two or more files that do not have the same point format (see #508) -
plot()
forLAS
gains argumentspal
,breaks
andnbreaks
similar tosf
. Argumentstrim
andcolorPalette
are deprecated
Fix
- The metric
itot
fromstdmetrics_i
which generates troubles (see #463 #514) is nowdouble
instead ofint
Documentation
- Man pages of
classify_*
,rasterize_*
,*_metrics
,segment_*
andnormalize_*
were grouped. - The pdf version of the manual contains more documentation (more functions) but is 20 pages shorter, meaning that we tidied and cleaned up the documentation.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 3 years ago

lidR - v3.2.2
lidR v3.2.2 (Release date: 2021-10-20)
- Enhance:
grid_*()
functions support aRasterLayer
smaller than the point cloud (#483) - Fix:
las_check()
with aLAScatalog
and withdeep = TRUE
failed with a output file template (#484). - Fix:
readLAS()
no longer reads LAS files on some Windows/Mac machine (#485). It seems it is an issue with CRAN binaries. By releasing 3.2.2 we hope to trigger a new build. - Enhance:
get_range()
and consequentlyrange_correction()
no longer throw high range error for highly variable range sensor like TLS (#490).
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 3 years ago

lidR - v3.2.0
lidR v3.2.0 (Release date: 2021-09-26)
ANNOUCEMENT
rgdal
and rgeos
will be retired on Jan 1st 2024. raster
and sp
are based on rgdal
/rgeos
. lidR
is based on raster
and sp
because it was created before sf
, terra
and stars
. This means that sooner or later lidR
will run into trouble (actually it has already started to be the case). So, it is time to fully embrace sf
, terra
/stars
and to leave sp
and raster
. This will require an in-depth rebase of lidR
. We have started the work and we plan to release lidR
4.0.0 that will no longer have any internal code that uses sp
and raster
. This version already no longer uses rgdal
. We hope make these changes with minimal breakage in backward compatibility by maintaining the conversion to sp
/raster
for functions from v < 4.0.0, but some backward incompatibilities will necessarily arise. In particular, LAS
will no longer inherit the sp::Spatial
class and will no longer contain a sp::CRS
but a sf::crs
and LAScatalog
will no longer be sp::SpatialPolygonDataFrame
. Our plan is (hopefully) to rebase lidR
in such a way that nobody will notice the changes expect users who dig a little deeper into the objects.
CHANGES
-
hexbin_metrics()
was an unused function and has been removed fromlidR
. It can be retrieved inlidRplugins
-
Functions using the former namespace such as
lassomething()
that were renamed intoverb_noun()
in version 3.0.0 now throw a warning. In v3.0.0 they were still usable for backward compatibility but not documented. In v3.1.0 they printed a message saying to move on to the new namespace. Now in 3.2.0 they throw a formal warning saying to move on to the new namespace. They will throw an error in the next version.
NEW FEATURES
-
classify_poi()
. New function capable of attributing a class of choice to any points that meet a logical criterion (e.g. Z > 2) and/or a spatial criterion (e.g. inside a polygon). For example, the following will attribute the class "high vegetation" to each non-ground point that is not in the lake polygon.las <- classify_poi(las, LASHIGHVEGETATION, poi = ~Classification != 2, roi = lakes, inverse = TRUE)
-
LAScatalog
- New function
rbind()
forLAScatalog
. - New functions
projection()<-
andcrs()<-
forLAScatalog
. Those two functions were already working in previous versions but in absence of dedicated functions in lidR the functions that were actually called wereraster::projection()
andraster::crs()
thanks to class inheritance. However the functions fromraster
do not supportcrs
fromsf
or numbers as input. Adding a dedicated function in lidR brings consistency betweenLAS
andLAScatalog
(#405):projection(ctg) <- st_crs(3625) # or projection(ctg) <- 3625
- The processing engine has a new option to drop some chunks under
ctg@chunk_options$drop
. This generates regions that won't be processed. This option accepts a vector of chunk IDs that are dropped and is thus versatile, but its main role is to allow restarting a computation that failed. We consequently introduced the functionopt_restart()
. Let's assume that the computation failed after few hours at 80% in chunk number 800. Users get a partial output for the first 799 chunks but chunk 800 has a problem that can be solved. It is now possible to restart at 800 and get the second part of the output without restarting from 0:output <- catlog_apply(ctg, myfun, param) # Failed after 80%, 'output' contains a partial output # Fix the trouble opt_restart(ctg) <- 800 output2 <- catlog_apply(ctg, myfun, param) # Merge 'output' and 'output2'
- The vignette
LAScatalog engine
and the manualLAScatalog-class
were updated to reflect these features
- New function
-
LASheader
- The function
LASheader()
can now create aLASheader
object from adata.frame
. This addition aims to facilitate the creation of validLAS
objects from external data. las_check()
can now check a standaloneLASheader
las_check(las@header)
- The function
-
LAS
- The function
LAS
now automatically fixes the font case of attributes names to match the naming convention of therlas
package. This simplifies the creation of compatible objects from non-LAS file sources.data <- data.frame(x = runif(10), Y = runif(10), z = runif(10), pointsourceid = 1:10) las <- LAS(data) #> Attribute 'x' renamed 'X' to match with default attribute names. #> Attribute 'z' renamed 'Z' to match with default attribute names. #> Attribute 'pointsourceid' renamed 'PointSourceID' to match with default attribute names. las$PointSourceID #> [1] 1 2 3 4 5 6 7 8 9 10
- The function
-
Full waveform: with most recent versions of the
rlas
package, full waveform (FWF) can be read andlidR
provides some compatible functions. However the support of FWF is still a work in progress in therlas
package. How it is read, interpreted and represented in R may change. Consequently, tools provided bylidR
may also change until the support of FWF becomes mature and stable inrlas
.- New function
interpret_waveform()
to transform waveform into a regular point cloud - New supported flag
W
for parameterselect
inreadLAS()
- New automatic colouring scheme for attribute
Amplitude
inplot(las, color = "Amplitude")
that aims to be used with FWF.
- New function
-
catalog_intersect()
now supportssf
,sfc
,Extent
andbbox
objects -
Concave hull: lidR now includes its own C++ code to compute concave hulls using concaveman-cpp.
- New function
concaveman()
to compute concave hulls delineate_crowns()
using concave hulls is now between 10 to 50 times faster.LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR") las = readLAS(LASfile, select = "xyz0") concave_hulls <- delineate_crowns(las, "concave") # Before v3.2.0: 7.1 seconds # From v3.2.0 : 0.2 seconds
grid_terrain()
withis_concave = TRUE
should also be faster.
- New function
-
New function
catalog_boundary()
to compute the actual shape of the point-cloud -
In
find_trees()
andsegment_trees()
thebitmerge
strategy to generate robust unique IDs was not actually a valid and robust procedure. It had the advantage of generating integers but was not 100% unique. The probability to generate duplicates was low but we changed the strategy to use a true bit-merging procedure anyway. The new IDs thus generated are weird decimal number such as 5.001120e-310 but are guaranteed to be unique. The documentation has been updated to explain the method. -
New algorithm
random_per_voxel()
fordecimate_points
that keep n points per voxel (#406). -
3D rendering:
plot()
gains a new parametervoxels = TRUE
orvoxels = 0.5
to render a point cloud with voxels. This is useful to render the output ofvoxelize_points()
orvoxel_metrics()
, for example. This is computationally demanding and takes time so it should be reserved to small scenes with 30,000 or 40,000 voxels maximum, but note that there is no hard coded limit.vm <- voxel_metrics(las, ~list(N = length(Z)), 8) plot(vm, color = "V1", voxels = T)
- specular reflections are now disable in
plot()
.
-
New function
plot_metrics()
that wraps several other functions into one seamless function that extracts ground inventory plots, computes metrics for each plot and returns a ready to usedata.frame
for statistical modelling. -
New function
point_eigenvalue()
that is equivalent topoint_metrics(las, .stdshapemetrics)
but specialized, optimized and parallelized to be 10 times faster. -
grid_metrics()
gains a new parametersby_echo
allowing users to compute the metrics for different types of echos independently. It is now possible to map e.g.mean(Intensity)
for first returns only + multiple return only + single return only. All metrics are computed in a single run and returned in a raster stack. -
merge_spatial()
supportssfc
ENHANCEMENTS
grid_density()
is 10 times faster
FIXES
- Fix:
quantize()
now preservesNaN
values instead of converting them into minus infinity (#460). - Fix:
stdmetrics_i()
now fails with an informative message when the sum of intensities is greater than.Machine$integer.max
and becomesdouble
(#463) - Fix:
find_localmaxima()
respects thefilter
argument. It was previously not considered.
MISCELLANEOUS
- Remove
crayon
andhexbin
dependencies - Packages
RCSF
andrgeos
are now only suggested and they are consequently no longer installed by default with lidR - Change:
rgdal
will be retired in 2024. Code usingrgdal
internally has been removed. In many cases this will not change anything for users but in some cases it may fail when assigning an EPSG code to the LAS file. Also, old versions ofrgdal
built with old versions ofgdal
andproj
are no longer supported (#466)
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 3 years ago

lidR - v3.1.4
lidR v3.1.4 (Release date: 2021-06-22)
- Change:
manual()
now uses the middle button to perform the selection. Historically the button was "right" but later the right button was added in lidR and attributed to the dragging action. By using "right" in this function this disabled the possibility to drag the scene. Consequently we changed the default to use the middle button. (#442). - Change:
manual()
now removes all apices in the selection rectangle when removing some false positive (#445). - Doc: fix some code block rendering in
catalog_apply
man page - Fix: fix catalog processing engine edge case when the last chunks fail (#435).
- Fix:
voxel_metrics()
withall_voxels = TRUE
did not work as expected. The insertion of empty voxels corrupted some of the real voxels. This bug lead to invalid output and some floating points precision errors lead to supernumerary voxels (#437, #439). - Fix:
grid_terrain()
used with aLAScatalog
no longer propagated the options. For example when usinguse_class = c(2L, 8L, 9L, 10L)
this was not propagated and the option was actually the default one i.e.use_class = c(2L, 9L)
. This bug was introduced in 3.1.0 - Fix:
delineate_crowns()
now returnsNULL
if the input point-cloud has only points with treeID = NA. It also triggers a warning. (#438). - Fix:
manual()
the function that allow for finding the trees manually was no longer working probably because of some slight modifications in thergl
package. - Enhance: the
plot
function used to display the output ofvoxel_metrics()
now internally uses the same function thanLAS
objects. This enhances the rendering using theclear_artifact
option by default and allows for a lot more flexibility in the rendering. - Enhance: new parameter
button
inmanual()
to choose which button to use. - Enhance:
segment_trees()
now print a message if all points areNA
to suggest to use other parameters
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 4 years ago

lidR - v3.1.3
lidR v3.1.3 (Release date: 2021-05-20)
- Fix:
las_check(..., deep = TRUE)
was not working in parallel (#411). - Fix: the LAScatalog processing engine printed the outputs twice for rare functions that print something like
las_check()
(#414) - Fix: the internal way lidR is checking for nested parallelism has been reworked in depth fixing some bugs and allowing to support more strategies thanks to @Lenostatos (#418, #421)
- Fix:
merge_spatial()
did not work withsf
objects. - New:
las_check()
introduces a new type of message called "message". Some message previously classified as "warning" are now classified as "message". Warnings are now displayed in orange and messages in yellow. The output oflas_check()
has now 3 items instead of 2. - New:
stdmetrics_z
gains a new parameterzmin = 0
to control the lower bound of the integration for metricszpcumx
(#424). - Enhance:
max_cr_factor
insilva2019()
is now allowed to be in [0, inf[ instead of [0,1] (#417) - Enhance: added a workaround to avoid
sp
printingproj_create: crs not found
for non recognized EPSG codes and avoid throwing warningDiscarded datum [...] in Proj4 definition
- Enhance:
readLAScatalog()
throws a more informative error when attempting to read an non-existing folder. - Enhance:
readXXXLAS()
now throws an error forLAScluster
(#430). - Doc: Updates and clarifications in the doc of
stdmetrics
. - Misc: removed
LazyData
inDESCRIPTION
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 4 years ago

lidR - v3.1.2
lidR v3.1.2 (Release date: 2021-03-11)
- New: the class
LASheader
has a new slot@EVLR
for the extended variable length records.print()
has been extended to display EVLR. While this change is compatible withrlas <= 1.3.9
it is only used with version ofrlas >= 1.4.0
. - New: algorithm
lowest()
fordecimate_points()
- Fix: usban outside the range of representable values of type 'char' for spatial indexes built with 0 point.
- Fix: build failure with GCC 4.x
- Fix:
catalog_apply()
now works with cluster planplan(cluster)
meaning that it can be used on HPC e.g. with MDPI. We took advantage of this bug to better detect the parallel strategy used and disable or not OpenMP. WhenlidR
is not able to figure out if the strategy involves multiple machines or multiple cores of a single machine, then a warning is thrown and OpenMP is disabled by security.The parallel evaluation strategy was no recognized and lidR does not know if OpenMP should be disabled. OpenMP has been disabled by security. Use options(lidR.check.nested.parallelism = FALSE) and set_lidr_threads() for a fine control of parallelism.
- Fix: incorrect offset computation in
spTransform()
have for consequences to make the function failing with error:Non quantizable value outside the range of representable values of type 'int'
. - Fix: attribution of a WKT string with
projection()
when using an epsg code as input (projection(las) <- 12345
). - Fix: partial processing mode now respects the raster alignment when processed by file
- Fix:
readLAScatalog()
now reads the WKT CRS of LAS files format 1.4. To support both EPSG and WKT the table of attribute of aLAScatalog
now has a column namedCRS
that replace former columnEPSG
. - Fix:
print()
for aLAScatalog
now prints the CRS exactly likeprint
forLAS
. - Doc: documentation of
options(lidR.check.nested.parallelism = FALSE)
was missing. Information can now be found in?lidR-package
and?lidR-parallelism
- Enhance: in
catalog_apply()
iflidR.check.nested.parallelism = FALSE
it now respects the input ofset_lidr_thread()
instead of the output ofget_lidr_threads()
. For example ifset_lidr_thread(0)
it now propagates the information 0 (all cores) instead of the output ofget_lidr_thread()
which might be e.g. 4 on the master worker but might be different on the slave workers. Similarlyset_lidr_thread(20)
will request 20 cores to the workers even ifget_lidr_thread()
returns 4 on the local machine. - Enhance:
set_lidr_thread()
accepts inputs < 1 such as 0.5 or 0.25 to mean 'half' or 'quarter' of available cores. - Enhance:
grid_density()
now returns 0 for pixels with 0 points instead ofNA
which make more sense and corresponds to what should be expected.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 4 years ago

lidR - v3.1.1
lidR v3.1.1 (Release date: 2021-01-22)
- Fix usban issue: outside the range of representable values of type 'int' for spatial indexes built with 0 point.
- Fix usban issue: outside the range of representable values of type 'int' when quantizing or counting non quantized values that are not quantizable according the the given scale and offset.
- Remove lax files in example data.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 4 years ago

lidR - 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)
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 4 years ago

lidR - v3.0.4
lidR v3.0.4 (Release date: 2020-10-08)
- Fix: in
readLAScatalog()
the documentation states that...
is propagated tolist.files()
, but the argumentpattern
was actually hard coded internally and this prevents it being overwritten. When usingreadLAScatalog(..., pattern = "xxx")
this previously triggered an error,formal argument "pattern" matched by multiple actual arguments
. It now works. See #368. - Fix: in
spTransform()
the reprojected point cloud now has quantized coordinates and is thus LAS compliant #369. - Fix: The local maximum filter algorithm more robustly finds local maxima when two or more close points or pixels share the exact same height and are both locally the highest. Previously, if two or more points in a close neighbourhood were both the highest, they may all be missed depending on the order they were processed (which is somewhat random). The fix allows users to retain one local maximum among multiple ones with a precedence to the first one identified as local maximum. The consequences of this fix are that slightly more apices may be found, especially when processing a CHM in
RasterLayer
. - Fix:
classify_ground()
no longer erases the previous classification when no ground points were recorded but some points are classified with other classes. - Fix #365. Poor interpolation at the very edge of the Delaunay triangulation in some cases. Triangles with too steep a slope are now removed. This triggers a knnidw interpolation instead.
- Fix #371:
las_reoffset()
may not have caught extremely rare Z coordinate overflow when converting to integers. - Fix #372.
las_reoffset()
incorrectly converted decimal coordinates to integers usingtrunc
instead ofround
. - Fix:
projection<-()
andcrs<-()
properly attributesNA
CRS for LAS 1.4 objects - Change: in
print
the CRS ofLAS
andLAScatalog
is no longer displayed as a proj4 string but uses the WTK string withsf
style display. E.g.NAD83 / UTM zone 17N
is displayed instead of+proj=utm +zone=17 +datum=NAD83 +units=m +no_defs
. This is part of the migration toward WTK instead of proj4. - Change:
lidR
now explicitly depends onrgdal >= 1.5.8
. - Change:
grid_canopy()
now rounds the values of the pixels for not outputing pixels that with an irrelevant number of decimal digits. - Enhance:
epsg()
now throws a warning if the LAS is in format 1.4 and CRS is stored as WKT. - New:
projection()<-
supportscrs
fromsf
and numeric values for espg code:projection(las) <- 26918
. - New: in
spTransform()
it is now possible to use a parameterscale
to change the scale factor after reprojection. This is useful for projecting from lon-lat datalas2 = spTransform(las, crs, scale = 0.01)
. - Internal: better support in
projection<-
of the current changes with CRS representation in the R spatial ecosystem. - Doc: new CITATION file.
citation("lidR")
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 4 years ago

lidR - v3.0.3
lidR v3.0.3 (Release date: 2020-08-05)
- New:
tin()
gains a parameterextrapolate
to control how the method treats interpolation of points outside the convex hull determined by ground points. This solves #356 - Doc: supported processing options in
grid_terrain()
were incorrect especially the buffer that is required. - Doc: in
Wing2015()
the mention about weak performance was removed since it was not longer true for a while. - Doc: clarification of the supported templates in man page named
clip
- Enhance: a more informative error is thrown when using
{ORIGINALFILENAME}
as a template inclip_*()
. - Misc: fix C++ error that will happen in next version of
Rcpp
ahead of the release ofRcpp
. Thanks to @waltersom in #358
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 4 years ago

lidR - v3.0.2
lidR v3.0.2 (Release date: 2020-06-30)
- Fix: in
grid_metrics()
andgrid_canopy()
when processing aLAScatalog
the option to process by files without buffer and disabling the wall-to-wall guarantees (processing independant filles) is now repected. See also. - Fix: in
grid_metrics()
NA pixels were zeroed. They are now properly initialized to NA.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 5 years ago

lidR - v3.0.1
lidR v3.0.1 (Release date: 2020-06-19)
- Fix: in
grid_terrain()
andnormalize_height()
we introduced few releases ago an optionuse_class
but we did not removed an internal test consisting in failling in absance of point classified 2. This invalidated the possibility to use e.g.use_class = 1
in files that do not respect ASPRS standards #350. - Fix: many troubles introduced in v3.0.0 on CRAN
- Fix: package explicitly depends on sp >= 1.4.2
- Fix:
readLAS(filter = "-help")
was not working but was suggested in the documentation.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 5 years ago

lidR - v3.0.0
lidR v3.0.0 (Release date: 2020-06-08)
MAJOR CHANGES
Summary
In lidR version 3.0.0, 80% of the functions were renamed. Old functions were soft-deprecated, meaning that they still exist so version 3 is fully compatible with version 2, at least for 1 year. Users should start to use the new names. See ?lidR::deprecated
for the list of deprecated functions and their new names. The plan is to remove these functions in 1 year so they will progressively print a message, then throw a warning, then throw an error, after which they will be definitively removed.
Full explanation
At the very beginning of the development of lidR we started to name the functions that return a LAS object lassomething()
. At that point there were 5 functions and ~10 users. As lidR grew up, we kept going with this naming convention but now lidR is used worldwide and this naming convention now overlaps with the LAStools software suite created by Martin Isenburg. This creates confusion for users which is problematic both for Martin and for us. This situation is likely to get worse as more tools are released into LAStools. We discussed the issue with Martin Isenburg and we took the decision to rename the functions in the lidR package so that the overlaps in namespace will progressively disappear.
The new naming convention follows the currently trending verb_noun
syntax initiated by the tidyverse
. For example, lasnormalize()
becomes normalize_height()
, while lasground()
becomes classify_ground()
. The full list of changes can be found in ?lidR::deprecated
.
In efforts to avoid breaking users' scripts version 3 is fully backwards-compatible. For example, the function lasground()
still exists and can be used without throwing a warning or error message. But this will progressively change with versions 3.1.0, 3.2.0 and 3.3.0. First a message will be displayed to invite users to change to using the new names, then a warning, then finally an error. After a year, maybe 18 months, the function will no longer exist. So users are invited to adopt the new naming convention as soon as possible.
NEW FEATURES
-
readLAScatalog()
has new parameters to tune the processing options at read time without using the functionsopt_*()
.readLAScatalog("folder/", chunk_buffer = 60, filter = "-drop_z_below 2")
-
New function
clip_transect()
to extract a transect between two points. The function has the capability to reorient the point cloud to put it on XZ coordinates and easily create some 2D rendering of the transects in e.g.ggplot2.
-
New function
readMSLAS()
to read multisprectral data from 3 different files.readMSLAS("channel1.las", "channel2.las", "channel3.las", filter = "-keep_first")
-
delineate_crowns()
(formerly namedtree_hulls()
) now returns 3 metrics:XTOP
,YTOP
andZTOP
, that contain the coordinates of the apices of the trees. -
segment_trees()
(formerly namedlastrees()
) andfind_trees()
(formerlytree_detection()
) can now perform the computation on aLAScatalog
using two strategies to ensure that tree IDs are always unique on a coverage and that trees that belong on the edge of two tiles will independently get the same IDs. -
point_metrics()
- supports a knn neighborhood search with missing
r
and givenk
- supports a spherical neighborhood search with missing
k
and givenr
- supports a knn neighborhood + a radius limit with
k
andr
given - default setting is now
xyz = FALSE
- if
xyz = FALSE
the the output now contains a column (the first one) namedpointID
that references the point of the original las object. See #325
- supports a knn neighborhood search with missing
-
normalize_height()
(formerly namedlasnormalize()
)- new argument
add_lasattribute
. IfTRUE
the absolute elevation (above sea level) is retained as before, but the header is updated so the absolute elevation becomes an extrabyte attribute writable on a las file. Otherwise the information is discarded at write time. - new argument
Wdegenerated
. IfFALSE
the function does not warn about degenerated points. Degenerated points are removed anyway.
- new argument
-
New function
find_localmaxima()
to find local maxima with different windows. This function is designed for programming purposes, not to find individual trees. This latter task is still performed byfind_trees()
(formerly calledtree_detection()
). Instead,find_localmaxima()
may help with finding other human-made structures. -
Internal global variables were exported to help with ASPRS LAS classification standard. Instead of remembering the classification table of the specification it is now possible to use one of
LASNONCLASSIFIED
,LASUNCLASSIFIED
,LASGROUND
,LASLOWVEGETATION
,LASMEDIUMVEGETATION
,LASHIGHVEGETATION
,LASBUILDING
,LASLOWPOINT
,LASKEYPOINT
,LASWATER
,LASRAIL
,LASROADSURFACE
,LASWIREGUARD
,LASWIRECONDUCTOR
,LASTRANSMISSIONTOWER
,LASBRIGDE
,LASNOISE
. e.g.:filter_poi(las, !Classification %in% c(LASWIRECONDUCTOR, LASTRANSMISSIONTOWER))
-
The internal function
catalog_makechunks()
has been exported. It is not actually intended to be used by regular users but might be useful in some specifc cases for debugging purposes. -
lasmetrics()
,grid_metrics3d()
,grid_hexametrics()
were deprecated in previous versions. They are now defunct. -
las_check()
(formerly namedlascheck()
):- gains an option
print = FALSE
. - now returns a
list
for further automatic processing/parsing. Ifprint = TRUE
the list is returned invisibly so the former behavior looks the same.
las_check(las, FALSE) #> $warnings #> [1] "1 points are duplicated and share XYZ coordinates with other points" #> [2] "There were 1 degenerated ground points. Some X Y Z coordinates were repeated." #> [3] "There were 1 degenerated ground points. Some X Y coordinates were repeated but with different Z coordinates." #> #> $errors #> [1] "Invalid header: X scale factors should be factor ten of 0.1 or 0.5 or 0.25 not 0.123" #> [2] "Invalid file: the data contains a 'gpstime' attribute but point data format is not set to 1, 3, 6, 7 or 8."
- gains an option
deep = TRUE
with aLAScatalog
only. In this case it performs a deep inspection of each file reading each point cloud. - the coordinates of the points are expected to be given with a resolution e.g. 0.01 meaning a centimetre accuracy. It means we are expecting values like 12345.67 and not like 12345.6712. This is always the case when read from a LAS file but users (or lidR itself) may transform the point cloud and generate LAS objects where this rule is no longer respected.
lidR
always ensures to returnLAS
objects that are stricly valid with respect to ASPRS standard. If not valid this may lead to failure inlidR
because some functions, such astin()
,dsmtin()
,pitfree()
work with the integer representation of the coordinates. This is why we introduced a quantization check inlas_check()
. - now reports problems for invalid data reported in #327
- gains an option
-
merge_spatial()
(formerly namedlasmergespatial()
) now supportssf
POLYGON objects. -
plot()
- for LAS object gains an argument
add
to overprint two point clouds with e.g. different color palettes #325.
las = readLAS("classified.las") nonveg = filter_poi(las, Classification != LASHIGHVEGETATION) veg = filter_poi(las, Classification == LASHIGHVEGETATION) x = plot(nonveg, color = "Classification") plot(veg, add = x)
- for LAScatalog objects gains an argument
overlaps = TRUE
to highlight the overlaps.
- for LAS object gains an argument
-
New function
add_lasrgb()
to add RGB attributes. The function updates the header in such a way that the LAS object has a valid point format that supports RGB. -
LAScatalog
processing engine- gains a generic option
opt_merge(ctg) <- FALSE
to disable final merging and force the engine to return a list - gains a generic option
opt_independent_files(ctg) <- TRUE
to set adequate options to a collection of independent files, for example a set of circular ground inventory plots. It is equivalent to set no buffer, processing by file and no wall-to-wall guarantee. - gains an option
autoread = TRUE
incatalog_apply()
. Not actually intended to be used widely but might be convenient for some use cases.
- gains a generic option
-
New function
get_range()
. -
knnidw()
gains an argumentrmax
to set a maximum radius search in which to find the knn. This fixes computation time issues with non-convex point clouds. -
track_sensor()
(formerlysensor_tracking()
)- now has two available algorithms.
- supports systems with multiple pulses emission which formerly failed
-
writeLAS()
gains a parameterindex = TRUE
to automatically write a lax file along with the las/laz file.
ENHANCEMENTS
-
readLAS()
now warns when reading incompatible files. Point coordinates are recomputed on-the-fly as it has always been done but now the user is aware of potential problems or precision loss. -
A new vignette named LAScatalog processing engine has been added and documents in-depth the
catalog_apply()
engine of lidR. -
In
clip_*()
several lines of codes were removed because they were not used. We suspected these lines covered old cases from lidR v1.x.y that are no longer relevant. If a user encounters problems, please report. -
The arguments
select
andfilter
fromreadLAS()
are not expected to be used with aLAScluster
when processing aLAScatalog
. The options are carried by theLAScatalog
itself withopt_select()
andopt_filter()
. If used, a warning is now thrown. -
Enhancements made here and there to improve the support of the CRS when reading and checking a LAS file.
-
When processing by file with a raster output, automatic chunk extension to match with a raster resolution now performs a tighter extension.
-
Minor modification of
print()
methods to enhance information displayed. -
All algorithms such as
tin()
,p2r()
,knnidw()
,li2012()
, and so on, now have the classesc("lidRAlgorithm", "something")
and a dedicated print function. The source code is no longer displayed when printing these objectsf = lmf(2) f #> Object of class lidR algorithm #> Algorithm for: individual tree detection #> Designed to be used with: find_trees #> Native C++ parallelization: yes #> Parameters: #> - circ = TRUE <logical> #> - hmin = 2 <numeric> #> - shape = circular <character> #> - ws = 2 <numeric>
-
In
grid_metrics()
theRasterBrick
is built much faster.
FIXES
-
In
delineate_crowns()
, formerly namedtree_hull()
, when applied to aLAScatalog
the buffer was not properly removed. The polygons were simply clipped using the bounding box of the chunk. Now the trees that have an apex in the buffer are removed and the trees that have an apex outside the buffer are retained. Thus, when merging, everything is smooth and continuous. -
catalog_retile()
returns aLAScatalog
with only the newly created files even if the folder contains other las files. It formerly read every las file in the folder leading to an invalid catalog if the folder already contained las files. -
Previously in automatic filename generation the template
YCENTER
was not actually recognized. However,XCENTER
was recognized but actually contained the value forYCENTER
. This was working forlasclip()
thanks to a previous fix but was still a problem in other functions when processing chunks. -
Function
wkt()
no longer masks the new functionwkt()
insp
. -
merge_spatial()
(formerly namedlasmergespatial()
) no longer fails with a LAS object containing a single point.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 5 years ago

lidR - v2.2.4
lidR v2.2.4 (Release date: 2020-04-24)
FIXES
-
Fix segfault on Windows 64 bits when constructing a proj4 from some specific modern WTK strings using
doCheckCRSArgs = FALSE
. #323 sp #75 -
Fix wrong gpstime matching in
lasrangecorrection()
at the edge of flightlines #327. -
Fix error when building the clusters with a partial processing and a realignment #332.
-
Fix error in
lasclip()
andlasmergespatial()
withsf
objects when the coordinates are not stored in a column namedgeometry
. Thank to Michael Koontz in #335. -
lasrangecorrection()
no longer mess-up the original sensor data. See #336
ENHANCEMENTS
-
Enhancements made here and there to improve the support of the CRS when reading and checking a LAS file.
-
crs not found
message is no longer displayed when building a LAS object. This message appeared with an update ofrgdal
orsp
. It is now gone. -
sensor_tracking()
now throws an error for the invalid case reported in #327 -
lascheck()
now reports trouble for invalid data reported in #327 -
grid_metrics()
returns a raster full of NAs instead of failing if aRasterLayer
is given as a layout but this layer does not encompase the point cloud -
opt_output_file()
now applies tilde-expansion to the path. -
When processing by file with an raster output, automatic chunk extension to match with a raster resolution now perform a tighter extension.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 5 years ago

lidR - v2.2.3
lidR v2.2.3
FIXES
-
This fix breaks backward compatibility. In
catalog_apply()
ifautomerge = TRUE
and the output contains alist
of strings the list was expected to be merged into a character vector. But actually, the raw list was returned, which was not the intended behavior. This appends withSpatial*
andsf
objects and withdata.frame
. This bug should not have affected too many people.opt_output_files(ctg) <- paste0(tempdir(), "/{ORIGINALFILENAME}") option <- list(automerge = TRUE) ret <- catalog_apply(ctg, sptest, .options = option) # now returns a vector print(ret) #> "/tmp/RtmpV4CQll/file38f1.txt" "/tmp/RtmpV4CQll/file38g.txt" "/tmp/RtmpV4CQll/file38h.txt" "/tmp/RtmpV4CQll/file38i.txt"
-
When using a
grid_*
function with aRasterLayer
used as layout, if the layout was not empty or full of NAs, the values of the layout were transferred to the NA cells of the output #318. -
lascheck()
no longer warns about "proj4string found but no CRS in the header". This was a false positive. Overall, CRS are better checked.
ENHANCEMENTS
-
opt_output_files()
now prints a message when using theORIGINALFILENAME
template with a chunk size that is not 0 to inform users that it does not make sense.opt_chunk_size(ctg) <- 800 opt_output_files(ctg) <- "{ORIGINALFILENAME}" #> ORIGINALFILENAME template has been used but the chunk size is not 0. This template makes sense only when processing by file.
-
Internally when building the chunks an informative error is now thrown when using the
ORIGINALFILENAME
template with a chunk size that is not 0 to inform users that it does not make sense instead of the former uninformative error,Error in eval(parse(text = text, keep.source = FALSE), envir) : objet 'ORIGINALFILENAME' not found
.#> Erreur : The template {ORIGINALFILENAME} makes sense only when processing by file (chunk size = 0). It is undefined otherwise.
-
When using a "by file" processing strategy + a buffer around each file, up to 9 files may be read. Internally the chunks (
LAScluster
) are now built in such a way that the first file read is the main one (and not one of the "buffer file"). This way, if the 9 files do not have the same scales and the same offsets, the main file has precedence over the other ones when rescaling and re-offsetting on-the-fly. This reduces the risk of incompatibilities and preserves the original pattern when processing a LAScatalog. -
grid_metrics()
now constructs aRasterBrick
in a better way and this reduces the risk of bugs with users' functions that sometimes return 0 length objects. TheRasterBrick
will now be properly filled withNAs
. -
lascheck()
now reports information if some points are flagged 'withheld', 'synthetic' or 'keypoint'. -
We moved the internal logic of chunk realignment with a raster from
catalog_apply()
to the internal functioncatalog_makecluster()
. This simplifies the source code, make it easier to maintain and test and will enable us to provide access, at the user level, to more internal functions in future releases.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 5 years ago

lidR - v2.2.2
lidR v2.2.2
FIXES
-
We introduced a bug in v2.2.0 in the catalog processing engine. Empty chunks triggered and error
i[1] is 1 which is out of range [1,nrow=0]
internally. It now works again. -
Fix heap-buffer-overflow in
lasrangecorrection()
when throwing an error about invalid range.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - v2.2.1
lidR v2.2.1
BREAKING CHANGE
-
imager
was used to drive themcwatershed()
algorithm.imager
is an orphaned package that generated a warning on CRAN. Consequentlymcwatershed()
has been removed. In attempt to provide an informative message to users, the function still exists but generates an error. Anyway this method was weak and buggy and it was a good reason to remove it... -
In version 2.2.0 we missed to put the parameter
r
inpoint_metrics()
. It is not yet supported but will be.
NEW FEATURES
- LAScatalog processing engine:
- In
catalog_apply()
the optionsautomerge
now supports automerging ofsf
anddata.frame
objects. - New function
catalog_sapply()
strictly equivalent tocatalog_apply()
but with the optionautomerge = TRUE
enforced to simplify the output whenever it is possible.
- In
ENHANCEMENTS
-
In the catalog processing engine, the graphical progression map is now able to plot the actual shape of the chunks. In the case of
lasclip
it means that discs and polygons are displayed instead of bounding boxes. -
Multi-layers VRTs are returned as
RasterBrick
instead ofRasterStack
for consistency with in memory raster that are returns asRasterBrick
. -
grid_
functions now try to preserve the layer names when returning a VRT built from files written on disk. This works only with file formats that support to store layer name (e.g. notGTiff
). -
There are now more than 900 unit tests for a coverage of 91%.
FIXES
-
Fix access to not mapped memory in one unit test (consequentless for users).
-
In
lasclip()
the templateXCENTER
actually gave the Y coordinate. It is now the correct X coordinate of the center of the clipped region. -
In
lasclip()
the templateYCENTER
was not actually defined. It is now the correct Y coordinate of the center of the clipped region. -
Fix heap-buffer-overflow in
lasrangecorrection()
. The range was likely to be badly computed for points that have a gpstime later than the last sensor position
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - v2.2.0
lidR v2.2.0 (Release date: 2020-01-06)
NEW FEATURES
-
LAScatalog processing engine:
-
catalog_apply()
gains an optionautomerge = TRUE
.catalog_apply()
used to return alist
that had to be merged by the user. This new option allows for automatic merging. This is a fail-safe feature. In the worst case, if the user-defined function returns a non-supported list of objects that cannot be merged it falls back to the former behavior i.e. it returns alist
. Thus there is no risk associated with adding the optionautomerge = TRUE
but by defaut it is set toFALSE
for retrocompatibility. This might be switched toTRUE
in future releases. -
opt_output_file()
now interprets*
as{ORIGINALFILENAME}
for shorter syntax. The following is now accepted:
opt_output_file(ctg) <- "/home/user/data/norm/*_norm" # {*} is valid as well # instead of opt_output_file(ctg) <- "/home/user/data/norm/{ORIGINALFILENAME}_norm"
- The engine now supports "alternative directories". This is a very specific and undocumented feature useful in a single case of remote computing. More details on the wiki page.
ctg = readLAScatalog("~/folder/LASfiles/") ctg@input_options$alt_dir = c("/home/Alice/data/", "/home/Bob/remote/project1/data/")
- LAScatalog modification constraints are now relaxed. It is now possible to add or modify an attribute if this attribute has a name that is not reserved.
ctg$newattr <- 1 # is now allowed ctg$GUID <- TRUE # is still forbidden #> Erreur : LAScatalog data read from standard files cannot be modified
- The engine supports partial processing. It is possible to flag some files that will, or will not, be processed. These files are not removed from the LAScatalog. They are used to load a buffer, if required, for the files that are actually processed. To activate this option a new boolean attribute named
processed
can be added in the catalog.
ctg$processed <- TRUE ctg$processed[3:5] <- FALSE
-
-
3D rendering:
- The argument
colorPalette
of the functionplot()
forLAS
objects is now set to"auto"
by default. This allows for this argument to not be specified even when plotting an attribute other than Z, and having an appropriate color palette by default. More interestingly, it will automatically apply a nice color scheme to the point cloud with the attribute 'Classification' following the ASPRS specifications. See #275.
plot(las) plot(las, color = "Intensity") plot(las, color = "ReturnNumber") plot(las, color = "Classification")
- In
plot.lasmetrics3d()
the parametertrim
is now set toInf
by default.
- The argument
-
New function
point_metrics()
- very similar togrid_metrics()
but at the point level. The 'metrics' family is now complete.cloud_metrics()
computes user-defined metrics at the point cloud level.grid_metrics()
andhexbin_metrics()
compute user-defined metrics at the pixel level.voxel_metrics
computes user-defined metrics at the voxel level.point_metrics()
computes user-defined metrics at the point level. -
lasnormalize()
:- Gains an argument
use_class
to control the points used as ground. - By default 'ground point' now includes points classified as water by default. This might be useful in regions with a lot of water because in this case
lasnormalize()
can take forever to run (see #295)).
- Gains an argument
-
New function
sensor_tracking()
to retrieve the position of the sensor in the sky. -
New function
lasrangecorrection()
to normalize intensity using the sensor position (range correction) -
catalog_select
now also allows files to process to be flagged interactively:ctg <- catalog_select(ctg, method = "flag_processed") ctg <- catalog_select(ctg, method = "flag_unprocessed")
-
grid_terrain()
- Have a new argument
use_class
to control which points are considered as ground points - With a
LAScatalog
it now uses the filter-keep_class
by default respecting the classes given inuse_class
.
- Have a new argument
CHANGES
-
LAS()
now rounds the values to 2 digits if no header is provided to fit with the default header automatically generated. This ensures that a perfectly validLAS
object is built out of external data. This change is made by reference, meaning that the original dataset is also rounded.pts <- data.frame(X = runif(10), Y = runif(10), Z = runif(10)) las <- LAS(pts) # 'las' contains rounded values but 'pts' as well to avoid data copying
-
lasmetrics()
is deprecated. Alllas*
functions returnLAS
objects exceptlasmetrics()
. For consistency across the packagelasmetrics()
becomescloud_metrics()
. -
grid_metrics3d()
andgrid_hexametrics()
are deprecated. They are renamedvoxel_metrics()
andhexbin_metrics()
for naming consistency. -
The example dataset
Topography.laz
is now larger and include attributes gpstime, PointSourceID and some classified lakes.
ENHANCEMENTS
-
Internally the package used a QuadTree as spatial index in versions <= 2.1.3. Spatial index has been rewritten and changed for a grid partition which is twice as fast as the former QuadTree. This change provides a significant boost (i.e. up to two times faster) to many algorithms of the package that rely on a spatial index. This includes
lmf()
,shp_*()
,wing2015()
,pmf()
,lassmooth()
,tin()
,pitfree()
. Benchmark on a Intel Core i7-5600U CPU @ 2.60GHz × 2.# 1 x 1 km, 13 pts/m², 13.1 million points set_lidr_threads(n) tree_detection(las, lmf(3)) #> v2.1: 1 core: 80s - 4 cores: 38s #> v2.2: 1 core: 38s - 4 cores: 20s # 500 x 500 m, 12 pt/m², 3.2 million points lassnags(las, wing2015(neigh_radii = nr, BBPRthrsh_mat = bbpr_th)) #> v2.1: 1 core: 66s - 4 cores: 33s #> v2.2: 1 core: 43s - 4 cores: 21s # 250 x 250 m, 12 pt/m², 717.6 thousand points lasdetectshape(las3, shp_plane()) #> v2.1 - 1 cores: 12s - 4 cores: 7s #> v2.2 - 1 cores: 6s - 4 cores: 3s
-
Internally the Delaunay triangulation has been rewritten with
boost
instead of relying on thegeometry
package. The Delaunay triangulation and the rasterization of the Delaunay triangulation are now written in C++ providing an important speed-up (up to three times faster) totin()
,dsmtin()
andpitfree()
. However, for this to work, the point cloud must be converted to integers. This implies that the scale factors and offset in the header must be properly populated, which might not be the case if users have modified these values manually or if using a point cloud coming from a format other than las/laz. Benchmark on an Intel Core i7-5600U CPU @ 2.60GHz × 2.# 1.7 million ground points set_lidr_threads(n) grid_terrain(las, 0.5, tin()) #> v2.1: 1 core: 48s - 4 cores: 37s #> v2.2: 1 core: 22s - 4 cores: 20s # 560 thousand first returns (1.6 pts/m²) grid_canopy(las, res = 0.5, dsmtin()) #> v2.1: 1 core: 8s - 4 cores: 7s #> v2.2: 1 core: 3s - 4 cores: 3s # 560 thousand first returns (1.6 pts/m²) grid_canopy(las, res = 0.5, pitfree(c(0,2,5,10,15), c(0, 1.5))) #> v2.1: 1 core: 30s - 4 cores: 28s #> v2.2: 1 core: 11s - 4 cores: 9s
-
There are more than 100 new unit tests in
testthat
. The coverage increased from 68 to 87%. -
The vignette named Speed-up the computations on a LAScatalog gains a section about the possible additional speed-up using the argument
select
fromreadLAS()
. -
The vignette named LAScatalog formal class gains a section about partial processing.
-
Harmonization and review of the sections 'Supported processing options' in the man pages.
FIXES
-
Several minor fixes in
lascheck()
for very improbable cases ofLAS
objects likely to have been modified manually. -
Fix colorization of boolean data when plotting an object of class
lasmetrics3d
(returned byvoxel_metrics()
) #289 -
The LAScatalog engine now calls
raster::writeRaster()
withNAflag = -999999
because it seems that the default-Inf
generates a lot of trouble on windows when building a virtual raster mosaic withgdalUtils::gdalbuildvrt()
. -
plot.LAS()
better handles the case when coloring with an attribute that has only two values:NA
and one other value. -
lasclip()
was not actually able to retrieve the attributes of theSpatial*DataFrame
orsf
equivalent when usingopt_output_file(ctg) <- "/dir/{PLOTID}"
. -
opt_stop_early()
was not actually working as expected. The processing was aborted without logs. It now prevent the catalog processing engine to stop
even when an error occurs. -
In
tree_detection()
if no tree is found (e.g. in a lake) the function crashed. It now returns an emptySpatialPointDataFrame
. -
The argument
keep_lowest
ingrid_terrain
returned dummy output full of NAs because NAs have the precedence on actual numbers.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - v2.1.4
lidR v2.1.4 (Release date: 2019-10-15)
NEW FEATURES
-
grid_terrain()
gains an argumentfull_raster = FALSE
. -
lasnormalize()
gains an argument...
to tuneraster::extract()
and use, for example,method = "bilinear"
.
FIXES
-
In
lasground()
iflast_returns = TRUE
and theLAS
is not properly populated i.e. no last return, the classification was not actually computed. The expected behavior was to use all the points. This is now the case. -
lasclip()
is now able to clip into aLAS
objects usingSpatialPoints
orsf POINT
. It previously worked only intoLAScatalog
objects. -
lasaddextrabyte_manual()
was not actually working because thetype
was not converted to a numeric value according to the LAS specifications. -
Fix double precision floating point error in
grid_*
function in some specific cases. This fix affect alsohighest()
and other raster-based algorithms #273. -
lasreoffset()
now checks for integer overflow and throws an error in case of invalid user request #274. -
Tolerance for internal
point_in_triangle()
have been increased to fix double precision error in rasterization of a triangulation. This fixes some rareNA
s inpitfree()
,dsmtin()
andtin()
. -
The NAs are now correctly interpreted when writing a GDAL virtual raster #283.
-
Fix
lasmergespatial()
with 'on disk' rasters #285. -
Fix
pitfree()
with a single triangle case #288.
ENHANCEMENTS
pitfree()
handles more errors and fails more nicely in some specific cases #286.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - v2.1.3
lidR v2.1.3 (Release date: 2019-09-10)
NEW FEATURES
-
New functions
lasrescale()
andlasreoffset()
to modify the scale factors and the offsets. The functions update the header and recompute the coordinates to get the proper rounded values in accordance with the new header. -
readLAS()
throw (again) warnings for invalid files such as files with invalid scale factors, invalid bounding box, invalid attributes ReturnNumber and so on.
ENHANCEMENT
-
readLAScatalog()
is 60% faster -
The progress bar of the LAScatalog processing engine has been removed in non interactive sessions and replaced by regular but more informative prints. This allows to track the state of the computation with a stream redirection to a file when running a script remotely for example.
R -f script.R &> log.txt &
FIXES
-
Fix an infinite loop in the knn search when k > number of points. This bug may affect
lasdetectectshape()
,wing2012()
and other functions that rely on a knn search. -
Using remote futures now works for any function that supports a
LAScatalog
input. Previously remote evaluation of futures failed because of the presence ofreturn()
statement in the code future#333plan(remote, workers = "132.203.41.25")
-
lasclipCircle()
behaves identically forLAS
andLAScatalog
object. It now returns the points that are strictly inside the circle. Previously forLAS
objects it also returned the point belonging on the disc. -
The bounding box is updated after
lastransform()
#270 -
The offsets are updated after
lastransform()
to prevent integer overflow when writing the point cloud in.las
files #272 -
Removed deprecated C++ functions
std::bind2nd
as requested by CRAN.
NOTE
- All C++ source code has been reworked in a tidy framework to clean-up 4 years of mess. It is almost invisible for regular users but the size of the package has been reduced of several MB and many new tools will now be possible to build.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - V2.1.1
lidR v2.1.1 (Release date: 2019-08-06)
NEW FEATURES
- #266
lasmetrics
has now a dispatch toLAS
andLAScluster
cluster objects. It means thatlasmetrics
can be used withcatalog_apply
in some specific cases where it has a meaning (see also #266):
opt_chunk_buffer(ctg) <- 0
opt_chunk_size(ctg) <- 0
opt_filter(ctg) <- "-keep_first"
opt_output_files(new_ctg) <- ""
output <- catalog_apply(new_ctg, lasmetrics, func = .stdmetrics)
output <- data.table::rbindlist(output)
ENHANCEMENT
-
lastrees
now uses S3 dispatcher system. When trying to use it with aLAScatalog
object, user will have a standard R message to state thatLAScatalog
is not supported instead of an uninformative message that state that 'no slot of name "header" for this object of class "LAScatalog"' -
Internal code has been modifiy to drastically reduce probability of name intersection in
catalog_apply()
. For example, the use of a function that have a parameterp
incatalog_apply()
failed because of partial matching between the true argumentp
and the internal argumentprocessing_option
. -
lasfilterdecimate
with algorithmhighest
is now more than 20 times faster.lasfiltersurfacepoints
, being a proxy of this algorithm, had the same speed-up -
plot
forLAS
objects gained the pan capability.
FIXES
- #267. A dummy character was introduced by mistake in a variable name breaking the automatic exportation of user object in
grid_metrics
when used with a parallelized plan (tree_metrics
was also affected).
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 5 years ago

lidR - v2.1.0
lidR v2.1.0
VISIBLE CHANGES
Several algorithms are now natively parallelized at the C++ level with OpenMP
. This has for consequences for speed-up of some computations by default but implies visible changes for users. For more details see help("lidR-parallelism")
. The following only explains how to modify code to restore the exact former behavior.
In versions < 2.1.0
the catalog processing engine has R-based parallelism capabilities using the future
package. The addition of C++-based parallelism introduced additional complexity. To prevent against nested parallelism and give the user the ability to use either R-based or C++-based parallelism (or a mix of the two), the function opt_cores()
is no longer supported. If used it generates a message and does nothing. The strategy used to process the tiles in parallel must now be explicitly declared by users. This is anyway how it should have been designed from the begining! For users, restoring the exact former behavior implies only one change.
In versions < 2.1.0
the following was correct:
library(lidR)
ctg <- catalog("folder/")
opt_cores(ctg) <- 4L
hmean <- grid_metrics(ctg, mean(Z))
In versions >= 2.1.0
this must be explicitely declared with the future
package:
library(lidR)
library(future)
plan(multisession)
ctg <- catalog("folder/")
hmean <- grid_metrics(ctg, mean(Z))
NEW FEATURES
-
readLAS()
:- LAS 1.4 and point formats > 6 are now better suported.
lascheck()
andprint()
were updated to work correctly with these formats (#204) - New function
readLASheader()
to read the header of a file in aLASheader
object.
- LAS 1.4 and point formats > 6 are now better suported.
-
Coordinate Reference System:
- New function
wkt()
to store a WKT CRS in a LAS 1.4 file. This function is the twin ofepsg()
to store CRS. It updates theproj4string
and the header of the LAS object. This function is not expected to be used by users. Users must prefer the new functionprojection()
instead. - New function
projection<-
that updates both the slotproj4string
and the header with an EPSG code or a WKT string from aproj4string
or asp:CRS
object. This function supersedesepsg()
andwkt()
that are actually only useful internally and in specific cases. The vignetteLAS-class
has been updated accordingly.
projection(las) <- projection(raster)
- New function
-
LAScatalog processing engine:
- Progression estimation displayed on a map now handles warnings by coloring the chunks in orange.
- Progression estimation displayed on a map now colors in blue the chunks that are processing.
- The engine now returns the partial result in case of a fail.
- The engine now has a log system to help users reload the chunk that throws an error and try to understand what going wrong with this cluster specifically. If something went wrong a message like the following is displayed:
An error occurred when processing the chunk 190. Try to load this chunk with: chunk <- readRDS("/tmp/RtmpAlHUux/chunk190.rds") las <- readLAS(chunk)
-
grid_metrics()
:- New function
stdshapemetrics()
and lazy coding.stdshapemetrics
to compute eigenvalue-related features (#217). - New argument
filter
ingrid_metrics()
. This argument enables users to compute metrics on a subset of selected points such as "first returns", for example, without creating a copy of the point cloud. Such an argument is expected to be added later in several other functions.
hmean <- grid_metrics(las, ~mean(Z), 20, filter = ~ReturnNumber == 1)
- New function
-
New functions
lasdetectshape()
for water and human-made structure detection with three algorithmsshp_plane()
,shp_hplane()
,shp_line()
. -
plot()
:- For LAS objects
plot()
gained an argumentaxis = TRUE
to display axis. - For LAS objects
plot()
gained an argumentlegend = TRUE
to display color gradient legend (#224).
- For LAS objects
-
tree_hull()
:- Gained an argument
func
to compute metrics for each tree, liketree_metrics()
convhulls <- tree_hulls(las, func = ~list(imean = mean(Intensity)))
- Gained an argument
-
Miscellaneous tools:
- The function
area()
has been extended toLASheader
objects. - New functions
npoints()
anddensity()
available forLAS
,LASheader
andLAScatalog
objects that return what users may expect.
las <- readLAS("file.las", filter = "-keep_first") header <- readLASheader(file) ctg <- catalog("folder/") npoints(las) #> [1] 55756 npoints(header) #> [1] 81590 npoints(ctg) #> [1] 1257691 density(las) #> [1] 1.0483 density(header) #> [1] 1.5355 density(ctg) #> [1] 1.5123
- The function
-
Several functions are natively parallelized at the C++ level with OpenMP. See
help("lidR-parallelism")
for more details. -
New function
catalog_select
for interactive tile selection.
NOTE
-
grid_metrics()
,grid_metrics3d()
,tree_metrics()
,tree_hull()
,grid_hexametrics()
andlasmetrics()
expect a formula as input. Users should not writegrid_metrics(las, mean(Z))
butgrid_metrics(las, ~mean(Z))
. The first syntax is still valid, for now. -
The argument named
field
intree_metrics()
is now namedattribute
for consistency with all other functions. -
The documentation of supported options in
tree_*()
functions was inccorect and has been fixed. -
readLAScatalog()
replacescatalog()
.catalog()
is soft-deprecated.
FIX
- #264
grid_terrain
now filter degenerated ground points.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 6 years ago

lidR - v2.0.3
lidR v2.0.3 (Release date: 2019-05-08)
- Fix: in
li2012()
the doc states that If R = 0 all the points are automatically considered as
local maxima and the search step is skipped (much faster). This is now true. - Fix: in
lasmergespatial
used with aSpatialPolygonDataFrame
when the bounding boxes do not match the full search was performed uselessly. Now the function exits early without searching anything. - Fix: #242 on Windows when using multicore options to process a LAScatalog the parameter of the algorithms were not exported to each session.
- Enhance: internally the function
tsearch
that searches in a triangulation is 25% faster giving a small speed-up topitfree()
andtin()
algorithms. - Enhance: in
lasmergespatial
used with aSpatialPolygonDataFrame
the function checks the bounding box of the polygon to speed-up the computation with complex polygons. - Doc: add a
?lidR
page to the manual.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 6 years ago

lidR - v2.0.2
lidR v2.0.2 (Release date: 2019-03-02)
- Fix: #222
grid_*()
functions return consistently aRasterLayer
if there is a single layer. virtual raster mosaic were returned asRasterStack
no matter the number of layers. - Fix: #223
lasmergespatial()
wrongly copied shapefile attributes to each point when the paramterattribute
was the name of an attribute of the shapefile. - Fix: #225
laspulse()
,lasflightline()
,lasscanline()
were broken since v2.0.0. - Fix: #227 When processing a LAScatalog the chunks are better computed. In former version it was possible to have chunks that lie on tile only because of the buffer. These chunks are not build anymore.
- Fix: #227 When processing a LAScatalog some chunks may belong in a file/tile but when actually reading the points in the file the chunks could be empty with points only in the buffer region. In these case an empty point cloud is returned and the computation is be skipped.
- Fix: #228
lasmergespatial()
andlasclip()
loose precision when extracting polygons due to missing digits in the WKT string used to rebuild the polygons at C++ level.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 6 years ago

lidR - v2.0.1
lidR v2.0.1 (Release date: 2010-02-02)
- Change: the function
catalog
has been slightly modified in prevision of the release of the packagerlas 1.3.0
to preserve future compatibility. This is invisible for the users. - New:
lasnormalize
gained a parameterna.rm = TRUE
- Fix: an error occurend when plotting a LAScatalog with the option
chunk_pattern = TRUE
: objet 'ctg' introuvable. - Fix: examples in documentation of
tin()
andknnidw()
were inverted. - Fix: #213 bug when using option
keep_lowest
ingrid_terrain
. - Fix: #212 bug when merging big rasters that exeed the memory allowed by the raster package
- Fix: bug when merging rasters when some of then only have one cell
- Fix: bug when printing a 0 point LAS object
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 6 years ago

lidR - v2.0.0
lidR v2.0.0 (Release date: 2019-01-02)
> 2.0
are incompatible with versions 1.x.y
?
Why versions The lidR package versions 1 were mainly built upon "personal R scripts" I wrote 3 years ago. These scripts were written for my own use at a time when the lidR package was much smaller (both in term of code and users). The lidR package became a relatively large framework built on top of an unstructured base so it became impossible to develop it further. Many features and functions were missing because the way lidR was built did not allow them to be written. The new release (lidR version 2) breaks the former code to build a more robust, more consistent and more scalable framework that is intended and expected to continue for years without the need to break anything more in the future.
Old binaries can still be found here for 6 months:
Overview of the main visible changes
lidR as a GIS tool
lidR versions 1 was not a GIS tool. For example, rasterization functions such as grid_metrics()
or grid_canopy()
returned a data.frame
. Tree tops extraction with tree_detection()
also returned a data.frame
. Tree segmentation with lastrees()
accepted RasterLayer
or data.frame
as input in a very inconsistent way. Moreover, the CRS of the point cloud was useless and never propagated to the outputs because outputs were not spatial objects.
lidR version 2 consistently uses Raster*
and Spatial*
objects everywhere. Rasterization functions such as grid_metrics()
or grid_canopy()
return Raster*
objects. Tree tops extraction returns SpatialPointDataFrame
objects. Tree segmentation methods accept SpatialPointDataFrame
objects only in a consistent way across functions. The CRS of the point cloud is always propagated to the outputs. LAS
objects are Spatial
objects. LAScatalog
objects are SpatialPolygonDataFrame
objects. In short, lidR version 2 is now a GIS tool that is fully compatible with the R ecosystem.
No longer any update by reference
Several lidR functions used to update objects by reference. In lidR versions 1 the user wrote: lasnormalize(las)
instead of las2 <- lasnormalize(las1)
. This used to make sense in R < 3.1 but now the gain is no longer as relevant because R makes shallow copies instead of deep copies.
To simplfy, let's assume that we have a 1 GB data.frame
that stores the point cloud. In R < 3.1 las2
was a copy of las1
i.e. las1
+ las2
= 2GB . This is why we made functions that worked by reference that implied no copy at all. This was memory optimized but not common or traditional in R. The question of memory optimization is now less relevant since R >= 3.1. In the previous example las2
is no longer a deep copy of las1
, but a shallow copy. Thus lidR now consistently uses the traditional syntax y <- f(x)
.
Algorithm dispatch
The frame of lidR versions 1 was designed at a time when there were fewer algorithms. The increasing number of algorithms led to inconsistent ways to dispatch algorithms. For example:
grid_canopy()
implemented one algorithm and a second functiongrid_tincanopy()
was created to implement another algorithm. With two functions the switch was possible by using two different names (algorithms dispatched by names).grid_tincanopy()
actually implemented two algorithms in one function. The switch was possible by changing the input parameters in the function (algorithm dispatched by input).lastrees()
had several variants that provided access to several algorithms:lastrees_li()
,lastrees_dalpontes()
,lastrees_watershed()
, and so on. With several functions the switch was possible by using several different names (algorithms dispatched by names).tree_detection
did not have several variants, thus it was impossible to introduce a new algorithm (no dispatch at all).
lidR version 2 comes with a flexible and scalable dispatch method that unifies all the former functions. For example, grid_canopy()
is the only function to make a CHM. There is no longer the need for a second function grid_tincanopy()
. grid_canopy()
unifies the two functions by accepting as input an algorithm for a digital surface model:
chm = grid_canopy(las, res = 1, algo = pitfree())
chm = grid_canopy(las, res = 1, algo = p2r(0.2))
The same idea drives several other functions including lastrees
, lassnags
, tree_detection
, grid_terrain
, lasnormalize
, and so on. Examples:
ttops = tree_detection(las, algo = lmf(5))
ttops = tree_detection(las, algo = lidRplugins::multichm(1,2))
lastrees(las, algo = li2012(1.5, 2))
lastrees(las, algo = watershed(chm))
lasnormalize(las, algo = tin())
lasnormalize(las, algo = knnidw(k = 10))
This allows lidR
to be extended with new algorithms without any restriction either in lidR or even from third-party tools. Also, how lidR functions are used is now more consistent across the package.
LAScatalog processing engine
lidR versions 1 was designed to run algorithms on medium-sized point clouds loaded in memory but not to run algorithms over a set of files covering wide areas. In addition, lidR 1 had a poorly and inconsistently designed engine to process catalogs of las files. For example:
- It was possible to extract a polygon of points from a
LAScatalog
but not multipart-polygons or polygons with holes. This was only possible withLAS
objects i.e loaded in memory (inconsistent behaviors within a function). - It was possible to run
grid_metrics()
on aLAScatalog
i.e. over a wide area not loaded in memory, but notlasnormalize
,lasground
ortree_detection
(inconsistent behavior across the functions).
lidR version 2 comes with a powerful and scalable catalog processing engine. Almost all the lidR functions can be used seamlessly with either LAS
or LAScatalog
objects. The following chunks of code are now possible:
ctg = catalog("folfer/to/las/file")
opt_output_file(ctg) <- "folder/to/normalized/las/files/{ORIGINALFILENAME}_normalized"
new_ctg = lasnormalize(ctg, algo = tin())
Complete description of visible changes
LAS class
- Change: the
LAS
class is now aSpatial
object or, more technically, it inherits aSpatial
object. - Change: being a
Spatial
object, aLAS
object no longer has a@crs
slot. It has now a slot@proj4string
that is accessible with the functionsraster::projection
orsp::proj4string
- New: being a
Spatial
object, aLAS
object inherits multiple functions fromraster
andsp
, such$
and[[
accessors orraster::extent
,sp::bbox
,raster::projection
, and so on. However, the replacement method$<-
,[[<-
have restricted capabilities to ensure aLAS
object cannot be modified in a way that implies loosening the properties of the LAS specifications. - New: empty
LAS
objects with 0 points are now allowed. This has repercussions for several functions includinglasfilter
,lasclip
, andreadLAS
that do not returnNULL
for empty data but aLAS
object with 0 points. This new behavior has been introduced to fix the old inconsistent behavior of functions that return eitherLAS
orNULL
objects.LAS
objects are always returned.
LAScatalog class
- Change: the
LAScatalog
class is now aSpatialPolygonsDataFrame
or, more technically, it inherits aSpatialPolygonsDataFrame
. - Change: being a
SpatialPolygonsDataFrame
object, aLAScatalog
no longer has a@crs
slot. It has now a slot@proj4string
that is accessible with the functionsraster::projection
orsp::proj4string
. - Change: being a
SpatialPolygonsDataFrame
aLAScatalog
can be plotted withsp::spplot()
. - Change: there are no longer any slots
@cores
,@by_file
,@buffer
, and so on. They are replaced by more generic and scalable slots@processing_options
,@output_options
,@clustering_options
and@input_options
that are list of options classified by their main roles. - Change: documentation has been entirely rewritten to explain the whole potential of the class.
- Change: functions
by_file
,progress
,tiling_size
,buffer
were replaced byopt_chunk_size
,opt_chunk_buffer
,opt_progress
, and so on. These allow for a consistent set of functions that do not overlap with functions fromraster
orsp
. - Change: standard column names were renamed to make syntactically-valid names and for compatibility with
sp
functions.
readLAS
- Change:
readLAS
no longer supports optionPFC
. Users must use the functionslaspulse
,lasflightlines
manually.
lasclip
- New:
lasclip
now works both with aLAS
object and aLAScatalog
object in a seamless and consistent way. There are no longer any differences between the capabilities of theLAS
version or theLAScatalog
one. - New:
lasclip
support many geometries including multipart polygons and polygons with holes, both with aLAS
object and aLAScatalog
object. - Change: The option
inside
has been removed for consistency because it cannot be safely supported both onLAS
andLAScatalog
. - Change: The option
ofile
has been removed for consistency and this option in now managed by theLAScatalog
processing engine. For example, one can extract ground inventories and write them inlaz
files automatically named after their center coordinates like this:
ctg = catalog(folder)
output_files(ctg) <- "path/to/a/file_{XCENTER}_{YCENTER}"
laz_compression(ctg) <- TRUE
new_ctg = lasclipCircle(ctg, xc,yc, r)
- Change: documentation has been reviewed and extended
- Change:
lasclip
does not returnNULL
anymore for empty queries but an emptyLAS
object. - Fix:
lasclipRectangle
returns the same output both with aLAS
and aLAScatalog
. With aLAS
the rectangle is now closed on the bottom and the left and open on the right and the top.
catalog_queries
- Change:
catalog_queries
has been removed because it is superseded bylasclip
.
lasnormalize
- Change:
lasnormalize()
no longer updates the original object by reference. - Change: remove the old option
copy = TRUE
that is now meaningless. - Change:
lasnormalize()
now relies on lidR algorithms dispatch (see also the main new features above). - New:
lasnormalize()
can be applied on aLAScatalog
to write a new normalized catalog using the catalog processing engine (see also the main new features above).
lasclassify
- Change:
lasclassify()
is now namedlasmergespatial()
to free the namelasclassify
that should be reserved for other usage. - Change:
lasmergespatial()
no longer updates the original object by reference. - Fix: the classification, when made with a
RasterLayer
, preserves the data type of theRasterLayer
. This also fixes the fact thatlastrees()
used to classify the tree withdouble
instead ofint
.
tree_detection
- Change:
tree_detection()
now relies on the new dispatch method (see also the main new features above). - New: algorithm
lmf
has user-defined variable-sized search windows and two possible search window shapes (square or disc). - New: introduction of the
manual
algorithm for manual correction of tree detection. - New:
tree_detection
algorithms are seamlessly useable with aLAScatalog
object by using the catalog processing engine (see also the main new features above). Thus, the following just works:
ctg <- catalog(folder)
ttop <- tree_detection(ctg, lmf(5))
- Change: the
lmf
algorithm, when used with aRasterLayer
as input, expects parameters given in the units of the map and no longer in pixels. - Change:
tree_detection()
function consistently returns aSpatialPointsDataFrame
whatever the algorithm. - Change:
tree_detection()
function based on a CHM no longer support alasmetric
object as input. Anyway, this class no longer exists.
tree_metrics
- Change:
tree_metrics()
returns aSpatialPointsDataFrame
. - Change:
tree_metrics()
is seamlessly useable with aLAScatalog
using the catalog processing engine (see also the main new features above). Thus, this just works if the las file has extra bytes attributes that store the tree ids:
ctg <- catalog(folder)
metrics <- tree_metrics(ctg, list(`Mean I` = mean(Intensity)))
lastrees
- Change:
lastrees()
now relies on the new algorithms dispatch method (see also the main new features above). - New: introduction of the
mcwatershed
algorithm that implements a marker-controlled watershed.
grid_metrics
- Change:
grid_metrics()
as well as othergrid_*
functions consistently return aRasterLayer
or aRasterBrick
instead of adata.table
. - Change: option
splitlines
has been removed.grid_metrics()
used to return adata.table
because of thesplitlines
option and lidR was built on top of that feature from the very beginning. Now lidR consistently usessp
andraster
and this option is no longer supported.
grid_terrain
- Change:
grid_terrain()
now relies on the new algorithms dispatch method (see also the main new features above). - Change:
grid_terrain()
consistently returns aRasterLayer
instead of adata.table
, whatever the algorithm used.
grid_canopy
- Change:
grid_canopy()
now relies on the new algorithms dispatch method (see also the main new features above). It unifies the former functionsgrid_canopy()
andgrid_tincanopy()
. - Change:
grid_canopy()
consistently returns aRasterLayer
instead of adata.table
, whatever the algorithm used. - Fix: the pitfree algorithm fails if a layer contains only 1 or 2 points.
- Fix: the p2r algorithm is five times faster with the subcircle tweak.
grid_tincanopy
- Change:
grid_tincanopy()
has been removed. Digital Surface Models are consistently driven by the functiongrid_canopy()
and the lidR algorithm dispatch engine. The algorithms that replacedgrid_tincanopy()
aredsmtin
andpitfree
.
grid_hexametrics
- Change: as for
grid_metrics
, the parametersplitlines
has been removed. - Change: the function returns a
hexbin
object or a list ofhexbin
objects and no longerdata.table
objects.
grid_catalog
- Change:
grid_catalog()
has been removed. The newLAScatalog
processing engine means that this function is no longer useful.
class lasmetrics
data.table
with a classlasmetrics
no longer exists. It has been consistently replaced byRasterLayer
andRasterBrick
everywhere.as.raster
no longer exists because it used to convertlasmetrics
intoRasterLayer
andRasterStack
.as.spatial
no longer convertslasmetrics
toSpatialPixelsDataFrame
but still convertsLAS
toSpatialPointsDataFrame
.plot.lasmetrics
has been removed obviously.
lasroi
- Change:
lasoi()
has been removed. It was not useful and 'buggy'. It might be reintroduced later inlasclipManual
.
lascolor
- Change:
lascolor()
has been removed. It was one of the first functions of the package and is no longer useful becauseplot()
has enhanced capabilities.
lasfilterdecimate
- Change: now relies on the new algorithms dispatch method (see also the main new features above).
- New: introduction of the algorithm
highest
available inlasfilterdecimate()
. This supersedes the functionlasfiltersurfacepoints()
.
lassnags
- Change:
lassnags()
now relies on the new algorithms dispatch method (see also the main new features above). - New:
lasnsnags()
can be applied on aLAScatalog
to write a new catalog using the catalog processing engine (see also the main new features above).
lidr_options
- Change:
lidr_option()
has been removed. The options are now managed by regular R base options with functionoptions()
. Available lidR options are named with the prefixlidR
.
Example files
- New: the three example files are now georeferenced with an EPSG code that is read and converted to a
proj4string
. - New: the example file
MixedConifers.laz
contains the segmented trees in extra bytes 0.
plot
- New:
plot()
forLAS
objects supportsRGB
as a color attribute. - New: option
color
supports lazy evaluation. This syntax is correct:plot(las, color = Classification)
. - New: option
clear_artifact = TRUE
shifts the point cloud to (0,0) and reduces the display artifact due to the use of floating point inrgl
. - New: new functions
add_treetops3d
,add_dtm3d
andplot_dtm3d
add elements in the point cloud. - Change:
trim
does not trim on a percentile of values but on the values themselves.
Coordinate reference system
- New: coordinate reference system is supported everywhere and can be written in las files. See function
epsg()
. - New: function
lastranform
that returns transformed coordinates of aLAS
object using the CRS argument.
New functions
- New: function
lasfilterduplicates
- New: function
lascheck
- New: function
lasvoxelize
Other changes that are not directly visible
- Change: the code that drives the
point_in_polygon
algorithm relies onboost
and drastically simplifies the former code oflasmergespatial()
- Change: many memory optimizations
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 6 years ago

lidR - v1.6.1
lidR v1.6.1 (2018-08-21)
BUG FIXES
- [#161] Fix tree ID matching.
- Fix undefined variable in
cluster_apply
on mac and linux if multicore processing is used. - Fix rare case of unit test failure due to the random nature of the test dataset using seeds.
- [#165] Unexported function in
catalog_apply
on Windows.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 6 years ago

lidR - v1.6.0
lidR v1.6.0 (2018-07-20)
NEW FEATURE
- New function
tree_hulls
that computes a convex or concave hull for each segmented tree. - New option
stop_early
that enables processing of an entire catolog or stops if an error occurs. - New function
catalog_retile
supersedes the functioncatalog_reshape
and performs the same task while adding much more functionality.
ENHANCEMENTS
- When processing a
LAScatalog
, error handling has been seriouly improved. A process can now run until the end even with errors. In this case clusters with errors are skipped. - When processing a
LAScatalog
, the graphical progress now uses 3 colors. green: ok, red: error, gray: null. as.spatial()
forLAS
object preserves the CRS.- All the functions now have strong assertions to check user inputs.
plot.LAScatalog
always displays the catalog withmapview
by default even if the CRS is empty.- In
lastrees_dalponte
the matching between the seeds and the canopy is more tolerant. Rasters can have different resolution and/or extent. lasground
uses (as an option) only the last and single returns to perform the segmentation.
OTHER CHANGES
catalog()
displays a message when finding overlaps between files.- The LAScatalog class is more thoroughly documented.
- Clusters now align on (0,0) by default when processing a
LAScatalog
by cluster.
BUG FIXES
lasscanline()
did not compute the scanline because the conditional statement that checked if the field was properly populated was incorrect.- [#146] Fix matching between tree tops, raster and canopy raster.
tree_detection
when used with a point cloud was not properly coded and tended to miss some trees.- In
lasclip*
ifofile
was non empty, the function wrote properly the file but returned a non-expected error. - [#155] user supplied function was being analysed by
future
and some function were missing. User supplied function is now manually analysed. - [#156] Fix error when
lasclip
was used with aSpatialPolygonDataFrame
.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 6 years ago

lidR - v1.5.0
lidR v1.5.0 (2018-05-13)
SIGNIFICANT CHANGES
catalog_options()
is formally deprecated. UseLAScatalog
properties instead (see?catalog
).- The package
magrittr
is no longer loaded withlidR
. Thus, piping operators are no longer usable by default. To use piping operators uselibrary(magrittr)
.
NEW FEATURES
- New
lassmooth
function. A point cloud-based smoothing function. - New
lasfiltersurfacepoints
function to filter surface points. - New
grid_catalog
function is a simplified and more powerful function likecatalog_apply
but specifically dedicated togrid_*
outputs. - New functions
lasadddata
,lasaddextrabyte
andlasaddextrabyte_manual
to add new data in aLAS
object. lasclip
can clip aSpatialPolygonsDataFrame
lasclipRectangle
andlasclipCircle
can clip multiple selections (non-documented feature).- The
treeID
computed withlastrees_*
functions can now be written in alas/laz
file by default.
OTHER CHANGES
LAScatalog
objects are processed with a single core by default.lasdecimate
is formally deprecated. Uselasfilterdecimate
grid_density
now returns both the point and the pulse density, where possible.- The option
P
is no longer set by default inreadLAS
. - The documentation of
lastrees
has been split into several pages. - When a catalog is processed using several cores, if an error is raised the process triggers an early signal to stop the loop. In previous releases the entire process was run and the error was raised at the end when the futures were evaluated.
BUG FIXES
grid_metrics(lidar, stdmetrics_i(Intensity))
returned and emptydata.table
- [#128] Fix raster data extraction using the slower and memory-greedy, but safer
raster::extract
function. - [#126] propagate the CRS in filter functions.
- [#116] Fix clash between function
area
fromlidR
and fromraster
. - [#110] Fix out-of-bounds rasterization.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 7 years ago

lidR - v1.4.1
lidR v1.4.1 (2018-02-01)
OTHER CHANGES
- Removed examples and unit tests that imply the watershed segmentation to make CRAN check happy with the new rules relative to bioconductor packages.
NEW FEATURES
- Parameter
start
has been enabled ingrid_metrics
withcatalogs
.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 7 years ago

lidR - v1.4.0
lidR v1.4.0 (2018-01-24)
NEW FEATURES
lasclip
andlasclip*
can extract from a catalog.lasclip
supportssp::Polygon
objects.lastrees
gains a new algorithm from Silva et al. (2016).lastrees
with the Li et al. (2012) algorithm gains a new parameter to prevent over-segmentation.- new function
lassnags
for classifying points as snag points or for segmenting snags. - new function
tree_detection
to detect individual trees. This feature has been extracted fromlastrees
's algorithms and it is now up to the users to uselidR
's algos or other input sources. plot
supports natively thePointCloudViewer
package avaible on github.
BUG FIXES
- Fix missing pixel in DTM that made normalization impossible.
- [#80] fix segfault.
- [#84] fix bug in
lasscanline
.
ENHANCEMENTS
lastrees
with the Li et al. (2012) algorithm is now 5-6 times faster and much more memory efficient.lastrees
with the Li et al. (2012) algorithm no longer sorts the original point cloud.lastrees
with the Dalponte et al (2016) algorithm is now computed in linear time and is therefore hundreds to millions times faster.catalog_reshape()
streams the data and uses virtually zero memory to run.grid_canopy()
has been rewritten entirely in C++ and is now 10 to 20 times faster both with the optionsubcircle
or without it.grid_canopy()
with the optionsubcircle
uses only 16 bytes of extra memory to run, while this feature previously required the equivalent of several copies of the point cloud (several hundreds of MB).as.raster()
is now three times faster.lasclassify
now uses a QuadTree and is therefore faster. This enables several algorithms to run faster, such aslastrees
with Silva's algo.
OTHER CHANGES
lasground
with the PMF algorithm now accepts user-defined sequences.lasground
with the PMF algorithm has simplified parameter names to make them easier to type and understand, and to prepare the package for new algorithms.lasground
documentation is more explicit about the actual algorithm used.lasground
now computes the windows size more closely in line with the original Zhang paper.lastrees
when used with raster-based methods now accepts a missing las object. In that caseextra
is turned totrue
.- new parameter
p
(for power) added to functions that enable spatial interpolation with IDW.
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 7 years ago

lidR - v1.3.0
lidR v1.3.0 (Release date: 2017-09-16)
This version is dedicated to extending functions and processes to entire catalogs in a continuous way.
Major changes are:
- How
catalog_apply
works. More powerful but no longer compatible with previous releases - Former existing functions that now natively support a
Catalog
- Management of buffered areas
NEW FEATURES
catalog_apply
has been entirely re-designed. It is more flexible, more user-friendly and enables loading of buffered data.catalog_queries
has now an argument...
to pass any argument ofreadLAS
.catalog_queries
has now an argumentbuffer
to load extra buffered points around the region of interest.grid_metrics
accepts a catalog as input. It allows users to grid an entire catalog in a continuous way.grid_density
also inherits this new featuregrid_terrain
also inherits this new featuregrid_canopy
also inherits this new featuregrid_tincanopy
also inherits this new featuregrid_metrics
has now has an argumentfilter
for streaming filters when used with a catalog- New function
catalog_reshape
OTHER CHANGES
lasnormalize
updates the point cloud by reference and avoids making deep copies. An optioncopy = TRUE
is available for compatibility with former versions.readLAS
arguments changed. The new syntax is simpler. The previous syntax is still supported.catalog_index
is no longer an exported function. It is now an internal function.plot.Catalog
accepts the usualplot
argumentscatalog_queries
andcatalog_apply
do not expect a parametermc.cores
. This is now driven by global options incatalog_options()
.grid_metrics
andlasmetrics
do not expect a parameterdebug
. This is now driven by global options inlidr_options
.catalog
can build a catalog from a set of paths to files instead of a path to a folder.- removed
$
access to LAS attribute (incredibly slow) catalog_select
is more pleasant an more interactive to use.- S3
Catalog
class is now a S4LAScatalog
class LAS
andLAScatalog
class gain a slotcrs
automatically filled with a proj4 stringplot.LAScatalog
display a google map background if the catalog has a CRS.plot.LAScatalog
gains an argumenty
to display a either a terrain, raod, satellite map.lasarea
is deprecated. Use the more generic functionarea
BUG FIXES
- Computer precision errors lead to holes in raster computed from a Delaunay triangulation.
- Message in
writeLAS
for skipped fields when no field is skipped is now correct.
ENHANCEMENTS
grid_terrain
with delaunay allocates less memory, makes fewer deep copies and is 2 to 3 times fastergrid_terrain
with knnidw allocates less memory, makes fewer deep copies and is 2 to 3 times fasterlasnormalize
andlasclassify
no longer rely onraster::extract
but on internalfast_extract
, which is memory efficient and more than 15 times faster.catalog
enables aLAScatalog
to be built 8 times faster than previously.- removed dependencies to
RANN
package using internal k-nearest neighbor search (2 to 3 times faster)
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain over 7 years ago

lidR - v1.2.1
lidR v1.2.1 (Release data: 2017-06-12)
NEW FEATURES
- new function
tree_metrics
. - new function
stdtreemetrics
. grid_tincanopy()
gains a parametersubcircle
likegrid_canopy()
- new function
rumple_index
for measuring roughness of a digital model (terrain or canopy) - global options to parameterize the package - avaible with
lidr_options()
BUG FIXES
- Installation fails if package sp is missing.
- Memory leak in QuadTree algorithm. Memory is now free after QuadTree deletion.
- Dalponte's algorithm had a bug due to the use of std::abs which works with intergers. Replaced by std::fabs which works with doubles.
- In
grid_tincanopy
x > 0
was replaced byx >= 0
to avoid errors in the canopy height models - Triangle boudaries are now taken into account in the rasterization of the Delaunay triangulation
OTHER CHANGES
lastrees
Li et al. algorithm for tree segmentation is now ten to a thousand of times faster than in v1.2.0grid_terrain
, the interpolation is now done only within the convex hull of the point cloudgrid_tincanopy
makes the triangulation only for highest return per grid cell.grid_tincanopy
andgrid_terrain
using Delaunay triangulation is now ten to a hundred times faster than in v1.2.0as.raster
now relies onsp
and is more flexibleas.raster
automatically returns aRasterStack
if no layer is provided.plot.lasmetrics
inheritsas.raster
changes and can display aRasterStack
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain almost 8 years ago

lidR - v1.2.0
lidR v1.2.0 (Release date: 2017-03-26)
NEW FEATURES
- new function
lasground
for ground segmentation. - new function
grid_tincanopy
. Canopy height model using Khosravipour et al. pit-free algorithm. - new function
grid_hexametrics
. Area-based approach in hexagonal cells. lasnormalize
allows for "non-discretized" normalization i.e interpolating each point instead of using a raster.- internally
lascheck
performs more tests to check if the header is in accordance with the data.
BUG FIXES
- [#48]
gap_fraction_profile()
bug with negative values (thanks to Florian de Boissieu) - [#49] typo error leading to the wrong metric in
stdmetric_i
- [#50] typo error leading to the wrong metric in
stdmetric
- Fix bug in
stdmetric_z
whenmax(Z) = 0
- [#54] better recomputation of the header of LAS objects.
OTHER CHANGES
- Slightly faster point classification from shapefiles.
- [#51] in
grid_terrain
, forcing the lowest point to be retained is now an optionkeep_lowest = FALSE
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 8 years ago

lidR - v1.1.0
lidR v1.1.0 (Release date: 2017-02-05)
NEW FEATURES
lastree()
for individual tree segmentationreadLAS()
gains a parameterfilter
fromrlas (>= 1.1.0)
catalog_queries()
relies onrlas (>= 1.1.0)
. It saves a lot of memory, it is 2 to 6 times faster and supports .lax files.
OTHER CHANGES
colorPalette
parameter inplot.LAS()
now expects a list of colors instead of a function. Useheight.colors(50)
instead ofheight.colors
- The header of a LAS object is now an S4 class called
LASheader
- The spatial interpolation method called
akima
is now calleddelaunay
because it corresponds to what is actually computed. - The spatial interpolation method called
akima
lost its parameterlinear
. - The spatial interpolation method called
kriging
now performs a KNN kriging. catalog_queries()
lost the parameter...
all the fields are loaded by default.- Removed
lasterrain()
which was not consistent with other functions and not useful.
BUG FIXES
- The header of LAS objects automatically updates
Number of point records
andNumber of nth return
. lasnormalize()
updates the header and returns warnings for some behaviors- #39 - interpolation with duplicated ground points
Biosphere - Forest Remote Sensing
- R
Published by Jean-Romain about 8 years ago
