R package for downloading OpenStreetMap data

Deprecate `nodes_only` argument in `opq()`. Superseeded by argument `osm_types`

FIX #312

+66 -71
+1 -1
DESCRIPTION
··· 1 1 Package: osmdata 2 2 Title: Import 'OpenStreetMap' Data as Simple Features or Spatial Objects 3 - Version: 0.2.5.056 3 + Version: 0.2.5.058 4 4 Authors@R: c( 5 5 person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre")), 6 6 person("Bob", "Rudis", role = "aut"),
+1
NEWS.md
··· 8 8 - Remove `magrittr` from imports. User code relaying on reexported pipe `%>%` from `osmdata` must exlicitly load it 9 9 with `library(magrittr)`. Code examples, tests and vignettes now use the pipe from base (`|>`) available since R 4.1 10 10 (#361) 11 + - Deprecate `nodes_only` argument in `opq()`. Superseeded by argument `osm_types` (#362) 11 12 12 13 ## Minor changes 13 14
+36 -38
R/opq.R
··· 12 12 #' or \link{bbox_to_string} with a `data.frame` from `getbb(..., format_out 13 13 #' = "data.frame")` to select all areas combined (relations and ways). 14 14 #' @param nodes_only WARNING: this parameter is equivalent to 15 - #' `osm_types = "node"` and will be DEPRECATED. If `TRUE`, query OSM nodes 16 - #' only. Some OSM structures such as `place = "city"` or 15 + #' `osm_types = "node"` and is DEPRECATED. If `TRUE`, query OSM nodes 16 + #' only. 17 + #' @param osm_types A character vector with several OSM types to query: `node`, 18 + #' `way` and `relation` is the default. `nwr`, `nw`, `wr`, `nr` and `rel` 19 + #' are also valid types. Some OSM structures such as `place = "city"` or 17 20 #' `highway = "traffic_signals"` are represented by nodes only. Queries are 18 21 #' built by default to return all nodes, ways, and relation, but this can 19 - #' be very inefficient for node-only queries. Setting this value to `TRUE` 20 - #' for such cases makes queries more efficient, with data returned in the 21 - #' `osm_points` list item. 22 - #' @param osm_types A character vector with several OSM types to query: `node`, 23 - #' `way` and `relation` is the default. `nwr`, `nw`, `wr`, `nr` and `rel` 24 - #' are also valid types. Ignored if `nodes_only = TRUE`. 25 - #' `osm_types = "node"` is equivalent to `nodes_only = TRUE`. 22 + #' be very inefficient for node-only queries. Setting this value to `"node"` 23 + #' for such cases makes queries more efficient and, in [`osmdata_sf()`], the 24 + #' data will be returned in the `osm_points` list item only. 26 25 #' @param out The level of verbosity of the overpass result: `body` (geometries 27 26 #' and tags, the default), `tags` (tags without geometry), `meta` (like 28 27 #' body + Timestamp, Version, Changeset, User, User ID of the last ··· 82 81 #' add_osm_feature ("amenity", "pub") 83 82 #' c (osmdata_sf (q1), osmdata_sf (q2)) # all restaurants OR pubs 84 83 #' 85 - #' # Use nodes_only to retrieve single point data only, such as for central 84 + #' # Use `osm_types = "node"` to retrieve single point data only, such as for central 86 85 #' # locations of cities. 87 - #' opq <- opq (bbox, nodes_only = TRUE) |> 86 + #' opq <- opq (bbox, osm_types = "node") |> 88 87 #' add_osm_feature (key = "place", value = "city") |> 89 88 #' osmdata_sf (quiet = FALSE) 90 89 #' 91 90 #' # Filter by a search area 92 91 #' qa1 <- getbb ("Catalan Countries", format_out = "osm_type_id") |> 93 - #' opq (nodes_only = TRUE) |> 92 + #' opq (osm_types = "node") |> 94 93 #' add_osm_feature (key = "capital", value = "4") 95 94 #' opqa1 <- osmdata_sf (qa1) 96 95 #' # Filter by a multiple search areas 97 96 #' bb <- getbb ("Vilafranca", format_out = "data.frame") 98 97 #' qa2 <- bbox_to_string (bb [bb$osm_type != "node", ]) |> 99 - #' opq (nodes_only = TRUE) |> 98 + #' opq (osm_types = "node") |> 100 99 #' add_osm_feature (key = "place") 101 100 #' opqa2 <- osmdata_sf (qa2) 102 101 #' } 103 - opq <- function (bbox = NULL, nodes_only = FALSE, 102 + opq <- function (bbox = NULL, nodes_only = NULL, 104 103 osm_types = c ("node", "way", "relation"), 105 104 out = c ("body", "tags", "meta", "skel", "tags center", "ids"), 106 105 datetime = NULL, datetime2 = NULL, adiff = FALSE, ··· 109 108 timeout <- format (timeout, scientific = FALSE) 110 109 prefix <- paste0 ("[out:xml][timeout:", timeout, "]") 111 110 112 - if (nodes_only) { 113 - osm_types <- "node" 114 - } else { 115 - osm_types <- try ( 116 - match.arg (osm_types, 117 - choices = c ( 118 - "node", "way", "rel", "relation", 119 - "nwr", "nw", "wr", "nr" 120 - ), 121 - several.ok = TRUE 122 - ), silent = TRUE) 123 - if (inherits (osm_types, "try-error")) { 124 - stop ('osm_types parameter must be a vector with values from ', 125 - '"node", "way", "rel", "relation", ', 126 - '"nwr", "nw", "wr" and "nr".', 127 - call. = FALSE 128 - ) 111 + if (!is.null(nodes_only)) { 112 + .Deprecated(msg = paste("The 'nodes_only' argument is deprecated", 113 + "and will be removed in a future version.", 114 + "Use 'osm_types = \"node\"' instead.")) 115 + if (nodes_only) { 116 + osm_types <- "node" 129 117 } 130 118 } 131 119 120 + osm_types <- try ( 121 + match.arg (osm_types, 122 + choices = c ( 123 + "node", "way", "rel", "relation", 124 + "nwr", "nw", "wr", "nr" 125 + ), 126 + several.ok = TRUE 127 + ), silent = TRUE) 128 + if (inherits (osm_types, "try-error")) { 129 + stop ('osm_types parameter must be a vector with values from ', 130 + '"node", "way", "rel", "relation", ', 131 + '"nwr", "nw", "wr" and "nr".', 132 + call. = FALSE 133 + ) 134 + } 135 + 132 136 out <- try (match.arg (out), silent = TRUE) 133 137 if (inherits (out, "try-error")) { 134 138 stop ("out parameter must be ", ··· 137 141 ) 138 142 } 139 143 140 - has_geometry <- !nodes_only && out %in% c ("body", "meta", "skel") 144 + has_geometry <- !all (osm_types == "node") && out %in% c ("body", "meta", "skel") 141 145 if (has_geometry) { 142 146 suffix <- paste0 (");\n(._;>;);\nout ", out, ";") # recurse down 143 147 } else { ··· 193 197 class (res) <- c (class (res), "overpass_query") 194 198 attr (res, "datetime") <- datetime 195 199 attr (res, "datetime2") <- datetime2 196 - attr (res, "nodes_only") <- nodes_only 197 200 198 201 return (res) 199 202 } ··· 756 759 ) 757 760 class (res) <- c (class (res), "overpass_query") 758 761 attr (res, "datetime") <- attr (res, "datetime2") <- NULL 759 - attr (res, "nodes_only") <- FALSE 760 762 attr (res, "enclosing") <- enclosing 761 763 762 764 return (res) ··· 914 916 opq_string_intern <- function (opq, quiet = TRUE) { 915 917 916 918 lat <- lon <- NULL # suppress no visible binding messages 917 - 918 - if (attr (opq, "nodes_only")) { 919 - opq$osm_types <- "node" 920 - } 921 919 922 920 map_to_area <- grepl ("(node|way|relation|rel)\\(id:[0-9, ]+\\)", opq$bbox) 923 921
+13 -14
man/opq.Rd
··· 6 6 \usage{ 7 7 opq( 8 8 bbox = NULL, 9 - nodes_only = FALSE, 9 + nodes_only = NULL, 10 10 osm_types = c("node", "way", "relation"), 11 11 out = c("body", "tags", "meta", "skel", "tags center", "ids"), 12 12 datetime = NULL, ··· 28 28 or \link{bbox_to_string} with a \code{data.frame} from \code{getbb(..., format_out = "data.frame")} to select all areas combined (relations and ways).} 29 29 30 30 \item{nodes_only}{WARNING: this parameter is equivalent to 31 - \code{osm_types = "node"} and will be DEPRECATED. If \code{TRUE}, query OSM nodes 32 - only. Some OSM structures such as \code{place = "city"} or 33 - \code{highway = "traffic_signals"} are represented by nodes only. Queries are 34 - built by default to return all nodes, ways, and relation, but this can 35 - be very inefficient for node-only queries. Setting this value to \code{TRUE} 36 - for such cases makes queries more efficient, with data returned in the 37 - \code{osm_points} list item.} 31 + \code{osm_types = "node"} and is DEPRECATED. If \code{TRUE}, query OSM nodes 32 + only.} 38 33 39 34 \item{osm_types}{A character vector with several OSM types to query: \code{node}, 40 35 \code{way} and \code{relation} is the default. \code{nwr}, \code{nw}, \code{wr}, \code{nr} and \code{rel} 41 - are also valid types. Ignored if \code{nodes_only = TRUE}. 42 - \code{osm_types = "node"} is equivalent to \code{nodes_only = TRUE}.} 36 + are also valid types. Some OSM structures such as \code{place = "city"} or 37 + \code{highway = "traffic_signals"} are represented by nodes only. Queries are 38 + built by default to return all nodes, ways, and relation, but this can 39 + be very inefficient for node-only queries. Setting this value to \code{"node"} 40 + for such cases makes queries more efficient and, in \code{\link[=osmdata_sf]{osmdata_sf()}}, the 41 + data will be returned in the \code{osm_points} list item only.} 43 42 44 43 \item{out}{The level of verbosity of the overpass result: \code{body} (geometries 45 44 and tags, the default), \code{tags} (tags without geometry), \code{meta} (like ··· 105 104 add_osm_feature ("amenity", "pub") 106 105 c (osmdata_sf (q1), osmdata_sf (q2)) # all restaurants OR pubs 107 106 108 - # Use nodes_only to retrieve single point data only, such as for central 107 + # Use `osm_types = "node"` to retrieve single point data only, such as for central 109 108 # locations of cities. 110 - opq <- opq (bbox, nodes_only = TRUE) |> 109 + opq <- opq (bbox, osm_types = "node") |> 111 110 add_osm_feature (key = "place", value = "city") |> 112 111 osmdata_sf (quiet = FALSE) 113 112 114 113 # Filter by a search area 115 114 qa1 <- getbb ("Catalan Countries", format_out = "osm_type_id") |> 116 - opq (nodes_only = TRUE) |> 115 + opq (osm_types = "node") |> 117 116 add_osm_feature (key = "capital", value = "4") 118 117 opqa1 <- osmdata_sf (qa1) 119 118 # Filter by a multiple search areas 120 119 bb <- getbb ("Vilafranca", format_out = "data.frame") 121 120 qa2 <- bbox_to_string (bb [bb$osm_type != "node", ]) |> 122 - opq (nodes_only = TRUE) |> 121 + opq (osm_types = "node") |> 123 122 add_osm_feature (key = "place") 124 123 opqa2 <- osmdata_sf (qa2) 125 124 }
+6 -6
tests/testthat/test-data_frame-osm.R
··· 68 68 rownames (bb) <- c ("x", "y") 69 69 colnames (bb) <- c ("min", "max") 70 70 71 - q0 <- opq (bb, nodes_only = TRUE, datetime = "1714-09-11T00:00:00Z") |> 71 + q0 <- opq (bb, osm_types = "node", datetime = "1714-09-11T00:00:00Z") |> 72 72 add_osm_feature ("does not exist", "&%$") 73 73 74 74 osm_empty <- test_path ("fixtures", "osm-empty.osm") ··· 100 100 # q0 <- getbb ("Països Catalans", featuretype = "relation") |> 101 101 q0 <- opq ( 102 102 bb, 103 - nodes_only = TRUE, 103 + osm_types = "node", 104 104 datetime = "1714-09-11T00:00:00Z", 105 105 adiff = TRUE 106 106 ) |> ··· 176 176 bb <- rbind (c (2.01, 2.66), c (42.42, 42.71)) 177 177 rownames (bb) <- c ("x", "y") 178 178 colnames (bb) <- c ("min", "max") 179 - q <- opq (bb, nodes_only = TRUE, datetime = "2020-11-07T00:00:00Z") |> 179 + q <- opq (bb, osm_types = "node", datetime = "2020-11-07T00:00:00Z") |> 180 180 add_osm_feature ("natural", "peak") |> 181 181 add_osm_feature ("prominence") |> 182 182 add_osm_feature ("name:ca") ··· 254 254 rownames (bb) <- c ("x", "y") 255 255 colnames (bb) <- c ("min", "max") 256 256 q <- opq (bb, 257 - nodes_only = TRUE, out = "meta", 257 + osm_types = "node", out = "meta", 258 258 datetime = "2020-11-07T00:00:00Z", 259 259 datetime2 = "2022-12-04T00:00:00Z" 260 260 ) |> ··· 307 307 rownames (bb) <- c ("x", "y") 308 308 colnames (bb) <- c ("min", "max") 309 309 q <- opq (bb, 310 - nodes_only = TRUE, out = "meta", 310 + osm_types = "node", out = "meta", 311 311 datetime = "2020-11-07T00:00:00Z", adiff = TRUE 312 312 ) |> 313 313 add_osm_feature ("natural", "peak") |> ··· 416 416 rownames (bb) <- c ("x", "y") 417 417 colnames (bb) <- c ("min", "max") 418 418 q <- opq (bb, 419 - nodes_only = TRUE, 419 + osm_types = "node", 420 420 datetime = "2012-11-07T00:00:00Z", 421 421 datetime2 = "2016-11-07T00:00:00Z", 422 422 adiff = TRUE
+9 -11
tests/testthat/test-opq.R
··· 136 136 expect_equal (n_fts_in_query, n_fts * length(q2$osm_types)) 137 137 138 138 # nodes_only 139 - q3 <- opq (bbox = c (-0.118, 51.514, -0.115, 51.517), nodes_only = TRUE) 139 + q3 <- opq (bbox = c (-0.118, 51.514, -0.115, 51.517), osm_types = "node") 140 140 expect_silent ( 141 141 q4 <- opq ( 142 142 bbox = c (-0.118, 51.514, -0.115, 51.517), 143 - nodes_only = TRUE, 144 - osm_types = "blah" # ignored if nodes_only == TRUE 145 - ) 143 + osm_types = "node" ) 146 144 ) 147 145 148 146 expect_identical (q3, q4) ··· 182 180 }) 183 181 184 182 # nodes_only 185 - q1 <- opq (bbox = c (-0.118, 51.514, -0.115, 51.517), nodes_only = TRUE) 183 + q1 <- opq (bbox = c (-0.118, 51.514, -0.115, 51.517), osm_types = "node") 186 184 expect_error ( 187 185 q <- opq ( 188 186 bbox = c (-0.118, 51.514, -0.115, 51.517), ··· 194 192 q_geo <- lapply (c ("meta", "skel"), function (x) { 195 193 q <- opq ( 196 194 bbox = c (-0.118, 51.514, -0.115, 51.517), 197 - nodes_only = TRUE, out = x 195 + osm_types = "node", out = x 198 196 ) 199 197 expect_true (!identical (q1, q)) 200 198 expect_identical (names (q1), names (q)) ··· 207 205 q_no_geo <- lapply (c ("tags", "tags center", "ids"), function (x) { 208 206 q <- opq ( 209 207 bbox = c (-0.118, 51.514, -0.115, 51.517), 210 - nodes_only = TRUE, out = x 208 + osm_types = "node", out = x 211 209 ) 212 210 expect_true (!identical (q1, q)) 213 211 expect_identical (names (q1), names (q)) ··· 264 262 # nodes_only parameter: 265 263 q1 <- opq ( 266 264 bbox = c (-0.118, 51.514, -0.115, 51.517), 267 - nodes_only = TRUE 265 + osm_types = "node" 268 266 ) 269 267 s1 <- opq_string (q1) 270 268 # nodes only, so "out" instead of "out body" and no way nor relation ··· 273 271 274 272 q1 <- opq ( 275 273 bbox = "relation(id:11747082)", 276 - nodes_only = TRUE 274 + osm_types = "node" 277 275 ) 278 276 s1 <- opq_string (q1) 279 277 # nodes only, so "out" instead of "out body" and no way nor relation on clauses ··· 283 281 # nodes_only parameter with features: 284 282 q1 <- opq ( 285 283 bbox = c (-0.118, 51.514, -0.115, 51.517), 286 - nodes_only = TRUE 284 + osm_types = "node" 287 285 ) 288 286 q1 <- add_osm_feature (q1, key = "amenity", value = "restaurant") 289 287 s1 <- opq_string (q1) ··· 293 291 294 292 q1 <- opq ( 295 293 bbox = "relation(id:11747082)", 296 - nodes_only = TRUE 294 + osm_types = "node" 297 295 ) 298 296 q1 <- add_osm_feature (q1, key = "amenity", value = "restaurant") 299 297 s1 <- opq_string (q1)
-1
vignettes/osmdata.Rmd
··· 278 278 features = c ("[\"natural\"=\"water\"]", "[\"name:en\"=\"Dian\"]") 279 279 ) 280 280 attr (q, "class") <- c ("list", "overpass_query") 281 - attr (q, "nodes_only") <- FALSE 282 281 ``` 283 282 284 283 Note that the `"="` symbols here requests features whose values exactly match