在给定的空间范围内创建一个正多边形网格,并旋转一定角度。

15

大家好,

我在这个问题上感到困惑,希望有人能提出一个简单的解决方案。

我的目标是在多边形的范围内创建一个正多边形网格,但旋转一个用户定义的角度

我知道我可以轻松地使用sf创建南/北多边形网格,例如:

library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.2.3, proj.4 4.9.3
inpoly <- st_read(system.file("shape/nc.shp", package="sf"))[1,] %>% 
  sf::st_transform(3857) %>% 
  sf::st_geometry()
grd <- sf::st_make_grid(inpoly, cellsize = 3000)
plot(inpoly, col = "blue")
plot(grd, add = TRUE)

我也知道我可以通过给定的角度轻松地旋转它:

rotang = 20
rot = function(a) matrix(c(cos(a), sin(a), -sin(a), cos(a)), 2, 2)
grd_rot <- (grd - st_centroid(st_union(grd))) * rot(rotang * pi / 180) +
  st_centroid(st_union(grd))
plot(inpoly, col = "blue")
plot(grd_rot, add = TRUE)

我的问题是,根据旋转角度、输入多边形的一般“方向”和单元格大小,旋转后的网格可能不再完全覆盖多边形,如下所示:

rotang = 45
rot = function(a) matrix(c(cos(a), sin(a), -sin(a), cos(a)), 2, 2)
grd_rot <- (grd - st_centroid(st_union(grd))) * rot(rotang * pi / 180) +
  st_centroid(st_union(grd))
plot(inpoly, col = "blue")
plot(grd_rot, add = TRUE)

有没有什么聪明的想法可以解决这个问题并且创建一个旋转的网格完全覆盖多边形(除了通过创建一个更大的网格来开始,对于小单元格大小而言相当低效?)

无论是sf 还是 sp 的解决方案都将受到欢迎。“奖励分”如果可能的话,使网格从多边形的极端顶点之一开始(即,网格的第一行“触摸”多边形的北部顶点),但这不是“强制性”的。

reprex包(v0.2.0)于2018-07-11创建。


2
也许可以先对多边形进行(计数器)旋转,然后用网格覆盖它,再将其旋转以覆盖原始多边形? - Josh O'Brien
好主意!我会尝试一下。 - lbusett
很遗憾,@JoshO'Brien的建议对我没有起作用...仍然无法完全覆盖...还有其他人吗? - lbusett
1个回答

15

你没有具体说明@JoshO'Brien的建议为什么对你不起作用,但我怀疑你将多边形和网格围绕不同的旋转中心旋转。您没有在旋转原点上指定任何约束条件,因此在下面的代码片段中,我假设它不重要,但只要两个旋转使用相同的点,您可以使用任何点:

library(sf)
rotang = 45
rot = function(a) matrix(c(cos(a), sin(a), -sin(a), cos(a)), 2, 2)
tran = function(geo, ang, center) (geo - center) * rot(ang * pi / 180) + center
inpoly <- st_read(system.file("shape/nc.shp", package="sf"))[1,] %>% 
  sf::st_transform(3857) %>% 
  sf::st_geometry()
center <- st_centroid(st_union(inpoly))
grd <- sf::st_make_grid(tran(inpoly, -rotang, center), cellsize = 3000)
grd_rot <- tran(grd, rotang, center)
plot(inpoly, col = "blue")
plot(grd_rot, add = TRUE)

确实,你是对的!我之前使用旋转后的多边形重心来旋转网格,而不是使用“原始”多边形的重心。你的解决方案似乎完美地解决了这个问题。非常感谢! - lbusett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接