11 Raster-vector interactions
- This chapter requires the following packages:
This section focuses on interactions between raster and vector geographic data models, introduced in Chapter 2. It includes four main techniques: raster cropping and masking using vector objects (section 11.2); extracting raster values using different types of vector data (section 11.3); and raster-vector conversion (sections 11.4 and 11.5). The above concepts are demonstrated using data used in previous chapters to understand their potential real-world applications.
11.2 Raster cropping
Many geographic data projects involve integrating data from many different sources, such as remote sensing images (rasters) and administrative boundaries (vectors). Often the extent of input raster datasets is larger than the area of interest. In this case raster cropping and masking are useful for unifying the spatial extent of input data. Both operations reduce object memory use and associated computational resources for subsequent analysis steps, and may be a necessary preprocessing step before creating attractive maps involving raster data.
We will use two objects to illustrate raster cropping:
srtmrepresenting elevation (meters above sea level) in Southwestern Utah.
- A vector (
zionrepresenting Zion National Park.
Both target and cropping objects must have the same projection.
The following code chunk therefore not only loads the datasets, from the spDataLarge package installed in Chapter 2.
It also reprojects
zion (see section 5.2 for more on reprojection):
We will use
crop() from the raster package to crop the
crop() reduces the rectangular extent of the object passed to its first argument based on the extent of the object passed to its second argument, as demonstrated in the command below (which generates Figure 11.1:B — note the smaller extent of the raster background):
crop() is the raster function
mask(), which sets values outside of the bounds a the object passed to its second argument to
The following command therefore masks every cell outside of the the Zion National Park boundaries (Figure 11.1:C):
Changing the settings of
mask() yields in different results.
maskvalue = 0, for example, would set all pixels outside the national park to 0.
inverse = TRUE would mask everything inside the bounds of the park (see
?mask for details).
11.3 Raster extraction
Raster extraction is the process of identifying and returning the values associated with a ‘target’ raster at specific locations, based on a (typically vector) geographic ‘selector’ object.
The results depend on the type of selector used (points, lines or polygons) and arguments passed to the
raster::extract() function, which we use to demonstrate raster extraction.
The reverse of raster extraction — assigning raster cell values based on vector objects — is rasterization, described in section 11.4.
The simplest example is extracting the value of a raster cell at specific points.
For this purpose we will use
zion_points, which contain a sample of 30 locations with the Zion National Park (Figure 11.2).
The following command extracts elevation values from
srtm and assigns the resulting vector to a new column (
elevation) in the
buffer argument can be used to specify a buffer radius (in meters) around each point.
The result of
raster::extract(srtm, zion_points, buffer = 1000), for example, is a list of vectors, each of which representing the values of cells inside the buffer associated with each point.
In practice this example is a special case of extraction with a polygon selector, described below.
Raster extraction also works with line selectors.
To demonstrate this, the code below creates
zion_transect, a straight line going from northwest to southeast of the Zion National Park, illustrated in Figure 11.3:A (see section 2.1 for a recap on the vector data model):
The utility of extracting heights from a linear selector is illustrated by imagining that you are planning a hike. The method demonstrated below provides an ‘elevation profile’ of the route (the line does not need to be straight), useful for estimating how long it will take due to long climbs:
Note the use of
along = TRUE and
cellnumbers = TRUE arguments to return cell IDs along the path.
The result is a list containing a matrix of cell IDs in the first column and elevation values in the second.
The subsequent code chunk first converts this tricky matrix-in-a-list object into a simple data frame, returns the coordinates associated with each extracted cell and finds the associated distances along the transect (see
?geosphere::distm() for details):
transect_df can be used to create elevation profiles, as illustrated in Figure 11.3:B.
The final type of geographic vector object for raster extraction is polygons.
Like lines and buffers, polygons tend to return many raster values per polygon.
This is demonstrated in the command below, which results in a data frame with column names
ID (the row number of the polygon) and
srtm (associated elevation values):
Such results can be used to generate summary statistics for raster values per polygon, for example to to characterize a single region or to compare many regions.
The generation of summary statistics is demonstrated the code below, which creates the object
zion_srtm_df containing summary statistics for elevation values in Zion National Park (see 11.4:A):
The preceding code chunk used the tidyverse to provide summary statistics for cell values per polygon ID, as described in Chapter 3. The results provide useful summaries, for example that the maximum height in the park is around 2,661 meters (other summary statistics such as standard deviation can also be calculated in this way). Because there is only one polygon in the example a data frame with a single row is returned, but the method works when multiple selector polygons are used.
The same approach works for counting occurrences of categorical raster values within polygons.
This is illustrated with a land cover dataset (
nlcd) from the spDataLarge package in 11.4:B and demonstrated in the code below:
zion_nlcd = raster::extract(nlcd, zion, df = TRUE, factors = TRUE) dplyr::select(zion_nlcd, ID, levels) %>% gather(key, value, -ID) %>% group_by(ID, key, value) %>% tally() %>% spread(value, n, fill = 0) #> # A tibble: 1 x 9 #> # Groups: ID, key  #> ID key Barren Cultivated Developed Forest Herbaceous Shrubland #> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1. levels 98285. 62. 4205. 298299. 235. 203701. #> # ... with 1 more variable: Wetlands <dbl>
So far we have seen how
raster::extract() is a flexible way of extracting raster cell values from a range of input geographic objects.
An issue with the function, however, is that it is slow.
If this is a problem it is useful to know about alternatives and work-arounds, three of which are presented below.
- Parallelization: this approach works when using many geographic vector selector objects by splitting them into groups and extracting cell values independently for each group (see
?raster::clusterR()for details of this approach).
- Use the velox package (Hunziker 2017), which provides a fast method for extracting raster data that fits in memory (see the packages
extractvignette for details).
- Using R-GIS bridges (see Chapter 10): efficient calculation of raster statistics from polygons can be found in the SAGA function
saga:gridstatisticsforpolygons, for example, which can be accessed via RQGIS.
Rasterization is the conversion of vector objects into their representation in raster objects. Usually, the output raster is used for quantitative analysis (e.g. analysis of terrain) or modeling. As we saw in Chapter 2 the raster data model has some characteristics that make it conducive to certain methods. Furthermore, the process of rasterization can help simplify datasets because the resulting values all have the same spatial resolution: rasterization can be seen as a special type of geographic data aggregation.
The raster package contains the function
rasterize() for doing this work.
Its first two arguments are
x, vector object to be rasterized and
y, a ‘template raster’ object defining the extent, resolution and CRS of the output.
The geographic resolution of the input raster has a major impact on the results: if it is too low (cell size is too large) the result may miss the full geographic variability of the vector data; if it is too high computational times may be excessive.
There are no simple rules to follow when deciding an appropriate geographic resolution, which is heavily dependent on the intended use of the results.
To demonstrate rasterization in action, we will use a template raster that has the same extent and CRS as the input vector data
cycle_hire_osm_projected (a dataset on cycle hire points in London illustrated in Figure 11.5:A) and spatial resolution of 1000 meters:
Rasterization is a very flexible operation: the results depend not only on the nature of the template raster, but also on the type of input vector (e.g. points, polygons) and a variety arguments taken by the
To illustrate this flexibility we will try three different approaches rasterization.
First we create a raster representing the presence or absence of cycle hire points (known as presence/absence rasters).
In this case
rasterize() requires only one argument in addition to
y (the aformentioned vector and raster objects): a value to be transferred to all non-empty cells specified by
field (results illustrated Figure 11.5:B).
fun argument specifies summary statistics used to covert multiple observations in close proximity into associate cells in the raster object.
fun = 'last is used but other options such as
fun = "count" can be used, in this case to count the number of cycle hire points in each grid cell (the results of this operation are illustrated in Figure 11.5:C).
The new output,
ch_raster2, shows the number of cycle hire points in each grid cell.
The cycle hire locations have different numbers of bicycles described by the
capacity variable, raising the question, what’s the capacity in each grid cell?
To calculate that we must
sum the field (
"capacity"), resulting in output illustrated in Figure 11.5:D, calculated with the following command (other summary functions such as
mean could be used):
Another dataset based on California’s polygons and borders (created below) illustrates raterization of lines. After casting the polygon objects into a multilinestring, a template raster is created, with a resolution of a 0.5 degree:
Line rasterization is demonstrated in the code below. In the resulting raster, all cells that are touched by a line get a value, as illustrated in Figure 11.6:A.
Polygon rasterization, by contrast, selects only cells whose centroids are inside the selector polygon, as illustrated in Figure 11.6:B.
raster::rasterize() works well for most cases but is not performance optimized.
Fortunately, there are several alternatives, including the
The former is much (100 times+) faster than
rasterize() but is currently limited to polygon rasterization.
The latter is part of GDAL and therefore requires a vector file (instead of an
sf object) and rasterization parameters (instead of a
Raster* template object) as inputs.64
11.5 Spatial vectorization
Spatial vectorization is the counterpart of rasterization 11.4, but in the opposite direction. It involves converting spatially continuous raster data into spatially discrete vector data such as points, lines or polygons.
for-loops and alike by doing things like
1:10 / 2(see also Wickham (2014)).
The simplest form of vectorization is to convert the centroids of raster cells into points.
rasterToPoints() does exactly this for all non-
NA raster grid cells (Figure 11.7).
spatial parameter to
TRUE ensures the output is a spatial object, not a matrix.
Another common type of spatial vectorization is the creation of contour lines representing lines of continuous height or temperatures (isotherms) for example.
We will use a real-world digital elevation model (DEM) because the artificial raster
elev produces parallel lines (task: verify this and explain why this happens).
Contour lines can be created with the raster function
rasterToContour(), which is itself a wrapper around
contourLines(), as demonstrated below:
Contours can be added to existing plots with functions such as
As illustrated in Figure 11.8 (which was created using the tmap package described in Chapter 9), isolines can be labelled.
The final type of vectorisation involves conversion of rasters to polygons.
This can be done with
raster::rasterToPolygons(), wich converts each raster cell into a polygon consisting of five coordinates, all of which are stored in memory (explaining why rasters are often fast compared with vectors!)
This is illustrated below by converting the
grain object into polygons and subsequently dissolving borders between polygons with the same attribute values.
Attributes in this case are stored in a collumn called
layer (see section 5.3.6 and Figure 11.9).
(Note: a convenient alternative for converting rasters into polygons is
spex::polygonize() which by default returns an
The next two exercises will use a vector (
random_points) and raster dataset (
ndvi) from the RQGIS package.
It also uses a polygonal ‘convex hull’ derived from the vector dataset (
ch) to represent the area of interest:
ndviraster using (1) the
random_pointsdataset and (2) the
chdataset. Are there any difference in the output maps? Next, mask
ndviusing these two datasets. Can you see any difference now? How can you explain that?
Firstly, extract values from
ndviat the points represented in
random_points. Next, extract average values of
ndviusing a 90 buffer around each point from
random_pointsand compare these two sets of values. When would extracting values by buffers be more suitable than by points alone?
- Subset points higher than 3100 meters in New Zealand (the
nz_heightobject) and create a template raster with a resolution of 3km. Using these objects:
- Count numbers of the highest points in each grid cell.
- Find the maximum elevation in each grid cell.
- Polygonize the
graindataset and filter all squares representing clay.
- Name two advantages and disadvantages of vector data over raster data.
- At which points would it be useful to convert rasters to vectors in your work?
Hunziker, Philipp. 2017. Velox: Fast Raster Manipulation and Extraction.
Wickham, Hadley. 2014. Advanced R. CRC Press.