ropensci / osmdata

R package for downloading OpenStreetMap data
https://docs.ropensci.org/osmdata
316 stars 46 forks source link

Adding overpass_trim() for filtering by area in overpass #258

Open Mashin6 opened 2 years ago

Mashin6 commented 2 years ago

This PR addresses suggestion #256.

Main changes are:

  1. New function added overpass_trim() that modifies OP query to subset OSM features by area rather than currently default bbox. Function parses entered information about areas to be used for trimming and stores them in a list in overpass_query object: trim_area = list (ways = c(ID, ... ), relations = c(ID, ...)
  2. opq_string_intern() was modified to accommodate changes necessary for area filtering.
  3. A new variable for feature type ftype was introduced in opq_string_intern that allows easy switching of which object types are queried. This can be easily extended to more types when #257 would be implemented.
  4. OP queries for nodes, ways, relations are not as 3 separate rows, but as a single nwr[...];
  5. WARNING: The most controversial change could be that I removed checks for if (is.null (bbox)) from functions: opq(), add_osm_feature(), add_osm_features() and introduced final check at the beginning of opq_string_intern. This was to allow opq() to be called without getbb(). So the queries can be now built like this:
opq() |>
        add_osm_feature(key = "natural",
                        value = "tree") |>
        overpass_trim(id = c(11597767, 43437030), 
                      type = c("relation", "way") ) |>
        osmdata_sf()

or

a <- getbb("portsmouth usa", format_out = "data.frame")
opq() |>
        add_osm_feature(key = "amenity",
                        value = "restaurant") |>
        overpass_trim(osm_area = a) |>
        osmdata_sf()

The only thing I am not happy about is that a typical user would expect trimming to work like this instead:

opq("portsmouth usa") |>
        add_osm_feature(key = "amenity",
                        value = "restaurant") |>
        overpass_trim() |>
        osmdata_sf()

But that would require making bbox_to_string return object id and type along with its bbox and let opq sort it out into $bbox and $trim_area. Any ideas?

jmaspons commented 1 year ago

Are you still open to work on this? I'm interested in the functionality and I can help in the implementation. Any feedback from the contributors would be useful.

mpadge commented 1 year ago

@jmaspons yes, i am very keen for something to happen with this - it's already been open way too long, which ain't good :scream: I should also be able to allocate some time to this soon too, but please feel free to see what you can do in the meantime. It's an important idea.

Mashin6 commented 1 year ago

@mpadge Would you be able to provide any feedback on the code/changes proposed? There were deeper modifications in the underlaying code and would be good to know your opinion if this is even in the right direction.

mpadge commented 1 year ago

Yeah, for sure @Mashin6, and great that you responded so promptly after such a long time - thank you! I'll get back to asap - hopefully in a few days when i find some time to look through it. Thanks!

Mashin6 commented 1 year ago

@jmaspons Did you have some ideas for implementing the overpass-side area trimming?

jmaspons commented 1 year ago

My idea is to pass a string in the form rel(id) to bbox parameter, which I would rename to area at some point. I have a draft https://github.com/jmaspons/osmdata/commit/cceab6f1a046a59f4b40f75cdd61e7752998ff75

Then, a get_area function, similar to getbb for areas, would help to get the string. If you like the idea, I can test the code and implement the get_area function and all de details.

Mashin6 commented 1 year ago

I like the simplicity of it. Would definitely like to see how it turns out.

mpadge commented 1 year ago

@Mashin6 There've been a few changes to opq.R recently. Would you please be able to merge those within your branch, and then push the updated version to this PR? Thanks!

jmaspons commented 1 year ago

I like the simplicity of it. Would definitely like to see how it turns out.

You can find a working implementation at https://github.com/ropensci/osmdata/pull/286