Raster-Vector Operations

Two worlds of spatial data

  • Till now, we have treated vector and raster data separately
  • However, in many cases, you will need to combine both types of data
  • For example, take the Zonal operation we discussed in the chapter Zonal: Typically, your “zones” will be vector polygons

Zonal operations with vector data

  • The zonal function in {terra} can handle vector data: however, it requires sf objects to be converted to terra’s own vector format, called SpatVector. - The function vect() can be used to convert sf objects to SpatVector objects:
mean_vals <- zonal(r, vect(zones), fun = mean, na.rm = TRUE)


zones$mean <- mean_vals$elevation
Figure 7.1: The original raster data
Figure 7.2: The original zones as vector polygons
Figure 7.3: The resulting zones (mean elevation per zone), also as vector data

Extracting raster values at vector points

  • A another common operation is to extract raster values at specific points
  • Let’s take the example of the city of Luxembourg (see Global Operation (2))
  • The function extract() can be used to extract raster values at specific points
  • extract returns a data.frame with
    • one column per raster band (1 in our case)
    • one row per point (also 1 in our case):

lux_elev <- extract(r, luxembourg_city)
lux_elev
  ID elevation
1  1  293.9805

Vector to raster conversion

  • Functions that combine raster and vector data usually convert vector to raster internally
  • Sometimes, we might want to do this conversion explicitly. This can be done using the rasterize() function
  • This function takes three arguments:
    1. x: The vector data (either of class sf or SpatVector)
    2. y: A raster object that defines the extent, resolution, and CRS of the resulting raster (i.e. a “template”)
    3. field: The name of the column in the vector data that should be used to fill the raster cells
# we can create a template using the input vector. All we have to specify 
# is the resolution of the output raster, which is evalutated in the units of
# the CRS of the input vector data (meters in our case).

template <- rast(zones, resolution = 1000)

zones_raster <- rasterize(zones, template, "zone")
(a) The original zones as polygon data
(b) The zones as raster data
Figure 7.4: Note how the conversion to polygons results in a loss of detail
Note

Note that rasters don’t store character information. The above zones are coded as integers with a corresponding look-up table (see ?terra::levels).

Raster to vector conversion

  • The opposite operation, converting raster data to vector data, can be done using the {terra} functions as.points, as.lines and as.polygons:
  • The resulting object will be of class SpatVector. This can be converted to the sf class using st_as_sf()
zones_poly <- as.polygons(zones_raster) |> 
  st_as_sf()
(a) The zones as raster data
(b) The zones as polygon data
Figure 7.5: Note how the conversion back to polygons preserves the cell boundaries

🪕 Tasks

  1. Import Arealstatistik.gpkg from Spatial_Analysis_II using {sf}
  2. To rasterize the data, we need a template raster object. Create a template raster object with a resolution of 100m using the rast() function
  3. Rasterize the arealstatistik data using the function rasterize, the tempalte from the previous step, and the column AS_4 as the field to fill the raster cells
  1. The resulting raster contains the integer values 1 to 4. These values correspond to the following land use categories (see metadata):
    1. Settlement and urban areas
    2. Agricultural areas
    3. Wooded areas
    4. Unproductive areas

To make the raster more interpretable, assign the corresponding names to the levels of the raster using the levels() function. The levels should be a data.frame with two columns: ID and name (see below)

levs <- data.frame(
  ID = 1:4, 
  name = c(
    "Settlement and urban areas", 
    "Agricultural areas", 
    "Wooded areas", 
    "Unproductive areas"
    ) 
  )

levels(areal_rast) <- levs

plot(areal_rast)