% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spatial.R
\name{spatial_clip}
\alias{spatial_clip}
\title{Clip or erase a streamed layer against a resident mask}
\usage{
spatial_clip(
  x,
  mask,
  erase = FALSE,
  geom = "geometry",
  coords = NULL,
  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{mask}{An \code{sf} or \code{sfc} object whose dissolved geometry clips (or, with
\code{erase = TRUE}, erases) the stream.}

\item{erase}{If \code{TRUE}, keep the parts of \code{x} \emph{outside} \code{mask} (difference)
rather than inside (intersection). Default \code{FALSE}.}

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

\item{coords}{Optional length-2 character vector naming the x and y
coordinate columns to assemble point geometry from (e.g. \code{c("x", "y")}),
for inputs such as \code{\link[=tiff_extract_points]{tiff_extract_points()}} output. The coordinate columns
are retained.}

\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 cut geometry with \code{x}'s attributes, backed by
temporary \code{.vtr} spills and carrying the input CRS.
}
\description{
Streams a large layer \code{x} through the engine and cuts each batch's geometry
against a small resident \code{mask} (a study boundary, a buffer, a set of
patches). By default this clips -- the intersection with the mask, the GIS
"Clip" tool -- keeping only the parts of \code{x} that fall inside \code{mask}. With
\code{erase = TRUE} it instead erases -- the difference, the "Erase"/"Difference"
tool -- keeping the parts of \code{x} outside \code{mask}. The mask is dissolved to a
single geometry once and held resident while the billion-row left stream
flows past one batch at a time.
}
\details{
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.
On projected or unprojected planar data the cut runs natively on the GEOS C
API straight off the hex-WKB column (the mask parsed once); geographic
coordinates with spherical geometry on (\code{sf::sf_use_s2()}) and
coordinate-assembled (\code{coords}) input cut through \pkg{sf} instead. When
\code{mask} carries no CRS it inherits the stream's.
}
\examples{
\dontshow{if (requireNamespace("sf", quietly = TRUE)) withAutoprint(\{ # examplesIf}
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
mask <- sf::st_union(nc[nc$NAME \%in\% c("Ashe", "Alleghany"), ])

f <- tempfile(fileext = ".vtr")
write_vtr(data.frame(
  NAME = nc$NAME,
  geometry = sf::st_as_binary(sf::st_geometry(nc), hex = TRUE)
), f)

# Clip every county polygon to the two-county mask, streaming.
clipped <- tbl(f) |> spatial_clip(mask, crs = sf::st_crs(nc))
collect_sf(clipped)
unlink(f)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=spatial_filter]{spatial_filter()}} to keep whole features by location without
cutting them, \code{\link[=spatial_map]{spatial_map()}} for per-feature transforms, \code{\link[=collect_sf]{collect_sf()}}.
}
