OSM - XML 文件中标签之间的迭代
Iteration among the tags inside an OSM - XML file
我正在处理如下所示的 osm 数据文件。
...
...
...
<node id="4165094897" lat="41.0492396" lon="29.0260049" version="1">
<tag k="name" v="Adnan Yeri"/>
<tag k="amenity" v="cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094899" lat="41.0492902" lon="29.0258856" version="1">
<tag k="name" v="Piano Restaurant Cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094900" lat="41.0493468" lon="29.0258547" version="1">
<tag k="name" v="28 Black"/>
<tag k="shop" v="yes"/>
<tag k="amenity" v="restaurant"/>
</node>
<node id="4165094901" lat="41.0494034" lon="29.0258145" version="1">
<tag k="name" v="Gratis"/>
<tag k="shop" v="yes"/>
...
...
...
我尝试获取标签内具有 amenity 属性的节点的 id、lat、lon、amenity 和 name 值。
例如,对于示例数据的第一个节点,因为它在标签内有一个便利属性,所以我想得到;
id lat lon name amenity
4165094897 41.0492396 29.0260049 Adnan Yeri cafe
但是,由于第二个节点没有便利设施,所以我想通过它。
为了实现这一点,我使用如下 osmar
库找到了包含 aminity 标签的节点;
require(XML)
data <- xmlParse("/users/maydin/Desktop/Istanbul.osm")
library(osmar)
datam<- as_osmar(data)
ids_a <- find(datam, node(tags(k== "amenity")))
length(ids_a)
15212 # Number of amenity in tags in nodes
之后,我使用了 XML
包,
for(i in 1:length(ids_a)) {
find1 <- paste0('//*/node[@id=\"',ids_a[i],'\"]')
find2 <- paste0('//*/node[@id=\"',ids_a[i],'\"]/tag[@k=\"name\"]')
find3 <- paste0('//*/node[@id=\"',ids_a[i],'\"]/tag[@k=\"amenity\"]')
on1 <- xmlAttrs(data[find1][[1]])
on2 <- xmlAttrs(data[find2][[1]])
on3 <- xmlAttrs(data[find3][[1]])
...
.... }
应用一些数据帧操作后,这些计算给出了预期的结果。但是一次迭代大约需要 7.3 秒。因为存在15212,所以就是31个小时!!
然后,我也试过了;
xpathSApply(data,"//*/node[@id=\"6554996802\"]")
# 6554996802 is just one of the ids out of 15212
它给了,
[[1]]
<node id="6554996802" lat="40.9220973" lon="29.1279101" version="1">
<tag k="name" v="Burcu Cafe"/>
<tag k="amenity" v="cafe"/>
</node>
由于只在数据内部进行一次搜索,所以速度相对较快。但是,我无法再进一步了。
有什么建议吗?
这应该工作得很快......
救援的 xpath :)
library(xml2)
library(magrittr) #for pipe-operator
#read in xml (see section below for sample data)
doc <- read_xml( "./test.xml" )
#get the parent-node 'node' from a tag-node where the k-attribute = amenity
nodes <- xml_find_all( doc, "//tag[@k='amenity']/parent::node" )
#build data.frame
data.frame( id = xml_attr( nodes, "id" ) %>% as.numeric(),
lat = xml_attr( nodes, "lat" ) %>% as.numeric(),
lon = xml_attr( nodes, "lon" ) %>% as.numeric(),
name = xml_find_first( nodes, ".//tag[@k='name']") %>% xml_attr("v"),
amenity = xml_find_first( nodes, ".//tag[@k='amenity']") %>% xml_attr("v"),
stringsAsFactors = FALSE
)
# id lat lon name amenity
# 1 4165094897 41.04924 29.02600 Adnan Yeri cafe
# 2 4165094900 41.04935 29.02585 28 Black restaurant
示例数据
test.xml
<nodes>
<node id="4165094897" lat="41.0492396" lon="29.0260049" version="1">
<tag k="name" v="Adnan Yeri"/>
<tag k="amenity" v="cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094899" lat="41.0492902" lon="29.0258856" version="1">
<tag k="name" v="Piano Restaurant Cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094900" lat="41.0493468" lon="29.0258547" version="1">
<tag k="name" v="28 Black"/>
<tag k="shop" v="yes"/>
<tag k="amenity" v="restaurant"/>
</node>
</nodes>
我正在处理如下所示的 osm 数据文件。
...
...
...
<node id="4165094897" lat="41.0492396" lon="29.0260049" version="1">
<tag k="name" v="Adnan Yeri"/>
<tag k="amenity" v="cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094899" lat="41.0492902" lon="29.0258856" version="1">
<tag k="name" v="Piano Restaurant Cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094900" lat="41.0493468" lon="29.0258547" version="1">
<tag k="name" v="28 Black"/>
<tag k="shop" v="yes"/>
<tag k="amenity" v="restaurant"/>
</node>
<node id="4165094901" lat="41.0494034" lon="29.0258145" version="1">
<tag k="name" v="Gratis"/>
<tag k="shop" v="yes"/>
...
...
...
我尝试获取标签内具有 amenity 属性的节点的 id、lat、lon、amenity 和 name 值。
例如,对于示例数据的第一个节点,因为它在标签内有一个便利属性,所以我想得到;
id lat lon name amenity
4165094897 41.0492396 29.0260049 Adnan Yeri cafe
但是,由于第二个节点没有便利设施,所以我想通过它。
为了实现这一点,我使用如下 osmar
库找到了包含 aminity 标签的节点;
require(XML)
data <- xmlParse("/users/maydin/Desktop/Istanbul.osm")
library(osmar)
datam<- as_osmar(data)
ids_a <- find(datam, node(tags(k== "amenity")))
length(ids_a)
15212 # Number of amenity in tags in nodes
之后,我使用了 XML
包,
for(i in 1:length(ids_a)) {
find1 <- paste0('//*/node[@id=\"',ids_a[i],'\"]')
find2 <- paste0('//*/node[@id=\"',ids_a[i],'\"]/tag[@k=\"name\"]')
find3 <- paste0('//*/node[@id=\"',ids_a[i],'\"]/tag[@k=\"amenity\"]')
on1 <- xmlAttrs(data[find1][[1]])
on2 <- xmlAttrs(data[find2][[1]])
on3 <- xmlAttrs(data[find3][[1]])
...
.... }
应用一些数据帧操作后,这些计算给出了预期的结果。但是一次迭代大约需要 7.3 秒。因为存在15212,所以就是31个小时!!
然后,我也试过了;
xpathSApply(data,"//*/node[@id=\"6554996802\"]")
# 6554996802 is just one of the ids out of 15212
它给了,
[[1]]
<node id="6554996802" lat="40.9220973" lon="29.1279101" version="1">
<tag k="name" v="Burcu Cafe"/>
<tag k="amenity" v="cafe"/>
</node>
由于只在数据内部进行一次搜索,所以速度相对较快。但是,我无法再进一步了。
有什么建议吗?
这应该工作得很快...... 救援的 xpath :)
library(xml2)
library(magrittr) #for pipe-operator
#read in xml (see section below for sample data)
doc <- read_xml( "./test.xml" )
#get the parent-node 'node' from a tag-node where the k-attribute = amenity
nodes <- xml_find_all( doc, "//tag[@k='amenity']/parent::node" )
#build data.frame
data.frame( id = xml_attr( nodes, "id" ) %>% as.numeric(),
lat = xml_attr( nodes, "lat" ) %>% as.numeric(),
lon = xml_attr( nodes, "lon" ) %>% as.numeric(),
name = xml_find_first( nodes, ".//tag[@k='name']") %>% xml_attr("v"),
amenity = xml_find_first( nodes, ".//tag[@k='amenity']") %>% xml_attr("v"),
stringsAsFactors = FALSE
)
# id lat lon name amenity
# 1 4165094897 41.04924 29.02600 Adnan Yeri cafe
# 2 4165094900 41.04935 29.02585 28 Black restaurant
示例数据
test.xml
<nodes>
<node id="4165094897" lat="41.0492396" lon="29.0260049" version="1">
<tag k="name" v="Adnan Yeri"/>
<tag k="amenity" v="cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094899" lat="41.0492902" lon="29.0258856" version="1">
<tag k="name" v="Piano Restaurant Cafe"/>
<tag k="wheelchair" v="limited"/>
</node>
<node id="4165094900" lat="41.0493468" lon="29.0258547" version="1">
<tag k="name" v="28 Black"/>
<tag k="shop" v="yes"/>
<tag k="amenity" v="restaurant"/>
</node>
</nodes>