Commit 1b5eaecd authored by Monnet Jean-Matthieu's avatar Monnet Jean-Matthieu
Browse files

version 4.0.1

parent 71247303
Package: lidaRtRee
Type: Package
Version: 4.0.0
Version: 4.0.1
Title: Forest Analysis with Airborne Laser Scanning (LiDAR) Data
Date: 2022-05-06
Date: 2022-05-23
Authors@R: c(
person("Jean-Matthieu", "Monnet", email = "jean-matthieu.monnet@inrae.fr", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-9948-9891")),
person("Pascal", "Obstétar", email = "pascal.obstetar@onf.fr", role = c("ctb"), comment = c(ORCID = "0000-0002-2811-7548")))
......@@ -10,11 +10,9 @@ Description: Provides functions for forest analysis using airborne laser scannin
URL: https://gitlab.irstea.fr/jean-matthieu.monnet/lidaRtRee
BugReports: https://gitlab.irstea.fr/jean-matthieu.monnet/lidaRtRee/-/issues
Depends: R (>= 4.0.0)
Imports: graphics, stats, methods, grDevices, terra, sf, stars, raster, imager, leaps, gvlma, car, reldist, lidR (>= 4.0.0)
License: GPL-3
Imports: graphics, stats, methods, grDevices, terra, sf, imager, leaps, gvlma, car, reldist, lidR (>= 4.0.0)
Suggests: stars, raster
License: GPL-3 + file LICENSE
LazyData: TRUE
RoxygenNote: 7.2.0
Encoding: UTF-8
Suggests:
testthat (>= 3.0.0)
Config/testthat/edition: 3
This diff is collapsed.
# Generated by roxygen2: do not edit by hand
export(.aba_metrics)
export(aa_las_chablais3)
export(aba_build_model)
export(aba_combine_strata)
export(aba_inference)
......@@ -31,7 +32,7 @@ export(maxima_detection)
export(maxima_selection)
export(plot_matched)
export(plot_tree_inventory)
export(pointList2sfPoly)
export(pointList2poly)
export(points2DSM)
export(points2DTM)
export(polar2Projected)
......
......@@ -358,9 +358,9 @@ lma_check <- function(formule,
#-------------------------------------------------------------------------------
#' Box-Cox Transformation
#'
#' @param x vector or RasterLayer. values to be transformed
#' @param x vector or raster. values to be transformed
#' @param lambda numeric. parameter of Box-Cox transformation
#' @return a vector or RasterLayer of transformed values
#' @return a vector or raster of transformed values
#' @seealso \code{\link{boxcox_itr}} inverse Box-Cox transformation,
#' \code{\link{boxcox_itr_bias_cor}} inverse Box-Cox transformation with bias correction.
#' @examples
......@@ -402,9 +402,9 @@ boxcox_tr <- function(x, lambda) {
#-------------------------------------------------------------------------------
#' Inverse Box-Cox transformation
#'
#' @param x vector or RasterLayer. values to be transformed
#' @param x vector or raster values to be transformed
#' @param lambda numeric. parameter of Box-Cox transformation
#' @return a vector or RasterLayer of transformed values
#' @return a vector or raster of transformed values
#' @seealso \code{\link{boxcox_tr}} Box-Cox transformation,
#' \code{\link{boxcox_itr_bias_cor}} inverse Box-Cox transformation with bias
#' correction.
......@@ -449,15 +449,15 @@ boxcox_itr <- function(x, lambda) {
#' Inverse Box-Cox transform with bias correction as suggested by Pu & Tiefelsdorf
#' (2015). Here `varmod` is not the local prediction variance as suggested in
#' the paper but the model residuals variance. For variance computation,
#' use `n-p` instead of `n-1`, with `p` the number of variables in the model.
#' uses `n-p` instead of `n-1`, with `p` the number of variables in the model.
#'
#' @param x vector or RasterLayer. values to be transformed
#' @param x vector or raster values to be transformed
#' @param lambda numeric. parameter of Box-Cox transformation
#' @param varmod numeric. model residuals variance
#' @references Xiaojun Pu and Michael Tiefelsdorf, 2015. A variance-stabilizing
#' transformation to mitigate biased variogram estimation in heterogeneous
#' surfaces with clustered samples. \doi{10.1007/978-3-319-22786-3_24}
#' @return a vector or RasterLayer
#' @return a vector or raster
#' @seealso \code{\link{boxcox_tr}} Box-Cox transformation,
#' \code{\link{boxcox_itr}} inverse Box-Cox transformation.
#' @examples
......@@ -507,7 +507,7 @@ boxcox_itr_bias_cor <- function(x, lambda, varmod) {
#' \itemize{
#' \item \code{model}: a list of regression models corresponding to each stratum
#' (output from \code{\link[stats]{lm}}),
#' \item \code{stats}:model statistics of each stratum-specific model (as in
#' \item \code{stats}: model statistics of each stratum-specific model (as in
#' \code{\link{aba_build_model}}) plus one line corresponding to statistics for all
#' strata (COMBINED)
#' \item \code{values}: data.frame with observed and values predicted in
......@@ -614,7 +614,7 @@ aba_combine_strata <- function(model.list, plotsId = NULL) {
#' black for single models, depends on stratum in stratified models
#' @param add_legend list. parameters to be passed to \code{\link[graphics]{legend}}. In case of a stratified model, legend is automatically set up.
#' @param ... other parameters to be passed to \code{\link[graphics]{plot}},
#' \code{xlab} and \code{ylab} are automatically setup
#' \code{xlab} and \code{ylab} are automatically added
#' @examples
#' # load Quatre Montagnes dataset
#' data(quatre_montagnes)
......@@ -691,7 +691,7 @@ aba_plot <-
#' \code{\link[lidR]{pixel_metrics}}
#' @param stratum string. indicates which layer of metrics.map contains the
#' \code{stratum} in case of a stratified \code{aba.model}. The layer should have a RAT
#' including a column with the same name (see \code{\link[raster]{is.factor}}).
#' including a column with the same name (see \code{\link[terra]{is.factor}}).
#' @param add_error boolean. indicates whether errors sampled from a normal distribution
#' N(0, sigma(residuals)) should be added to fitted values; implemented only for
#' \code{log} transformation case
......
......@@ -2,6 +2,25 @@
# Copyright INRAE
# Author(s): Jean-Matthieu Monnet
# Licence: GPL-3
#-------------------------------------------------------------------------------
#' Load las_chablais3
#'
#' Loads the external data: Airborne laser scanning data over the
#' Chablais 3 plot, acquired in 2009 by Sintegra
#' @return An object of class \code{\link[lidR]{LAS}}.
#' @seealso \code{\link{las_chablais3}}
#' @examples
#' las_chablais3 <- aa_las_chablais3()
#' @keywords internal
#' @export
aa_las_chablais3 <- function() {
LASfile <- system.file("extdata", "las_chablais3.laz", package="lidaRtRee")
las_chablais3 <- lidR::readLAS(LASfile)
# set projection
lidR::projection(las_chablais3) <- 2154
las_chablais3
}
#-------------------------------------------------------------------------------
#' Digital Surface Model
#'
......@@ -61,8 +80,7 @@ points2DSM <- function(.las, res = 1, xmin, xmax, ymin, ymax) {
#' resolution. Cell value is compute as the bilinear interpolation at the cell
#' center form an Delaunay triangulation. Relies on \code{\link[lidR]{rasterize_terrain}}
#' with algorithm \code{\link[lidR]{tin}}. In case a LAS object is provided, only
#' points classified as ground or water (2 or 9) will be used; a warning is issued
#' when the raster output inherits the projection info from LAS input.
#' points classified as ground or water (2 or 9) will be used.
#'
#' @param .las \code{\link[lidR]{LAS}} object or XYZ matrix/data.frame containing
#' only ground points
......@@ -366,7 +384,7 @@ plot_tree_inventory <- function(xy, height = NULL, diam = NULL,
#' @seealso \code{\link{raster_chull_mask}}
#' @examples
#' # create raster
#' r <- terra::rast(xmin=0, xmax = 40, ymin = 0, ymax = 40, resolution = 1, crs=NA)
#' r <- terra::rast(xmin=0, xmax = 40, ymin = 0, ymax = 40, resolution = 1, crs= NA )
#'
#' # xy positions
#' xy <- data.frame(
......@@ -484,7 +502,7 @@ raster_chull_mask <- function(xy, r) {
#' lines(ellipses1[[2]])
#' lines(ellipses2[[1]], col = "red")
#' lines(ellipses2[[2]], col = "red")
#' @seealso \code{\link{pointList2sfPoly}}
#' @seealso \code{\link{pointList2poly}}
#' @export
ellipses4Crown <- function(x, y, n, s, e, w, id = NULL, step = pi / 12,
angle.offset = 0) {
......@@ -539,61 +557,61 @@ ellipses4Crown <- function(x, y, n, s, e, w, id = NULL, step = pi / 12,
}
}
#' #-------------------------------------------------------------------------------
#' #' Convert list of points into Spatial Polygons DataFrame object
#' #'
#' #' Converts a list of points specifying polygons into a Spatial Polygons DataFrame
#' #' object
#' #'
#' #' @param points.list list of dataframes of xy coordinates. The first and last
#' #' coordinates in each dataframe must be the same
#' #' @param df data.frame. Optional data.frame to be associated to Spatial Polygons
#' #' @param ... arguments to be passed to \code{\link[sp]{SpatialPolygons}}
#' #' @return an object of class \link[sp]{SpatialPolygons-class}, or class
#' #' \link[sp]{SpatialPolygonsDataFrame-class} if input data.frame is specified.
#' #' @examples
#' #' # Compute coordinates of polygons
#' #' ellipses <- ellipses4Crown(c(0, 10), c(0, 10), c(2, 2), c(3, 4), c(2.5, 3), c(2, 3),
#' #' id = c("A", "B")
#' #' )
#' #' # Convert to Spatial object
#' #' ellipses1 <- pointList2SPDF(ellipses)
#' #' ellipses1
#' #' # Convert to Spatial object with data.frame
#' #' ellipses2 <- pointList2SPDF(ellipses, df = data.frame(info = 1:2))
#' #'
#' #' # draw ellipses
#' #' sp::plot(ellipses2, col = ellipses2$info)
#' #' @seealso \code{\link{ellipses4Crown}}
#' #' @export
#' pointList2SPDF <- function(points.list, df = NULL, ...) {
#' # convert each element of list of coodinates to Polygon
#' H <- lapply(points.list, FUN = function(x) {
#' sp::Polygon(x, hole = F)
#' })
#' # convert to Polygons
#' Hs <- lapply(H, function(x) {
#' sp::Polygons(list(x), "temp")
#' })
#' # change ID
#' if (!is.null(names(points.list))) {
#' for (i in 1:length(Hs)) {
#' Hs[[i]]@ID <- names(points.list)[i]
#' }
#' }
#' # convert to spatial polygons
#' sp.H <- sp::SpatialPolygons(Hs, ...)
#' if (!is.null(df)) {
#' sp::SpatialPolygonsDataFrame(sp.H, df, match.ID = FALSE)
#' } else {
#' sp.H
#' }
#' }
# #-------------------------------------------------------------------------------
# #' Convert list of points into Spatial Polygons DataFrame object
# #'
# #' Converts a list of points specifying polygons into a Spatial Polygons DataFrame
# #' object
# #'
# #' @param points.list list of dataframes of xy coordinates. The first and last
# #' coordinates in each dataframe must be the same
# #' @param df data.frame. Optional data.frame to be associated to Spatial Polygons
# #' @param ... arguments to be passed to \code{\link[sp]{SpatialPolygons}}
# #' @return an object of class \link[sp]{SpatialPolygons-class}, or class
# #' \link[sp]{SpatialPolygonsDataFrame-class} if input data.frame is specified.
# #' @examples
# #' # Compute coordinates of polygons
# #' ellipses <- ellipses4Crown(c(0, 10), c(0, 10), c(2, 2), c(3, 4), c(2.5, 3), c(2, 3),
# #' id = c("A", "B")
# #' )
# #' # Convert to Spatial object
# #' ellipses1 <- pointList2SPDF(ellipses)
# #' ellipses1
# #' # Convert to Spatial object with data.frame
# #' ellipses2 <- pointList2SPDF(ellipses, df = data.frame(info = 1:2))
# #'
# #' # draw ellipses
# #' sp::plot(ellipses2, col = ellipses2$info)
# #' @seealso \code{\link{ellipses4Crown}}
# #' @export
# pointList2SPDF <- function(points.list, df = NULL, ...) {
# # convert each element of list of coodinates to Polygon
# H <- lapply(points.list, FUN = function(x) {
# sp::Polygon(x, hole = F)
# })
# # convert to Polygons
# Hs <- lapply(H, function(x) {
# sp::Polygons(list(x), "temp")
# })
# # change ID
# if (!is.null(names(points.list))) {
# for (i in 1:length(Hs)) {
# Hs[[i]]@ID <- names(points.list)[i]
# }
# }
# # convert to spatial polygons
# sp.H <- sp::SpatialPolygons(Hs, ...)
# if (!is.null(df)) {
# sp::SpatialPolygonsDataFrame(sp.H, df, match.ID = FALSE)
# } else {
# sp.H
# }
# }
#-------------------------------------------------------------------------------
#' Convert list of points into sf polygons object
#' Convert a list of points into spatial polygons object
#'
#' Converts a list of points specifying polygons into an sf object
#' Converts a list of points specifying polygons into a spatial object
#'
#' @param points_list list of data frames of xy coordinates. In each data.frame
#' the last row must be the same as the first row
......@@ -606,21 +624,21 @@ ellipses4Crown <- function(x, y, n, s, e, w, id = NULL, step = pi / 12,
#' id = c("A", "B")
#' )
#' # Convert to sf object
#' ellipses1 <- pointList2sfPoly(ellipses)
#' ellipses1 <- pointList2poly(ellipses)
#' ellipses1
#' # Convert to sf object with user-defined data.frame
#' ellipses2 <- pointList2sfPoly(ellipses, df = data.frame(info = 1:2))
#' ellipses2 <- pointList2poly(ellipses, df = data.frame(info = 1:2))
#'
#' # draw ellipses
#' plot(ellipses2, col = ellipses2$info)
#' @seealso \code{\link{ellipses4Crown}}
#' @export
pointList2sfPoly <- function(points_list, df = NULL, ...) {
pointList2poly <- function(points_list, df = NULL, ...) {
points_list <- lapply(points_list, function(x) list(x))
# convert each element of list of coordinates to polygon
polygons <- lapply(points_list, sf::st_polygon)
# convert to geometry collection
polygons <- sf::st_sfc(polygons)
polygons <- sf::st_sfc(polygons, ...)
# add data.frame
if (is.null(df))
{
......
......@@ -4,20 +4,16 @@
#'
#' @details Additional information about the data
#' \itemize{
#' \item{Sensor: RIEGL LMS-Q560)}
#' \item{Sensor: RIEGL LMS-Q560}
#' \item{EPSG code of coordinates system: 2154}
#'}
#'
#' @docType data
#'
#' @format A compressed LAS file
#'
#' @keywords datasets
#'
#' @references Monnet, J.-M. 2011. Using airborne laser scanning for mountain forests mapping: Support vector regression for stand parameters estimation and unsupervised training for treetop detection. Ph.D. thesis. University of Grenoble, France. pp. 21-22. \url{https://tel.archives-ouvertes.fr/tel-00652698/document}
#'
#' @source Monnet J.-M. INRAE
#'
#' @seealso \code{\link{chm_chablais3}}, \code{\link{tree_inventory_chablais3}}
#' @examples
#' LASfile <- system.file("extdata", "las_chablais3.laz", package="lidaRtRee")
#' las_chablais3 <- lidR::readLAS(LASfile)
......
......@@ -15,7 +15,7 @@
#' @return A data frame with metrics in columns corresponding to LAS objects of
#' the list (lines)
#' @seealso \code{\link[lidR]{cloud_metrics}}, \code{\link[lidR]{stdmetrics}},
#' \code{\link{aba_metrics}}
#' \code{\link{aba_metrics}}, \code{\link[lidR]{pixel_metrics}}
#' @examples
#' # load LAS file
#' LASfile <- system.file("extdata", "las_chablais3.laz", package="lidaRtRee")
......@@ -117,10 +117,11 @@ clouds_metrics <- function(llasn,
#' llas <- lapply(llas, function(x) {
#' lidR::normalize_height(x, lidR::tin())
#' })
#' # computes metrics including strata
#' m1 <- clouds_metrics(llas, ~ aba_metrics(
#' # computes metrics
#' m <- clouds_metrics(llas, ~ aba_metrics(
#' Z, Intensity, ReturnNumber, Classification, 2
#' ))
#' head(m[,1:5])
#' @rdname aba_metrics
#' @export
aba_metrics <- function(z, i, rn, c, hmin = 2, breaksH = NULL) {
......@@ -181,7 +182,7 @@ aba_metrics <- function(z, i, rn, c, hmin = 2, breaksH = NULL) {
#' \item \code{Tree_meanCrownVolume}: mean volume of detected trees
#' \item \code{TreeCanopy_meanH}: mean height of union of crowns of detected trees
#' }
#' @seealso \code{\link{tree_extraction}}
#' @seealso \code{\link{tree_extraction}}, \code{\link{clouds_tree_metrics}}, \code{\link{raster_metrics}}
#' @examples
#' # sample 50 height values
#' h <- runif(50, 5, 40)
......@@ -213,9 +214,9 @@ std_tree_metrics <- function(x, area_ha = NA) {
#' \itemize{
#' \item{exposition}
#' \item{altitude}
#' \item{slope}
#' \item{slope}.
#' }
#' values are computed after fitting a plane to the points. It supposes a
#' Values are computed after fitting a plane to the points. It supposes a
#' homogeneous sampling of the plot by points. Points can be cropped on disk if
#' center and radius are provided. In case a centre is provided, the altitude
#' is computed by bilinear interpolation at the center location
......@@ -269,7 +270,7 @@ terrain_points_metrics <- function(p, centre = NULL, r = NULL) {
return(NULL)
}
# compute plane equation
modlin <- stats::lm(Z ~ X + Y, data = data.frame(X = p$X, Y = p$Y, Z = p$Z))
modlin <- stats::lm(altitude ~ X + Y, data = data.frame(X = p$X, Y = p$Y, altitude = p$Z))
# model z=a+bx+cy
# normal vector: b c -1 (under plane)
a <- modlin$coefficients[1]
......@@ -292,7 +293,7 @@ terrain_points_metrics <- function(p, centre = NULL, r = NULL) {
as.numeric(centre[1]) - 0.5, as.numeric(centre[1]) + 0.5,
as.numeric(centre[2]) - 0.5, as.numeric(centre[2]) + 0.5
), resolution = 1)
altitude <- terra::values(lidR::rasterize_terrain(p, dummyRaster, lidR::tin()))
altitude <- as.numeric(terra::values(lidR::rasterize_terrain(p, dummyRaster, lidR::tin())))
} else {
altitude <- NA
}
......@@ -357,7 +358,7 @@ terrain_points_metrics <- function(p, centre = NULL, r = NULL) {
#' data.frame(Tree.between.20.30 = length(dummy), Tree.meanH = mean(dummy))
#' }
#' clouds_tree_metrics(llas,
#' cbind(c(974350, 974390, 974350), c(6581680, 6581680, 6581640)),
#' cbind(c(974350, 974390), c(6581680, 6581680)),
#' 8,
#' res = 0.5, func = user_func
#' )
......
......@@ -13,7 +13,7 @@
#' names nir, r, g
#' @param all boolean. indicates whether all indices should be computed;
#' default:FALSE, only grvi, sr and ndvi are calculated
#' @return a RasterStack or data.frame with added bands or columns
#' @return a raster or data.frame with added bands or columns
#' @examples
#' df <- data.frame(nir = c(110, 150, 20), r = c(25, 50, 30), g = c(10, 60, 10))
#' add_vegetation_indices(df, all = TRUE)
......
......@@ -6,12 +6,12 @@
#' Computes metrics by aggregating a raster at lower resolution or summarizing
#' attributes based on XY locations
#'
#' Compute statistics by aggregating a raster at lower resolution. Aggregation
#' Computes statistics by aggregating a raster at lower resolution. Aggregation
#' groups are larger cells, new values are computed by applying a user-specified
#' function to original cells contained in the larger cells. Results are provided
#' as a data.frame which also contains the XY coordinates of the larger cells.
#' as a data.frame with the XY coordinates of the larger cells, or as SpatRaster.
#'
#' @param r SpatRaster object or data.frame with xy coordinates in two first columns
#' @param r SpatRaster object, data.frame with xy coordinates in two first columns, or POINT \code{\link[sf]{sf}} spatial object
#' @param res numeric. Resolution of the aggregation raster, should be a multiple
#' of r resolution if a raster is provided
#' @param fun function. Function to compute metrics in each aggregated cell from
......@@ -19,7 +19,7 @@
#' values) / data.frame (use x$colum_name to access values)
#' @param output string. indicates the class of output object "raster" for a SpatRaster or "data.frame"
#' @return a data.frame with the XY center coordinates of the aggregated cells,
#' and the values computed with the user-specified function or a SpatRaster object
#' and the values computed with the user-specified function, or a SpatRaster object
#' @examples
#' data(chm_chablais3)
#' chm_chablais3 <- terra::rast(chm_chablais3)
......@@ -60,8 +60,18 @@ raster_metrics <-
# convert to data.frame
st <- terra::as.points(r)
st <- cbind(terra::geom(st)[, c("x", "y")], as.data.frame(terra::as.points(r)))
# backup crs
projinfo <- terra::crs(r)
} else {
st <- r
if (inherits(r, "sf")) {
# convert to data.frame
st <- cbind(data.frame(sf::st_coordinates(r)), sf::st_drop_geometry(r))
# backup crs
projinfo <- sf::st_crs(r)$wkt
} else {
st <- r
projinfo <- NA
}
}
# compute coordinates of new cell center at metrics resolution
dummy <- data.frame(X = round((st[, 1] - res / 2) / res) * res + res / 2,
......@@ -76,13 +86,14 @@ raster_metrics <-
# add id column or coordinates
if (output == "raster") {
if (nrow(dummy) > 1) {
terra::rast(dummy, type = "xyz", crs = terra::crs(r))
terra::rast(dummy, type = "xyz", crs = projinfo)
} else { # an error is returned by rasterFromXYZ when only one cell
# ??? still necessary for rast ?
# duplicate row
dummy2 <- rbind(dummy, dummy)
dummy2[2, c("X", "Y")] <- dummy2[1, c("X", "Y")] + res
# convert to raster
dummy2 <- terra::rast(dummy2, type = "xyz", crs = terra::crs(r))
dummy2 <- terra::rast(dummy2, type = "xyz", crs = projinfo)
# crop to original extent
terra::crop(dummy2, terra::ext(dummy$X-res/2, dummy$X+res/2, dummy$Y-res/2, dummy$Y+res/2))
}
......
......@@ -87,7 +87,7 @@ create_disk <- function(width = 5) {
#' @export
dem_filtering <- function(dem, nl_filter = "Closing", nl_size = 5, sigmap = 0.3,
padding = TRUE) {
# convert rasterLayer to cimg object if necessary
# convert raster to cimg object if necessary
if (inherits(dem, "SpatRaster")) {
dem.c <- raster2Cimg(dem)
} else {
......@@ -204,7 +204,7 @@ dem_filtering <- function(dem, nl_filter = "Closing", nl_size = 5, sigmap = 0.3,
#' @seealso \code{\link{dem_filtering}}, \code{\link{maxima_selection}}
#' @export
maxima_detection <- function(dem, dem.res = 1, max.width = 21, jitter = TRUE) {
# convert rasterLayer to cimg object if necessary
# convert raster to cimg object if necessary
if (inherits(dem, "SpatRaster")) {
dem_gs <- raster2Cimg(dem)
dem.res <- terra::res(dem)[1]
......@@ -238,7 +238,7 @@ maxima_detection <- function(dem, dem.res = 1, max.width = 21, jitter = TRUE) {
}
# convert window size from pixels to meters
maxi[maxi > 0] <- (maxi[maxi > 0] + 1) * dem.res
# convert cimg objects to rasterLayer if necessary
# convert cimg objects to raster if necessary
if (inherits(dem, "SpatRaster")) {
maxi <- cimg2Raster(maxi, dem)
}
......@@ -310,7 +310,7 @@ maxima_selection <- function(maxi, dem_nl, hmin = 0, dmin = 0, dprop = 0) {
maxi_c[dem_nl < hmin] <- 0
# distance filter
maxi_c[maxi_c < (dmin + dem_nl * dprop)] <- 0
# convert to rasterLayer if necessary
# convert to raster if necessary
if (israster) {
cimg2Raster(maxi_c, maxi)
} else {
......@@ -321,7 +321,7 @@ maxima_selection <- function(maxi, dem_nl, hmin = 0, dmin = 0, dprop = 0) {
#-------------------------------------------------------------------------------
#' Image segmentation by seed-based watershed algorithm
#'
#' performs a seed-based watershed segmentation (wrapper for imager::watershed)
#' performs a seed-based watershed segmentation (wrapper for \code{\link[imager]{watershed}})
#'
#' @param maxi cimg or SpatRaster object. image with seed points (e.g. from
#' \code{\link{maxima_detection}} or \code{\link{maxima_selection}})
......@@ -661,7 +661,7 @@ tree_segmentation <- function(dem, nl_filter = "Closing", nl_size = 5, sigma = 0
#' @param r_maxi SpatRaster object. raster with positive values at local maxima
#' @param r_dem_w SpatRaster object. segmented raster
#' @param r_mask SpatRaster object. only segments which maxima are inside the mask are extracted. Values should be NA outside the mask, 1 inside.
#' @return A sf collection of POINTs with 5 fields: tree id, local maximum stats (height, dominance radius), segment stats (surface and volume).
#' @return A sf collection of POINTs with 7 fields: tree id, local maximum stats (height, dominance radius), segment stats (surface and volume), coordinates (x and y).
#' @examples
#' data(chm_chablais3)
#' chm_chablais3 <- terra::rast(chm_chablais3)
......@@ -730,7 +730,9 @@ tree_extraction <- function(r_dem_nl, r_maxi, r_dem_w, r_mask = NULL) {
segms <- merge(segms, sp, all.x = TRUE)
segms <- merge(segms, vp, all.x = TRUE)
}
segms <- sf::st_as_sf(segms, coords = c("x", "y"))
segms$X <- segms$x
segms$Y <- segms$y
segms <- sf::st_as_sf(segms, coords = c("X", "Y"))
sf::st_crs(segms) <- terra::crs(r_dem_nl)
}
segms
......@@ -748,7 +750,7 @@ tree_extraction <- function(r_dem_nl, r_maxi, r_dem_w, r_mask = NULL) {
#' data(chm_chablais3)
#' chm_chablais3 <- terra::rast(chm_chablais3)
#'
#' # convert rasterLayer to cimg object
#' # convert raster to cimg object
#' chm_cim <- raster2Cimg(chm_chablais3)
#'
#' # apply filtering
......@@ -790,13 +792,13 @@ cimg2Raster <- function(cimg, r = NULL) {
#-------------------------------------------------------------------------------
#' SpatRaster to Cimg conversion
#'
#' converts a SpatRaster object to Cimg object. NA values in raster are replaced.
#' converts a SpatRaster object to cimg object. NA values in raster are replaced.
#'
#' @param r SpatRaster object. raster of canopy height model, preferably
#' filtered to avoid effect of holes on volume and surface computation
#' @param NA_replace numeric. value to replace NA values with.
#' @param maxpixels numeric. maximum number of pixels to be converted to cimg
#' (argument passed to as.cimg).
#' (argument passed to \code{\link{as.cimg}}).
#' @return A cimg object
#' @examples
#' data(chm_chablais3)
......@@ -818,7 +820,7 @@ raster2Cimg <- function(r, NA_replace = 0, maxpixels = 1e+10) {
r[is.na(r)] <- NA_replace
# convert to cimg object
if (ncol(r) * nrow(r) > maxpixels) {
warning("Too many rasterLayer pixels: conversion to cimg partial; try with higher maxpixels arguments")
warning("Too many raster pixels: conversion to cimg partial; try with higher maxpixels arguments")
}
imager::as.cimg(matrix(r, ncol = nrow(r)), maxpixels = maxpixels)
}
......@@ -27,5 +27,11 @@
#' @examples
#' data(tree_inventory_chablais3)
#' summary(tree_inventory_chablais3)
#' # display tree inventory
#' plot_tree_inventory(tree_inventory_chablais3[, c("x", "y")],
#' diam = tree_inventory_chablais3$d, col = "red",
#' pch = tree_inventory_chablais3$e,
#' xlab = "X", ylab = "Y"
#' )
NULL
"tree_inventory_chablais3"
......@@ -4,14 +4,15 @@
# Installation
* `R` >= 4.0.3 recommended, package `lidR` >= 3.1.0 required
* `R` >= 4.0.3 recommended, package `lidR` >= 4.0.0 required
* **The package is available on [CRAN](https://cran.r-project.org/package=lidaRtRee)**, to install run in the `R` console `install.packages("lidaRtRee")`
* **build development version from source** with the `devtools` package by running in an `R` console: `devtools::install_git("https://gitlab.irstea.fr/jean-matthieu.monnet/lidaRtRee/", branch="dev")`
# Tutorials
**Tutorials** using `lidaRtRee` functions are available on the [lidaRtRee_tutorials](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/) repository, as `Rmarkdown` files, `html` and `pdf` files, and including datasets to run the code. The [wiki](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/home) presents the different tutorials:
**Tutorials** using `lidaRtRee` functions are available on the [lidaRtRee_tutorials](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/) repository, as `Rmarkdown` files and `html` files, and including datasets to run the code. The [wiki](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/home) presents the different tutorials:
* [ALS data pre-processing](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/ALS-data-preprocessing)
* [Tree detection](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/Tree-segmentation)
* [Forest field plot coregistration with ALS data](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/Field-plot-coregistration-with-ALS-data)
* [Forest gaps and edges detection](https://gitlab.irstea.fr/jean-matthieu.monnet/lidartree_tutorials/-/wikis/Forest-gaps-and-edges-detection)
......@@ -20,4 +21,5 @@
# Changelog
May 2022. Version 4.0.0 now relies on [terra](https://cran.r-project.org/package=terra) and [sf](https://cran.r-project.org/package=sf) packages instead of [raster](https://cran.r-project.org/package=raster) and [sp](https://cran.r-project.org/package=sp).
July 2021. Version 3.1.0 introduces names modifications for better constituency. Tests have been added.
\ No newline at end of file
......@@ -18,7 +18,7 @@ a list with three elements
\itemize{
\item \code{model}: a list of regression models corresponding to each stratum
(output from \code{\link[stats]{lm}}),
\item \code{stats}:model statistics of each stratum-specific model (as in
\item \code{stats}: model statistics of each stratum-specific model (as in
\code{\link{aba_build_model}}) plus one line corresponding to statistics for all
strata (COMBINED)
\item \code{values}: data.frame with observed and values predicted in
......
......@@ -51,10 +51,11 @@ llas <- lidR::clip_circle(las_chablais3,
llas <- lapply(llas, function(x) {
lidR::normalize_height(x, lidR::tin())
})
# computes metrics including strata
m1 <- clouds_metrics(llas, ~ aba_metrics(
# computes metrics
m <- clouds_metrics(llas, ~ aba_metrics(
Z, Intensity, ReturnNumber, Classification, 2
))
head(m[,1:5])
}
\references{
Bouvier et al. 2015. Generalizing predictive models of forest
......
......@@ -18,7 +18,7 @@ black for single models, depends on stratum in stratified models}
\item{add_legend}{list. parameters to be passed to \code{\link[graphics]{legend}}. In case of a stratified model, legend is automatically set up.}
\item{...}{other parameters to be passed to \code{\link[graphics]{plot}},
\code{xlab} and \code{ylab} are automatically setup}
\code{xlab} and \code{ylab} are automatically added}
}
\value{
nothing
......