首页 > 解决方案 > 使用 qtm() 和 openstreetmaps 在 do.call(rbind, x) 中出错

问题描述

我正在尝试在具有特殊边界(投票区)的德国建立一个联邦国家的地图:

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)

我明白了

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

它应该大致如下所示:

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

municipalities <- boundaries$osm_multipolygons

qtm(municipalities)

结果图:[比利时情节1

标签: ropenstreetmaptmap

解决方案


它似乎与某些特征的几何形状有关。

这有效:

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

在此处输入图像描述

但包含功能 2 或 4 会导致失败。请注意,通过绘制几何图形,我排除了它是属性问题的可能性。他们不在画面中。

我看不出特征 2 和 4 的几何形状有什么问题。他们都通过了st_is_valid测试,不像功能 3 失败(但会qtm好的):

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

所以这很奇怪。

通过零缓冲修复不良几何形状的技巧使我们能够克服错误,获得完整的情节:

> 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

在此处输入图像描述

(但我不确定这里看到的孔是否是错误的)。

由于引发此方法的错误 traceback(),进一步简化st_as_grob了这一点:

> 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

调试该方法时,代码会执行递归unlist,这会导致对象的任何功能都具有很长的名称。功能 2 和 4(以及其他)似乎超过了 10000 个字符的限制。当它尝试rbind一切时,名称太长了。

缓冲区技巧之所以有效,是因为它返回一个在几何上没有rbind行名的对象,因此在 之前构造的名称为 NULL。这很好,这些名称在这里没有真正的用途。

该名称看起来像是每个顶点的 OSM ID。解决方法是让opq维护者不将 OSM ID 附加到每个顶点(这也会增加生成的 R 对象的大小),或者让sf作者去除底层几何对象的暗名以阻止这种情况发生。但我不确定这是否会破坏现有代码。

可能值得一个问题报告给osmdatasf- 它不是一个tmap错误。对于临时修复,这个st_buffer技巧似乎有效,或者递归地将对象相关位上的所有行名设置为 NULL,或者可能是其他东西......


推荐阅读