首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当存在重复的图层名称时如何使用st_read读取多个图层

当存在重复的图层名称时如何使用st_read读取多个图层
EN

Stack Overflow用户
提问于 2018-01-13 06:46:20
回答 1查看 1.2K关注 0票数 1

我有一个kml文件,this的解压版本。它有几千个带有XML标记的层,其中许多层具有重复的层名称。

我想用sf::st_read把它加载到R中。诀窍是st_read一次只读取一个层,并且需要一个层名称。我很乐意遍历使用st_layers()获取的层名称,如果它们是唯一的,但它们不是唯一的。

有没有另一种方法可以指定所需的层,或者使用唯一Id批量重命名所有层?

谢谢。

根据下面接受的答案添加一些颜色。最初,我尝试使用'read_xml‘来编辑<name>节点,但似乎没有找到它们。

我下载了KMZ文件,将其加载到Google Earth中,然后将其保存为KML文件("Reports.kml")。这是我的第一个错误。生成的KML是以制表符分隔的,这会混淆read_xml。它是有效的XML,但是即使st_函数可以工作,read_xml也不能正确识别标记。最好对KMZ文件使用unzip。以下是使用Google-Earth保存版本的情况:

代码语言:javascript
运行
复制
layers<-st_layers("reports.kml")

data_frame(name=layers$name, type=flatten_chr(layers$geomtype)) %>%
  count(name, type, sort=TRUE)
# A tibble: 1,358 x 3
#            name  type     n
#           <chr> <chr> <int>
# 1     July 2006          25
# 2  October 2006          25
# 3   August 2008          20
# 4     July 2009          19
# 5   August 2005          18
# 6   August 2007          18
# 7 November 2006          18
# 8  October 2004          17
# 9   August 2000          16
#10 November 2012          16
# ... with 1,348 more rows

kml<-read_xml("reports.kml")

xml_find_all(kml, ".//Folder/name")
# {xml_nodeset (0)}

没什么!但这里面有点东西:

代码语言:javascript
运行
复制
xml_children(kml)
# {xml_nodeset (1)}
# [1] <Folder>\n  <name>Reports</name>\n  <open>1</open>\n  <Folder>\n    
# <name>Class A</name>\n  ...

以下是使用解压缩的KMZ会发生的情况:

代码语言:javascript
运行
复制
download.file(url="http://www.bfro.net/app/AllReportsKMZ.aspx",
                  destfile = "AllBFROReports.kmz",
                  mode="wb")
unzip("AllBFROReports.kmz",junkpaths = TRUE) #creates "doc.kml"


layers <- st_layers("doc.kml")

data_frame(name=layers$name, type=flatten_chr(layers$geomtype)) %>%
  count(name, type, sort=TRUE)
# # A tibble: 1,376 x 3
# name  type     n
# <chr> <chr> <int>
#   1     July 2006          25
# 2  October 2006          25
# 3   August 2008          20
# 4     July 2009          19
# 5   August 2005          18
# 6   August 2007          18
# 7 November 2006          18
# 8  October 2004          17
# 9   August 2000          16
# 10 November 2012          16
# # ... with 1,366 more rows

st_layers是一样的,但是现在可以正确地找到节点了!

代码语言:javascript
运行
复制
kml <- read_xml("doc.kml")
xml_find_all(kml, ".//Folder/name")
{xml_nodeset (3874)}
[1] <name>June 2000</name>
  [2] <name> 1995</name>
  [3] <name>February 2004</name>
  [4] <name>June 2004</name>
  [5] <name>February 2004</name>
  [6] <name>April 2008</name>
  [7] <name>July 2009</name>
  [8] <name>September 1981 and 1982</name>
  [9] <name>July 1999</name>
  [10] <name>November 1983</name>
  [11] <name>October 2000</name>
  [12] <name>August 1993</name>
  [13] <name> 79, 80, 99</name>
  [14] <name> 1978</name>
  [15] <name>November 1980</name>
  [16] <name>January 1997</name>
  [17] <name> 1990</name>
  [18] <name>December 1996</name>
  [19] <name> 2000</name>
  [20] <name> 2001</name>
  ...

现在,下面提供的答案就像是一个魔咒!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-13 21:23:55

做一点XML手术就可以解决这个问题。

首先,显示问题:

代码语言:javascript
运行
复制
library(sf)
library(xml2)
library(tidyverse)

layers <- st_layers("AllBFROReports.kml")

data_frame(name=layers$name, type=flatten_chr(layers$geomtype)) %>%
  count(name, type, sort=TRUE)
## # A tibble: 1,376 x 3
##             name  type     n
##            <chr> <chr> <int>
##  1     July 2006          25
##  2  October 2006          25
##  3   August 2008          20
##  4     July 2009          19
##  5   August 2005          18
##  6   August 2007          18
##  7 November 2006          18
##  8  October 2004          17
##  9   August 2000          16
## 10 November 2012          16
## # ... with 1,366 more rows

呃。一个非常刻薄的人做了那个文件。

现在,在“raw”中阅读它:

代码语言:javascript
运行
复制
kml <- read_xml("AllBFROReports.kml")

为每个图层名称添加一个连续的索引号:

代码语言:javascript
运行
复制
idx <- 0
xml_find_all(kml, ".//Folder/name") %>%
  walk(~{
    idx <<- idx + 1
    xml_text(.x) <- sprintf("%s-%s", idx, xml_text(.x))
  })

创建一个新文件:

代码语言:javascript
运行
复制
write_xml(kml, "AllBFROReports-unique.kml")

证明它是有效的:

代码语言:javascript
运行
复制
layers2 <- st_layers("AllBFROReports-unique.kml")

data_frame(name=layers2$name, type=flatten_chr(layers2$geomtype)) %>%
  count(name, type, sort=TRUE)
## # A tibble: 3,874 x 3
##                  name     type     n
##                 <chr>    <chr> <int>
##  1        1-June 2000              1
##  2   10-November 1983              1
##  3 100-September 1992              1
##  4  1000-October 1987              1
##  5  1001-October 1987              1
##  6  1002-October 1979              1
##  7     1003-June 1993 3D Point     1
##  8         1004- 1982 3D Point     1
##  9         1005- 1982 3D Point     1
## 10   1006-August 1977 3D Point     1
## # ... with 3,864 more rows

用新的索引化名称读入一层:

代码语言:javascript
运行
复制
st_read("AllBFROReports-unique.kml", layer = "10-November 1983")
## Reading layer `10-November 1983' from data source `/Users/bob/Desktop/AllBFROReports-unique.kml' using driver `KML'
## Simple feature collection with 2 features and 2 fields
## geometry type:  GEOMETRY
## dimension:      XYZ
## bbox:           xmin: -86.4677 ymin: 34.9484 xmax: -86.4441 ymax: 34.9637
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48235057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档