我想制作网格(在 x 和 y 坐标的 Dataframe 的意义上)在美国或美国的地区,抛出原始网格中超出美国边界的任何点。我有一些代码,似乎可以工作,但当我将网格增量缩小到1 km时,它非常慢(1e3
)左右。如何才能更快地完成这件事?也许有一种方法可以构建我需要的简单功能集合,而不需要lapply
或循环,或者也许这可以用MULTIPOINT
来完成,而不是POINT
s的简单功能集合。
library(sf)
crs.us.atlas = 2163 # https://epsg.io/2163
us = read_sf(paste0("/vsizip/",
"/tmp/us.zip")) # from: https://www2.census.gov/geo/tiger/GENZ2019/shp/cb_2019_us_state_500k.zip
# Filter down to the lower 48 + DC.
us = us[us$STUSPS %in% setdiff(c(state.abb, "DC"), c("AK", "HI")),]
us = st_transform(us, crs = crs.us.atlas)
l = as.list(st_bbox(us))
increment = 1e5
g = expand.grid(
x = seq(l$xmin, l$xmax, by = increment),
y = seq(l$ymin, l$ymax, by = increment))
message("Running the slow part")
print(system.time(g <- g[0 < sapply(FUN = length, st_intersects(
st_as_sfc(crs = crs.us.atlas, lapply(1 : nrow(g), function(i)
st_point(as.numeric(g[i, c("x", "y")])))),
us)),]))
print(nrow(g))
字符串
3条答案
按热度按时间ru9i0ody1#
我会解决这个问题如下。首先,加载包。
tmap
只用于Map,你可以很容易地忽略它字符串
下载和读入数据
型
过滤到较低的48 + DC。
型
定义增量、网格和
sfc
对象,关键是创建sfc_point
对象,为后续操作做准备型
查找美国境内包含的点的ID
型
可视化结果
型
x1c 0d1x的数据
重复1 e3(但我不会添加任何情节,因为这几乎是1300万点)
型
生成数据大约需要20秒
80秒内找到美国境内各点的身份证
创建于2021-01-13由reprex package(v0.3.0)
如果你需要更高效的东西,我建议你
polyclip
。b5lpy0ml2#
或者,您可以使用
fasterize
包以所需的分辨率围绕形状文件创建光栅网格,然后使用raster::rasterToPoints
函数提取网格坐标。这几乎可以立即收集xy位置。转换回sf对象需要大约10秒左右。
字符串
的数据
fykwrbwg3#
sf
有一个函数st_make_grid
可以帮助解决这个问题(在旧版本的sf
中,它甚至会自动裁剪到多边形),但奇怪的是,在撰写本文时它是quite slow。我可以通过使用
st_as_sf
将g
转换为简单的点特征集合来获得合理的性能,而无需额外的依赖性:字符串
然后,在@agila使用
unlist
之后,慢的部分变成了型
在
increment = 1e3
的情况下,在高端服务器上需要3分钟。