OSM-XML文件中的标签之间的迭代

时间:2019-07-14 05:51:44

标签: r xml openstreetmap

我正在处理以下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值。

例如,对于示例数据的第一个节点,由于它在标签内具有amenity属性,因此我想获取;

         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> 

由于仅在数据内部进行一次搜索,因此速度相对较快。但是,从这一点上讲,我无法走得更远。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

这应该工作很快... 救援的xpath:)

28

样本数据

test.xml

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