我在R中遇到了两个大型SpatialPolygonsDataFrame的交集问题。我的多边形数据代表建筑和行政边界,我正在尝试获取它们之间的交集多边形。
我知道raster包中的intersect函数和rgeos包中的gIntersection函数可以完成此任务(有一些区别),但它们无法同时处理我所有的多边形(大约50000个多边形/实体)。
因此,我必须在循环中分割我的计算,并保存每个步骤的结果。问题是:这些函数不断填充我的物理内存,而我无法清理它。我尝试使用rm()和gc(),但没有任何改变。内存问题会导致我的R会话崩溃,我无法进行计算。
是否有一种方法在模拟过程中释放RAM,在循环中?或避免这个内存问题?
下面是一个可重复的例子,使用随机多边形。
感谢您!
我知道raster包中的intersect函数和rgeos包中的gIntersection函数可以完成此任务(有一些区别),但它们无法同时处理我所有的多边形(大约50000个多边形/实体)。
因此,我必须在循环中分割我的计算,并保存每个步骤的结果。问题是:这些函数不断填充我的物理内存,而我无法清理它。我尝试使用rm()和gc(),但没有任何改变。内存问题会导致我的R会话崩溃,我无法进行计算。
是否有一种方法在模拟过程中释放RAM,在循环中?或避免这个内存问题?
下面是一个可重复的例子,使用随机多边形。
library(raster)
library(sp)
library(rgeos)
#Generating 50000 points (for smaller polygons) and 150000 (for larger polygons) in a square of side 100000
size=100000
Nb_points1=50000
Nb_points2=150000
start_point=matrix(c(sample(x = 1:size,size = Nb_points1,replace = T),sample(x = 1:size,size = Nb_points1,replace = T)),ncol=2)
start_point2=matrix(c(sample(x = 1:size,size = Nb_points2,replace = T),sample(x = 1:size,size = Nb_points2,replace = T)),ncol=2)
#Defining different sides length
radius=sample(x = 1:50,size = Nb_points1,replace = T)
radius2=sample(x = 1:150,size = Nb_points2,replace = T)
#Generating list of polygons coordinates
coords=list()
for(y in 1:Nb_points1){
xmin=max(0,start_point[y,1]-radius[y])
xmax=min(size,start_point[y,1]+radius[y])
ymin=max(0,start_point[y,2]-radius[y])
ymax=min(size,start_point[y,2]+radius[y])
coords[[y]]=matrix(c(xmin,xmin,xmax,xmax,ymin,ymax,ymax,ymin),ncol=2)
}
coords2=list()
for(y in 1:Nb_points2){
xmin=max(0,start_point2[y,1]-radius2[y])
xmax=min(size,start_point2[y,1]+radius2[y])
ymin=max(0,start_point2[y,2]-radius2[y])
ymax=min(size,start_point2[y,2]+radius2[y])
coords2[[y]]=matrix(c(xmin,xmin,xmax,xmax,ymin,ymax,ymax,ymin),ncol=2)
}
#Generating 75000 polygons
Poly=SpatialPolygons(Srl = lapply(1:Nb_points1,function(y) Polygons(srl = list(Polygon(coords=coords[y],hole = F)),ID = y)),proj4string = CRS('+init=epsg:2154'))
Poly2=SpatialPolygons(Srl = lapply(1:Nb_points2,function(y)Polygons(srl = list(Polygon(coords=coords2[y],hole = F)),ID = y)),proj4string = CRS('+init=epsg:2154'))
#Union of overlapping polygons
aaa=gUnionCascaded(Poly)
bbb=gUnionCascaded(Poly2)
aaa=disaggregate(aaa)
bbb=disaggregate(bbb)
intersection=gIntersects(spgeom1 = aaa,bbb,byid = T,returnDense = F)
#Loop on the intersect function
pb <- txtProgressBar(min = 0, max = ceiling(length(aaa)/1000), style = 3)
for(j in 1:ceiling(length(aaa)/1000)){
tmp_aaa=aaa[((j-1)*1000+1):(j*1000),]
tmp_bbb=bbb[unique(unlist(intersection[((j-1)*1000+1):(j*1000)])),]
List_inter=intersect(tmp_aaa,tmp_bbb)
gc()
gc()
gc()
setTxtProgressBar(pb, j)
}
感谢您!
gdalUtils
。 - lokigdalUtils
是一个非常好用且实用的软件包,但它在这里并没有帮助。它主要用于处理栅格数据。您使用了raster
软件包,但不是用于栅格数据,因此我怀疑它是否有所帮助。 - BastienRSAGA
是我最喜欢的,其次是RQGIS
,然后是更复杂的RGRASS7
。所有这些都需要您安装适当的软件(可以通过OSGEO4W一次性完成)。它们应该能够成功地完成您的任务。我现在有点忙,如果以后有机会,我会发布一个示例。 - Bastien