如何计算R中的土地覆盖面积

Tia*_*Qin 6 gis r geospatial r-raster

基本上,我以ASCII的形式计算了一个全局分布概率模型,比如说: gdpm.gdpm的值都在0到1之间.

然后我从shape文件中导入了一个本地地图:

shape <- file.choose()  
map <- readOGR(shape, basename(file_path_sans_ext(shape)))
Run Code Online (Sandbox Code Playgroud)

下一步,我进行栅格化gdpm,并使用本地地图进行裁剪:

ldpm <- mask(gdpm, map)
Run Code Online (Sandbox Code Playgroud)

然后,我将这个连续模型重新分类为离散模型(我将模型划分为6个级别):

recalc <- matrix(c(0, 0.05, 0, 0.05, 0.2, 1, 0.2, 0.4, 2, 0.4, 0.6, 3, 0.6, 0.8, 4, 0.8, 1, 5), ncol = 3, byrow = TRUE) 

ldpmR <- reclassify(ldpm, recalc)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我有一个裁剪和重新分类的栅格,现在我需要总结一下土地覆盖,也就是说,每个级别,我想计算它在本地地图每个区域的面积比例.(我不知道如何用术语来描述它).我发现并追随了一个例子(RobertH):

ext <- raster::extract(ldpmR, map)

tab <- sapply(ext, function(x) tabulate(x, 10))
tab <- tab / colSums(tab)
Run Code Online (Sandbox Code Playgroud)

但我不确定它是否有效,因为输出结果tab令人困惑. 那么如何正确计算土地覆盖面积呢?如何在每个多边形中应用正确的方法?

我的原始数据太大,我只能提供另一种栅格(我认为这个例子应该应用不同的重分类矩阵):

示例栅格

或者您可以生成测试栅格(RobertH):

library(raster)
s <- stack(system.file("external/rlogo.grd", package="raster")) 
writeRaster(s, file='testtif', format='GTiff', bylayer=T, overwrite=T)
f <- list.files(pattern="testtif_..tif")
Run Code Online (Sandbox Code Playgroud)

我还有一个关于绘制栅格的问题:

r <- as(r, "SpatialPixelsDataFrame")
r <- as.data.frame(r)
colnames(r) <- c("value", "x", "y")
Run Code Online (Sandbox Code Playgroud)

我做这个转换,使用ggplot2制作光栅图,是否有更简洁的方法?

Rob*_*ans 5

loki 的回答是可以的,但这可以通过光栅方式完成,这样更安全。重要的是要考虑坐标是角度(经度/纬度)还是平面(投影)

示例数据

library(raster)
r <- raster(system.file("external/test.grd", package="raster"))
r <- r / 1000
recalc <- matrix(c(0, 0.05, 0, 0.05, 0.2, 1, 0.2, 0.4, 2, 0.4, 0.6, 3, 0.6, 0.8, 4, 0.8, 2, 5), ncol = 3, byrow = TRUE) 
r2 <- reclassify(r, recalc)
Run Code Online (Sandbox Code Playgroud)

方法 1. 仅适用于平面数据

f <- freq(r2, useNA='no')
apc <- prod(res(r))
f <- cbind(f, area=f[,2] * apc)
f

#     value count    area
#[1,]     1    78  124800
#[2,]     2  1750 2800000
#[3,]     3   819 1310400
#[4,]     4   304  486400
#[5,]     5   152  243200
Run Code Online (Sandbox Code Playgroud)

方法 2. 对于角度数据(但也适用于平面数据)

a <- area(r2)
z <- zonal(a, r2, 'sum')
z
#     zone     sum
#[1,]    1  124800
#[2,]    2 2800000
#[3,]    3 1310400
#[4,]    4  486400
#[5,]    5  243200
Run Code Online (Sandbox Code Playgroud)

如果要按多边形进行汇总,可以执行以下操作:

# example polygons
a <- rasterToPolygons(aggregate(r, 25))
Run Code Online (Sandbox Code Playgroud)

方法一

# extract values (slow)
ext <- extract(r2, a)

# tabulate values for each polygon
tab <- sapply(ext, function(x) tabulate(x, 5))
# adjust for area (planar data only)
tab <- tab * prod(res(r2))

# check the results, by summing over the regions
rowSums(tab)
#[1]  124800 2800000 1310400  486400  243200    
Run Code Online (Sandbox Code Playgroud)

方法二

x <- rasterize(a, r2)
z <- crosstab(x, r2)
z <- cbind(z, area = z[,3] * prod(res(r2)))
Run Code Online (Sandbox Code Playgroud)

检查结果:

aggregate(z[, 'area', drop=F], z[,'Var2', drop=F], sum)
  Var2    area
#1    1  124800
#2    2 2800000
#3    3 1310400
#4    4  486400
#5    5  243200
Run Code Online (Sandbox Code Playgroud)

请注意,如果您正在处理 lon/lat 数据,则不能使用 prod(res(r)) 来获取像元大小。在这种情况下,我认为您将需要使用 area 函数并循环遍历类。

您还询问了绘图。有多种绘制 Raster* 对象的方法。基本的有:

 image(r2)
 plot(r2)
 spplot(r2)

 library(rasterVis); 
 levelplot(r2)
Run Code Online (Sandbox Code Playgroud)

更棘手的方法:

 library(ggplot2) # using a rasterVis method
 theme_set(theme_bw())
 gplot(r2) + geom_tile(aes(fill = value)) +
      facet_wrap(~ variable) +
      scale_fill_gradient(low = 'white', high = 'blue') +
      coord_equal()


 library(leaflet)
 leaflet() %>% addTiles() %>%
 addRasterImage(r2, colors = "Spectral", opacity = 0.8)       
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1589 次

最近记录:

7 年,9 月 前