【发布时间】:2014-08-21 04:18:57
【问题描述】:
如果我在 R 中有一个 spatialpolygons 对象,我如何生成一组位于该多边形边缘的 n 个点?
我原本以为我可以只从多边形顶点中采样,但看起来有时会出现没有顶点的拉伸,因为多边形边缘是一条直线......
【问题讨论】:
如果我在 R 中有一个 spatialpolygons 对象,我如何生成一组位于该多边形边缘的 n 个点?
我原本以为我可以只从多边形顶点中采样,但看起来有时会出现没有顶点的拉伸,因为多边形边缘是一条直线......
【问题讨论】:
一个简单的解决方案是使用包sf 中的st_segmentize(),将点添加到直线,然后沿着这些更精细的点进行采样。
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
【讨论】:
假设您想在周边绘制点,我会将其分为两部分:
P(点 p 在边 e) = P(点 p | 边 e) P(边 e)
其中 P(Edge 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) )
【讨论】: