I managed to merge osmar objects with 99% accuracy, and would like to share my code with you. The idea is to rewrite the c() function in order to manually group the dataframes inside of osmar objects.
Warning : In the code below, relations are completely ignored because I don't use them. Those of you willing to properly use relations should adapt the code accordingly.
# This is the equivalent of the c function for osmar objects
# l : list of objects of class "osmar"
osmar_c_list <- function(l, verbose = F) {
# C is the result of the script. We initialise it as l[[1]], but will rewrite its components
c <- first(l)
# Data.table does not like POSIXlt, so we have to convert timestamps
l <- lapply(X = l, FUN = function(elem) {
elem$nodes$attrs$timestamp <- as.POSIXct(elem$nodes$attrs$timestamp)
elem$ways$attrs$timestamp <- as.POSIXct(elem$ways$attrs$timestamp)
elem$relations$attrs$timestamp <- as.POSIXct(elem$relations$attrs$timestamp)
elem
})
# The idea here is to rbind every dataframe in the osmar object
# After that, we call the "unique" function to make sure we don't add the same object twice
require(data.table)
c$nodes$attrs <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$nodes$attrs )))
c$nodes$tags <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$nodes$tags )))
c$ways$attrs <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$ways$attrs )))
c$ways$tags <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$ways$tags )))
c$ways$refs <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$ways$refs )))
c$relations$attrs <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$relations$attrs)))
c$relations$tags <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$relations$tags )))
c$relations$refs <- unique(rbindlist(lapply(X = l, FUN = function(elem) elem$relations$refs )))
# Calling the unique function was not without problem though. Indeed, in the case of a loop
# i.e. a road from node A to node A, we have destroyed the last segment.
# Let's detect duplicated nodes in ways and append them
duplic_i <- rbindlist(lapply(X = l, FUN = function(elem) elem$ways$refs[duplicated(elem$ways$refs),]))
c$ways$refs <- rbind(c$ways$refs, unique(duplic_i))
c$ways$refs <- c$ways$refs[order(c$ways$refs$id),]
# Lets go back to POSIXlt
c$nodes$attrs <- data.frame(c$nodes$attrs)
c$ways$attrs <- data.frame(c$ways$attrs)
c$relations$attrs <- data.frame(c$relations$attrs)
c$nodes$attrs$timestamp <- as.POSIXlt(c$nodes$attrs$timestamp)
c$ways$attrs$timestamp <- as.POSIXlt(c$ways$attrs$timestamp)
c$relations$attrs$timestamp <- as.POSIXlt(c$relations$attrs$timestamp)
return(c)
}
Warning : This code produces 99% accuracy for me, not 100%. I advise against using it as-is if your application requires high levels of accuracy.
Final note, I use this code to merge files with overlapping bounding boxes. I don't think it would work without some overlap.