如何在图层名重复时用sf::st_read读取KML多图层?
解决KML重复图层名无法批量加载的问题
针对你遇到的「包含数千个重复图层名的KML文件,无法用sf::st_read()批量加载」的问题,结合你之前踩的坑,这里整理出一套可行的解决方案:
先明确关键坑点
你最初尝试用read_xml修改<name>节点时失败,是因为用Google Earth重新保存的KML是制表符分隔的格式化版本,导致xml2的XPATH查询无法匹配到节点;而直接解压KMZ得到的原始doc.kml是标准XML结构,能被xml2正确解析——这是解决问题的前提。
解决方案:批量重命名KML图层为唯一ID
我们可以通过修改KML中的<name>节点,给重复的图层名添加唯一后缀,之后就能正常遍历加载所有图层了,步骤如下:
1. 正确获取可解析的KML文件
直接下载并解压KMZ,不要用Google Earth二次保存:
# 下载KMZ文件 download.file(url="http://www.bfro.net/app/AllReportsKMZ.aspx", destfile = "AllBFROReports.kmz", mode="wb") # 解压得到标准XML格式的doc.kml unzip("AllBFROReports.kmz", junkpaths = TRUE)
2. 解析KML并批量重命名重复图层
用xml2包定位所有图层名称节点,给重复名称添加递增后缀:
library(xml2) library(purrr) library(dplyr) # 读取原始KML kml <- read_xml("doc.kml") # 获取所有Folder下的name节点 name_nodes <- xml_find_all(kml, ".//Folder/name") # 提取当前图层名 current_names <- xml_text(name_nodes) # 生成唯一名称(重复名称会自动添加_1、_2后缀) unique_names <- make.unique(current_names, sep = "_") # 更新KML中的name节点文本 walk2(name_nodes, unique_names, ~xml_set_text(.x, .y)) # 保存修改后的KML文件 write_xml(kml, "doc_renamed.kml")
3. 批量加载所有图层
现在所有图层名都是唯一的,就可以遍历st_layers()的结果批量读取:
library(sf) # 获取重命名后KML的所有图层信息 layers <- st_layers("doc_renamed.kml") # 批量读取所有图层并合并为一个数据框 all_kml_data <- map_dfr(layers$name, function(layer_name) { st_read("doc_renamed.kml", layer = layer_name) }) # 查看合并后的数据结构 str(all_kml_data)
验证效果
修改后再用st_layers()检查,会发现所有图层名都是唯一的:
layers_renamed <- st_layers("doc_renamed.kml") data_frame(name = layers_renamed$name, type = flatten_chr(layers_renamed$geomtype)) %>% count(name, type, sort = TRUE) # 此时不会再出现同一name对应多个n的情况
内容的提问来源于stack exchange,提问作者Art
相关产品推荐
相关产品推荐

