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

拟墨画扇 提交于 2019-12-13 20:10:40

问题


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)

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

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


回答1:


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

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



回答2:


There are no negative slopes, so I assume you want those that are less than 5 degrees

library(raster)
elevation <- getData('alt', country='CHE')
x <- terrain(elevation, opt='slope', unit='degrees')

z <- x <= 5

Now you can count cells with freq

f <- freq(z)

If you have a planar coordinate reference system (that is, with units in meters or similar) you can do

f <- cbind(f, area=f[,2] * prod(res(z)))

to get areas. But for lon/lat data, you would need to correct for different sized cells and do

a <- area(z)
zonal(a, z, fun=sum)

And there are different ways to plot, but the most basic one

plot(z)


来源:https://stackoverflow.com/questions/47675851/mapping-slope-of-an-area-and-returning-percent-above-and-below-a-threshold-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!