% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/metrics_cloud.R, R/metrics_crowns.R,
%   R/metrics_hexagons.R, R/metrics_pixels.R, R/metrics_plot.R,
%   R/metrics_polygon.R, R/metrics_template.R, R/metrics_voxels.R
\name{aggregate}
\alias{aggregate}
\alias{cloud_metrics}
\alias{crown_metrics}
\alias{hexagon_metrics}
\alias{pixel_metrics}
\alias{plot_metrics}
\alias{polygon_metrics}
\alias{template_metrics}
\alias{voxel_metrics}
\title{Metric derivation at different levels of regularization}
\usage{
cloud_metrics(las, func, ...)

crown_metrics(
  las,
  func,
  geom = "point",
  concaveman = c(3, 0),
  attribute = "treeID",
  ...
)

hexagon_metrics(las, func, area = 400, ...)

pixel_metrics(las, func, res = 20, start = c(0, 0), ...)

plot_metrics(las, func, geometry, ..., radius)

polygon_metrics(las, func, geometry, ...)

template_metrics(las, func, template, filter = NULL, by_echo = "all", ...)

voxel_metrics(las, func, res = 1, ..., all_voxels = FALSE)
}
\arguments{
\item{las}{An object of class \link[lidR:LAS-class]{LAS} or \link[lidR:LAScatalog-class]{LAScatalog}.}

\item{func}{formula or expression. An expression to be applied to each element of the template (see
section "Parameter func").}

\item{...}{propagated to \code{template_metrics} i.e. \code{filter} and \code{by_echo}. \code{pixel_metrics()} also
supports \code{pkg = "terra|raster|stars"} to get an output in \code{SpatRaster}, \verb{Raster*}
or \code{stars} format. Default is \code{getOption("lidR.raster.default")}.}

\item{geom}{character. Geometry type of the output. Can be 'point', 'convex', 'concave' or 'bbox'.}

\item{concaveman}{numeric. Only if \code{type = "concave"}. Vector with the two parameters of the
function \link{concaveman}.}

\item{attribute}{character. The column name of the attribute containing tree IDs. Default is
\code{"treeID"}}

\item{area}{numeric. Area of the hexagons}

\item{res}{numeric. The resolution of the output. Can optionally be a \code{RasterLayer} or a \code{stars} or
a \code{SpatRaster}. In that case the raster is used as the template.}

\item{start}{vector of x and y coordinates for the reference raster. Default is (0,0) meaning that the
grid aligns on (0,0). Not consiered if \code{res} is a raster}

\item{geometry}{A spatial vector object. \code{sp} and \code{sf}' objects are supported. \code{plot_metrics()}
supports point and polygons but \code{polygon_metrics()} supports only polygons.}

\item{radius}{numeric. If the geometry is spatial points a radius must be defined. Support one
radius or a vector of radii for variable plot sizes.}

\item{template}{can be of many types and corresponds to the different levels of regularization.
\code{RasterLayer/stars/SpatRaster}, \code{sf/sfc} (polygons), \code{numeric}, \code{bbox}, \code{NULL}. The metrics are
computed for each element of the template. See examples.}

\item{filter}{formula of logical predicates. Enables the function to run only on points of interest
in an optimized way. See examples.}

\item{by_echo}{characters. The metrics are computed multiple times for different echo types. Can
be one or more of "all", "first", "intermediate", "lastofmany", "single", and "multiple". See examples.
Default is "all" meaning that it computes metrics with all points provided.}

\item{all_voxels}{boolean. By default the function returns only voxels that
contain 1 or more points. Empty voxels do not exist as the metrics are undefined.
If \code{all_voxels = TRUE} all the voxels are returned and metrics are NA for
voxels with 0 points.}
}
\value{
Depends on the function, the template and the number of metrics. Can be a \code{RasterLayer},
a \code{RasterBrick}, a \code{stars}, a \code{SpatRaster} a \code{sf/sfc}, a \code{list}, a \code{SpatialPolygonDataFrame}, or
a \code{data.table}. Functions are supposed to return an object that is best suited for storing the level
of regularization needed.
}
\description{
\code{template_metrics()} computes a series of user-defined descriptive statistics for a LiDAR dataset
within each element of a template. Depending on the template it can be for each pixel of a raster
(area-based approach), or each polygon, or each segmented tree, or on the whole point cloud. Other
functions are convenient and simplified wrappers around \code{template_metrics()} and are expected to be
the actual functions used. See Details and Examples.
}
\details{
\describe{
\item{\code{pixel_metrics}}{Area-based approach. Computes metrics in a square tessellation. The output is a
raster.}
\item{\code{hexagon_metrics}}{Computes metrics in an hexagon tessellation. The output is a \code{sf/sfc_POLYGON}}
\item{\code{plot_metrics}}{Computes metrics for each plot of a ground inventory by 1. clipping the plot
inventories with \link{clip_roi}, 2. computing the user's metrics for each plot with  \link{cloud_metrics}, and
3. combining spatial data and metrics into one data.frame ready for statistical modelling with
\code{cbind}. The output is of the class of the input.}
\item{\code{cloud_metrics}}{Computes a series of user-defined descriptive statistics for an entire point cloud.
The output is a \code{list}}
\item{\code{crown_metrics}}{Once the trees are segmented, i.e. attributes exist in the
point cloud that reference each tree, computes a set of user-defined descriptive statistics for
each individual tree. The output can be spatial points or spatial polygons (\code{sf/sfc_POINT} or \code{sf/sfc_POLYGON})}
\item{\code{voxel_metrics}}{Is a 3D version of \code{pixel_metrics}. It creates a 3D matrix of voxels with a given
resolution. It creates a voxel from the cloud of points if there is at least one point. The output is
a \code{data.frame}}
\item{\code{point_metrics}}{Is a bit more complex and is documented in \link{point_metrics}}
}
}
\section{Parameter \code{func}}{

The function to be applied to each cell is a classical function (see examples) that
returns a labelled list of metrics. For example, the following function \code{f} is correctly formed.
\preformatted{
f = function(x) {list(mean = mean(x), max = max(x))}
}
And could be applied either on the \code{Z} coordinates or on the intensities. These two
statements are valid:
\preformatted{
pixel_metrics(las, f(Z), res = 20)
voxel_metrics(las, f(Intensity), res = 2)
}
The following existing functions allow the user to
compute some predefined metrics: \link[=stdmetrics]{stdmetrics}
\link[=entropy]{entropy}, \link[=VCI]{VCI}, \link[=LAD]{LAD}. But usually users must write their own
functions to create metrics. \code{template_metrics} will dispatch the point cloud in the user's
function.
}

\examples{
LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las <- readLAS(LASfile, filter = "-keep_random_fraction 0.5")
col <- sf::sf.colors(15)
fun1 <- ~list(maxz = max(Z))
fun2 <- ~list(q85 = quantile(Z, probs = 0.85))

set_lidr_threads(1) ; data.table::setDTthreads(1) # for cran only

# ================
# CLOUD METRICS
# ================

cloud_metrics(las, .stdmetrics_z)

# ================
# PIXEL METRICS
# ================

m <- pixel_metrics(las, fun1, 20)
#plot(m, col = col)

# ================
# PLOT METRICS
# ================

shpfile <- system.file("extdata", "efi_plot.shp", package="lidR")
inventory <- sf::st_read(shpfile, quiet = TRUE)
inventory # contains an ID and a Value Of Interest (VOI) per plot

m <- plot_metrics(las, fun2, inventory, radius = 11.28)
#plot(header(las))
#plot(m["q85"], pch = 19, cex = 3, add = TRUE)

\donttest{
# Works with polygons as well
inventory <- sf::st_buffer(inventory, 11.28)
#plot(header(las))
#plot(sf::st_geometry(inventory), add = TRUE)
m <- plot_metrics(las, .stdmetrics_z, inventory)
#plot(m["zq85"], pch = 19, cex = 3, add = TRUE)
}

# ================
# VOXEL METRICS
# ================

m <- voxel_metrics(las, length(Z), 8)
m <- voxel_metrics(las, mean(Intensity), 8)
#plot(m, color = "V1", colorPalette = heat.colors(50), trim = 60)
#plot(m, color = "V1", colorPalette = heat.colors(50), trim = 60, voxel = TRUE)

# ================
# CROWN METRICS
# ================

# Already tree-segmented point cloud
LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
trees <- readLAS(LASfile, filter = "-drop_z_below 0")

metrics <- crown_metrics(trees, .stdtreemetrics)
#plot(metrics["Z"], pch = 19)

metrics <- crown_metrics(trees, .stdtreemetrics, geom = "convex")
#plot(metrics["Z"])

metrics <- crown_metrics(trees, .stdtreemetrics, geom = "bbox")
#plot(metrics["Z"])

\donttest{
metrics <- crown_metrics(trees, .stdtreemetrics, geom = "concave")
#plot(metrics["Z"])
}
# ================
# ARGUMENT FILTER
# ================

# Compute using only some points: basic
first = filter_poi(las, ReturnNumber == 1)
metrics = pixel_metrics(first, mean(Z), 20)

# Compute using only some points: optimized
# faster and uses less memory. No intermediate object
metrics = pixel_metrics(las, mean(Z), 20, filter = ~ReturnNumber == 1)

# Compute using only some points: best
# ~50\% faster and uses ~10x less memory
las = readLAS(LASfile, filter = "-keep_first")
metrics = pixel_metrics(las, mean(Z), 20)

# ================
# ARGUMENT BY_ECHO
# ================

func = ~list(avgI = mean(Intensity))
echo = c("all", "first","multiple")

# func defines one metric but 3 are computed respectively for: (1) all echo types,
# (2) for first returns only and (3) for multiple returns only
metrics <- pixel_metrics(las, func, 20, by_echo = echo)
#plot(metrics, col = heat.colors(25))

cloud_metrics(las, func, by_echo = echo)

\dontrun{
# ================
# TEMPLATE METRICS
# ================

# a raster as template
template <- raster::raster(extent(las), nrow = 15, ncol = 15)
raster::crs(template) <- crs(las)
m <- template_metrics(las, fun1, template)
#plot(m, col = col)

# a sfc_POLYGON as template
sfc <- sf::st_as_sfc(st_bbox(las))
template <- sf::st_make_grid(sfc, cellsize = 20, square = FALSE)
m <- template_metrics(las, fun1, template)
#plot(m)

# a bbox as template
template <- st_bbox(las) + c(50,30,-50,-70)
plot(sf::st_as_sfc(st_bbox(las)), col = "gray")
plot(sf::st_as_sfc(template), col = "darkgreen", add = TRUE)
m <- template_metrics(las, fun2, template)
print(m)

# ================
# CUSTOM METRICS
# ================

# Define a function that computes custom metrics
# in an R&D perspective.
myMetrics = function(z, i) {
  metrics = list(
     zwimean = sum(z*i)/sum(i), # Mean elevation weighted by intensities
     zimean  = mean(z*i),       # Mean products of z by intensity
     zsqmean = sqrt(mean(z^2))) # Quadratic mean

   return(metrics)
}

# example with a stars template
template <- stars::st_as_stars(st_bbox(las), dx = 10, dy = 10)
m <- template_metrics(las, myMetrics(Z, Intensity), template)
#plot(m, col = col)
}
}
