如果我在R中有一个spatialpolygons对象,我该如何生成一组位于该多边形边缘的n个点?
我原本以为我可以从多边形顶点进行采样,但看起来有时会出现没有顶点的延伸,因为多边形边是一条直线......
答案 0 :(得分:1)
假设你想在周边画点,我会把它分成两部分:
P(边e上的点p)= P(点p |边e)P(边e)
P(边e)与其长度成正比。因此,首先对边缘进行采样,然后对点进行采样 在它上面。
这是一个示例三角形:
poly <- Polygon(list(x=c(1,2,3,1),y=c(1,2,1,1)))
我们将计算边长:
require(gsl) #for fast hypot function
xy <- poly@coords
dxy <- diff(xy)
h <- hypot(dxy[,"x"], dxy[,"y"])
并绘制一个随机的一面:
e <- sample(nrow(dxy), 1, probs=h)
然后在那边画一个点:
u <- runif(1)
p <- xy[e,] + u * dxy[e,]
将整个事物包装在一个函数中,我们有:
rPointOnPerimeter <- function(n, poly) {
xy <- poly@coords
dxy <- diff(xy)
h <- hypot(dxy[,"x"], dxy[,"y"])
e <- sample(nrow(dxy), n,replace=TRUE, prob=h)
u <- runif(n)
p <- xy[e,] + u * dxy[e,]
p
}
带演示:
plot( rPointOnPerimeter(100,poly) )
答案 1 :(得分:0)
一种简单的解决方案是使用软件包st_segmentize()
中的sf
,该软件包将点添加到直线上,然后沿这些更细的点进行采样。
st_segmentize()
具有参数dfMaxLength
,该参数定义了沿一条线允许的最大距离。您设置的越小,积分就越多。它至少应与任意两点之间的最小距离一样小。
library(sf)
library(tidyverse)
## original form
poly <- st_polygon(x=list(cbind(x=c(1,2,3,1),y=c(1,2,1,1))))
# segmentize, then convert to points
poly_points <- st_segmentize(poly, dfMaxLength = 0.1) %>%
st_coordinates() %>%
as.data.frame() %>%
select(X, Y) %>%
st_as_sf(coords = c("X", "Y"))
## plot: you can just use sample() now on your point dataset
plot(poly, reset = FALSE, main = "segmentize (black point), then sample 5 (red points)")
plot(poly_points, reset = FALSE, add = TRUE)
plot(poly_points[sample(1:nrow(poly_points), size = 5),], add = TRUE, col = 2, pch = 19)
要获取任意两点之间的最小距离(请注意零):
poly %>%
st_coordinates() %>%
as.data.frame() %>%
st_as_sf(coords = c("X", "Y")) %>%
st_distance() %>% c() %>%
unique() %>%
sort