简体   繁体   English

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

[英]How to compute land cover area in R

Basically, I computed a global distribution probability model in the form of ASCII, say: gdpm . 基本上,我以ASCII的形式计算了一个全局分布概率模型,比如: gdpm gdpm 's values are all between 0 and 1. gdpm的值都在0到1之间。

Then I imported a local map from shape file: 然后我从shape文件中导入了一个本地地图:

shape <- file.choose()  
map <- readOGR(shape, basename(file_path_sans_ext(shape)))

The next step, I rasterized gdpm , and cropped using the local map: 下一步,我光栅化gdpm ,并使用本地地图裁剪:

ldpm <- mask(gdpm, map)

Then, I reclassified this continuous model into a discrete model (I divided the model into 6 levels): 然后,我将这个连续模型重新分类为离散模型(我将模型划分为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)

在此输入图像描述

I've got a cropped and reclassified raster, now I need to summarize land cover, that is, to each level, I want to calculate its proportion of area in each region of the local map. 我有一个裁剪和重新分类的栅格,现在我需要总结一下土地覆盖,也就是说, 每个级别,我想计算它在本地地图每个区域的面积比例。 (I don't know how to describe it in terminology). (我不知道如何用术语来描述它)。 I found and followed an example ( RobertH ): 我发现并追随了一个例子( RobertH ):

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

tab <- sapply(ext, function(x) tabulate(x, 10))
tab <- tab / colSums(tab)

But I'm not sure if it works, since the output of tab is confusing. 但我不确定它是否有效,因为tab的输出令人困惑。 So how to compute land cover area correctly? 那么如何正确计算土地覆盖面积呢? How can I apply the correct method within each polygon? 如何在每个多边形中应用正确的方法?

My original data is too large, I can only provide an alternative raster (I think this example should apply a different reclassify matrix): 我的原始数据太大,我只能提供另一种栅格(我认为这个例子应该应用不同的重分类矩阵):

Example raster 示例栅格

Or you can generate a test raster ( RobertH ): 或者您可以生成测试栅格( 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")

I also have a question about plotting a raster: 我还有一个关于绘制栅格的问题:

r <- as(r, "SpatialPixelsDataFrame")
r <- as.data.frame(r)
colnames(r) <- c("value", "x", "y")

I do this conversion to make a raster plot-able with ggplot2, is there a more concise method? 我做这个转换,使用ggplot2制作光栅图,是否有更简洁的方法?

Seems like you can get the area by the number of pixels. 好像你可以通过像素数来获得该区域。
Let's start with a reproducible example: 让我们从一个可重现的例子开始:

r <- raster(system.file("external/test.grd", package="raster"))
plot(r)

在此输入图像描述

Since, the values in this raster are in another range than your data, let's adapt them to your values: 由于此栅格中的值与您的数据不在另一个范围内,因此我们将它们调整为您的值:

r <- r / 1000
r[r>1,] <- 1

Afterwards, we apply your reclassification: 之后,我们会应用您的重新分类:

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) 
r2 <- reclassify(r, recalc)
plot(r2)

在此输入图像描述

Now, how do we get the area? 现在,我们如何获得该地区?
Since you are working with a projected raster, you can simply use the number of pixels and the raster resolution. 由于您使用的是投影栅格,因此您只需使用像素数和栅格分辨率即可。 Therefore, we first need to check the resolution and the map units of the projection: 因此,我们首先需要检查投影的分辨率和地图单位:

res(r)
# [1] 40 40
crs(r)
# CRS arguments:
#   +init=epsg:28992
# +towgs84=565.237,50.0087,465.658,-0.406857,0.350733,-1.87035,4.0812 +proj=sterea
# +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000
# +y_0=463000 +ellps=bessel +units=m +no_defs

Now, we know that we are dealing with pixels of 40 x40 meters, since we have a metric CRS. 现在,我们知道我们正在处理40 x40米的像素,因为我们有一个公制CRS。

Let's use this information to calculate the area of each class. 让我们用这些信息来计算每个班级的面积。

app <- res(r)[1] * res(r)[2] # area per pixel

table(r2[]) * app
#      1       2       3       4       5 
# 124800 2800000 1310400  486400  243200 

For the plotting of georeferenced rasters, I would like to refer you to an older question here on SO 对于地理参考栅格的绘图,我想在这里向您推荐一个较旧的问题

loki's answer is OK, but this can be done the raster way, which is safer. loki的答案还可以,但这可以用光栅方式完成,这样更安全。 And it is important to consider whether the coordinates are angular (longitude/latitude) or planar (projected) 重要的是要考虑坐标是角度(经度/纬度)还是平面(投影)

Example data 示例数据

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)

Approach 1. Only for planar data 方法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

Approach 2. For angular data (but also works for planar data) 方法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

If you want to summarize by polygons, you can do something like this: 如果要按多边形进行汇总,可以执行以下操作:

# example polygons
a <- rasterToPolygons(aggregate(r, 25))

Approach 1 方法1

# 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    

Approach 2 方法2

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

Check results: 检查结果:

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

Note that if you are dealing with lon/lat data you cannot use prod(res(r)) to get the cell size. 请注意,如果您正在处理lon / lat数据,则无法使用prod(res(r))来获取单元格大小。 In that case you will need to use the area function and loop over classes, I think. 在这种情况下,你需要使用区域函数并循环遍历类。

You also asked about plotting. 你还问了一下情节。 There are many ways to plot a Raster* object. 绘制Raster *对象的方法有很多种。 The basic ones are: 基本的是:

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

 library(rasterVis); 
 levelplot(r2)

More tricky approaches: 更棘手的方法:

 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)       

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM