Search code examples
rrasterterrainr-rastergis

Mapping slope of an area and returning percent above and below a threshold in R


I am trying to figure our the proportion of an area that has a slope of 0, +/- 5 degrees. Another way of saying it is anything above 5 degrees and below 5 degrees are bad. I am trying to find the actual number, and a graphic.

To achieve this I turned to R and using the Raster package. Let's use a generic country, in this case, the Philippines

{list.of.packages <- c("sp","raster","rasterVis","maptools","rgeos")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)}

library(sp)  # classes for spatial data
library(raster)  # grids, rasters
library(rasterVis)  # raster visualisation
library(maptools)
library(rgeos)

Now let's get the altitude information and plot the slopes.

elevation <- getData("alt", country = "PHL")
x <- terrain(elevation, opt = c("slope", "aspect"), unit = "degrees")
plot(x$slope)

enter image description here Not very helpful due to the scale, so let's simply look at the Island of Palawan

e <- drawExtent(show=TRUE) #to crop out Palawan (it's the long skinny island that is roughly midway on the left and is oriented between 2 and 8 O'clock)
gewataSub <- crop(x,e)
plot(gewataSub, 1)## Now visualize the new cropped object

The Island of Palawan

A little bit better to visualize. I get a sense of the magnitude of the slopes and that with a 5 degree restriction, I am mostly confined to the coast. But I need a little bit more for analysis.

I would like Results to be something to be in two parts: 1. " 35 % (made up) of the selected area has a slope exceeding +/- 5 degrees" or " 65 % of the selected area is within +/- 5 degrees". (with the code to get it) 2. A picture where everything within +/- 5 degrees is one color, call it good or green, and everything else is in another color, call it bad or red.

Thanks


Solution

  • You can use reclassify from the raster package to achieve that. The function assigns each cell value that lies within a defined interval a certain value. For example, you can assign cell values within interval (0,5] to value 0 and cell values within the interval (5, maxSlope] to value 1.

    library(raster)  
    library(rasterVis)  
    
    elevation <- getData("alt", country = "PHL")
    x <- terrain(elevation, opt = c("slope", "aspect"), unit = "degrees")
    plot(x$slope)
    
    e <- drawExtent(show = TRUE)
    gewataSub <- crop(x, e)
    plot(gewataSub$slope, 1)
    
    m <- c(0, 5, 0,  5, maxValue(gewataSub$slope), 1)
    rclmat <- matrix(m, ncol = 3, byrow = TRUE)
    rc <- reclassify(gewataSub$slope, rclmat)
    
    levelplot(
      rc,
      margin = F,
      col.regions = c("wheat", "gray"),
      colorkey = list(at = c(0, 1, 2), labels = list(at = c(0.5, 1.5), labels = c("<= 5", "> 5")))
    )
    

    enter image description here

    After the reclassification you can calculate the percentages:

    length(rc[rc == 0]) / (length(rc[rc == 0]) + length(rc[rc == 1])) # <= 5 degrees
    [1] 0.6628788
    length(rc[rc == 1]) / (length(rc[rc == 0]) + length(rc[rc == 1])) # > 5 degrees
    [1] 0.3371212