% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spatial.R
\name{spatial_smooth}
\alias{spatial_smooth}
\title{Smooth streamed line and polygon geometry}
\usage{
spatial_smooth(
  x,
  iterations = 2L,
  keep_ends = TRUE,
  geom = "geometry",
  crs = NA,
  out_geom = NULL,
  flush_rows = NULL
)
}
\arguments{
\item{x}{A \code{vectra_node} (from \code{\link[=tbl]{tbl()}}, \code{\link[=tbl_tiff]{tbl_tiff()}}, any verb chain, ...).
It is consumed by the stream.}

\item{iterations}{Number of corner-cutting passes (a positive integer). Each
pass roughly doubles the vertex count. Default \code{2}.}

\item{keep_ends}{If \code{TRUE} (default), pin the first and last vertex of an open
line so it is not shortened at its tips. Ignored for closed rings.}

\item{geom}{Name of the input geometry column holding hex-WKB or WKT strings.
Default \code{"geometry"}. Ignored when \code{coords} is given.}

\item{crs}{Coordinate reference system of the input geometry, in any form
\code{\link[sf:st_crs]{sf::st_crs()}} accepts (EPSG integer, WKT, proj string). Defaults to the
CRS the upstream node carries, or unknown.}

\item{out_geom}{Name of the output geometry column. Defaults to \code{geom}
(or \code{"geometry"} when \code{coords} is used).}

\item{flush_rows}{Transformed rows buffered before a spill flush. Larger
values mean fewer, bigger temporary files. Defaults to
\code{getOption("vectra.spatial_flush", 5e5)}.}
}
\value{
A \code{vectra_node} of the smoothed geometry with \code{x}'s attributes, backed
by temporary \code{.vtr} spills (removed when the node is garbage-collected) and
carrying the input CRS.
}
\description{
Rounds the corners of every line and polygon in a streamed layer by Chaikin
corner-cutting, one batch at a time. Each iteration replaces every vertex with
two points a quarter and three-quarters of the way along its adjacent edges,
so sharp angles become a sequence of short chamfers that read as a smooth
curve; more \code{iterations} give a smoother result with more vertices. Open lines
keep their endpoints (\code{keep_ends}); polygon rings are cut cyclically and shrink
slightly, as Chaikin smoothing does. Point geometry passes through unchanged.
}
\details{
The smoothing is computed directly on the coordinates (no GEOS call), so it is
dependency-light; \pkg{sf} is used only to decode and rebuild each batch.
Geometry travels through the engine as hex-encoded WKB in a string column and
the CRS is carried on the returned node; use \code{\link[=collect_sf]{collect_sf()}} to materialize.
}
\examples{
\dontshow{if (requireNamespace("sf", quietly = TRUE)) withAutoprint(\{ # examplesIf}
zig <- sf::st_linestring(rbind(c(0, 0), c(1, 1), c(2, 0), c(3, 1), c(4, 0)))
f <- tempfile(fileext = ".vtr")
write_vtr(data.frame(
  id = 1L, geometry = sf::st_as_binary(sf::st_sfc(zig), hex = TRUE)
), f)

# Smooth the zig-zag with three corner-cutting passes.
tbl(f) |> spatial_smooth(iterations = 3) |> collect_sf()
unlink(f)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=spatial_map]{spatial_map()}} for per-feature transforms such as densifying with
\code{~ sf::st_segmentize(.x, dfMaxLength)} or sampling points along a line with
\code{~ sf::st_line_sample(.x, n)}, \code{\link[=collect_sf]{collect_sf()}} to materialize as \code{sf}.
}
