R 更有效地覆盖多边形或从空间线提取()光栅数据
我有一个包含15亿条空间线的庞大数据集,我使用37000个点的所有组合创建了该数据集对于每一条空间线,我想提取线接触到的多边形(或光栅-任何更快的)的最大值。本质上这是一个非常大的“空间连接”,用圆弧术语来说。如果在多边形层上叠加线,则输出将是所有属性字段中空间线的最大值,每个属性字段表示一年中的一个月。我还包括了一个光栅数据集,它是从1990年1月的多边形文件中创建的,分辨率约为30米-光栅代表了一种我认为可能节省时间的替代方法。多边形和光栅层表示一个大的空间区域:大约30km x 10km。数据是可用的。我在.zip中包含的空间线数据集只有9900条线,是从15亿条线的整个数据集中随机抽样的 首先读入数据R 更有效地覆盖多边形或从空间线提取()光栅数据,r,overlay,extract,gis,R,Overlay,Extract,Gis,我有一个包含15亿条空间线的庞大数据集,我使用37000个点的所有组合创建了该数据集对于每一条空间线,我想提取线接触到的多边形(或光栅-任何更快的)的最大值。本质上这是一个非常大的“空间连接”,用圆弧术语来说。如果在多边形层上叠加线,则输出将是所有属性字段中空间线的最大值,每个属性字段表示一年中的一个月。我还包括了一个光栅数据集,它是从1990年1月的多边形文件中创建的,分辨率约为30米-光栅代表了一种我认为可能节省时间的替代方法。多边形和光栅层表示一个大的空间区域:大约30km x 10km。
#polygons
poly<-readShapePoly("ls_polys_bin",proj4string=CRS("+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"))
poly$SP_ID<-NULL #deleting this extra field in prep for overlay
#raster - this represents only one month (january 1990)
#raster created from polygon layer but one month only
raster.jan90<-readGDAL("rast_jan90.tif")
raster.jan90<-raster(raster.jan90) #makes it into a raster
#lines (9900 of 1.5 billion included)
lines<-readShapeLines("l_spatial",proj4string=CRS("+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"))
首先,我尝试了覆盖,但以目前的速度,整个15亿数据集在我的机器上运行大约需要844天
ptm <- proc.time() #start clock
overlays.all<-over(lines.50,poly, fn=max)
ptm.sec.overlay<-proc.time() - ptm # stop clock
ptm.sec.overlay #.56 sec w/ n=12 lines; 2.3 sec w/ 50 lines
ptm我认为最快的方法是将线光栅化为与光栅数据相同的光栅
但是,我不会在R中对它们进行光栅化。我会编写一些C代码,获取光栅和37000点位置的数据,然后使用Bresenham线条绘制算法获得线条的光栅位置。在这些位置对光栅进行采样,然后根据需要对这些数据执行任何操作。Bresenham算法的快速代码应该很容易获得,您甚至可以找到在GPU上运行的版本,以实现大规模加速。有什么比图形卡画直线快
我假设你的空间线是两点之间的直线段
或者,只需从亚马逊(或其他云服务提供商)租用1000台服务器,为期半天 这里有一个技巧,可以给出一个很好的近似值。它可能会得到改进(getCrds需要很多时间),包括采取更大的步骤(我不知道这对您是否合适)
库(光栅)
raster.jan90所有37000点对(不包括零长度线A-A)应仅提供684481500条线进行检查,因为A-B与B-A命中相同的多边形。因此,这是422天。。。
plot(raster.jan90)#where green=1
plot(poly, axes=T,cex.axis=0.75, add=T)
plot(lines.50, col="red", add=TRUE)
ptm <- proc.time() #start clock
overlays.all<-over(lines.50,poly, fn=max)
ptm.sec.overlay<-proc.time() - ptm # stop clock
ptm.sec.overlay #.56 sec w/ n=12 lines; 2.3 sec w/ 50 lines
ptm <- proc.time() # Start clock
ext.rast.jan90<-extract(raster.jan90,lines.50, fun=max, method=simple)
ptm.sec.ext<-proc.time() - ptm # stop clock
ptm.sec.ext #32 sec w/ n=12 lines; 191 sec w/ n=50 lines
library(raster)
raster.jan90 <- raster("rast_jan90.tif")
lines <- shapefile("l_spatial.shp", p4s="+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs")
lines.50<-lines[sample(nrow(lines),50),]
test <- function(lns) {
getCrds <- function(i) {
p <- z[[i]][[1]]
s <- (p[2,] - p[1,]) / res(raster.jan90)
step <- round(max(abs(s)))
if ( step < 1 ) {
# these probably should not exist, but they do
return( cbind(i, cellFromXY(raster.jan90, p[1, , drop=FALSE])) )
}
x <- seq(p[1,1], p[2,1], length.out=step)
y <- seq(p[1,2], p[2,2], length.out=step)
cbind(i, unique(cellFromXY(raster.jan90, cbind(x, y))))
}
z <- coordinates(lns)
crd <- sapply(1:length(z), getCrds )
crd <- do.call(rbind, crd)
e <- extract(raster.jan90, crd[, 2])
tapply(e, crd[,1], max)
}
system.time(res <- test(lines.50))
# user system elapsed
# 0.53 0.01 0.55
system.time(res <- test(lines))
# user system elapsed
# 59.72 0.85 60.58