R/node_utils.r

Defines functions process_osm_nodes osm_nodes_to_sptsdf

# find all the nodes and store them in a data frame
process_osm_nodes <- function(doc) {

  # efficiently find all node attributes (lat/lon)
  # and get them into a data frame
  tmp <- xml2::xml_attrs(xml_find_all(doc, "//node"))
  nodes <- as.data.frame(t(do.call(cbind, tmp)), stringsAsFactors=FALSE)
  nodes <- nodes[, c("id", "lon", "lat")]

  # find all the nodes with tags
  nodes_with_tags <- tryCatch(xml2::xml_find_all(doc, "//node[child::tag]"),
                              errror=function(err){ return(list(0)) })

  # if there are any, add the tag key/value to make a wide data frame
  if (length(nodes_with_tags) > 0) {
    dplyr::bind_rows(lapply(nodes_with_tags, function(x) {
      v <- xml2::xml_attr(xml_find_all(x, "tag"), "v")
      names(v) <- xml2::xml_attr(xml_find_all(x, "tag"), "k")
      pts <- cbind.data.frame(id=xml2::xml_attr(x, "id"), t(v),
                              stringsAsFactors=FALSE)
    })) -> node_attrs
    nodes <- dplyr::left_join(nodes, node_attrs, by="id")
  }

  # need numeric lon/lat
  dplyr::mutate(nodes, lon=as.numeric(lon), lat=as.numeric(lat))

}

# take a data frame of osm nodes and return a SpatialPointsDataFrame
osm_nodes_to_sptsdf <- function(osm_nodes) {
  df <- data.frame(filter(osm_nodes, -lon, -lat))
  spdf <- SpatialPointsDataFrame(as.matrix(osm_nodes[, c("lon", "lat")]), df)
  spdf
}
hrbrmstr/overpass documentation built on May 17, 2019, 5:11 p.m.