% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/spatial_topology.R
\name{spatial_locate}
\alias{spatial_locate}
\title{Locate streamed points along a resident line layer}
\usage{
spatial_locate(
  x,
  line,
  geom = "geometry",
  coords = NULL,
  crs = NA,
  y_id = NULL,
  id_col = "line",
  measure_col = "measure",
  dist_col = "distance",
  snap = FALSE,
  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{line}{An \code{sf} or \code{sfc} object of the reference lines (the resident
layer).}

\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{y_id}{Optional name of a column in \code{line} whose value identifies the
matched line in the output. Default \code{NULL} uses \code{line}'s 1-based row index.}

\item{id_col, measure_col, dist_col}{Names of the output columns holding the
matched-line identifier, the measure along the line, and the perpendicular
distance. Defaults \code{"line"}, \code{"measure"}, \code{"distance"}.}

\item{snap}{If \code{TRUE}, replace each point's geometry with its projection onto
the nearest line. Default \code{FALSE} keeps the original points.}

\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 \code{x}'s rows -- geometry included (or snapped onto
the line) -- plus the matched-line identifier, the measure, and the
perpendicular distance, backed by temporary \code{.vtr} spills (removed when the
node is garbage-collected) and carrying the input CRS.
}
\description{
Streams a large point layer \code{x} through the engine and, for each point, finds
the nearest line of a small resident \code{line} layer and where the point falls
along it -- linear referencing (\code{sf::st_line_project}). Each point gets the
identifier of its nearest line, the \strong{measure} (distance along that line from
its start to the point's projection), and the perpendicular distance to the
line. With \code{snap = TRUE} the point geometry is moved onto the line at that
measure. This is the two-layer companion to a per-feature
\code{sf::st_line_interpolate}, which goes the other way (a measure back to a
point); the billion-row point stream never materializes, while \code{line} (the
reference network) stays resident.
}
\details{
Nearest line and distance are \pkg{sf}'s \link[sf:st_nearest_feature]{sf::st_nearest_feature} and
\link[sf:st_distance]{sf::st_distance}: planar (CRS units) on projected or unprojected planar data,
great-circle (metres) on geographic coordinates with spherical geometry on
(\code{sf::sf_use_s2()}). Points arrive either as a hex-WKB geometry column
(\code{geom}) or as two coordinate columns (\code{coords}). The \pkg{sf} package is an
optional dependency (Suggests).
}
\examples{
\dontshow{if (requireNamespace("sf", quietly = TRUE)) withAutoprint(\{ # examplesIf}
line <- sf::st_sfc(
  sf::st_linestring(rbind(c(0, 0), c(10, 0))),
  sf::st_linestring(rbind(c(0, 5), c(0, 15))))
line <- sf::st_sf(road = c("main", "side"), geometry = line)
pts  <- data.frame(id = 1:2, x = c(3, 1), y = c(1, 9))
f <- tempfile(fileext = ".vtr")
write_vtr(pts, f)

# Each point's position along its nearest road.
tbl(f) |>
  spatial_locate(line, coords = c("x", "y"), y_id = "road") |>
  collect()
unlink(f)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=spatial_knn]{spatial_knn()}} for nearest neighbours with distances,
\code{\link[=spatial_join]{spatial_join()}} for a nearest-feature attribute join, \code{\link[=spatial_map]{spatial_map()}} with
\code{~ sf::st_line_interpolate(line, .x$m)} for the inverse, \code{\link[=collect_sf]{collect_sf()}} to
materialize as \code{sf}.
}
