st_contains内存耗尽问题求助:18GB内存下批量处理仍失败
空间包含分析内存耗尽问题优化方案
问题背景
需要判断piracy_sf中的点是否包含在eez_t_final的多边形内,18GB内存下执行仍触发内存耗尽。已尝试批量分析、几何简化方案,但未解决问题。
核心优化方案
从空间索引、批量逻辑、计算效率、内存复用四个维度调整,大幅降低内存占用:
1. 提前构建空间索引
为点数据构建空间索引,直接缩小每个多边形需要检查的点范围,避免全量遍历:
# 仅保留必要列,减少内存负载 piracy_sf <- piracy_sf[, c("geometry", "eez_country")] # 确保几何有效性并构建S2空间索引 piracy_sf <- st_make_valid(piracy_sf) st_index(piracy_sf) <- st_s2_index(piracy_sf)
2. 优化批量处理逻辑
原代码重复执行几何简化、每次仍全量遍历点,调整为单次简化+候选点过滤的批量逻辑:
sf_use_s2(TRUE) batch_size <- 20 # 适当调大批次,减少循环开销 num_batches <- ceiling(nrow(eez_t_final) / batch_size) # 提前初始化结果列,避免动态扩容占用内存 eez_t_final$piracy_count <- 0L eez_t_final$eez_country <- "" for (i in 1:num_batches) { start <- (i - 1) * batch_size + 1 end <- min(i * batch_size, nrow(eez_t_final)) eez_chunk <- eez_t_final[start:end, ] # 仅执行一次几何简化,保留多边形形状 eez_chunk <- ms_simplify(eez_chunk, keep = 0.05, keep_shapes = TRUE) # 修复无效几何 eez_chunk <- st_make_valid(eez_chunk) for (j in 1:nrow(eez_chunk)) { poly <- eez_chunk[j, ] # 通过空间索引筛选可能在多边形内的候选点 candidate_points <- st_filter(piracy_sf, poly, predicate = st_intersects) if (nrow(candidate_points) == 0) { count <- 0L countries <- "" } else { # 仅对候选点执行包含判断 contains_idx <- st_contains(poly, candidate_points, sparse = TRUE)[[1]] count <- length(contains_idx) countries <- paste(unique(candidate_points$eez_country[contains_idx]), collapse = ", ") } # 直接赋值到原数据框,避免存储大索引列表 eez_t_final$piracy_count[start + j - 1] <- count eez_t_final$eez_country[start + j - 1] <- countries } # 主动释放内存 rm(eez_chunk) gc(verbose = FALSE) } print(head(eez_t_final))
3. 可选内存优化技巧
- 若不需要球面计算,关闭S2引擎:
sf_use_s2(FALSE),平面计算内存占用更低 - 将数据转换到投影坐标系(如UTM):
st_transform(..., crs = 对应UTM编码),减少球面计算开销 - 用
st_as_sfc单独提取几何列处理,避免数据框冗余字段占用内存
内容的提问来源于stack exchange,提问作者chiara ausenda
相关产品推荐
相关产品推荐

