如何指定 sf::st_sample 中点之间的最小距离?

How to specify a minimum distance between points in sf::st_sample?

有没有办法为 type = 随机或常规指定 sf::st_sample 中点之间的最小距离?

library(sf)

#Data download

download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.dbf", 
              destfile = "SP_3543907_USO.dbf", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.prj", 
              destfile = "SP_3543907_USO.prj", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.shp", 
              destfile = "SP_3543907_USO.shp", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.shx", 
              destfile = "SP_3543907_USO.shx", mode = "wb")

#Data import

uso <- sf::st_read("SP_3543907_USO.shp") # pode demorar
uso

#Data plot

plot(uso$geometry)

#Random points

pts <- st_sample(uso, size = 20, type="random")
pts <- st_sf(pts)

虽然在对随机点进行采样时无法指定最小距离(我们怎么可能?它会使它们有序,即不是随机的),但可以在之后修剪随机点列表,强制执行最小距离.

关于这个工作流程的具体示例,建立在我之前关于这个主题的博客 post 上 - https://www.jla-data.net/eng/creating-and-pruning-random-points-and-polygons/

library(sf)

#Data download

download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.dbf", 
              destfile = "SP_3543907_USO.dbf", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.prj", 
              destfile = "SP_3543907_USO.prj", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.shp", 
              destfile = "SP_3543907_USO.shp", mode = "wb")
download.file(url = "http://geo.fbds.org.br/SP/RIO_CLARO/USO/SP_3543907_USO.shx", 
              destfile = "SP_3543907_USO.shx", mode = "wb")

#Data import

uso <- sf::st_read("SP_3543907_USO.shp") # pode demorar
uso

#Data plot

plot(uso$geometry)

#Random points

pts <- st_sample(uso, size = 20, type="random")
pts <- st_sf(pts)

original <- pts # for comparison later :)


i <- 1 # iterator start

buffer_size <- 5000 # minimal distance to be enforced (in units of your CRS)

repeat( {
  #  create buffer around i-th point
  buffer <- st_buffer(pts[i,], buffer_size ) 
  
  offending <- pts %>%  # start with the intersection of master points... 
    st_intersects(buffer, sparse = F) # ... and the buffer, as a vector
  
  # i-th point is not really offending - it is the origin (not to be excluded)
  offending[i] <- FALSE
  
  # if there are any offending points left - re-assign the master points, 
  # with the offending ones excluded / this is the main pruning part :)
  pts <- pts[!offending,] 
  
  if ( i >= nrow(pts)) {
    # the end was reached; no more points to process
    break 
  } else {
    # rinse & repeat
    i <- i + 1 
  }
  
} )


plot(original, pch = 4, col = "grey25") # result of the st_sample()
plot(pts, pch = 4, col = "red", add = T) # pruned points