| spatial_overlay | R Documentation |
Splits a polygon layer along all its own overlaps into disjoint pieces and
returns a lazy node with one row per piece per covering polygon: where k
polygons overlap, that piece appears k times, each row carrying one source
polygon's attributes. This is the union overlay GIS tools expose as
"Union (single layer)", with the overlap retained once per contributing
feature rather than dissolved. Resolve the duplicates with a grouped
slice_min() / slice_max() – for example earliest designation year wins:
group_by(piece_id) |> slice_min(year).
spatial_overlay(
x,
y = NULL,
vars = NULL,
vars_y = NULL,
how = c("intersection", "union", "identity", "symdiff"),
piece = "piece_id",
geom = "geometry",
grid = NULL,
precision = NULL,
dedup = TRUE,
exact = FALSE,
flush_rows = NULL,
mem_limit = NULL,
threads = NULL,
quiet = TRUE,
layer = NULL,
query = NULL,
layer_y = NULL,
query_y = NULL,
read_chunk = NULL
)
x |
An |
y |
Optional second layer to overlay |
vars |
Character vector of attribute columns of |
vars_y |
Character vector of attribute columns of |
how |
For a two-layer overlay, which pieces to keep: |
piece |
Name of the integer piece-id column added to the output (the key
you group by to resolve overlaps). Default |
geom |
Name of the output hex-WKB geometry column. Default |
grid |
Fixed-precision snapping grid size in CRS units. Coordinates are
snapped to this grid before noding so near-duplicate shared boundaries merge
into one. |
precision |
Fixed-precision grid size, in CRS units, for noding the
boundary linework. Noding on a fixed grid is deterministic and avoids the
floating noder's repair-and-retry on dense overlapping linework, which is
what makes a large dense layer feasible to overlay. It is far finer than
|
dedup |
Overlay one representative per group of byte-identical cleaned
geometries and fan the per-record attributes back onto its pieces afterwards.
Duplicates add no faces, so the result is identical; this only removes the
redundant noding when many records are stacked over one site (common in
WDPA-style data). |
exact |
How a piece is credited to the inputs that cover it. Each piece is
a face of the arrangement of all input boundaries, so it lies wholly inside or
outside every input up to snap-rounding slivers along the boundary. With
|
flush_rows |
Exploded rows buffered before a spill flush. |
mem_limit |
Approximate peak working-set budget in bytes, bounding the
per-tile size ( |
threads |
Number of OpenMP threads for the per-component overlay within a
chunk. |
quiet |
If |
layer |
When |
query |
When |
layer_y, query_y |
The |
read_chunk |
Features per read/parse batch. |
The topology is done once with sf/GEOS and tiled over connected overlap
clusters (disjoint clusters never share a piece, so the tiling is exact and
bounded in memory), then the exploded pieces are streamed to a .vtr and
handed back as a lazy node. Geometry rides through the engine as hex-encoded
WKB in a string column; the CRS is carried on the node for collect_sf().
The overlay runs on a fixed-precision model: coordinates are snapped to a
grid derived from their own magnitude so the pieces come out disjoint and
their areas reconstruct the union of the inputs, instead of drifting by the
fraction of a percent that floating-point sliver artefacts on invalid input
otherwise introduce. Inputs are also passed through sf::st_make_valid().
With a second layer y, the same machinery overlays two layers instead of
self-unioning one: both layers are noded together into one planar partition,
and each piece carries the attributes of the x record and the y record
that cover it. how selects which pieces to keep – the intersection (pieces
covered by both), the union (every piece of either), x split by y
("identity"), or the parts in exactly one layer ("symdiff"). With
y = NULL (the default) the function self-unions x and how is ignored.
A vectra_node over the exploded overlay, backed by temporary .vtr
spills removed when the node is garbage-collected, carrying the CRS of x
for collect_sf(). For a self-union it is one row per piece per covering
polygon; for a two-layer overlay one row per piece per covering
x-record / y-record pair, with the columns of both layers.
slice_min() / slice_max() to resolve each piece to one winner,
collect_sf() to materialize as sf.
# Two overlapping squares designated in different years.
sq <- function(a, b) sf::st_polygon(list(rbind(
c(a, 0), c(b, 0), c(b, 1), c(a, 1), c(a, 0))))
polys <- sf::st_sf(year = c(1990L, 2010L),
geometry = sf::st_sfc(sq(0, 2), sq(1, 3)))
# Split into disjoint pieces; earliest year wins where they overlap.
first <- spatial_overlay(polys) |>
group_by(piece_id) |>
slice_min(year, n = 1, with_ties = FALSE) |>
collect_sf()
first
# Two-layer overlay: intersect the squares with a zone layer, keeping both
# sets of attributes on each overlapping piece.
zones <- sf::st_sf(zone = c("A", "B"),
geometry = sf::st_sfc(sq(0, 1.5), sq(1.5, 3)))
inter <- spatial_overlay(polys, zones, how = "intersection") |> collect_sf()
inter
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.