diff --git a/DESCRIPTION b/DESCRIPTION index e54feb2c..1dbd7869 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: osmapiR Title: 'OpenStreetMap' API -Version: 0.2.1.9001 +Version: 0.2.1.9002 Authors@R: c( person("Joan", "Maspons", , "joanmaspons@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0003-2286-8727")), @@ -33,6 +33,7 @@ VignetteBuilder: Config/testthat/edition: 3 Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 +OSMWikiVersion: 2775892 X-schema.org-keywords: open street map, openstreetmap, OSM, openstreetmap-api, osmapi, API diff --git a/NEWS.md b/NEWS.md index 42bc72d0..ba04eaa8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,10 @@ # osmapiR (development version) * Use the new function `httr2::oauth_cache_clear()` from httr2 1.0.6 (#58 by @hadley). +* Update documentation and code for server-side changes documented in OSMWikiVersion + [2711808 -> 2775892](https://wiki.openstreetmap.org/w/index.php?title=API_v0.6&type=revision&diff=2775892&oldid=2711808) + (#60). + * Add new parameters to `osm_query_changesets(..., from, to)`. # osmapiR 0.2.1 diff --git a/R/osm_get_changesets.R b/R/osm_get_changesets.R index 513c6212..25f03431 100644 --- a/R/osm_get_changesets.R +++ b/R/osm_get_changesets.R @@ -26,48 +26,66 @@ #' ## `format = "xml"` #' Returns a [xml2::xml_document-class] with the following format: #' ``` xml -#' -#' -#' -#' -#' ... -#' -#' -#' Did you verify those street names? -#' -#' -#' sure! -#' -#' ... -#' -#' -#' -#' ... -#' +#' +#' +#' +#' +#' ... +#' +#' +#' Did you verify those street names? +#' +#' +#' sure! +#' +#' ... +#' +#' +#' +#' ... +#' #' #' ``` #' #' ## `format = "json"` +#' *Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to* +#' *align it with the existing Rails format.* +#' #' Returns a list with the following json structure: #' ``` json #' { -#' "version": "0.6", -#' "elements": [ -#' {"type": "changeset", -#' "id": 10, -#' "created_at": "2005-05-01T16:09:37Z", -#' "closed_at": "2005-05-01T17:16:44Z", -#' "open": False, -#' "user": "Petter Reinholdtsen", -#' "uid": 24, -#' "minlat": 59.9513092, -#' "minlon": 10.7719727, -#' "maxlat": 59.9561501, -#' "maxlon": 10.7994537, -#' "comments_count": 1, -#' "changes_count": 10, -#' "discussion": [{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\n"}] -#' }, ...] +#' "version": "0.6", +#' "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", +#' "copyright": "OpenStreetMap and contributors", +#' "attribution": "http://www.openstreetmap.org/copyright", +#' "license": "http://opendatacommons.org/licenses/odbl/1-0/", +#' "changeset": [ +#' { +#' "id": 10, +#' "created_at": "2005-05-01T16:09:37Z", +#' "open": false, +#' "comments_count": 1, +#' "changes_count": 10, +#' "closed_at": "2005-05-01T17:16:44Z", +#' "min_lat": 59.9513092, +#' "min_lon": 10.7719727, +#' "max_lat": 59.9561501, +#' "max_lon": 10.7994537, +#' "uid": 24, +#' "user": "Petter Reinholdtsen", +#' "comments": [ +#' { +#' "id": 836447, +#' "visible": true, +#' "date": "2022-03-22T20:58:30Z", +#' "uid": 15079200, +#' "user": "Ethan White of Cheriton", +#' "text": "wow no one have said anything here 3/22/2022\n" +#' } +#' ] +#' }, +#' ... +#' ] #' } #' ``` #' diff --git a/R/osm_query_changesets.R b/R/osm_query_changesets.R index 73741ff6..8a2fb853 100644 --- a/R/osm_query_changesets.R +++ b/R/osm_query_changesets.R @@ -6,7 +6,11 @@ #' @param user Find changesets by the user with the given user id (numeric) or display name (character). #' @param time Find changesets **closed** after this date and time. See details for the valid formats. #' @param time_2 find changesets that were **closed** after `time` and **created** before `time_2`. In other words, any -#' changesets that were open **at some time** during the given time range `time` to `time_2`. +#' changesets that were open **at some time** during the given time range `time` to `time_2`. See details for the +#' valid formats. +#' @param from Find changesets **created** at or after this value. See details for the valid formats. +#' @param to Find changesets **created** before this value. `to` requires `from`, but not vice-versa. If `to` is +#' provided alone, it has no effect. See details for the valid formats. #' @param open If `TRUE`, only finds changesets that are still **open** but excludes changesets that are closed or have #' reached the element limit for a changeset (10,000 at the moment `osm_capabilities()$api$changesets`). #' @param closed If `TRUE`, only finds changesets that are **closed** or have reached the element limit. @@ -32,8 +36,9 @@ #' – see the [current state](https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/api/changesets_controller.rb#L174)). #' Reverse ordering cannot be combined with `time`. #' -#' Te valid formats for `time` and `time_2` parameters are anything that -#' [`Time.parse` Ruby function](https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse) will parse. +#' Te valid formats for `time`, `time_2`, `from` and `to` parameters are [POSIXt] values or characters with anything +#' that [`Time.parse` Ruby function](https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse) will +#' parse. #' #' @return #' If `format = "R"`, returns a data frame with one OSM changeset per row. If `format = "sf"`, returns a `sf` object @@ -42,48 +47,51 @@ #' ## `format = "xml"` #' Returns a [xml2::xml_document-class] with the following format: #' ``` xml -#' -#' -#' -#' -#' ... -#' -#' -#' Did you verify those street names? -#' -#' -#' sure! -#' -#' ... -#' -#' -#' -#' ... -#' +#' +#' +#' +#' +#' ... +#' +#' +#' ... +#' #' #' ``` #' #' ## `format = "json"` +#' *Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to* +#' *align it with the existing Rails format.* +#' #' Returns a list with the following json structure: #' ``` json #' { -#' "version": "0.6", -#' "elements": [ -#' {"type": "changeset", -#' "id": 10, -#' "created_at": "2005-05-01T16:09:37Z", -#' "closed_at": "2005-05-01T17:16:44Z", -#' "open": False, -#' "user": "Petter Reinholdtsen", -#' "uid": 24, -#' "minlat": 59.9513092, -#' "minlon": 10.7719727, -#' "maxlat": 59.9561501, -#' "maxlon": 10.7994537, -#' "comments_count": 1, -#' "changes_count": 10, -#' "discussion": [{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\n"}] -#' }, ...] +#' "version": "0.6", +#' "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", +#' "copyright": "OpenStreetMap and contributors", +#' "attribution": "http://www.openstreetmap.org/copyright", +#' "license": "http://opendatacommons.org/licenses/odbl/1-0/", +#' "changesets": [ +#' { +#' "id": 10, +#' "created_at": "2005-05-01T16:09:37Z", +#' "open": false, +#' "comments_count": 1, +#' "changes_count": 10, +#' "closed_at": "2005-05-01T17:16:44Z", +#' "min_lat": 59.9513092, +#' "min_lon": 10.7719727, +#' "max_lat": 59.9561501, +#' "max_lon": 10.7994537, +#' "uid": 24, +#' "user": "Petter Reinholdtsen", +#' "tags": { +#' "comment": "Just adding some streetnames", +#' "created_by": "JOSM 1.61" +#' } +#' }, +#' ... +#' ] #' } #' ``` #' @@ -108,7 +116,8 @@ #' closed = TRUE #' ) #' chsts2 -osm_query_changesets <- function(bbox, user, time, time_2, open, closed, changeset_ids, order = c("newest", "oldest"), +osm_query_changesets <- function(bbox, user, time, time_2, from, to, open, closed, changeset_ids, + order = c("newest", "oldest"), limit = getOption("osmapir.api_capabilities")$api$changesets["default_query_limit"], format = c("R", "sf", "xml", "json"), tags_in_columns = FALSE) { format <- match.arg(format) @@ -137,6 +146,13 @@ osm_query_changesets <- function(bbox, user, time, time_2, open, closed, changes } stopifnot(is.null(time) && is.null(time_2) || !is.null(time)) + if (missing(from)) { + from <- NULL + } + if (missing(to)) { + to <- NULL + } + if (missing(open)) { open <- NULL } else { @@ -176,7 +192,7 @@ osm_query_changesets <- function(bbox, user, time, time_2, open, closed, changes if (limit <= getOption("osmapir.api_capabilities")$api$changesets["maximum_query_limit"]) { # no batch needed out <- .osm_query_changesets( - bbox = bbox, user = user, time = time, time_2 = time_2, open = open, closed = closed, + bbox = bbox, user = user, time = time, time_2 = time_2, from = from, to = to, open = open, closed = closed, changeset_ids = changeset_ids, order = order, limit = limit, format = .format, tags_in_columns = tags_in_columns ) @@ -206,7 +222,7 @@ osm_query_changesets <- function(bbox, user, time, time_2, open, closed, changes ## TODO: simplify and split in different functions ---- while (n_out < limit && n > 0) { outL[[i]] <- .osm_query_changesets( - bbox = bbox, user = user, time = time, time_2 = time_2, open = open, closed = closed, + bbox = bbox, user = user, time = time, time_2 = time_2, from = from, to = to, open = open, closed = closed, changeset_ids = changeset_ids, order = order, limit = min(limit - n_out, getOption("osmapir.api_capabilities")$api$changesets["maximum_query_limit"]), format = .format, tags_in_columns = FALSE diff --git a/R/osmapi_changesets.R b/R/osmapi_changesets.R index fdd4f6f9..b594a506 100644 --- a/R/osmapi_changesets.R +++ b/R/osmapi_changesets.R @@ -146,16 +146,17 @@ osm_create_changeset <- function(comment, ..., # Returns the single changeset element containing the changeset tags with a content type of `text/xml` # GET /api/0.6/changeset/#id?include_discussion=true # -# +# +# # # # # ... # -# +# # Did you verify those street names? # -# +# # sure! # # ... @@ -167,26 +168,39 @@ osm_create_changeset <- function(comment, ..., ### Response JSON ---- # Returns the single changeset element containing the changeset tags with a content type of `application/json` # GET /api/0.6/changeset/#id.json?include_discussion=true +# Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to align it with the existing Rails format. # -# { -# "version": "0.6", -# "elements": [ -# {"type": "changeset", -# "id": 10, -# "created_at": "2005-05-01T16:09:37Z", -# "closed_at": "2005-05-01T17:16:44Z", -# "open": False, -# "user": "Petter Reinholdtsen", -# "uid": 24, -# "minlat": 59.9513092, -# "minlon": 10.7719727, -# "maxlat": 59.9561501, -# "maxlon": 10.7994537, -# "comments_count": 1, -# "changes_count": 10, -# "discussion": [{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\n"}] -# }] -# } +# { +# "version": "0.6", +# "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", +# "copyright": "OpenStreetMap and contributors", +# "attribution": "http://www.openstreetmap.org/copyright", +# "license": "http://opendatacommons.org/licenses/odbl/1-0/", +# "changeset": { +# "id": 10, +# "created_at": "2005-05-01T16:09:37Z", +# "open": false, +# "comments_count": 1, +# "changes_count": 10, +# "closed_at": "2005-05-01T17:16:44Z", +# "min_lat": 59.9513092, +# "min_lon": 10.7719727, +# "max_lat": 59.9561501, +# "max_lon": 10.7994537, +# "uid": 24, +# "user": "Petter Reinholdtsen", +# "comments": [ +# { +# "id": 836447, +# "visible": true, +# "date": "2022-03-22T20:58:30Z", +# "uid": 15079200, +# "user": "Ethan White of Cheriton", +# "text": "wow no one have said anything here 3/22/2022\n" +# } +# ] +# } +# } # # ### Error codes ---- @@ -224,16 +238,16 @@ osm_create_changeset <- function(comment, ..., #' ## `format = "xml"` #' Returns a [xml2::xml_document-class] with the following format: #' ``` xml -#' +#' #' #' #' #' ... #' -#' +#' #' Did you verify those street names? #' -#' +#' #' sure! #' #' ... @@ -243,26 +257,41 @@ osm_create_changeset <- function(comment, ..., #' ``` #' #' ## `format = "json"` +#' *Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to* +#' *align it with the existing Rails format.* +#' #' Returns a list with the following json structure: #' ``` json #' { -#' "version": "0.6", -#' "elements": [ -#' {"type": "changeset", -#' "id": 10, -#' "created_at": "2005-05-01T16:09:37Z", -#' "closed_at": "2005-05-01T17:16:44Z", -#' "open": False, -#' "user": "Petter Reinholdtsen", -#' "uid": 24, -#' "minlat": 59.9513092, -#' "minlon": 10.7719727, -#' "maxlat": 59.9561501, -#' "maxlon": 10.7994537, -#' "comments_count": 1, -#' "changes_count": 10, -#' "discussion": [{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\n"}] -#' }] +#' "version": "0.6", +#' "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", +#' "copyright": "OpenStreetMap and contributors", +#' "attribution": "http://www.openstreetmap.org/copyright", +#' "license": "http://opendatacommons.org/licenses/odbl/1-0/", +#' "changeset": { +#' "id": 10, +#' "created_at": "2005-05-01T16:09:37Z", +#' "open": false, +#' "comments_count": 1, +#' "changes_count": 10, +#' "closed_at": "2005-05-01T17:16:44Z", +#' "min_lat": 59.9513092, +#' "min_lon": 10.7719727, +#' "max_lat": 59.9561501, +#' "max_lon": 10.7994537, +#' "uid": 24, +#' "user": "Petter Reinholdtsen", +#' "comments": [ +#' { +#' "id": 836447, +#' "visible": true, +#' "date": "2022-03-22T20:58:30Z", +#' "uid": 15079200, +#' "user": "Ethan White of Cheriton", +#' "text": "wow no one have said anything here 3/22/2022\n" +#' } +#' ] +#' } #' } #' ``` #' @@ -479,13 +508,13 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) ## Query: `GET /api/0.6/changesets` ---- -# This is an API method for querying changesets. It supports querying by different criteria. +# This is an API method for getting a list of changesets. It supports filtering by different criteria. # # Where multiple queries are given the result will be those which match all of the requirements. The contents of the returned document are the changesets and their tags. To get the full set of changes associated with a changeset, use the ''download'' method on each changeset ID individually. # # Modification and extension of the basic queries above may be required to support rollback and other uses we find for changesets. # -# This call returns latest changesets matching criteria. The default ordering is newest first, but you can specify '''order=oldest''' to reverse the sort orderhttps://github.com/openstreetmap/openstreetmap-website/blob/f1c6a87aa137c11d0aff5a4b0e563ac2c2a8f82d/app/controllers/api/changesets_controller.rb#L174 - see the current state at https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/api/changesets_controller.rb#L174. Reverse ordering cannot be combined with '''time'''. +# This call returns changesets matching criteria, ordered by their creation time. The default ordering is newest first, but you can specify '''order=oldest''' to reverse the sort orderhttps://github.com/openstreetmap/openstreetmap-website/blob/f1c6a87aa137c11d0aff5a4b0e563ac2c2a8f82d/app/controllers/api/changesets_controller.rb#L174 - see the current state at https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/api/changesets_controller.rb#L174. Reverse ordering cannot be combined with '''time'''. # ### Parameters ---- # ; bbox=min_lon,min_lat,max_lon,max_lat (W,S,E,N) @@ -493,9 +522,11 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) # ; user=#uid '''or''' display_name=#name # : Find changesets by the user with the given user id or display name. Providing both is an error. # ; time=T1 -# : Find changesets ''closed'' after T1 +# : Find changesets ''closed'' after T1. Compare with '''from=T1''' which filters by creation time instead. # ; time=T1,T2 # : Find changesets that were ''closed'' after T1 and ''created'' before T2. In other words, any changesets that were open ''at some time'' during the given time range T1 to T2. +# ; from=T1 [& to=T2] +# : Find changesets ''created'' at or after T1, and (optionally) before T2. '''to''' requires '''from''', but not vice-versa. If '''to''' is provided alone, it has no effect. # ; open=true # : Only finds changesets that are still ''open'' but excludes changesets that are closed or have reached the element limit for a changeset (10.000 at the momenthttps://api.openstreetmap.org/api/0.6/capabilities "") # ; closed=true @@ -522,13 +553,18 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) #' Query changesets #' -#' This is an API method for querying changesets. It supports querying by different criteria. +#' This is an API method for getting a list of changesets. It supports filtering by different criteria. #' #' @param bbox Find changesets within the given bounding box coordinates (`left,bottom,right,top`). #' @param user Find changesets by the user with the given user id (numeric) or display name (character). -#' @param time Find changesets **closed** after this date and time. See details for the valid formats. -#' @param time_2 find changesets that were **closed** after `time` and **created** before `time_2`. In other words, any -#' changesets that were open **at some time** during the given time range `time` to `time_2`. +#' @param time Find changesets **closed** after this date and time. Compare with `from=T1` which filters by creation +#' time instead. See details for the valid formats. +#' @param time_2 Find changesets that were **closed** after `time` and **created** before `time_2`. In other words, any +#' changesets that were open **at some time** during the given time range `time` to `time_2`. See details for the +#' valid formats. +#' @param from Find changesets **created** at or after this value. See details for the valid formats. +#' @param to Find changesets **created** before this value. `to` requires `from`, but not vice-versa. If `to` is +#' provided alone, it has no effect. See details for the valid formats. #' @param open If `TRUE`, only finds changesets that are still **open** but excludes changesets that are closed or have #' reached the element limit for a changeset (10,000 at the moment `osm_capabilities()$api$changesets`). #' @param closed If `TRUE`, only finds changesets that are **closed** or have reached the element limit. @@ -549,14 +585,15 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) #' Modification and extension of the basic queries above may be required to support rollback and other uses we find for #' changesets. #' -#' This call returns latest changesets matching criteria. The default ordering is newest first, but you can specify -#' `order="oldest"` to reverse the sort order (see +#' This call returns changesets matching criteria, ordered by their creation time. The default ordering is newest first, +#' but you can specify `order="oldest"` to reverse the sort order (see #' [ordered by `created_at`](https://github.com/openstreetmap/openstreetmap-website/blob/f1c6a87aa137c11d0aff5a4b0e563ac2c2a8f82d/app/controllers/api/changesets_controller.rb#L174) #' – see the [current state](https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/api/changesets_controller.rb#L174)). #' Reverse ordering cannot be combined with `time`. #' -#' Te valid formats for `time` and `time_2` parameters are anything that -#' [`Time.parse` Ruby function](https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse) will parse. +#' Te valid formats for `time`, `time_2`, `from` and `to` parameters are [POSIXt] values or characters with anything +#' that [`Time.parse` Ruby function](https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse) will +#' parse. #' #' @return #' If `format = "R"`, returns a data frame with one OSM changeset per row. @@ -564,24 +601,15 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) #' ## `format = "xml"` #' Returns a [xml2::xml_document-class] with the following format: #' ``` xml -#' -#' -#' -#' -#' ... -#' -#' -#' Did you verify those street names? -#' -#' -#' sure! -#' -#' ... -#' -#' -#' -#' ... -#' +#' +#' +#' +#' +#' ... +#' +#' +#' ... +#' #' #' ``` #' @@ -589,23 +617,32 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) #' Returns a list with the following json structure: #' ``` json #' { -#' "version": "0.6", -#' "elements": [ -#' {"type": "changeset", -#' "id": 10, -#' "created_at": "2005-05-01T16:09:37Z", -#' "closed_at": "2005-05-01T17:16:44Z", -#' "open": False, -#' "user": "Petter Reinholdtsen", -#' "uid": 24, -#' "minlat": 59.9513092, -#' "minlon": 10.7719727, -#' "maxlat": 59.9561501, -#' "maxlon": 10.7994537, -#' "comments_count": 1, -#' "changes_count": 10, -#' "discussion": [{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\n"}] -#' }, ...] +#' "version": "0.6", +#' "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", +#' "copyright": "OpenStreetMap and contributors", +#' "attribution": "http://www.openstreetmap.org/copyright", +#' "license": "http://opendatacommons.org/licenses/odbl/1-0/", +#' "changesets": [ +#' { +#' "id": 10, +#' "created_at": "2005-05-01T16:09:37Z", +#' "open": false, +#' "comments_count": 1, +#' "changes_count": 10, +#' "closed_at": "2005-05-01T17:16:44Z", +#' "min_lat": 59.9513092, +#' "min_lon": 10.7719727, +#' "max_lat": 59.9561501, +#' "max_lon": 10.7994537, +#' "uid": 24, +#' "user": "Petter Reinholdtsen", +#' "tags": { +#' "comment": "Just adding some streetnames", +#' "created_by": "JOSM 1.61" +#' } +#' }, +#' ... +#' ] #' } #' ``` #' @@ -630,8 +667,8 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) #' closed = "true" #' ) #' chsts2 -.osm_query_changesets <- function(bbox = NULL, user = NULL, time = NULL, time_2 = NULL, open = NULL, closed = NULL, - changeset_ids = NULL, order = NULL, +.osm_query_changesets <- function(bbox = NULL, user = NULL, time = NULL, time_2 = NULL, from = NULL, to = NULL, + open = NULL, closed = NULL, changeset_ids = NULL, order = NULL, limit = getOption( "osmapir.api_capabilities" )$api$changesets["default_query_limit"], @@ -657,6 +694,13 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) time <- paste0(time, ",", time_2) } + if (!is.null(from) && inherits(from, "POSIXt")) { + from <- format(from, "%Y-%m-%dT%H:%M:%SZ") + } + if (!is.null(to) && inherits(to, "POSIXt")) { + to <- format(to, "%Y-%m-%dT%H:%M:%SZ") + } + if (format == "json") { ext <- "changesets.json" } else { @@ -669,7 +713,7 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) req <- httr2::req_url_query(req, bbox = bbox, user = user, display_name = display_name, - time = time, + time = time, from = from, to = to, open = open, closed = closed, changesets = changeset_ids, order = order, @@ -747,6 +791,8 @@ osm_download_changeset <- function(changeset_id, format = c("R", "osc", "xml")) # : Or if the user trying to update the changeset is not the same as the one that created it # : Or if the diff contains elements with changeset IDs which don't match the changeset ID that the diff was uploaded to # : Or any of the error messages that could occur as a result of a create, update or delete operation for one of the elements +# ; HTTP status code 413 (Payload too large/Content too large) +# : If, while uploading, the permitted bounding box size is exceeded, an error "Changeset bounding box size limit exceeded." is returned. # ; HTTP status code 429 (Too many requests) # : When the request has been blocked due to rate limiting # ; Other status codes diff --git a/R/osmapi_elements.R b/R/osmapi_elements.R index 80d7e9a9..d9426d67 100644 --- a/R/osmapi_elements.R +++ b/R/osmapi_elements.R @@ -250,7 +250,7 @@ osm_read_object <- function(osm_type = c("node", "way", "relation"), ## Update: `PUT /api/0.6/[node|way|relation]/#id` ---- -# Updates data from a preexisting element. A full representation of the element as it should be after the update has to be provided. Any tags, way-node refs, and relation members that remain unchanged must be in the update as well. A version number must be provided as well, it must match the current version of the element in the database. +# Updates data from a preexisting element. A full representation of the element as it should be after the update has to be provided. Any tags, way-node refs, and relation members that remain unchanged must be in the update as well. A version number must be provided as well, it '''must match''' the current version of the element in the database. # # This example is an update of the node 4326396331, updating the version 1 to alter existing tags. This change is made while the changeset with id 188021 is still open: # @@ -261,15 +261,29 @@ osm_read_object <- function(osm_type = c("node", "way", "relation"), # # # +# Example for way 22935194 adding a new key zoning_code with value B. Remember that when making the PUT to an existing way, you need to add all existing tags (excluded here some for brevity) and the same version as the version from OSM +# +# +# +# +# +# +# +# +# +# +# +# ### Response ---- # Returns the new version number with a content type of `text/plain`. # ### Error codes ---- # ; HTTP status code 400 (Bad Request) - `text/plain` -# : When there are errors parsing the XML. A text message explaining the error is returned. This can also happen if you forget to pass the Content-Length header. +# : When there are errors parsing the XML. A text message explaining the error is returned. (Example: Version is required when updating) This can also happen if you forget to pass the Content-Length header. # : When a changeset ID is missing (unfortunately the error messages are not consistent) # : When a node is outside the world # : When there are too many nodes for a way +# : # ; HTTP status code 409 (Conflict) - `text/plain` # : When the version of the provided element does not match the current database version of the element # : If the changeset in question has already been closed (either by the user itself or as a result of the auto-closing feature). A message with the format "`The changeset #id was closed at #closed_at.`" is returned @@ -298,7 +312,7 @@ osm_read_object <- function(osm_type = c("node", "way", "relation"), #' @details #' A full representation of the element as it should be after the update has to be provided. Any tags, way-node refs, #' and relation members that remain unchanged must be in the update as well. A version number must be provided as well, -#' it must match the current version of the element in the database. +#' it **must match** the current version of the element in the database. #' #' If `x` is a data.frame, the columns `type`, `id`, `visible`, `version`, `changeset`, and `tags` must be present + #' column `members` for ways and relations + `lat` and `lon` for nodes. For the xml format, see the @@ -525,7 +539,7 @@ osm_delete_object <- function(x, changeset_id) { ## History: `GET /api/0.6/[node|way|relation]/#id/history` ---- -# Retrieves all old versions of an element. ([https://api.openstreetmap.org/api/0.6/way/250066046/history example]) +# Retrieves all old versions of an element, sorted by version number from oldest to newest. ([https://api.openstreetmap.org/api/0.6/way/250066046/history example]) # ### Error codes ---- # ; HTTP status code 404 (Not Found) @@ -533,7 +547,7 @@ osm_delete_object <- function(x, changeset_id) { #' Get the history of an object #' -#' Retrieves all old versions of an object from OSM. +#' Retrieves all old versions of an object from OSM, sorted by version number from oldest to newest. #' #' @param osm_type Object type (`"node"`, `"way"` or `"relation"`). #' @param osm_id Object id represented by a numeric or a character value. @@ -662,7 +676,7 @@ osm_version_object <- function(osm_type = c("node", "way", "relation"), osm_id, ### Parameters ---- # ; [nodes|ways|relations]=comma separated list # : The parameter has to be the same in the URL (e.g. /api/0.6/nodes?nodes=123,456,789) -# : Version numbers for each object may be optionally provided following a lowercase "v" character, e.g. /api/0.6/nodes?nodes=421586779v1,421586779v2 +# : Version numbers for each object may be optionally provided following a lowercase "v" character, e.g. /api/0.6/nodes?nodes=421586779v1,421586779v2 (Currently supported only in CGImap, used on osm.org https://github.com/openstreetmap/openstreetmap-website/pull/1189/) # ### Error codes ---- # ; HTTP status code 400 (Bad Request) @@ -1042,7 +1056,7 @@ osm_full_object <- function(osm_type = c("way", "relation"), osm_id, # ### Notes ---- # * only permitted for OSM accounts with the moderator role (DWG and server admins) -# * requires either write_redactions or write_api OAuth scope; write_redactions is being phased out +# * requires write_redactions OAuth scope; before September 2024 required either write_api or write_redactions, and before December 2023 required write_api; those older scope requirements may still be around on other openstreetmap-website-based servers such as [[OpenHistoricalMap]] # * the #redaction_id is listed on https://www.openstreetmap.org/redactions # * more information can be found in [https://git.openstreetmap.org/rails.git/blob/HEAD:/app/controllers/redactions_controller.rb the source] # * This is an extremely specialized call @@ -1067,6 +1081,11 @@ osm_full_object <- function(osm_type = c("way", "relation"), osm_id, #' The `redaction_id` is listed on . More information can be found in #' [the source](https://git.openstreetmap.org/rails.git/blob/HEAD:/app/controllers/redactions_controller.rb). #' +#' @note +#' Requires `write_redactions` OAuth scope; before September 2024 required either `write_api` or `write_redactions`, and +#' before December 2023 required `write_api`; those older scope requirements may still be around on other +#' openstreetmap-website-based servers such as [OpenHistoricalMap](https://www.openhistoricalmap.org). +#' #' @return Nothing is returned upon successful redaction or unredaction of an object. #' @family functions for moderators #' @export diff --git a/R/osmapi_miscellaneous.R b/R/osmapi_miscellaneous.R index 013611b4..7c037d42 100644 --- a/R/osmapi_miscellaneous.R +++ b/R/osmapi_miscellaneous.R @@ -319,6 +319,7 @@ osm_bbox_objects <- function(bbox, format = c("R", "xml", "json"), tags_in_colum # * allow_write_prefs (modify user preferences) # * allow_write_diary (create diary entries, comments and make friends) # * allow_write_api (modify the map) +# * allow_write_redactions (redact element versions) # * allow_read_gpx (read private GPS traces) # * allow_write_gpx (upload GPS traces) # * allow_write_notes (modify notes) @@ -336,6 +337,7 @@ osm_bbox_objects <- function(bbox, format = c("R", "xml", "json"), tags_in_colum #' * allow_write_prefs (modify user preferences) #' * allow_write_diary (create diary entries, comments and make friends) #' * allow_write_api (modify the map) +#' * allow_write_redactions (redact element versions) #' * allow_read_gpx (read private GPS traces) #' * allow_write_gpx (upload GPS traces) #' * allow_write_notes (modify notes) diff --git a/R/osmapi_user_data.R b/R/osmapi_user_data.R index c7cb3a43..a1fdf607 100644 --- a/R/osmapi_user_data.R +++ b/R/osmapi_user_data.R @@ -415,7 +415,7 @@ osm_details_logged_user <- function(format = c("R", "xml", "json")) { } -## Preferences of the logged-in user: `GET /api/0.6/user/preferences` ---- +## Preferences of the logged-in user: `GET|PUT|DELETE /api/0.6/user/preferences` ---- # The OSM server supports storing arbitrary user preferences. This can be used by editors, for example, to offer the same configuration wherever the user logs in, instead of a locally-stored configuration. For an overview of applications using the preferences-API and which key-schemes they use, see [[preferences|this wiki page]]. # # You can retrieve the list of current preferences using diff --git a/inst/WORDLIST b/inst/WORDLIST index 18ac2247..d7935674 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -45,6 +45,7 @@ cdf ce cff CGImap +cgimap Changelog changelogs changeset @@ -102,6 +103,7 @@ deca del desc describeIn +Desseanu dev developmentStatus devtools @@ -292,6 +294,8 @@ OLTAmk onAttach onLoad opendatacommons +OpenHistoricalMap +openhistoricalmap OpenStreetBugs openstreetmap OpenStreetMap @@ -321,6 +325,7 @@ OsmChange's osmdata osmextract osmfoundation +OSMWikiVersion osn outL packageEvent @@ -422,6 +427,7 @@ spdx sprintf stdlib stopifnot +Strada streetnames strftime strsplit diff --git a/man/osm_get_changesets.Rd b/man/osm_get_changesets.Rd index 4bcfd400..1ef4ff6d 100644 --- a/man/osm_get_changesets.Rd +++ b/man/osm_get_changesets.Rd @@ -29,50 +29,68 @@ from \pkg{sf}. Returns a \link[xml2:oldclass]{xml2::xml_document} with the following format: -\if{html}{\out{
}}\preformatted{ - - - - ... - - - Did you verify those street names? - - - sure! - - ... - - - - ... - +\if{html}{\out{
}}\preformatted{ + + + + ... + + + Did you verify those street names? + + + sure! + + ... + + + + ... + }\if{html}{\out{
}} } \subsection{\code{format = "json"}}{ +\emph{Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to} +\emph{align it with the existing Rails format.} + Returns a list with the following json structure: \if{html}{\out{
}}\preformatted{\{ - "version": "0.6", - "elements": [ - \{"type": "changeset", - "id": 10, - "created_at": "2005-05-01T16:09:37Z", - "closed_at": "2005-05-01T17:16:44Z", - "open": False, - "user": "Petter Reinholdtsen", - "uid": 24, - "minlat": 59.9513092, - "minlon": 10.7719727, - "maxlat": 59.9561501, - "maxlon": 10.7994537, - "comments_count": 1, - "changes_count": 10, - "discussion": [\{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\\n"\}] - \}, ...] + "version": "0.6", + "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "changeset": [ + \{ + "id": 10, + "created_at": "2005-05-01T16:09:37Z", + "open": false, + "comments_count": 1, + "changes_count": 10, + "closed_at": "2005-05-01T17:16:44Z", + "min_lat": 59.9513092, + "min_lon": 10.7719727, + "max_lat": 59.9561501, + "max_lon": 10.7994537, + "uid": 24, + "user": "Petter Reinholdtsen", + "comments": [ + \{ + "id": 836447, + "visible": true, + "date": "2022-03-22T20:58:30Z", + "uid": 15079200, + "user": "Ethan White of Cheriton", + "text": "wow no one have said anything here 3/22/2022\\n" + \} + ] + \}, + ... + ] \} }\if{html}{\out{
}} } diff --git a/man/osm_history_object.Rd b/man/osm_history_object.Rd index d824469c..199d35af 100644 --- a/man/osm_history_object.Rd +++ b/man/osm_history_object.Rd @@ -29,7 +29,7 @@ If \code{format = "R"}, returns a data frame with a version of the OSM object pe returns a list with a json structure following the \href{https://wiki.openstreetmap.org/wiki/OSM_JSON}{OSM_JSON format}. } \description{ -Retrieves all old versions of an object from OSM. +Retrieves all old versions of an object from OSM, sorted by version number from oldest to newest. } \examples{ node <- osm_history_object(osm_type = "node", osm_id = 35308286) diff --git a/man/osm_permissions.Rd b/man/osm_permissions.Rd index c5ae12c5..ab0ba3e2 100644 --- a/man/osm_permissions.Rd +++ b/man/osm_permissions.Rd @@ -24,6 +24,7 @@ Currently the following permissions can appear in the result, corresponding dire \item allow_write_prefs (modify user preferences) \item allow_write_diary (create diary entries, comments and make friends) \item allow_write_api (modify the map) +\item allow_write_redactions (redact element versions) \item allow_read_gpx (read private GPS traces) \item allow_write_gpx (upload GPS traces) \item allow_write_notes (modify notes) diff --git a/man/osm_query_changesets.Rd b/man/osm_query_changesets.Rd index 2878245b..bec1bfd1 100644 --- a/man/osm_query_changesets.Rd +++ b/man/osm_query_changesets.Rd @@ -9,6 +9,8 @@ osm_query_changesets( user, time, time_2, + from, + to, open, closed, changeset_ids, @@ -26,7 +28,13 @@ osm_query_changesets( \item{time}{Find changesets \strong{closed} after this date and time. See details for the valid formats.} \item{time_2}{find changesets that were \strong{closed} after \code{time} and \strong{created} before \code{time_2}. In other words, any -changesets that were open \strong{at some time} during the given time range \code{time} to \code{time_2}.} +changesets that were open \strong{at some time} during the given time range \code{time} to \code{time_2}. See details for the +valid formats.} + +\item{from}{Find changesets \strong{created} at or after this value. See details for the valid formats.} + +\item{to}{Find changesets \strong{created} before this value. \code{to} requires \code{from}, but not vice-versa. If \code{to} is +provided alone, it has no effect. See details for the valid formats.} \item{open}{If \code{TRUE}, only finds changesets that are still \strong{open} but excludes changesets that are closed or have reached the element limit for a changeset (10,000 at the moment \code{osm_capabilities()$api$changesets}).} @@ -52,50 +60,53 @@ from \pkg{sf}. Returns a \link[xml2:oldclass]{xml2::xml_document} with the following format: -\if{html}{\out{
}}\preformatted{ - - - - ... - - - Did you verify those street names? - - - sure! - - ... - - - - ... - +\if{html}{\out{
}}\preformatted{ + + + + ... + + + ... + }\if{html}{\out{
}} } \subsection{\code{format = "json"}}{ +\emph{Please note that the JSON format has changed on August 25, 2024 with the release of openstreetmap-cgimap 2.0.0, to} +\emph{align it with the existing Rails format.} + Returns a list with the following json structure: \if{html}{\out{
}}\preformatted{\{ - "version": "0.6", - "elements": [ - \{"type": "changeset", - "id": 10, - "created_at": "2005-05-01T16:09:37Z", - "closed_at": "2005-05-01T17:16:44Z", - "open": False, - "user": "Petter Reinholdtsen", - "uid": 24, - "minlat": 59.9513092, - "minlon": 10.7719727, - "maxlat": 59.9561501, - "maxlon": 10.7994537, - "comments_count": 1, - "changes_count": 10, - "discussion": [\{"date": "2022-03-22T20:58:30Z", "uid": 15079200, "user": "Ethan White of Cheriton", "text": "wow no one have said anything here 3/22/2022\\n"\}] - \}, ...] + "version": "0.6", + "generator": "openstreetmap-cgimap 2.0.0 (4003517 spike-08.openstreetmap.org)", + "copyright": "OpenStreetMap and contributors", + "attribution": "http://www.openstreetmap.org/copyright", + "license": "http://opendatacommons.org/licenses/odbl/1-0/", + "changesets": [ + \{ + "id": 10, + "created_at": "2005-05-01T16:09:37Z", + "open": false, + "comments_count": 1, + "changes_count": 10, + "closed_at": "2005-05-01T17:16:44Z", + "min_lat": 59.9513092, + "min_lon": 10.7719727, + "max_lat": 59.9561501, + "max_lon": 10.7994537, + "uid": 24, + "user": "Petter Reinholdtsen", + "tags": \{ + "comment": "Just adding some streetnames", + "created_by": "JOSM 1.61" + \} + \}, + ... + ] \} }\if{html}{\out{
}} } @@ -117,8 +128,9 @@ This call returns latest changesets matching criteria. The default ordering is n – see the \href{https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/api/changesets_controller.rb#L174}{current state}). Reverse ordering cannot be combined with \code{time}. -Te valid formats for \code{time} and \code{time_2} parameters are anything that -\href{https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse}{\code{Time.parse} Ruby function} will parse. +Te valid formats for \code{time}, \code{time_2}, \code{from} and \code{to} parameters are \link{POSIXt} values or characters with anything +that \href{https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html#method-c-parse}{\code{Time.parse} Ruby function} will +parse. } \examples{ chst_ids <- osm_query_changesets(changeset_ids = c(137627129, 137625624)) diff --git a/man/osm_redaction_object.Rd b/man/osm_redaction_object.Rd index ea5226b3..c4c85d07 100644 --- a/man/osm_redaction_object.Rd +++ b/man/osm_redaction_object.Rd @@ -33,6 +33,11 @@ elements containing data privacy or copyright infringements. Only permitted for The \code{redaction_id} is listed on \url{https://www.openstreetmap.org/redactions}. More information can be found in \href{https://git.openstreetmap.org/rails.git/blob/HEAD:/app/controllers/redactions_controller.rb}{the source}. } +\note{ +Requires \code{write_redactions} OAuth scope; before September 2024 required either \code{write_api} or \code{write_redactions}, and +before December 2023 required \code{write_api}; those older scope requirements may still be around on other +openstreetmap-website-based servers such as \href{https://www.openhistoricalmap.org}{OpenHistoricalMap}. +} \examples{ \dontrun{ ## WARNING: this example will edit the OSM (testing) DB with your user! diff --git a/man/osm_update_object.Rd b/man/osm_update_object.Rd index 3abbfa85..98fa42b2 100644 --- a/man/osm_update_object.Rd +++ b/man/osm_update_object.Rd @@ -22,7 +22,7 @@ Updates data from a preexisting element. \details{ A full representation of the element as it should be after the update has to be provided. Any tags, way-node refs, and relation members that remain unchanged must be in the update as well. A version number must be provided as well, -it must match the current version of the element in the database. +it \strong{must match} the current version of the element in the database. If \code{x} is a data.frame, the columns \code{type}, \code{id}, \code{visible}, \code{version}, \code{changeset}, and \code{tags} must be present + column \code{members} for ways and relations + \code{lat} and \code{lon} for nodes. For the xml format, see the diff --git a/tests/testthat/_snaps/changesets.md b/tests/testthat/_snaps/changesets.md index 2c643e04..17f230c7 100644 --- a/tests/testthat/_snaps/changesets.md +++ b/tests/testthat/_snaps/changesets.md @@ -200,6 +200,24 @@ 2 6 tags: changesets_count=155 | comment=--- | created_by=iD 2.25.2 | host=https:/... 3 6 tags: changesets_count=154 | comment=--- | created_by=iD 2.25.2 | host=https:/... +--- + + Code + print(x) + Output + id created_at closed_at open user + 1 137626916 2023-06-22 02:05:19 2023-06-22 02:05:19 FALSE Mementomoristultus + 2 137626898 2023-06-22 02:03:57 2023-06-22 02:03:57 FALSE Mementomoristultus + uid min_lat min_lon max_lat max_lon comments_count + 1 19648429 38.9100720 1.4302823 38.9101137 1.4304540 1 + 2 19648429 38.8835173 1.3845938 38.9299968 1.4634214 0 + changes_count + 1 1 + 2 1 + tags + 1 6 tags: changesets_count=146 | comment=23 | created_by=iD 2.25.2 | host=https://... + 2 6 tags: changesets_count=145 | comment=112 | created_by=iD 2.25.2 | host=https:/... + --- Code diff --git a/tests/testthat/mock_query_changesets/osm.org/api/0.6/changesets-b87e70.xml b/tests/testthat/mock_query_changesets/osm.org/api/0.6/changesets-b87e70.xml new file mode 100644 index 00000000..fa62e26b --- /dev/null +++ b/tests/testthat/mock_query_changesets/osm.org/api/0.6/changesets-b87e70.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/test-changesets.R b/tests/testthat/test-changesets.R index b9e918e0..613c13d0 100644 --- a/tests/testthat/test-changesets.R +++ b/tests/testthat/test-changesets.R @@ -267,6 +267,12 @@ test_that("osm_query_changesets works", { time = "2023-06-22T02:23:23Z", time_2 = "2023-06-22T00:38:20Z" ) + chaset$from_to <- osm_query_changesets( + bbox = c(-1.241112, 38.0294955, 8.4203171, 42.9186456), + user = "Mementomoristultus", + from = as.POSIXlt("2023-06-22T00:38:20Z", tz = "GMT", format = "%Y-%m-%dT%H:%M:%S"), + to = as.POSIXlt("2023-06-22T02:23:23Z", tz = "GMT", format = "%Y-%m-%dT%H:%M:%S") + ) chaset$closed <- osm_query_changesets( bbox = "-9.3015367,41.8073642,-6.7339533,43.790422", user = "Mementomoristultus", diff --git a/tests/testthat/test-user_data.R b/tests/testthat/test-user_data.R index e0a66d13..f8feb744 100644 --- a/tests/testthat/test-user_data.R +++ b/tests/testthat/test-user_data.R @@ -126,7 +126,7 @@ test_that("osm_details_logged_user works", { }) -## Preferences of the logged-in user: `GET /api/0.6/user/preferences` ---- +## Preferences of the logged-in user: `GET|PUT|DELETE /api/0.6/user/preferences` ---- test_that("osm_set-get_preferences_user works", { with_mock_dir("mock_get_prefs_user", {