Skip to contents

pixel_extract() returns raster pixel values for a set of geospatial point locations. The coordinates are given as a two-column matrix of (x, y) values in the same spatial reference system as the input raster (unless xy_srs is specified). Values are extracted from all bands of the raster by default, or specific band numbers may be given. An optional interpolation method may be specified for bilinear (2 x 2 kernel), cubic convolution (4 x 4 kernel, GDAL >= 3.10), or cubic spline (4 x 4 kernel, GDAL >= 3.10). Alternatively, an optional kernel dimension may be given to extract values of the individual pixels within an N x N kernel centered on the pixel containing the point location. If xy_srs is given, the function will attempt to transform the input points to the projection of the raster with a call to transform_xy().

Usage

pixel_extract(
  raster,
  xy,
  bands = NULL,
  interp = NULL,
  krnl_dim = NULL,
  xy_srs = NULL,
  max_ram = 300
)

Arguments

raster

Either a character string giving the filename of a raster, or an object of class GDALRaster for the source dataset.

xy

A two-column numeric matrix or two-column data frame of geospatial (x, y) coordinates, or vector (x, y) for a single point, in the same spatial reference system as raster.

bands

Optional numeric vector of band numbers. All bands in raster will be processed by default if not specified.

interp

Optional character string specifying an interpolation method. Must be one of "bilinear", "cubic", "cubicspline", or "nearest" (the default if not specified, i.e., no interpolation). GDAL >= 3.10 is required for "cubic" and "cubicspline".

krnl_dim

Optional integer value specifying the dimension of an N x N kernel for which all individual pixel values will be returned. Only supported when extracting from a single raster band. Ignored if interp is specified as other than "nearest" (i.e., will always use the kernel implied by the interpolation method).

xy_srs

Optional character string specifying the spatial reference system for xy. May be in WKT format or any of the formats supported by srs_to_wkt().

max_ram

Numeric value giving the maximum amount of RAM (in MB) to use for potentially copying a remote raster into memory for processing (see Note). Defaults to 300 MB. Set to zero to disable potential copy of remote files into memory.

Value

A numeric matrix of pixel values with number of rows equal to the number of rows in xy, and number of columns equal to the number of bands, or if krnl_dim = N is used, number of columns equal to N * N. Named columns indicate the band number, e.g., "b1". If krnl_dim is used, named columns indicate band number and pixel, e.g., "b1_p1", "b1_p2", ..., "b1_p9" if krnl_dim = 3. Pixels are in left-to-right, top-to-bottom order in the kernel.

Note

Depending on the number of input points, extracting from a raster on a remote filesystem may require a large number of HTTP range requests which may be slow (i.e., URLs/remote VSI filesystems). In that case, it may be faster to copy the raster into memory first (either as MEM format or to a /vsimem filesystem). pixel_extract() will attempt to automate that process if the total size of file(s) that would be copied does not exceed the threshold given by max_ram, and length(xy) > 1 (requires GDAL >= 3.6).

For alternative workflows that involve copying to local storage, the data management functions (e.g., copyDatasetFiles()) and the VSI filesystem functions (e.g., vsi_is_local(), vsi_stat(), vsi_copy_file()) may be of interest.

Examples

pt_file <- system.file("extdata/storml_pts.csv", package="gdalraster")
# id, x, y in NAD83 / UTM zone 12N, same as the raster
pts <- read.csv(pt_file)
print(pts)
#>    id   xcoord  ycoord
#> 1   1 324650.9 5103344
#> 2   2 324171.0 5103034
#> 3   3 323533.4 5103329
#> 4   4 325220.0 5103508
#> 5   5 325703.1 5102377
#> 6   6 326297.8 5103924
#> 7   7 325520.4 5104146
#> 8   8 326247.7 5102506
#> 9   9 327711.7 5104476
#> 10 10 324181.7 5103901

raster_file <- system.file("extdata/storml_elev.tif", package="gdalraster")

pixel_extract(raster_file, pts[-1])
#> extracting from band 1...
#> 0...10...20...30...40...50...60...70...80...90...100 - done.
#>         b1
#>  [1,] 2648
#>  [2,] 2865
#>  [3,] 2717
#>  [4,] 2560
#>  [5,] 2916
#>  [6,] 2633
#>  [7,] 2548
#>  [8,] 2801
#>  [9,] 2475
#> [10,] 2822

# or as GDALRaster object
ds <- new(GDALRaster, raster_file)
pixel_extract(ds, pts[-1])
#> extracting from band 1...
#> 0...10...20...30...40...50...60...70...80...90...100 - done.
#>         b1
#>  [1,] 2648
#>  [2,] 2865
#>  [3,] 2717
#>  [4,] 2560
#>  [5,] 2916
#>  [6,] 2633
#>  [7,] 2548
#>  [8,] 2801
#>  [9,] 2475
#> [10,] 2822

# interpolated values
pixel_extract(raster_file, pts[-1], interp = "bilinear")
#> extracting from band 1...
#> 0...10...20...30...40...50...60...70...80...90...100 - done.
#>             b1
#>  [1,] 2649.217
#>  [2,] 2881.799
#>  [3,] 2716.290
#>  [4,] 2558.797
#>  [5,] 2920.404
#>  [6,] 2629.495
#>  [7,] 2548.250
#>  [8,] 2810.543
#>  [9,] 2478.609
#> [10,] 2819.776

# individual pixel values within a kernel
pixel_extract(raster_file, pts[-1], krnl_dim = 3)
#> extracting from band 1...
#> 0...10...20...30...40...50...60...70...80...90...100 - done.
#>       b1_p1 b1_p2 b1_p3 b1_p4 b1_p5 b1_p6 b1_p7 b1_p8 b1_p9
#>  [1,]  2660  2654  2651  2652  2648  2646  2653  2647  2645
#>  [2,]  2924  2895  2901  2893  2865  2869  2863  2838  2841
#>  [3,]    NA  2709  2704    NA  2717  2717    NA  2725  2728
#>  [4,]  2554  2558  2562  2557  2560  2564  2559  2562  2566
#>  [5,]  2932  2920  2908  2927  2916  2903  2923  2911  2899
#>  [6,]  2633  2642  2650  2627  2633  2640  2619  2624  2630
#>  [7,]  2548  2548  2550  2549  2548  2550  2550  2548  2550
#>  [8,]  2785  2777  2776  2807  2801  2803  2833  2825  2827
#>  [9,]  2489  2482  2475  2479  2475  2470  2474  2471  2468
#> [10,]  2832  2810  2789  2839  2822  2800  2833  2811  2788

# lont/lat xy
pts_wgs84 <- transform_xy(pts[-1], srs_from = ds$getProjection(),
                          srs_to = "WGS84")

# transform the input xy
pixel_extract(ds, xy = pts_wgs84, xy_srs = "WGS84")
#> extracting from band 1...
#> 0...10...20...30...40...50...60...70...80...90...100 - done.
#>         b1
#>  [1,] 2648
#>  [2,] 2865
#>  [3,] 2717
#>  [4,] 2560
#>  [5,] 2916
#>  [6,] 2633
#>  [7,] 2548
#>  [8,] 2801
#>  [9,] 2475
#> [10,] 2822

ds$close()