我在用R和Python解析这个KML文件的层时遇到困难。我已经包括了一个从我的Dropbox下载文件的链接。此文件最初与我共享。然而,有人告诉我,该文件起源于Distilleries Fighting Covid,但我不知道如何找到或访问它
我想要的是提取所有层,并最终将它们分离到它们自己的csv
文件中。我想要检索的节点是名称、地址、城市、州、邮政编码。我用它得到的最接近的是堆栈postRead multiple layers of KML file using R
对于第一次尝试,我的代码如下所示:
library(rgdal)
allKmlLayers <- function(kmlfile){
lyr <- ogrListLayers(kmlfile)
mykml <- list()
for (i in 1:length(lyr)){
mykml[i] <- readOGR(kmlfile, lyr[i])
}
names(mykml) <- lyr
return(mykml)
}
kmlfile <- "Distilleries and Hospitals.kml"
mykml <- allKmlLayers(kmlfile)
但是,执行此操作时,我收到以下错误和警告:
Error in readOGR("Distilleries and Hospitals.kml", "Distilleries") :
no features found In addition: Warning message: In ogrFIDs(dsn = dsn, layer = layer) : no features found
现在,我能够读取存储在lyr变量中的层
下面的代码将生成一个包含7个字符的列表
lyr <- ogrListLayers("Distilleries and Hospitals.kml")
接下来,我尝试使用以下代码从一层中拉出:
mykml <- readOGR("Distilleries and Hospitals.kml", "Distilleries")
这导致以下错误和警告(同上):
Error in readOGR("Distilleries and Hospitals.kml", "Distilleries") :
no features found In addition: Warning message: In ogrFIDs(dsn = dsn, layer = layer) : no features found
最后,我尝试使用sf
包对lapply
使用类似的方法
library(sf)
kmlfile <- "Distilleries and Hospitals.kml"
mykml <- lapply(lyr, function(i) st_read(kmlfile, i))
names(mykml) <- lyr
我得到了7个没有信息的0x3列表
这方面的任何帮助都将是非常好的
最后请注意,如果您最终从网站上获取了文件,请注意,在文件末尾附近有几个实例,其中R由于特殊字符而不会读取文件(至少我不会)。当使用sf函数时,错误将告诉您这是在哪里
谢谢你在这方面花时间
KML File at Dropbox for Download (~28mb)
编辑1: 从下面留下的注释来看,该文件中的层似乎是空的。如果这是正确的,那么问题是,我将如何从这个文件中获取所需的数据并将其转换为CSV文件
编辑2:
进一步调查KML文档,似乎我的所有信息都可以在placemark
标记(…)中找到。然而,我不确定如何提取这些数据。这是最终目标。如果这些不是层,那么如果有人能告诉我解决这个问题的方向,那就太好了。再次,我想提前感谢你的帮助
编辑3个数据摘录和Python尝试: 我已经手动操作了这个文件,从长远来看,删除了我并不真正感兴趣的所有内容。下面是该文件的一个小摘录。它列出了前三家公司
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Folder>
<name>Distilleries</name>
<Placemark>
<name>Bomb City Enterprises</name>
<description><![CDATA[Address: 306 S Cleveland St<br>Address Line2: <br>City: Amarillo<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 79102<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
<ExtendedData>
<Data name="Address">
<value>306 S Cleveland St</value>
</Data>
<Data name="Address Line2">
<value/>
</Data>
<Data name="City">
<value>Amarillo</value>
</Data>
<Data name="Location">
<value>Alabama</value>
</Data>
<Data name="State_Abbrev">
<value>AL</value>
</Data>
<Data name="Postal Code">
<value>79102</value>
</Data>
<Data name="unnamed (1)">
<value/>
</Data>
<Data name="unnamed (2)">
<value/>
</Data>
<Data name="unnamed (3)">
<value/>
</Data>
<Data name="Updated 2020-04-12 20:30:13.383810">
<value/>
</Data>
</ExtendedData>
</Placemark>
<Placemark>
<name>Cahaba Brewing Company</name>
<address>4500 5th Ave. S building C Birmingham Alabama AL 35222</address>
<description><![CDATA[Address: 4500 5th Ave. S<br>Address Line2: building C<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
<styleUrl>#icon-1517-0288D1</styleUrl>
<ExtendedData>
<Data name="Address">
<value>4500 5th Ave. S</value>
</Data>
<Data name="Address Line2">
<value>building C</value>
</Data>
<Data name="City">
<value>Birmingham</value>
</Data>
<Data name="Location">
<value>Alabama</value>
</Data>
<Data name="State_Abbrev">
<value>AL</value>
</Data>
<Data name="Postal Code">
<value>35222</value>
</Data>
<Data name="unnamed (1)">
<value/>
</Data>
<Data name="unnamed (2)">
<value/>
</Data>
<Data name="unnamed (3)">
<value/>
</Data>
<Data name="Updated 2020-04-12 20:30:13.383810">
<value/>
</Data>
</ExtendedData>
</Placemark>
<Placemark>
<name>Redmont Distilling Company</name>
<address>4550 5th Ave South building N Birmingham Alabama AL 35222</address>
<description><![CDATA[Address: 4550 5th Ave South<br>Address Line2: building N<br>City: Birmingham<br>Location: Alabama<br>State_Abbrev: AL<br>Postal Code: 35222<br>unnamed (1): <br>unnamed (2): <br>unnamed (3): <br>Updated 2020-04-12 20:30:13.383810: ]]></description>
<styleUrl>#icon-1517-0288D1</styleUrl>
<ExtendedData>
<Data name="Address">
<value>4550 5th Ave South</value>
</Data>
<Data name="Address Line2">
<value>building N</value>
</Data>
<Data name="City">
<value>Birmingham</value>
</Data>
<Data name="Location">
<value>Alabama</value>
</Data>
<Data name="State_Abbrev">
<value>AL</value>
</Data>
<Data name="Postal Code">
<value>35222</value>
</Data>
<Data name="unnamed (1)">
<value/>
</Data>
<Data name="unnamed (2)">
<value/>
</Data>
<Data name="unnamed (3)">
<value/>
</Data>
<Data name="Updated 2020-04-12 20:30:13.383810">
<value/>
</Data>
</ExtendedData>
</Placemark>
<Placemark>
因为我在R上没有运气,所以我在下面添加了我的Python尝试。我希望如此。然而,随着数据的增加,如果有人能够在R中做到这一点,我也会很高兴
我想得到的是第一个名字。然后,从扩展数据部分,我最后得到地址1、地址2、城市、州缩写和邮政编码。我很好,如果我结束了一切,只要它把一个空字段中没有数据。例如,地址2通常是空的,只需返回一个空字段并继续移动,这样当我合并列表时,所有内容都会对齐
下面的示例仅尝试获取第1行的名称和地址。我想,如果我能做到这一点,那么我应该能够把它一直延伸下去
我尝试过的其他代码如下:
import xml.etree.ElementTree as et
doc = et.parse(filename)
nmsp = '{http://www.opengis.net/kml/2.2}'
name = []
address1 = []
for pm in doc.iterfind('.//{0}Placemark'.format(nmsp)):
print(pm.find('{0}name'.format(nmsp)).text)
name.append(pm.find('{0}name'.format(nmsp)).text)
for adr1 in pm.iterfind('{0}ExtendedData//{0}value'.format(nmsp)):
address1.append(adr1.text.strip().replace('\n',''))
print(adr1.text.strip().replace('\n',''))
当我运行此操作时,我得到第一条记录,第一个地址行为1,但我也得到以下错误:
AttributeError: 'NoneType' object has no attribute 'strip'
我相信这是因为在第一条记录中,地址2是空的。因此,我相信这实际上是试图从扩展数据中一次提取所有内容,这也不是我想要的
我遇到的真正困难是拉<Data name = "..."> ... </Data>
字段
这是我第一次尝试XML/KML解析,因此我非常感谢您的帮助。现在我真的不知道下一步该怎么做
结束文件将是一个CSV文件,标题为:名称、地址1、地址2、城市、州、邮政编码。老实说,我是我也可以把地址2去掉。拥有并不重要
如果您需要进一步的澄清,请直接询问。提前感谢您抽出时间
由于KML文件是XML文件,请考虑XSLT,专门用于将XML文件转换成不同的XML、HTML、甚至CSV格式的专用语言。p>
带有
lxml
模块的Python和带有xslt
(扩展包到xml2
)模块的R都可以运行XSLT1.0脚本XSLT(另存为.xsl,一个特殊的.xml文件)
Online Demo
Python
R
相关问题 更多 >
编程相关推荐