根据固定距离缩小sf多边形

4
我是一个有用的助手,可以为您进行文本翻译。

我正在尝试通过固定距离来缩小一个sf多边形。

以这个简单的多边形为例:

coords <- list(rbind(c(0,0), c(2,0), c(2,2), c(1,2), c(1,1), c(0,1), c(0,0)))
p <- sf::st_polygon(x = coords)
ggplot() + geom_sf(data = p,  fill = "white", color = "black")

enter image description here

我想制作一个与原多边形形状相同的多边形,但是所有边缘都与原多边形相比确切地偏移0.1个单位。这是目标:

target.coords <- list(rbind(c(0.1,0.1), c(1.9,0.1), c(1.9,1.9), c(1.1,1.9), c(1.1,0.9), c(0.1,0.9), c(0.1,0.1)))
target <- sf::st_polygon(x = target.coords)
ggplot() + 
  geom_sf(data = p,  fill = "white", color = "black") +
  geom_sf(data = target,  fill = "green", color = "dark green")

enter image description here

我以为sf::st_buffer()可以帮我实现,但外角并不完全匹配。
p1 <- sf::st_buffer(x = p, dist = -0.1)
ggplot() +
  geom_sf(data = p,  fill = "white", color = "black") + 
  geom_sf(data = p1, fill = "red",   color = "dark red")

enter image description here

是否有替代设置sf::st_buffer()的方法,可以让我实现目标多边形?或者是否有其他函数可以实现这一点?偏移量需要是固定距离,而不是相对缩小多边形(例如90%)。


1
你可以进行仿射变换,同时保持精确的形状(即你明确排除的90%缩小)。但是,在我看来,红色内部多边形的行为符合预期:外角周围的圆曲线描述了所有距离原始点1/10个单位距离的点。你绿色多边形的内角实际上比那个远1 sqrt(2)... - Jindra Lacko
@JindraLacko 我也注意到了这个角落,不过我很好奇为什么凸出的角是正方形(因此与白色角落的距离为sqrt(2)),而凹进去的角却不是。 - camille
这并不是特定于R的,但之前的帖子总体上看到了这种类型的算法,可能会有所帮助 https://dev59.com/iXNA5IYBdhLWcg3wC5Xh - camille
@Camille,凸点在负缓冲区内很容易处理;有两个方向可以测量距离,所以没有问题。它们会在正缓冲区情况下带来麻烦/而凹点则非常容易。所以你得权衡选择,但你不能两全其美 :) - Jindra Lacko
1个回答

7

如果问题只与那个角落有关,我认为您可以使用参数 joinStylemitreLimit 更改 st_buffer 的默认行为。例如:

# packages
library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(ggplot2)

# data
coords <- list(rbind(c(0,0), c(2,0), c(2,2), c(1,2), c(1,1), c(0,1), c(0,0)))
p <- sf::st_polygon(x = coords)
p1 <- st_buffer(x = p, dist = -0.1, joinStyle  = "MITRE", mitreLimit = 2)

# plot
ggplot() +
  geom_sf(data = p,  fill = "white", color = "black") + 
  geom_sf(data = p1, fill = "red",   color = "dark red")

# Check 
target.coords <- list(rbind(c(0.1,0.1), c(1.9,0.1), c(1.9,1.9), c(1.1,1.9), c(1.1,0.9), c(0.1,0.9), c(0.1,0.1)))
(target <- sf::st_polygon(x = target.coords))
#> POLYGON ((0.1 0.1, 1.9 0.1, 1.9 1.9, 1.1 1.9, 1.1 0.9, 0.1 0.9, 0.1 0.1))
st_equals(p1, target)
#> Sparse geometry binary predicate list of length 1, where the predicate was `equals'
#>  1: 1

此文档由Reprex包(v2.0.0)于2021-06-17创建。

更多有关使用st_buffer()的示例,请参见此处


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