Read a (potentially very large) vector source while pushing the spatial
filter down to the GDAL/OGR read, so that only geometries overlapping
aoi are materialised in R. This is the memory-efficient way to work with
enormous polygon datasets (e.g. provincial landbase coverages): the bulk of
the features never enter R.
read_vector_aoi(src, aoi, fields = NULL, layer = NULL, relation = "intersects")A SpatVector, or a file path / data source readable by
terra::vect() (e.g. a shapefile, GeoPackage, or File Geodatabase).
A SpatVector (or a source readable by terra::vect()) defining
the area of interest. May be in any CRS.
Optional character vector of attribute columns to keep. Columns
not present in the source are ignored; NULL (the default) keeps all.
Optional layer name, for sources (e.g. a File Geodatabase) with more than one layer.
Character. The spatial predicate passed to
terra::relate() used to refine the GDAL filter (default
"intersects").
A SpatVector in the source CRS, containing only the features of
src related to aoi and only the requested fields. Callers should test
nrow() == 0L for the no-overlap case.
The read proceeds in three steps:
the source CRS is obtained without reading any geometries (via a
terra::vect() proxy), and aoi is projected into it;
the layer is read via terra::query() on the proxy, pushing both the
column selection (vars = fields) and a spatial filter (the projected
aoi) down to the GDAL/OGR read – so wide attribute tables (a landbase
coverage can have >100 columns) are never materialised in R. GDAL
guarantees all extent-overlapping features are returned but may return
extras;
the result is refined with terra::relate() so exactly the features
satisfying relation are kept.
If the driver cannot honour the pushed-down read it falls back to a spatial
filter-only read with the columns subset in R; the relate() refinement
(and a final column subset) run regardless, so the result is correct even
when a driver silently ignores the pushed-down filter.
aoi <- terra::vect("POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))")
terra::crs(aoi) <- "EPSG:3857"
near <- terra::vect("POLYGON ((1 1, 2 1, 2 2, 1 2, 1 1))")
far <- terra::vect("POLYGON ((20 20, 21 20, 21 21, 20 21, 20 20))")
src <- rbind(near, far)
terra::crs(src) <- "EPSG:3857"
read_vector_aoi(src, aoi)
#> class : SpatVector
#> geometry : polygons
#> dimensions : 1, 0 (geometries, attributes)
#> extent : 1, 2, 1, 2 (xmin, xmax, ymin, ymax)
#> coord. ref. : WGS 84 / Pseudo-Mercator (EPSG:3857)