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>