【问题标题】:Reclassify values in a RasterBrick by the use of an additional Raster (Digital elevation model)通过使用附加栅格(数字高程模型)重新分类 RasterBrick 中的值
【发布时间】:2018-11-05 19:49:02
【问题描述】:

我有一个 RasterBrick,其中包含每日积雪数据,其值为 1、2 和 3(1= 下雪,2= 无雪,3= 被云遮挡)。

一天的积雪示例:

> snowcover
class       : Large RasterBrick 
dimensions  : 26, 26, 2938  (nrow, ncol, nlayers)
resolution  : 231, 232  (x, y)
extent      : 718990, 724996, 5154964, 5160996  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=32 +datum=WGS84 +units=m +no_defs +ellps=WGS84       
              +towgs84=0,0,0  

现在我希望插入被云遮挡的像素(但仅限于单个 RasterLayer 中云量少于 90% 的情况,否则应为该图层保留原始值)。

对于空间插值,我想使用数字高程模型(相同的研究区域并且已经具有相同的分辨率)来提取上部和RasterBrick 的每一层分别降低雪线边界。上面的雪线代表海拔高度 所有无云像素都被归类为雪。较低的雪线标识 在此高度以下,所有无云像素也无雪。

> dem
class       : RasterLayer 
resolution  : 231, 232  (x, y)
extent      : 718990.2, 724996.2, 5154964, 5160996 (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=32 +datum=WGS84 +units=m +no_defs +ellps=WGS84       
              +towgs84=0,0,0 
values      : 1503, 2135  (min, max)

对于上层雪线,我需要雪覆盖像素的最小高度(值 = 1)。现在,RasterBrick 的 RasterLayer 中高于此最低海拔的所有像素值为 3,应重新分类为值 1(假设被雪覆盖)。

另一方面,对于下雪线,我需要确定无雪像素的最大海拔(值 = 2)。现在,RasterBrick 的 RasterLayer 中高于此最大高程的所有值为 3 的像素都应重新分类为值 2(假设无雪)。

这可以使用 R 吗?

我尝试使用叠加功能,但卡在那里。

# For the upper snowline:
overlay <- overlay(snowcover, dem, fun=function(x,y){ x[y>=minValue(y[x == 1])] <- 1; x})

【问题讨论】:

  • 是的,有可能。为了让我们能够有效地帮助您,请提供一些代码生成的示例数据(或手册中的示例),以及一些代码来展示您的尝试。
  • 谢谢!我已经编辑了我的问题。
  • 我可能在吹毛求疵,但 Google 云端硬盘并不是存储使您的问题可重现的数据的最佳位置(链接可能会中断,不太可能由 archive.org 存档)。理想的做法是在问题的文本中包含数据(但在这种情况下,XML 太大,因此您必须使用另一种格式)。或者将 XML 代码放在更基于 html 的东西上,比如 pastebin(我刚刚检查过,那里的许可证与 SO 上的相同)。
  • raster 包有很多例子说明如何做到这一点。还有上百个stackoverflow的例子

标签: r classification interpolation missing-data spatial-interpolation


【解决方案1】:

这是一些示例数据

library(raster)
dem <- raster(ncol=8, nrow=7, xmn=720145, xmx=721993, ymn=5158211, ymx=5159835, crs='+proj=utm +zone=32 +datum=WGS84')
values(dem) <- ncell(dem):1
snow <- setValues(dem, c(1, 1, rep(1:3, each=18)))
snow[,c(2,5)] <- NA
snow[3] <- 3


plot(snow)
lines(as(dem, 'SpatialPolygons'))
text(dem)

该图显示了雪等级(1、2、3),高程值位于顶部。

我们可以使用掩码,但需要处理缺失值。

msnow <- reclassify(snow, cbind(NA, 0))
# mask to get only the snow elevations
x <- mask(dem, msnow, maskvalue=1, inverse=TRUE)

# minimum elevation of the snow-covered cells
minsnow <- minValue(x)
minsnow 
#[1] 37

# snow elevation = 1
snowy <- reclassify(dem, rbind(c(-Inf, minsnow, NA), c(minsnow, Inf, 1)))
newsnow <- cover(snow, snowy)

s <- stack(dem, snow, newsnow)
names(s) <- c("elevation", "old_snow", "new_snow")

你已经很亲近了,你可以做到的

 r <- overlay(dem, snow, fun=function(e, s){ s[e >= minsnow] <- 1; s})

但请注意,这也会覆盖没有雪的高单元格。

可以这样解决:

r <- overlay(dem, snow, fun=function(e, s){ s[e >= minsnow & is.na(s)] <- 1; s})

要选择具有超过 x% 单元格且值为 3 的层(这里我使用 34% 的阈值):

threshold = .34
s <- stack(snow, snow+1, snow+2)
f <- freq(snow)
f 
#     value count
#[1,]     1    14
#[2,]     2    13
#[3,]     3    15
#[4,]    NA    14

nas <- f[is.na(f[,1]), 2]

ss <- subs(s, data.frame(from=3, to=1, subsWithNA=TRUE))
cs <- cellStats(ss, sum)
csf <- cs / (ncell(snow) - nas)
csf
#  layer.1   layer.2   layer.3 
#0.3571429 0.3095238 0.3333333 

i <- which(csf < threshold)
use <- s[[i]]
#use
class       : RasterStack 
dimensions  : 7, 8, 56, 2  (nrow, ncol, ncell, nlayers)
resolution  : 231, 232  (x, y)
extent      : 720145, 721993, 5158211, 5159835  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=32 +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
names       : layer.2, layer.3 
min values  :       2,       3 
max values  :       4,       5 

【讨论】:

  • 哇,感谢这个不错的解决方案!现在我只需要弄清楚如何排除 RasterBrick 的所有图层,其像素超过 90%,值为 3(90% 云量)。
  • 我添加了一些代码来展示如何选择图层
  • csf 向我展示了一些不同的东西。它显示计数为 15.21429?
  • 我忘了一行!对不起
猜你喜欢
  • 2016-08-22
  • 2018-07-18
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 2019-12-15
  • 2021-01-25
  • 1970-01-01
  • 2015-09-08
相关资源
最近更新 更多