% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spatial_topology.R
\name{spatial_simplify}
\alias{spatial_simplify}
\title{Simplify a polygon coverage without tearing shared edges}
\usage{
spatial_simplify(
  x,
  tolerance,
  by = NULL,
  geom = "geometry",
  crs = NA,
  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{tolerance}{Distance tolerance for the boundary simplification, in CRS
units: vertices that deviate less than this from the simplified line are
dropped. Larger values simplify more.}

\item{by}{Character vector of attribute columns whose groups are each
simplified as an independent coverage. \code{NULL} (default) treats the whole
layer as one coverage.}

\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{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 simplified polygons, each carrying its source
feature's attributes and the input CRS, backed by temporary \code{.vtr} spills
removed when the node is garbage-collected.
}
\description{
Simplifies polygon boundaries while keeping a shared border between two
polygons identical on both sides, so adjacent polygons stay edge-matched with
no slivers or gaps -- the topology-preserving simplification that a per-feature
\code{spatial_map(~ sf::st_simplify(.x))} cannot give, because it simplifies each
polygon's copy of a shared border independently. The boundaries of each group
are unioned so a shared border is one line, noded into arcs at every junction,
each arc simplified once (its junction endpoints pinned), and the arcs
re-polygonized; each resulting face inherits the attributes of the source
polygon containing it. Like \code{\link[=spatial_dissolve]{spatial_dissolve()}} it rides the \strong{partition
tier}: \code{x} is spilled once and routed into one disjoint shard per \code{by} group
in a single bounded pass, and each group is simplified as an independent
coverage. Peak memory is the routing budget during the pass, then one group's
geometry while it is simplified -- partition on a key whose groups fit in
memory. With no \code{by}, the whole layer is one coverage.
}
\details{
The simplification is topology-preserving Douglas-Peucker (\code{dTolerance = tolerance}) on the noded boundary arcs. Geometry travels through the engine as
hex-encoded WKB in a string column and the CRS is carried on the returned
node; the noding is \pkg{sf}/GEOS and expects projected or unprojected planar
data. The \pkg{sf} package is an optional dependency (Suggests).
}
\examples{
\dontshow{if (requireNamespace("sf", quietly = TRUE)) withAutoprint(\{ # examplesIf}
p1 <- sf::st_polygon(list(rbind(
  c(0, 0), c(1, 0), c(1, 0.5), c(1, 1), c(0, 1), c(0, 0))))
p2 <- sf::st_polygon(list(rbind(
  c(1, 0), c(2, 0), c(2, 1), c(1, 1), c(1, 0.5), c(1, 0))))
f <- tempfile(fileext = ".vtr")
write_vtr(data.frame(
  id = c("a", "b"),
  geometry = sf::st_as_binary(sf::st_sfc(p1, p2), hex = TRUE)
), f)

# The shared edge is simplified once, so the two polygons stay edge-matched.
tbl(f) |> spatial_simplify(tolerance = 0.6) |> collect_sf()
unlink(f)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=spatial_map]{spatial_map()}} with \code{~ sf::st_simplify(.x)} for independent
per-feature simplification, \code{\link[=spatial_smooth]{spatial_smooth()}} for Chaikin corner-rounding,
\code{\link[=collect_sf]{collect_sf()}} to materialize as \code{sf}.
}
