lidR v2.1.2 (Release date: 2019-08-07)

  1. Fix a serious issue of unitialized values in an internal C++ function but this issue is consequentless for the package.

lidR v2.1.1 (Release date: 2019-08-06)

NEW FEATURES

  1. #266 lasmetrics has now a dispatch to LAS and LAScluster cluster objects. It means that lasmetrics can be used with catalog_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

  1. lastrees now uses S3 dispatcher system. When trying to use it with a LAScatalog object, user will have a standard R message to state that LAScatalog is not supported instead of an uninformative message that state that ‘no slot of name “header” for this object of class “LAScatalog”’

  2. 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 parameter p in catalog_apply() failed because of partial matching between the true argument p and the internal argument processing_option.

  3. lasfilterdecimate with algorithm highest is now more than 20 times faster. lasfiltersurfacepoints, being a proxy of this algorithm, had the same speed-up

  4. plot for LAS objects gained the pan capability.

FIXES

  1. #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).

lidR v2.1.0 (Release date: 2019-07-13)

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

  1. readLAS():
  2. Coordinate Reference System:
  3. LAScatalog processing engine:
    An error occurred when processing the chunk 190. Try to load this chunk with:
    chunk <- readRDS("/tmp/RtmpAlHUux/chunk190.rds")
    las <- readLAS(chunk)
  4. grid_metrics():
  5. New functions lasdetectshape() for water and human-made structure detection with three algorithms shp_plane(), shp_hplane(), shp_line().

  6. plot():
  7. tree_hull():
  8. Miscellaneous tools:
  9. Several functions are natively parallelized at the C++ level with OpenMP. See help("lidR-parallelism") for more details.

  10. New function catalog_select for interactive tile selection.

  11. lasground have lost the argument last_returns for a mor generic argument filter. Retro-compatibility as been preserved by interpreting adding an ellipsis.

NOTE

  1. grid_metrics(), grid_metrics3d(), tree_metrics(), tree_hull(), grid_hexametrics() and lasmetrics() expect a formula as input. Users should not write grid_metrics(las, mean(Z)) but grid_metrics(las, ~mean(Z)). The first syntax is still valid, for now.

  2. The argument named field in tree_metrics() is now named attribute for consistency with all other functions.

  3. The documentation of supported options in tree_*() functions was inccorect and has been fixed.

  4. readLAScatalog() replaces catalog(). catalog() is soft-deprecated.

FIX

  1. #264 grid_terrain now filter degenerated ground points.

  2. #238 fix a floating point precision error in p2r algorithm.

ENHANCEMENT
  1. 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.

lidR v2.0.3 (Release date: 2019-05-02)

lidR v2.0.2 (Release date: 2019-03-02)

lidR v2.0.1 (Release date: 2019-02-02)

lidR v2.0.0 (Release date: 2019-01-02)

Why versions > 2.0 are incompatible with versions 1.x.y?

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:

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:

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

LAScatalog class

readLAS

lasclip

ctg = catalog(folder)
output_files(ctg) <- "path/to/a/file_{XCENTER}_{YCENTER}"
laz_compression(ctg) <- TRUE
new_ctg = lasclipCircle(ctg, xc,yc, r)

catalog_queries

lasnormalize

lasclassify

tree_detection

ctg  <- catalog(folder)
ttop <- tree_detection(ctg, lmf(5))

tree_metrics

ctg <- catalog(folder)
metrics <- tree_metrics(ctg, list(`Mean I` = mean(Intensity)))

lastrees

grid_metrics

grid_terrain

grid_canopy

grid_tincanopy

grid_hexametrics

grid_catalog

class lasmetrics

lasroi

lascolor

lasfilterdecimate

lassnags

lidr_options

Example files

plot

Coordinate reference system

New functions

Other changes that are not directly visible

lidR v1.6.1 (2018-08-21)

BUG FIXES

lidR v1.6.0 (2018-07-20)

NEW FEATURE

ENHANCEMENTS

OTHER CHANGES

BUG FIXES

lidR v1.5.1 (2018-06-14)

BUG FIXES

lidR v1.5.0 (2018-05-13)

SIGNIFICANT CHANGES

NEW FEATURES

OTHER CHANGES

BUG FIXES

lidR v1.4.2 (2018-04-19)

BUG FIXES

NEW FEATURES

lidR v1.4.1 (2018-02-01)

OTHER CHANGES

NEW FEATURES

lidR v1.4.0 (2018-01-24)

NEW FEATURES

BUG FIXES

ENHANCEMENTS

OTHER CHANGES

lidR v1.3.1 (Release date: 2017-09-20)

BUG FIXES

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:

NEW FEATURES

OTHER CHANGES

BUG FIXES

ENHANCEMENTS

lidR v1.2.1 (Release date: 2017-06-12)

NEW FEATURES

BUG FIXES

OTHER CHANGES

lidR v1.2.0 (Release date: 2017-03-26)

NEW FEATURES

BUG FIXES

OTHER CHANGES

lidR v1.1.0 (Release date: 2017-02-05)

NEW FEATURES

OTHER CHANGES

BUG FIXES

lidR v1.0.2 (Release date: 2016-12-31)

Third submission

lidR v1.0.1 (Release date: 2016-12-30)

Second submission - rejected

lidR v1.0.0 (Release date: 201-12-16)

First submission - rejected