[英]How to extract values from annual raster layer stack and use the raster that is closest in time
我有許多帶有時間日期戳的點位置和 18 個柵格層,每個柵格層包含 2002 年至 2019 年的年度 NDVI 值。我想從類似於位置年份的年份柵格層中提取這些位置的值時間戳。
例子:
location1 時間戳 12.04.2003 --> 從柵格層 2003 中提取值
location2 時間戳 12.06.2012 --> 從柵格層 2012 中提取值
這是我的位置數據示例 (EPSG 3035):
X id areas sex x_ y_ case time
1 1 1 13 f 4141879 2762606 1 2010-11-16 00:59:00
2 2 1 13 f 4142395 2759956 1 2010-11-16 21:59:00
3 3 1 13 f 4143634 2761615 1 2010-11-17 04:59:00
4 4 1 13 f 4143171 2761593 1 2010-11-17 11:59:00
5 5 1 13 f 4144488 2762547 1 2010-11-17 18:59:00
6 6 1 13 f 4143885 2761944 1 2010-11-18 08:59:00
首先,我創建了一個包含所有 18 個柵格圖層的柵格堆棧,並為每個圖層添加了日期:
#create raster stack NDVI
setwd("E:/MA_2Try/annual_NDVI/average")
grids <- list.files("E:/MA_2Try/annual_NDVI/average" , pattern = "*.tif$")
NDVI_stack=stack(grids)
#Add years to stack
dt<-as.data.frame(
as.POSIXct(c('2002-01-01','2003-01-01','2004-01-01','2005-01-01','2006-01-01',
'2007-01-01','2008-01-01','2009-01-01','2010-01-01','2011-01-01',
'2012-01-01','2013-01-01','2014-01-01','2015-01-01','2016-01-01',
'2017-01-01','2018-01-01','2019-01-01')))
NDVI_stack <- setZ(NDVI_stack, dt[,1], "SampleDate")
這是柵格 [[1]] 的結果信息
> NDVI_stack[[1]]
class : RasterLayer
dimensions : 4125, 5503, 22699875 (nrow, ncol, ncell)
resolution : 250, 250 (x, y)
extent : 3530500, 4906250, 2229250, 3260500 (xmin, xmax, ymin, ymax)
crs : +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs
source : ndvi_average_2002.tif.tif
names : ndvi_average_2002.tif
SampleDate : 2002-01-01
我怎樣才能做到這一點?
你可以嘗試這樣的事情:
library(raster)
library(sf)
rast <- raster::raster(matrix(1:100, ncol=10), xmn=0, ymn=0, xmx=10, ymx=10)
s <- stack(rast,rast/100,rast*100)
s <- setZ(s, c('2010-01-01','2011-01-01','2013-01-01'), "SampleDate")
pt1 = st_point(c(0,1))
pt2 = st_point(c(1,1))
d = data.frame(id = 1:2,sex=c("m","f"),date = c("2010-11-16 00:59:00","2011-11-16 21:59:00"))
d$geom = st_sfc(pt1, pt2)
df = st_as_sf(d)
myex <- function(rst,point){
ex <- as.list(1:nrow(point))
for (i in 1:nrow(point)) {
year_p <- as.integer(lubridate::year(point[i,]$date))
diff <- abs(year_p-as.integer(lubridate::year(unlist(rst@z))))
index <- which(diff==min(diff))
ex[[i]] <- raster::extract(rst[[index]],point[i,],include_cols=colnames(point))
}
ex <- as.data.frame(do.call(rbind,ex))
ex$id <- point$id
return(ex)
}
myex(s,df)
output 看起來像這樣:
V1 id
1 10.0 1
2 0.2 2
這個想法是選擇點日期和圖層日期之間差異最小的圖層並將其用於提取。 這里我使用了一個for
循環,但也可以使用lapply
或其並行版本之一(例如snowfall::sfLaplly
)。 此外,如果您在點周圍創建一個小緩沖區,則可以用exactextract::exact_extract
替換raster::extract
,這樣會更快
這是使用terra
執行此操作的方法(但應該很容易針對raster
進行調整)
示例數據
library(terra)
s <- rast(system.file("ex/logo.tif", package="terra"))
names(s) <- 2010:2012
pts <- matrix(c(14.53, 70.41, 12.93, 53.8, 60.21, 47.41), ncol=2, byrow=TRUE)
time <- as.POSIXct(c("2011-11-16 00:59:00", "2010-01-16 00:59:00", "2010-11-16 00:59:00"))
從時間戳中獲取所需的層(年)並將它們與層匹配。 如果月份 > 六月,一個簡單的方法是將年份四舍五入:
y <- format(time, format='%Y') |> as.integer()
m <- format(time, format='%m') |> as.integer()
y <- y + (m > 6)
y
#[1] 2012 2010 2011
現在使用提取物
e <- extract(s, vect(pts), layer=as.character(y))
e
# ID layer value
#1 1 2012 253
#2 2 2010 73
#3 3 2011 14
使用raster
,您可以像這樣執行最后一步:
ee <- extract(s, pts)
ee
# 2010 2011 2012
#1 255 255 253
#2 73 74 60
#3 6 14 27
j <- match(y, names(s))
j
#[1] 3 1 2
ee[cbind(1:nrow(ee), j)]
#[1] 253 73 14
但請注意,光柵可能會在圖層名稱前加上“X”,它們以 0 到 9 之間的字符開頭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.