合并全美人口普查区块组Shapefile文件的报错问题求解
问题根因
- 原代码使用FTP协议访问人口普查局数据源,Census的公共FTP服务限流严重、连接稳定性极差,FIPS编码06对应加利福尼亚州的区块组数据体积超50M,是所有州里体积最大的文件之一,下载中途断连就会触发你看到的「下载长度与声明长度不匹配」「无法打开目标URL」报错
- 原代码没有下载重试、文件完整性校验逻辑,单次下载失败就会直接中断全流程
- 原代码未做重复多边形处理逻辑,直接合并后会存在州界处重复要素、同位置重复多边形问题
- 依赖的
RCurl、rgdal包已经被R官方标记为退役状态,跨版本兼容性差,大文件读写效率极低
修复方案
整体替换为稳定性更高的实现逻辑,核心调整点:
- 替换为官方HTTPS数据源,连接稳定性远高于FTP源
- 下载步骤增加3次自动重试、本地文件完整性校验逻辑,已下载的完整文件不会重复拉取
- 用
sf包替代老旧的sp+rgdal组合,空间数据读写、合并速度提升3-5倍,不会出现要素ID冲突问题 - 合并完成后自动执行重复多边形删除逻辑
- 前置准备:先安装所需依赖包,执行
install.packages(c("sf", "httr", "curl"))即可
完整可运行代码如下:
library(sf) library(curl) library(httr) # 基础配置 base_url <- "https://www2.census.gov/geo/tiger/TIGER2019/BG/" temp_dir <- tempdir() shp_extract_dir <- file.path(temp_dir, "shps") dir.create(shp_extract_dir, recursive = TRUE, showWarnings = FALSE) # 提取目录下所有区块组压缩包地址 page_content <- rawToChar(curl_fetch_memory(base_url)$content) zip_names <- regmatches( page_content, gregexpr("tl_2019_[0-9]{2}_bg\\.zip", page_content) )[[1]] zip_urls <- paste0(base_url, zip_names) # 带重试的下载、解压流程 max_retry <- 3 for (i in seq_along(zip_urls)) { zip_path <- file.path(temp_dir, zip_names[i]) # 本地已有完整压缩包则跳过下载 if (file.exists(zip_path)) { zip_check <- tryCatch(unzip(zip_path, list = TRUE), error = function(e) NULL) if (!is.null(zip_check)) { unzip(zip_path, exdir = shp_extract_dir) cat("已完成处理:", i, "/", length(zip_urls), "\n") next } file.remove(zip_path) } # 失败重试 retry_count <- 0 download_success <- FALSE while (retry_count < max_retry & !download_success) { retry_count <- retry_count + 1 tryCatch({ GET( zip_urls[i], write_disk(zip_path, overwrite = TRUE), timeout(600) # 大文件设置10分钟超时阈值 ) # 校验压缩包完整性 unzip(zip_path, list = TRUE) download_success <- TRUE }, error = function(e) { if (file.exists(zip_path)) file.remove(zip_path) Sys.sleep(2) }) } if (!download_success) stop(paste("多次重试后仍下载失败:", zip_urls[i])) unzip(zip_path, exdir = shp_extract_dir) cat("已完成处理:", i, "/", length(zip_urls), "\n") } # 读取所有shapefile并合并 shp_list <- lapply( list.files(shp_extract_dir, pattern = "\\.shp$", full.names = TRUE), st_read, quiet = TRUE ) usa_bg <- do.call(rbind, shp_list) # 去除几何完全一致的重复多边形 usa_bg <- usa_bg[!duplicated(st_geometry(usa_bg)), ] # 输出最终合并后的shapefile st_write(usa_bg, "USA_BG_2019.shp", delete_layer = TRUE)
注意事项
- 全流程需要预留至少2G临时磁盘空间,最终输出的全美区块组shapefile文件大小约1.2G
- 如果个别文件多次重试仍下载失败,可以手动将对应压缩包解压后放到之前配置的
shp_extract_dir目录,代码会自动识别读取 - 默认去重逻辑仅删除几何完全一致的重复要素,如果需要处理州边界处的面重叠、几何拓扑错误,可以在去重前执行
usa_bg <- st_make_valid(usa_bg)修复几何,再按需做边界融合,不过这步会大幅增加运行时间
内容的提问来源于stack exchange,提问作者a_swoosh
相关产品推荐
相关产品推荐

