使用r基于最接近的单元格值从特定点的栅格中提取值

时间:2014-10-30 12:08:39

标签: r extract latitude-longitude raster

我正在尝试为某些站点数据分配值,这些数据位于我有天气数据的区域之外。我试图基于最近的单元格值提取,如果可能的话,提取40km内的单元格值。

我的栅格(r)看起来像这样:

class(r)

class       : RasterBrick 
dimensions  : 201, 464, 93264, 23376  (nrow, ncol, ncell, nlayers)
resolution  : 0.25, 0.25  (x, y)
extent      : -40.5, 75.5, 25.25, 75.5  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : \\ueahome\eressci5\zuw13bqu\data\NTProfile\Desktop\EOBS European data\rr_0.25deg_reg_v10.0.nc 
names       : X1950.01.01, X1950.01.02, X1950.01.03, X1950.01.04, X1950.01.05, X1950.01.06, X1950.01.07, X1950.01.08, X1950.01.09, X1950.01.10, X1950.01.11, X1950.01.12, X1950.01.13, X1950.01.14, X1950.01.15, ... 
Date        : 1950-01-01, 2013-12-31 (min, max)
varname     : rr 

我使用以下代码

基于纬度和经度数据进行提取
vals <- extract(r, matrix(c(issues[22,3], issues[22,2]), ncol = 2), buffer = 40000)

但不幸的是,我得到以下输出:

因为我没有声誉,所以*不能附上照片

X1950.01.01 X1950.01.02 X1950.01.03 X1950.01.04 X1950.01.05 X1950.01.06 X1950.01.07 X1950.01.08 X1950.01.09 X1950.01.10
1   0   4.8 4.6 0   0.2 0   0   0   0   0
2   0   4.7 4.5 0   1   0   0   0   0   0
3   0   4.7 4.5 0   1.1 0   0   0   0   0
4   0   4.6 4.3 0   1.2 0   0   0   0   0
5   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
6   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
7   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
8   0   4.1 3.9 0   0.7 0   0   0   0   0
9   0   4   3.7 0   0.9 0   0   0   0   0
10  0   4.1 3.8 0   1   0   0   0   0   0
11  0   4.1 3.8 0   1.1 0   0   0   0   0
12  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
13  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
14  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
15  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

* nb我检查了这个网站,这些行实际上都不是最接近的。

如何在不减小缓冲区大小的情况下选择最接近该点的单元格值,直到出现一个单元格值(我有太多此类网站为每个站点执行此操作)?

提前致谢

2 个答案:

答案 0 :(得分:3)

当找到距离r以外的点的最小距离的栅格r的单元格时,我们不需要计算到r的内部单元格的距离。

具体来说:

  1. 对于x < xmin(r)y < ymin(r)的点,r的最近点是左下角的单元格;
  2. 对于x > xmax(r)y < ymin(r)的点,r的最近点是右下角的单元格;
  3. 对于x < xmin(r)y > ymax(r)的点,r的最近点是左上角的单元格;
  4. 对于x > xmax(r)y > ymax(r)的点,r的最近点是右上角的单元格;
  5. 对于xmin(r) < x < xmax(r)y < ymin(r)的点,r的最近单元格将位于底边;
  6. 对于xmin(r) < x < xmax(r)y > ymax(r)的点,r的最近单元格将位于顶部边缘;
  7. 对于x < xmin(r)ymin(r) < y < ymax(r)的点,r的最近单元格将位于左边缘;
  8. 对于xmin(r) < x < xmax(r)y > ymax(r)的点,r的最近单元格将位于顶部边缘;和
  9. xmin(r) < x < xmax(r)ymin(r) < y < ymax(r)已经在栅格中的点。
  10. 这是一个函数,可以解决每个点落在这9个区域中的哪个区域,识别它们对应的栅格列或行,并识别沿相关边/角的该列或行的单元格。

    该函数接受2 x n坐标矩阵(x然后y)或SpatialPoints对象。如果您希望将移动的点返回为spatial=TRUE,请设置SpatialPoints

    请注意,假设点位于平面坐标系中。

    move.points <- function(r, pts, spatial=FALSE) {
      require(raster)
      require(sp)
    
      if (is(pts, 'SpatialPoints')) pts <- coordinates(pts)
      if (is(!r, 'Raster')) r <- raster(r)
    
      loc <- colSums(sapply(pts[, 1], '>', bbox(r)[1, ])) * 3 + 
        colSums(sapply(pts[, 2], '>', bbox(r)[2, ]))
    
      L <- split(as.data.frame(pts), loc)
    
      new.pts <- lapply(names(L), function(x) {
        switch(x, 
               '0' = xyFromCell(r, ncell(r) - ncol(r) + 1)[rep(1, nrow(L[[x]])), ],
               '1' = xyFromCell(r, cellFromXY(r, cbind(xmin(r), L[[x]][, 2]))),
               '2' = xyFromCell(r, 1)[rep(1, nrow(L[[x]])), ],
               '3' = xyFromCell(r, cellFromXY(r, cbind(L[[x]][, 1], ymin(r)))),
               '4' = {
                 xy <- as.matrix(L[[x]])
                 dimnames(xy) <- list(NULL, c('x', 'y'))
                 xy
               },
               '5' = xyFromCell(r, cellFromXY(r, cbind(L[[x]][, 1], ymax(r)))),
               '6' = xyFromCell(r, ncell(r))[rep(1, nrow(L[[x]])), ],
               '7' = xyFromCell(r, cellFromXY(r, cbind(xmax(r), L[[x]][, 2]))),
               '8' = xyFromCell(r, ncol(r))[rep(1, nrow(L[[x]])), ]
        )
      })
    
      new.pts <- unsplit(mapply(function(x, y) {
        row.names(x) <- row.names(y)
        as.data.frame(x)
      }, new.pts, L, SIMPLIFY=FALSE), loc)
    
      colnames(new.pts) <- colnames(pts)
      if(isTRUE(spatial)) new.pts <- SpatialPoints(new.pts)  
      return(new.pts)
    }
    

    一个1000 x 1000单元栅格的示例,随机放置1000个点(约890个单元格落在栅格范围之外):

    r <- raster(matrix(runif(1e6), ncol=1e3))
    pts <- cbind(lon=runif(1e3, -1, 2), lat=runif(1e3, -1, 2))
    system.time(new.pts <- move.points(r, pts, spatial=FALSE))
    
    #   user  system elapsed 
    #   0.03    0.00    0.04 
    

    对于2000 x 2000单元格栅格,有100万个点(光栅范围外约890000点):

    r <- raster(matrix(runif(4e6), ncol=2e3))
    pts <- cbind(lon=runif(1e6, -1, 2), lat=runif(1e6, -1, 2))
    system.time(new.pts <- move.points(r, pts, spatial=FALSE))
    
    #   user  system elapsed 
    #  12.71    0.23   13.12 
    

    这里有一个图表,展示了上面第一个例子的点数是如何移动的。

    plot(pts, asp=1, pch=20, panel.first=abline(h=0:1, v=0:1, lwd=2, col='gray'))
    segments(pts[, 1], pts[, 2], new.pts[, 1], new.pts[, 2], col='#00000050')
    plot(extent(r), add=TRUE, lwd=3)
    

    enter image description here

    完成此操作后,您可以使用extract(r, new.pts)

答案 1 :(得分:0)

我建议您将栅格强制转换为spatialPointsDataFrame,尽管这可能不是内存安全的。然后,在rgeos包中使用gDistance检索最近的点并计算摘要统计信息(在栅格点中的列之间)将是相当简单的。

一个有点复杂的解决方法是迭代你的积分,使用&#34; distanceFromPoints&#34;,转一切&gt;到NA的最小距离,屏蔽源栅格并计算可分配给(i)子集点的所需统计数据。这是一个快速而肮脏的例子(应该使用光栅范围之外的点)。

# Create example data
require(raster)
  r <- raster(ncol=36, nrow=18)
    r[] <- runif(ncell(r),1,20)
      pts <- SpatialPoints(cbind(-50, seq(-80, 80, by=20)))

# Calculate distance from first point   
dist <- distanceFromPoints(r, pts[1,])
  plot(dist)

# Set values > minimum distance to NA
dist[dist > minValue(dist)] <- NA
  plot(dist)

# Mask original raster to minimum distance raster, calulate summary statistics        
r.sub <- mask(r, dist)
  summary( getValues(r.sub),  na.rm=TRUE)