R中多边形边上的采样点

时间:2014-06-30 17:59:24

标签: r gis polygons

如果我在R中有一个spatialpolygons对象,我该如何生成一组位于该多边形边缘的n个点?

我原本以为我可以从多边形顶点进行采样,但看起来有时会出现没有顶点的延伸,因为多边形边是一条直线......

2 个答案:

答案 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)

enter image description here

要获取任意两点之间的最小距离(请注意零):

 poly %>% 
  st_coordinates() %>% 
  as.data.frame() %>% 
  st_as_sf(coords = c("X", "Y")) %>% 
  st_distance() %>%  c() %>% 
  unique() %>% 
  sort