The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

How to edit OpenStreetMap

WARNING: This vignette contain examples that can edit the data at OpenStreetMap.org. Please, create a user in the testing server and configure osmapiR to use it. You will be responsible for any edition!

library(osmapiR)
set_osmapi_connection(server = "testing") # set the testing server

Create some dummy OSM objects.

d <- data.frame(
  type = c("node", "node", "way", "relation"),
  id = -(1:4),
  lat = c(0, 1, NA, NA),
  lon = c(0, 1, NA, NA),
  name = c(NA, NA, "My way", "Our relation"),
  type.1 = c(NA, NA, NA, "Column clash!")
)
d$members <- list(
  NULL, NULL, -(1:2),
  matrix(
    c("node", "-1", "node", "-2", "way", "-3"),
    nrow = 3, ncol = 2, byrow = TRUE, dimnames = list(NULL, c("type", "ref"))
  )
)
obj <- osmapi_objects(d, tag_columns = c(name = "name", type = "type.1"))

Using OSMChange format and osm_diff_upload_changeset()

osmcha_crea <- osmchange_create(obj)
osmcha_crea

changeset_id <- osm_create_changeset(
  comment = "Add objects for testing editions with osmchange format.",
  hashtags = "#osmapiRvignette;#testing"
)
osmcha_diff <- osm_diff_upload_changeset(changeset_id = changeset_id, osmcha = osmcha_crea)

message("See changeset at:\n\t", paste0(get_osmapi_url(), "/changeset/", changeset_id))

Add a new node:

new_node <- data.frame(type = "node", id = -1, lat = 0, lon = 1)
new_node <- osmapi_objects(new_node)
osmcha_new_node <- osmchange_create(new_node)

Update the id of the created objects which we want to modify with the id assigned by the server:

mod_obj <- obj[3:4, ]
mod_obj$id <- osmcha_diff$new_id[match(mod_obj$id, osmcha_diff$old_id)]

mod_obj$members[[1]] <- osmcha_diff$new_id[match(mod_obj$members[[1]], osmcha_diff$old_id)]
mod_obj$members[[2]][, "ref"] <- osmcha_diff$new_id[match(mod_obj$members[[2]][, "ref"], osmcha_diff$old_id)]

Add the new node to the way and the relation

mod_obj$members[[1]] <- c(mod_obj$members[[1]], new_node$id)
mod_obj$members[[2]] <- rbind(mod_obj$members[[2]], as.character(new_node[, c("type", "id")]))
mod_obj <- osmapi_objects(mod_obj)

osmcha_mod <- osmchange_modify(mod_obj, tag_keys = FALSE, members = TRUE)

Unite modification and new node changes and commit changes

# Just for the rbind of `osmcha_create` and `osmcha_modify` which have different columns:
osmcha_new_node <- osmapi_objects(osmcha_new_node)
osmcha_new_node[, setdiff(names(osmcha_mod), names(osmcha_new_node))] <- NA

osmcha_2 <- rbind(osmcha_new_node, osmcha_mod)

osmcha_diff2 <- osm_diff_upload_changeset(changeset_id = changeset_id, osmcha = osmcha_2)

Even if it’s a testing server, better to leave it clean. Let’s remove the created objects and close the changeset:

osmcha_del <- unique(rbind(osmcha_diff[, c("type", "new_id")], osmcha_diff2[, c("type", "new_id")]))
names(osmcha_del) <- c("type", "id")
osmcha_del <- osmchange_delete(osmcha_del)
osmcha_del

osmcha_diff_del <- osm_diff_upload_changeset(changeset_id = changeset_id, osmcha = osmcha_del)
osmcha_diff_del

osm_close_changeset(changeset_id)

Using osmapi patterns

To avoid performance issues when uploading multiple objects, the use of transactions with [osm_diff_upload_changeset()] as in the former example is highly recommended.

changeset_id <- osm_create_changeset(
  comment = "Add objects for testing editions with osmapi.",
  hashtags = "#osmapiRvignette;#testing"
)

new_id <- character(nrow(obj))

# create nodes
for (i in 1:2) {
  obj$id[i] <- osm_create_object(obj[i, ], changeset_id = changeset_id)
}

# create way
obj$members[[3]] <- obj$id[1:2] # update id of the newly created nodes
obj$id[3] <- osm_create_object(obj[3, ], changeset_id = changeset_id)

# create relation
obj$members[[4]][, "ref"] <- obj$id[1:3] # update id of the newly created objects
obj$id[4] <- osm_create_object(obj[4, ], changeset_id = changeset_id)

message("See changeset at:\n\t", paste0(get_osmapi_url(), "/changeset/", changeset_id))

Update object:

upd_obj <- osm_get_objects(osm_type = obj$type[4], osm_id = obj$id[4])
new_tags <- upd_obj$tags[[1]]
new_tags$value[2] <- "test"
new_tags <- rbind(new_tags, data.frame(key = "name:ca", value = "La nostra relació"))
upd_obj$tags[[1]] <- new_tags

osm_update_object(upd_obj, changeset_id = changeset_id)

Delete everything and close the changeset:

obj$version <- "1"
obj$version[4] <- "2" # updated object
for (i in rev(seq_len(nrow(obj)))) { # reverse order to avoid error (Node xxx is still used by ways yyy.)
  osm_delete_object(obj[i, ], changeset_id = changeset_id)
}

osm_close_changeset(changeset_id)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.