r - 使用 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)
结果图:[
解决方案
它似乎与某些特征的几何形状有关。
这有效:
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
作者去除底层几何对象的暗名以阻止这种情况发生。但我不确定这是否会破坏现有代码。
可能值得一个问题报告给osmdata
和sf
- 它不是一个tmap
错误。对于临时修复,这个st_buffer
技巧似乎有效,或者递归地将对象相关位上的所有行名设置为 NULL,或者可能是其他东西......
推荐阅读
- php - 对多维数组进行多级排序
- java - 目标 org.codehaus.mojo:exec-maven-plugin:1.6.0:java 的参数“mainClass”丢失或无效
- python - 使用查询集搜索后 Django 重定向
- ios - 从firebase存储返回的url是nil Swift4
- sql - 特殊情况下如何计算就业经验
- python - 提高 python django models.py 查询的性能
- sql - 我怎样才能重复这个查询 100 次?
- java - 在未设置 CascadeType.REMOVE 时,Hibernate 在多对多关系中生成附加查询
- jquery - 如何同时对齐多个父 div 中的子 div?
- haskell - 与哈希表模式相结合的双向链表的 Haskell 替代方案