xx <- readOGR(paste(td, "cities.kml", sep="/"), "cities")
之后)。似乎“城市”是空间对象的名称。罗杰·比万德(Roger Bivand)承认“人们如何发现这个名称并不明显,因为OGR中的KML驱动程序需要它来访问文件。一种可能是:
system(paste("ogrinfo", paste(td, "cities.kml", sep="/")), intern=TRUE)
“
,但这对我也不起作用。这是一个可以试穿的测试.kml文件。使用它在我的工作目录中,
readOGR("x.kml", "id")
生成以下错误消息:Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv) :
Cannot open layer .
system(paste("ogrinfo", "x.kml"), intern=TRUE)
生成:[1] "Had to open data source read-only." "INFO: Open of `x.kml'"
[3] " using driver `KML' successful." "1: x (3D Polygon)"
,我根本不理解。
getKMLcoordinates
{maptools}是否有效?我也尝试过:
tkml <- getKMLcoordinates(kmlfile="x.kml", ignoreAltitude=T)
head(tkml[[1]])
tkml <- SpatialPolygons(tkml,
proj4string=CRS("+init=epsg:3857"))
坐标正确生成,但是我尝试将其转换回多边形对象的尝试失败,并显示以下消息:
Error in SpatialPolygons(tkml, proj4string = CRS("+init=epsg:3857")) :
cannot get a slot ("area") from an object of type "double"
#1 楼
要使用OGR驱动程序读取KML,请为其提供文件名和图层名称。罗格的注释是,图层名称隐藏在KML文件中,除非您知道KML的用法创建的文件无法从KML文件名推断出图层名称。
以您的示例KML为例,我可以看到:这告诉我层名称是
x
,而不是id
,因此:<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>x</name>
<Schema name="x" id="x">
工作正常。通过使用R XML解析器将KML解析为XML来获取名称,或者您可以尝试将R作为文本文件读取到R中,直到找到名称标签为止。
另一种方法是运行命令行ogrinfo程序,用于输出KML文件的层名称:
> foo = readOGR("/tmp/x.kml", "x")
OGR data source with driver: KML
Source: "/tmp/x.kml", layer: "x"
with 1 features and 2 fields
Feature type: wkbPolygon with 2 dimensions
此处显示了一个名为
x
的多边形层。评论
感谢您的回答。空格-立即解决问题。如此清晰的解释使我喜欢堆栈交换!一个“加分点”问题:我是否可以使用同一命令读取数据的子集(例如前100万个多边形)?否则,将寻求通过外部程序拆分巨大的kmls。
–RobinLovelace
13年4月16日在14:10
作为XML的KML并不是真正为随机访问而设计的。真正的解决方案是将空间数据放入空间数据库,并具有一些空间索引以提高速度。查看PostGIS。
– Spacedman
13年4月16日在14:33
好的计划-我已经告诉客户,PostGIS是处理如此大数据的前进之路,并且坚信这是他想要做的事情的正确选择。好借口,让我正确学习它!
–RobinLovelace
13年4月16日在14:53
sqlite是基于文件的数据库,在空间上也有扩展,与PostGIS相比,不需要安装服务并且需要的配置更少。
–坦率
16年2月10日在8:32
奇怪的是R中的系统需要在〜上进行path.expand才能使ogrinfo正常工作,即使它在命令行上的未扩展路径上也可以正常工作(macOS; Sys.which('ogrinfo')和哪个ogrinfo返回相同的路径)
– MichaelChirico
18年8月31日在3:30
#2 楼
如果要使用maptool做替代方法,这应该可以工作:评论
嗨@Seen,我尝试过您的方法,但似乎不起作用?我有一个错误:Polygon(tkml)中的错误:坐标必须是一个两列矩阵> head(tkml)[[1]] [1] -87.88141 30.49800 adn我有一个itas列表。矩阵坐标列表?谢谢!
– Maycca
16-4-22在21:16
这是一个非常老的帖子,所以我想检查问题是否比这里介绍的解决方案更好。如果不是,则Polygon(tkml)给我一个错误:选择函数'coordinates'的方法时评估参数'obj'时出错:参数表示行数不同:364、171、191、115、312、441 ,350、167、326、275、261、240 ...
–user30994
20-09-17在18:02
#3 楼
不知道这对其他人是否仍然是一个问题,但是与此同时,我在圈子里跑了一段时间。最终对我有用的是下面。它使用XML
软件包获取右侧节点的xmlValue
。我必须将layer
的readOGR
参数设置为kml文件内的文件夹之一的名称。当将layer
参数设置为kml文件的时,我将得到与上述RobinLovelace相同的错误。 下面显示的许多代码行仅显示如何查看kml文档的各个节点级别。我认为这将取决于kml的来源而略有不同。但是您应该能够使用相同的逻辑来确定正确的参数值。
此外,我创建了kml文件列表,因此可以轻松地将其制成可放入
lapply
-do.call
对。然后,这可以从一长串的kml文件中提取数据。或者,单个kml文件中的许多子文件夹似乎readOGR
无法处理kml文件中的多个子文件夹。library(rgdal); library(XML)
# SET WORKING DIRECTORY FIRST!!
dir <- getwd()
kmlfilelist <- list.files(dir, pattern =".kml$", full.names=TRUE, recursive=FALSE)
doc0 <- xmlTreeParse(kmlfilelist[2], useInternal = TRUE)
rootNode0 <- xmlRoot(doc0)
rootName0 <- xmlName(rootNode0)
element1Name0 <- names(rootNode0)
nodeNames <- names(rootNode0[1][[1]])
# entire rootNode - kml Document level
rootNode0[[1]]
# 1st element of rootNode - kml file name
rootNode0[[1]][[1]]
# 2nd element of rootNode - kml Style Map
rootNode0[[1]][[2]]
# 3rd element of rootNode - Style
rootNode0[[1]][[3]]
# 4th element of rootNode - Style
rootNode0[[1]][[4]]
# 5th element of rootNode - kml Folder with data in it.
rootNode0[[1]][[5]]
# 5th element 1st subelement of rootNode - kml Folder name with data in it.
# What to set readOGR() layer parameter to.
rootNode0[[1]][[5]][[1]]
kmlfoldername <- xmlValue(rootNode0[[1]][[5]][[1]]) # Folder name to set = layer.
readOGR(dsn=kmlfilelist[2], layer = kmlfoldername)
#4 楼
不知道我是否应该修改以前的答案。也许可以,但这涵盖了此答案中未涵盖的某些内容,因此我决定将其保留。它在kml文件中查找所有名为“文件夹”的xmlNode,然后将layer
的readOGR
参数设置为该xmlValue
。在大约6个单独的kml文件的工作目录上进行了测试。输出是导入的SpatialDataFrames对象的列表。每个SpatialDataFrame都可以轻松地成为列表的子集。仍然不能处理具有多个Folder节点的kml文件。但是可以轻松地通过另一个嵌套的
apply
函数添加该功能。library(rgdal); library(XML)
# SET WORKING DIRECTORY FIRST!!
dir <- getwd()
kmlfilelist <- list.files(dir, pattern =".kml$", full.names=TRUE, recursive=FALSE)
ImportKml <- function (kmlfile) {
doc0 <- xmlTreeParse(kmlfile, useInternal = TRUE)
rootNode0 <- xmlRoot(doc0)
rootName0 <- xmlName(rootNode0)
element1Name0 <- names(rootNode0)
kmlNodeNames <- unname(names(rootNode0[1][[1]]))
kmlFolderNodeNum <- which(kmlNodeNames == "Folder")
kmlFolderNodeName <- xmlValue(rootNode0[[1]][[kmlFolderNodeNum]][[1]])
kmlIn <- readOGR(dsn=kmlfile, layer = kmlFolderNodeName)
}
ImportedKmls <- lapply(kmlfilelist, ImportKml)
评论
您可以使用rgdal的功能ogrListLayers获取kml中的图层。