-
Fix colorisation of boolean data when ploting an object of class
lasmetrics3d(returned bygrid_metrics3d()) #289 -
The LAScatalog engine now call
raster::writeRaster()withNAflag = -999999because it seems that the default-Infgenerates a lot of trouble on windows when building a virtual raster mosaic withgdalUtils::gdalbuildvrt(). -
plot.LAS()better handle the case when coloring with an attibute that have only two values:NAand another value. -
lasclip()was not actually able to retrieve the attributes of theSpatial*DataFrameorsfequivalent when usingopt_output_file(ctg) <- "/dir/{PLOTID}".
-
In
plot.lasmetrics3d()the parametertrimis now set toInfby default. -
Harmonisation and review of the sections 'Supported processing options' in the man pages.
-
grid_terrain()gains an argumentfull_raster = FALSE. -
lasnormalize()gains an argument...to tuneraster::extract()and use, for example,method = "bilinear".
-
In
lasground()iflast_returns = TRUEand theLASis 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 aLASobjects usingSpatialPointsorsf POINT. It previously worked only intoLAScatalogobjects. -
lasaddextrabyte_manual()was not actually working because thetypewas 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 rareNAs 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.
pitfree()handles more errors and fails more nicely in some specific cases #286.
-
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.
-
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 &
-
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
LAScataloginput. 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 forLASandLAScatalogobject. It now returns the points that are strictly inside the circle. Previously forLASobjects 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.lasfiles #272 -
Removed deprecated C++ functions
std::bind2ndas requested by CRAN.
- 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.
- Fix a serious issue of uninitialized values in an internal C++ function but this issue is consequentless for the package.
-
#266
lasmetricshas now a dispatch toLASandLASclustercluster objects. It means thatlasmetricscan be used withcatalog_applyin 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)
-
lastrees()now uses S3 dispatcher system. When trying to use it with aLAScatalogobject, user will have a standard R message to state thatLAScatalogis 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 modified to drastically reduce probability of name intersection in
catalog_apply(). For example, the use of a function that have a parameterpincatalog_apply()failed because of partial matching between the true argumentpand 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 -
plotforLASobjects gained the pan capability.
- #267. A dummy character was introduced by mistake in a variable name breaking the automatic exportation of user object in
grid_metricswhen used with a parallelized plan (tree_metrics()was also affected).
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 beginning! 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 explicitly declared with the future package:
library(lidR)
library(future)
plan(multisession)
ctg <- catalog("folder/")
hmean <- grid_metrics(ctg, mean(Z))-
readLAS():- LAS 1.4 and point formats > 6 are now better supported.
lascheck()andprint()were updated to work correctly with these formats (#204) - New function
readLASheader()to read the header of a file in aLASheaderobject.
- LAS 1.4 and point formats > 6 are now better supported.
-
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 theproj4stringand 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 slotproj4stringand the header with an EPSG code or a WKT string from aproj4stringor asp:CRSobject. This function supersedesepsg()andwkt()that are actually only useful internally and in specific cases. The vignetteLAS-classhas 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.stdshapemetricsto compute eigenvalue-related features (#217). - New argument
filteringrid_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 = TRUEto display axis. - For LAS objects
plot()gained an argumentlegend = TRUEto display color gradient legend (#224).
- For LAS objects
-
tree_hull():- Gained an argument
functo 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 toLASheaderobjects. - New functions
npoints()anddensity()available forLAS,LASheaderandLAScatalogobjects 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_selectfor interactive tile selection. -
lasgroundhave lost the argumentlast_returnsfor a more generic argumentfilter. Retro-compatibility as been preserved by interpreting adding an ellipsis.
-
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
fieldintree_metrics()is now namedattributefor consistency with all other functions. -
The documentation of supported options in
tree_*()functions was incorrect and has been fixed. -
readLAScatalog()replacescatalog().catalog()is soft-deprecated.
-
#264
grid_terrainnow filter degenerated ground points. -
#238 fix a floating point precision error in
p2ralgorithm.
- When reading a file that contains extrabytes attributes and these data are not loaded (e.g.
readLAS(f, select = "xyzi")) the header is updated to remove the non-loaded extrabytes. This fixes the issue #234 and enables LAS objects to be written without updating the header manually.
- 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
lasmergespatialused with aSpatialPolygonDataFramewhen 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
tsearchthat searches in a triangulation is 25% faster giving a small speed-up topitfree()andtin()algorithms. - Enhance: in
lasmergespatialused with aSpatialPolygonDataFramethe function checks the bounding box of the polygon to speed-up the computation with complex polygons. - Doc: add a
?lidRpage to the manual. - 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
lasmergespatialwith aSpatialPolygonDataFramewhen the bounding boxes do not match instead of exiting early without searching anything the full search was performed uselessly.
- Fix: #222
grid_*()functions return consistently aRasterLayerif there is a single layer. virtual raster mosaic were returned asRasterStackno matter the number of layers. - Fix: #223
lasmergespatial()wrongly copied shapefile attributes to each point when the parameterattributewas 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.
- Change: the function
cataloghas been slightly modified in prevision of the release of the packagerlas 1.3.0to preserve future compatibility. This is invisible for the users. - New:
lasnormalizegained a parameterna.rm = TRUE - Fix: an error occured when plotting a LAScatalog with the option
chunk_pattern = TRUE: object 'ctg' not found. - Fix: examples in documentation of
tin()andknnidw()were inverted. - Fix: #213 bug when using option
keep_lowestingrid_terrain. - Fix: #212 bug when merging big rasters that exceed 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
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:
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_detectiondid 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
LAScatalogbut not multipart-polygons or polygons with holes. This was only possible withLASobjects i.e loaded in memory (inconsistent behaviors within a function). - It was possible to run
grid_metrics()on aLAScatalogi.e. over a wide area not loaded in memory, but notlasnormalize,lasgroundortree_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())LAS class
- Change: the
LASclass is now aSpatialobject or, more technically, it inherits aSpatialobject. - Change: being a
Spatialobject, aLASobject no longer has a@crsslot. It has now a slot@proj4stringthat is accessible with the functionsraster::projectionorsp::proj4string - New: being a
Spatialobject, aLASobject inherits multiple functions fromrasterandsp, such$and[[accessors orraster::extent,sp::bbox,raster::projection, and so on. However, the replacement method$<-,[[<-have restricted capabilities to ensure aLASobject cannot be modified in a way that implies loosening the properties of the LAS specifications. - New: empty
LASobjects with 0 points are now allowed. This has repercussions for several functions includinglasfilter,lasclip, andreadLASthat do not returnNULLfor empty data but aLASobject with 0 points. This new behavior has been introduced to fix the old inconsistent behavior of functions that return eitherLASorNULLobjects.LASobjects are always returned.
LAScatalog class
- Change: the
LAScatalogclass is now aSpatialPolygonsDataFrameor, more technically, it inherits aSpatialPolygonsDataFrame. - Change: being a
SpatialPolygonsDataFrameobject, aLAScatalogno longer has a@crsslot. It has now a slot@proj4stringthat is accessible with the functionsraster::projectionorsp::proj4string. - Change: being a
SpatialPolygonsDataFrameaLAScatalogcan 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_optionsand@input_optionsthat 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,bufferwere 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 fromrasterorsp. - Change: standard column names were renamed to make syntactically-valid names and for compatibility with
spfunctions.
readLAS
- Change:
readLASno longer supports optionPFC. Users must use the functionslaspulse,lasflightlinesmanually.
lasclip
- New:
lasclipnow works both with aLASobject and aLAScatalogobject in a seamless and consistent way. There are no longer any differences between the capabilities of theLASversion or theLAScatalogone. - New:
lasclipsupport many geometries including multipart polygons and polygons with holes, both with aLASobject and aLAScatalogobject. - Change: The option
insidehas been removed for consistency because it cannot be safely supported both onLASandLAScatalog. - Change: The option
ofilehas been removed for consistency and this option in now managed by theLAScatalogprocessing engine. For example, one can extract ground inventories and write them inlazfiles 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:
lasclipdoes not returnNULLanymore for empty queries but an emptyLASobject. - Fix:
lasclipRectanglereturns the same output both with aLASand aLAScatalog. With aLASthe rectangle is now closed on the bottom and the left and open on the right and the top.
catalog_queries
- Change:
catalog_querieshas been removed because it is superseded bylasclip.
lasnormalize
- Change:
lasnormalize()no longer updates the original object by reference. - Change: remove the old option
copy = TRUEthat is now meaningless. - Change:
lasnormalize()now relies on lidR algorithms dispatch (see also the main new features above). - New:
lasnormalize()can be applied on aLAScatalogto 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 namelasclassifythat 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 withdoubleinstead ofint.
tree_detection
- Change:
tree_detection()now relies on the new dispatch method (see also the main new features above). - New: algorithm
lmfhas user-defined variable-sized search windows and two possible search window shapes (square or disc). - New: introduction of the
manualalgorithm for manual correction of tree detection. - New:
tree_detectionalgorithms are seamlessly useable with aLAScatalogobject 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
lmfalgorithm, when used with aRasterLayeras input, expects parameters given in the units of the map and no longer in pixels. - Change:
tree_detection()function consistently returns aSpatialPointsDataFramewhatever the algorithm. - Change:
tree_detection()function based on a CHM no longer support alasmetricobject as input. Anyway, this class no longer exists.
tree_metrics
- Change:
tree_metrics()returns aSpatialPointsDataFrame. - Change:
tree_metrics()is seamlessly useable with aLAScatalogusing 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
mcwatershedalgorithm that implements a marker-controlled watershed.
grid_metrics
- Change:
grid_metrics()as well as othergrid_*functions consistently return aRasterLayeror aRasterBrickinstead of adata.table. - Change: option
splitlineshas been removed.grid_metrics()used to return adata.tablebecause of thesplitlinesoption and lidR was built on top of that feature from the very beginning. Now lidR consistently usesspandrasterand 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 aRasterLayerinstead 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 aRasterLayerinstead 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()aredsmtinandpitfree.
grid_hexametrics
- Change: as for
grid_metrics, the parametersplitlineshas been removed. - Change: the function returns a
hexbinobject or a list ofhexbinobjects and no longerdata.tableobjects.
grid_catalog
- Change:
grid_catalog()has been removed. The newLAScatalogprocessing engine means that this function is no longer useful.
class lasmetrics
data.tablewith a classlasmetricsno longer exists. It has been consistently replaced byRasterLayerandRasterBrickeverywhere.as.rasterno longer exists because it used to convertlasmetricsintoRasterLayerandRasterStack.as.spatialno longer convertslasmetricstoSpatialPixelsDataFramebut still convertsLAStoSpatialPointsDataFrame.plot.lasmetricshas 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
highestavailable 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 aLAScatalogto 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.lazcontains the segmented trees in extra bytes 0.
plot
- New:
plot()forLASobjects supportsRGBas a color attribute. - New: option
colorsupports lazy evaluation. This syntax is correct:plot(las, color = Classification). - New: option
clear_artifact = TRUEshifts 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_dtm3dandplot_dtm3dadd elements in the point cloud. - Change:
trimdoes 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
lastranformthat returns transformed coordinates of aLASobject using the CRS argument.
New functions
- New: function
lasfilterduplicates - New: function
lascheck - New: function
lasvoxelize
- Change: the code that drives the
point_in_polygonalgorithm relies onboostand drastically simplifies the former code oflasmergespatial() - Change: many memory optimizations
- [#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_applyon Windows.
- New function
tree_hullsthat computes a convex or concave hull for each segmented tree. - New option
stop_earlythat enables processing of an entire catalog or stops if an error occurs. - New function
catalog_retilesupersedes the functioncatalog_reshapeand performs the same task while adding much more functionality.
- When processing a
LAScatalog, error handling has been seriously 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()forLASobject preserves the CRS.- All the functions now have strong assertions to check user inputs.
plot.LAScatalogalways displays the catalog withmapviewby default even if the CRS is empty.- In
lastrees_dalpontethe matching between the seeds and the canopy is more tolerant. Rasters can have different resolution and/or extent. lasgrounduses (as an option) only the last and single returns to perform the segmentation.
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
LAScatalogby cluster.
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_detectionwhen used with a point cloud was not properly coded and tended to miss some trees.- In
lasclip*ifofilewas non empty, the function wrote properly the file but returned a non-expected error. - [#155] user supplied function was being analyzed by
futureand some function were missing. User supplied function is now manually analyzed. - [#156] Fix error when
lasclipwas used with aSpatialPolygonDataFrame.
- The area of a
LAScatalogwas wrongly computed for non square tiles because of a bad copy/paste in the code. - [#135] Fix
NULLclass objects returned bygrid_*functions when processing aLAScatalogif the first cluster is empty. - [#143]
rumple_indexreturnsNAif not computable.
catalog_options()is formally deprecated. UseLAScatalogproperties instead (see?catalog).- The package
magrittris no longer loaded withlidR. Thus, piping operators are no longer usable by default. To use piping operators uselibrary(magrittr).
- New
lassmoothfunction. A point cloud-based smoothing function. - New
lasfiltersurfacepointsfunction to filter surface points. - New
grid_catalogfunction is a simplified and more powerful function likecatalog_applybut specifically dedicated togrid_*outputs. - New functions
lasadddata,lasaddextrabyteandlasaddextrabyte_manualto add new data in aLASobject. lasclipcan clip aSpatialPolygonsDataFramelasclipRectangleandlasclipCirclecan clip multiple selections (non-documented feature).- The
treeIDcomputed withlastrees_*functions can now be written in alas/lazfile by default.
LAScatalogobjects are processed with a single core by default.lasdecimateis formally deprecated. Uselasfilterdecimategrid_densitynow returns both the point and the pulse density, where possible.- The option
Pis no longer set by default inreadLAS. - The documentation of
lastreeshas 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.
grid_metrics(lidar, stdmetrics_i(Intensity))returned and emptydata.table- [#128] Fix raster data extraction using the slower and memory-greedy, but safer
raster::extractfunction. - [#126] propagate the CRS in filter functions.
- [#116] Fix clash between function
areafromlidRand fromraster. - [#110] Fix out-of-bounds rasterization.
- [#103] fix user-defined function not exported in clusters on Windows
- [#104] fix potential bin exclusion in
entropyfunction - [#106] fix wrong count of points below 0
- Fix wrong type attribution in
lasclassifywhen using the shapefile table of attributes as data. - Fix column addition when
field = NULLinlasclassify. - Fix
NAreturn in entropy when negative value are found.
- Li et al algorithm has a new parameter Zu (see reference) that is no longer hard coded.
- Removed examples and unit tests that imply the watershed segmentation to make CRAN check happy with the new rules relative to bioconductor packages.
- Parameter
starthas been enabled ingrid_metricswithcatalogs.
lasclipandlasclip*can extract from a catalog.lasclipsupportssp::Polygonobjects.lastreesgains a new algorithm from Silva et al. (2016).lastreeswith the Li et al. (2012) algorithm gains a new parameter to prevent over-segmentation.- new function
lassnagsfor classifying points as snag points or for segmenting snags. - new function
tree_detectionto 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. plotsupports natively thePointCloudViewerpackage available on github.
- Fix missing pixel in DTM that made normalization impossible.
- [#80] fix segfault.
- [#84] fix bug in
lasscanline.
lastreeswith the Li et al. (2012) algorithm is now 5-6 times faster and much more memory efficient.lastreeswith the Li et al. (2012) algorithm no longer sorts the original point cloud.lastreeswith 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 optionsubcircleor without it.grid_canopy()with the optionsubcircleuses 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.lasclassifynow uses a QuadTree and is therefore faster. This enables several algorithms to run faster, such aslastreeswith Silva's algo.
lasgroundwith the PMF algorithm now accepts user-defined sequences.lasgroundwith the PMF algorithm has simplified parameter names to make them easier to type and understand, and to prepare the package for new algorithms.lasgrounddocumentation is more explicit about the actual algorithm used.lasgroundnow computes the windows size more closely in line with the original Zhang paper.lastreeswhen used with raster-based methods now accepts a missing las object. In that caseextrais turned totrue.- new parameter
p(for power) added to functions that enable spatial interpolation with IDW.
- Fix a bug of computer precision leading to non interpolated pixels at the boundaries of the QuadTree.
This version is dedicated to extending functions and processes to entire catalogs in a continuous way. Major changes are:
- How
catalog_applyworks. More powerful but no longer compatible with previous releases - Former existing functions that now natively support a
Catalog - Management of buffered areas
catalog_applyhas been entirely re-designed. It is more flexible, more user-friendly and enables loading of buffered data.catalog_querieshas now an argument...to pass any argument ofreadLAS.catalog_querieshas now an argumentbufferto load extra buffered points around the region of interest.grid_metricsaccepts a catalog as input. It allows users to grid an entire catalog in a continuous way.grid_densityalso inherits this new featuregrid_terrainalso inherits this new featuregrid_canopyalso inherits this new featuregrid_tincanopyalso inherits this new featuregrid_metricshas now has an argumentfilterfor streaming filters when used with a catalog- New function
catalog_reshape
lasnormalizeupdates the point cloud by reference and avoids making deep copies. An optioncopy = TRUEis available for compatibility with former versions.readLASarguments changed. The new syntax is simpler. The previous syntax is still supported.catalog_indexis no longer an exported function. It is now an internal function.plot.Catalogaccepts the usualplotargumentscatalog_queriesandcatalog_applydo not expect a parametermc.cores. This is now driven by global options incatalog_options().grid_metricsandlasmetricsdo not expect a parameterdebug. This is now driven by global options inlidr_options.catalogcan 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_selectis more pleasant an more interactive to use.- S3
Catalogclass is now a S4LAScatalogclass LASandLAScatalogclass gain a slotcrsautomatically filled with a proj4 stringplot.LAScatalogdisplay a google map background if the catalog has a CRS.plot.LAScataloggains an argumentyto display a either a terrain, road, satellite map.lasareais deprecated. Use the more generic functionarea
- Computer precision errors lead to holes in raster computed from a Delaunay triangulation.
- Message in
writeLASfor skipped fields when no field is skipped is now correct.
grid_terrainwith delaunay allocates less memory, makes fewer deep copies and is 2 to 3 times fastergrid_terrainwith knnidw allocates less memory, makes fewer deep copies and is 2 to 3 times fasterlasnormalizeandlasclassifyno longer rely onraster::extractbut on internalfast_extract, which is memory efficient and more than 15 times faster.catalogenables aLAScatalogto be built 8 times faster than previously.- removed dependencies to
RANNpackage using internal k-nearest neighbor search (2 to 3 times faster)
- new function
tree_metrics. - new function
stdtreemetrics. grid_tincanopy()gains a parametersubcirclelikegrid_canopy()- new function
rumple_indexfor measuring roughness of a digital model (terrain or canopy) - global options to parameterize the package - available with
lidr_options()
- 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 integers. Replaced by std::fabs which works with doubles.
- In
grid_tincanopyx > 0was replaced byx >= 0to avoid errors in the canopy height models - Triangle boundaries are now taken into account in the rasterization of the Delaunay triangulation
lastreesLi 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_tincanopymakes the triangulation only for highest return per grid cell.grid_tincanopyandgrid_terrainusing Delaunay triangulation is now ten to a hundred times faster than in v1.2.0as.rasternow relies onspand is more flexibleas.rasterautomatically returns aRasterStackif no layer is provided.plot.lasmetricsinheritsas.rasterchanges and can display aRasterStack
- new function
lasgroundfor 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. lasnormalizeallows for "non-discretized" normalization i.e interpolating each point instead of using a raster.- internally
lascheckperforms more tests to check if the header is in accordance with the data.
- [#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_zwhenmax(Z) = 0 - [#54] better re-computation of the header of LAS objects.
- Slightly faster point classification from shapefiles.
- [#51] in
grid_terrain, forcing the lowest point to be retained is now an optionkeep_lowest = FALSE
lastree()for individual tree segmentationreadLAS()gains a parameterfilterfromrlas (>= 1.1.0)catalog_queries()relies onrlas (>= 1.1.0). It saves a lot of memory, is 2 to 6 times faster and supports .lax files.
colorPaletteparameter 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 object called
LASheader - The spatial interpolation method
akimais now calleddelaunaybecause it corresponds to what is actually computed. - The spatial interpolation method
akimalost its parameterlinear. - The spatial interpolation method
krigingnow 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.
- The header of LAS objects automatically updates
Number of point recordsandNumber of nth return. lasnormalize()updates the header and returns warnings for some behaviors- [#39] interpolation with duplicated ground points
Third submission
- Change: explain LiDAR in the Description - requested by Kurt Hornik.
Second submission - rejected
- Change: split the package in two parts. 'lidR' relies on 'rlas' to read binary files.
First submission - rejected