0

I am trying to build a map of a federate state in germany with special borders (voting districts):

install.packages("OpenStreetMap")
install.packages("sf")
install.packages("osmdata")
install.packages("tmap")

library(OpenStreetMap)
library(sf)
library(osmdata)
library(tmap)


## I use this because the other overpass server didnt work that well    
set_overpass_url("https://overpass-api.de/api/interpreter")

##open the map of "baden-württemberg" and get the right boundaries, timeout is increased because the map is big and it sometimes timed out

boundaries <- opq(bbox = getbb("baden-württemberg"), timeout = 900) %>%
      add_osm_feature(key = 'admin_level', value = '6') %>%
      add_osm_feature(key = "boundary", value = "administrative") %>%
      osmdata_sf() %>% unique_osmdata()
    
    qtm(boundaries$osm_multipolygons)

I get

Error in do.call(rbind, x) : variable names are limited to 10000 bytes

It should approxamitly look something like this:

boundaries <- opq(bbox = 'Brussels, Belgium') %>%
  add_osm_feature(key = 'admin_level', value = '8') %>% 
  osmdata_sf %>% unique_osmdata

municipalities <- boundaries$osm_multipolygons

qtm(municipalities)

with the resulting plot: [Belgium Plot1

BanffBoss122
  • 149
  • 9
  • Always include at least `library` call for non-core packages. Better yet would be to include a conditional that would install package(s) when it(they) are rather thinly used and then load the package. – IRTFM May 13 '21 at 20:29
  • Thanks for the advice, I added the install.packages() and library() calls! – BanffBoss122 May 14 '21 at 07:53

1 Answers1

1

It appears to be related to the geometry of some features.

This works:

qtm(boundaries$osm_multipolygons$geometry[c(1,3,5,6,7,8,9)])

enter image description here

but including features 2 or 4 causes the failure. Note by plotting the geometry I've excluded the possibility of it being a problem with the attributes. They are out of the picture.

I can't immediately see anything wrong with feature 2 and 4's geometries. They both pass the st_is_valid test, unlike feature 3 which fails (but will qtm okay):

> st_is_valid(boundaries$osm_multipolygons$geometry[1:4])
[1]  TRUE  TRUE FALSE  TRUE

so that's weird.

The trick of fixing bad geometries by zero-buffering gets us past the error to a full plot:

> qtm(st_buffer(boundaries$osm_multipolygons,0))
dist is assumed to be in decimal degrees (arc_degrees).
Warning message:
In st_buffer.sfc(st_geometry(x), dist, nQuadSegs, endCapStyle = endCapStyle,  :
  st_buffer does not correctly buffer longitude/latitude data

enter image description here

(but I'm not sure if the holes seen here are errors).

Boiling this down further thanks to the error traceback() it occurs in st_as_grob which evokes this method:

> g = sf:::st_as_grob.sfc_MULTIPOLYGON(boundaries$osm_multipolygons$geometry[1])
> g = sf:::st_as_grob.sfc_MULTIPOLYGON(boundaries$osm_multipolygons$geometry[2])
Error in do.call(rbind, x) : variable names are limited to 10000 bytes

Debugging that method, the code does a recursive unlist which results in an object with a very long name for any feature. Features 2 and 4 (and others) take it over the 10000 char limit, it seems. When it tries to rbind everything, the names are too long.

The buffer trick works because it returns an object with no rownames on the geometry, so the constructed name before the rbind is NULL. Which is fine, these names serve no real purpose here.

The name looks like its the OSM ID of each vertex. The fix would be either for the opq maintainers to not attach the OSM ID to each vertex (which is bloating the size of the resulting R objects as well) or for the sf authors to strip dimnames of underlying geometry objects to stop this happening. But I'm not sure if that will break existing code.

Possibly worth an issue report to osmdata and sf - its not a tmap bug. For a temporary fix, the st_buffer trick seems to work, or recursively set all rownames on the relevant bits of the object to NULL, or maybe something else...

Spacedman
  • 92,590
  • 12
  • 140
  • 224
  • Filed as an issue here https://github.com/r-spatial/sf/issues/1678 – Spacedman May 15 '21 at 08:02
  • Thank you so much for your lengthy answer. I only understand 10% of what you wrote, but after your post (and some further research) I could identify that the problem was not on my side. It is a problem with osmdata that is fixed (with the current developement version). with the call unname_osmdata_sf() the problem is solved and qtm() is working (I will add that as an answer to my own question, if nodody posts another solution). The current cran vignette is fairly new 2021-03-22 but I dont think unname_osmdata_sf() is in that version. – BanffBoss122 May 15 '21 at 14:46
  • Ultimate cause is R itself, but with very clear error message here - if rownames were allowed to be > 10,000 bytes, there'd be no problem, but they aren't. In the meantime, the "official" solution is as @BanffBoss122 says, just to pipe final result through `unname_osmdata_sf()`. – mpadge May 17 '21 at 07:39