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")

Arguments

src

A SpatVector, or a file path / data source readable by terra::vect() (e.g. a shapefile, GeoPackage, or File Geodatabase).

aoi

A SpatVector (or a source readable by terra::vect()) defining the area of interest. May be in any CRS.

fields

Optional character vector of attribute columns to keep. Columns not present in the source are ignored; NULL (the default) keeps all.

layer

Optional layer name, for sources (e.g. a File Geodatabase) with more than one layer.

relation

Character. The spatial predicate passed to terra::relate() used to refine the GDAL filter (default "intersects").

Value

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.

Details

The read proceeds in three steps:

  1. the source CRS is obtained without reading any geometries (via a terra::vect() proxy), and aoi is projected into it;

  2. 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;

  3. 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.

Examples

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)