% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/segment.R, R/segment_shapes.R,
%   R/segment_snags.R, R/segment_trees.R
\name{segment}
\alias{segment}
\alias{segment_shapes}
\alias{segment_snags}
\alias{segment_trees}
\title{Segment a point cloud}
\usage{
segment_shapes(las, algorithm, attribute = "Shape", filter = NULL)

segment_snags(las, algorithm, attribute = "snagCls")

segment_trees(las, algorithm, attribute = "treeID", uniqueness = "incremental")
}
\arguments{
\item{las}{An object of class \link[lidR:LAS-class]{LAS} or \link[lidR:LAScatalog-class]{LAScatalog}.}

\item{algorithm}{function. An algorithm for segmentation. For individual tree segmentation, lidR
has \link{dalponte2016}, \link{watershed}, \link{li2012}, and \link{silva2016}. More experimental
algorithms may be found in the package \href{https://github.com/Jean-Romain/lidRplugins}{lidRplugins}.
For snag segmentation, \code{lidR} has \link{wing2015}. For geometry segmentation, lidR has
\link{shp_plane}, \link{shp_hplane}, and \link{shp_line}.}

\item{attribute}{character. The returned LAS object as a new attribute (in a new column).
This parameter controls the name of the new attribute.}

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

\item{uniqueness}{character. A method to compute a unique ID. Can be 'incremental', 'gpstime' or
'bitmerge'. See section 'Uniqueness'. This feature must be considered as 'experimental'.}
}
\description{
Segment a point cloud using different methods. \verb{segment_*} functions add a new attribute to the
point cloud to label each point. They segment either individual trees, snags, or
geometrical features.
}
\details{
\describe{
\item{\code{segment_trees}}{Individual tree segmentation with several possible algorithms. The returned
point cloud has a new extra byte attribute named after the parameter \code{attribute} independently
of the algorithm used.}
\item{\code{segment_shapes}}{Computes, for each point, the eigenvalues of the covariance matrix of the
neighbouring points. The eigenvalues are later used either to segment linear/planar points or to
compute derived metrics. The points that meet a given criterion based on the eigenvalue are labelled
as approximately coplanar/colinear or any other shape supported.}
\item{\code{segment_snags}}{Snag segmentation using several possible algorithms. The function attributes
a number identifying a snag class (\code{snagCls} attribute) to each point of the point cloud.
The classification/segmentation is done at the point cloud level and currently only one algorithm is
implemented, which uses LiDAR intensity thresholds and specified neighbourhoods to differentiate
bole and branch from foliage points.}
}
}
\section{Non-supported LAScatalog options}{

The option \code{select} is not supported and not respected because it always preserves the file format
and all the attributes. \code{select = "*"} is imposed internally.
}

\section{Uniqueness}{


By default the tree IDs are numbered from 1 to n, n being the number of trees found. The problem
with such incremental numbering is that, while it ensures a unique ID is assigned for each tree in
a given point-cloud, it also guarantees duplication of tree IDs in different tiles or chunks when
processing a \code{LAScatalog}. This is because each chunk/file is processed independently of the others
and potentially in parallel on different computers. Thus, the index always restarts at 1 on each
chunk/file. Worse, in a tree segmentation process, a tree that is located exactly between
2 chunks/files will have two different IDs for its two halves.

This is why we introduced some uniqueness strategies that are all imperfect and that should be seen
as experimental. Please report any troubleshooting. Using a uniqueness-safe strategy ensures that
trees from different files will not share the same IDs. It also ensures that two halves of a tree
on the edge of a processing chunk will be assigned the same ID.

\describe{
\item{incremental}{Number from 0 to n. This method \strong{does not} ensure uniqueness of the IDs. This
is the legacy method.}
\item{gpstime}{This method uses the gpstime of the highest point of a tree (apex) to create a
unique ID. This ID is not an integer but a 64-bit decimal number, which is suboptimal but at
least it is expected to be unique \strong{if the gpstime attribute is consistent across files}.
If inconsistencies with gpstime are reported (for example gpstime records the week time and was
reset to 0 in a coverage that takes more than a week to complete), there is a (low) probability of
getting ID attribution errors.}
\item{bitmerge}{This method uses the XY coordinates of the highest point (apex) of a tree to
create a single 64-bit number with a bitwise operation. First, XY coordinates are converted to
32-bit integers using the scales and offsets of the point cloud. For example, if the apex is at
(10.32, 25.64) with a scale factor of 0.01 and an offset of 0, the 32-bit integer coordinates are
X = 1032 and Y = 2564. Their binary representations are, respectively, (here displayed as 16 bits)
0000010000001000 and 0000101000000100. X is shifted by 32 bits and becomes a 64-bit integer. Y is kept
as-is and the binary representations are unionized into a 64-bit integer like (here displayed as 32 bit)
00000100000010000000101000000100 that is guaranteed to be unique. However R
does not support 64-bit integers. The previous steps are done at C++ level and the 64-bit binary
representation is reinterpreted into a 64-bit decimal number to be returned in R. The IDs thus generated
are somewhat weird. For example, the tree ID 00000100000010000000101000000100 which is 67635716 if
interpreted as an integer becomes 3.34164837074751323479078607289E-316 if interpreted as a decimal
number. This is far from optimal but at least it is guaranteed to be unique  \strong{if all files have
the same offsets and scale factors}.}
}

All the proposed options are suboptimal because they either do not guarantee uniqueness in all cases
(inconsistencies in the collection of files), or they imply that IDs are based on non-integers or
meaningless numbers. But at least it works and deals with some of the limitations of R.
}

\examples{
# ==============
# Segment trees
# ==============

LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
las <- readLAS(LASfile, select = "xyz", filter = "-drop_z_below 0")

# Using Li et al. (2012)
las <- segment_trees(las, li2012(R = 3, speed_up = 5))
#plot(las, color = "treeID")

# ==============
# Segment shapes
# ==============

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las <- readLAS(LASfile, filter = "-keep_random_fraction 0.5")

# Use the eigenvalues to estimate if points are part of a local plan
las <- segment_shapes(las, shp_plane(k = 15), "Coplanar")
#plot(las, color = "Coplanar")

\dontrun{
# Drop ground point at runtime
las <- segment_shapes(las, shp_plane(k = 15), "Coplanar", filter = ~Classification != 2L)
#plot(las, color = "Coplanar")

# ==============
# Segment snags
# ==============

LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
las <- readLAS(LASfile, select = "xyzi", filter="-keep_first") # Wing also included -keep_single

# For the Wing2015 method, supply a matrix of snag BranchBolePtRatio conditional
# assessment thresholds (see Wing et al. 2015, Table 2, pg. 172)
bbpr_thresholds <- matrix(c(0.80, 0.80, 0.70,
                            0.85, 0.85, 0.60,
                            0.80, 0.80, 0.60,
                            0.90, 0.90, 0.55),
                            nrow =3, ncol = 4)

# Run snag classification and assign classes to each point
las <- segment_snags(las, wing2015(neigh_radii = c(1.5, 1, 2), BBPRthrsh_mat = bbpr_thresholds))

# Plot it all, tree and snag points...
plot(las, color="snagCls", colorPalette = rainbow(5))

# Filter and plot snag points only
snags <- filter_poi(las, snagCls > 0)
plot(snags, color="snagCls", colorPalette = rainbow(5)[-1])

# Wing et al's (2015) methods ended with performing tree segmentation on the
# classified and filtered point cloud using the watershed method
}
}
