Search code examples
rrandomr-sfr-sp

Create random points based in distance and boundary conditions


In my example, I have:

# Packages
library(sf)
library(ggplot2)

# Create some points
set.seed(1)
df <- data.frame(
  gr = c(rep("a",5),rep("b",5)),
  x  = rnorm(10),
  y = rnorm(10)
)
df <- st_as_sf(df,coords = c("x","y"),remove = F, crs = 4326)
df.laea = st_transform(
  df,
  crs = "+proj=laea +x_0=4600000 +y_0=4600000 +lon_0=0.13 +lat_0=0.24 +datum=WGS84 +units=m"
)
# Create a countour of the area
ch <- st_convex_hull(st_union(df.laea))

ggplot() + 
  geom_sf(data = ch, fill = "white", color = "black") +
  geom_sf(data = df.laea,color = "black") 

areaExample

Now, I'd like to create 10 random points but the conditions are that this points must be inside the ch boundaries and a minimum distance of 10 meters of each df.laea points that exist inside this ch area.

Please, any help with it?


Solution

  • I think the only tricky thing here is that a simple st_difference() of your polygon and the buffered points will return ten polygons, each with one of the points removed. Thus you have to either use a for loop or reduce() to remove one buffered point after the other from the polygon. To use reduce() you have to transform the vector to a proper list of sf instead of an sfc vector. This is what I did below.

    # Packages
    library(sf)
    library(ggplot2)
    library(purrr)
    
    ch_minus <- df.laea$geometry |> 
      st_buffer(10000) |> 
      {\(vec) map(seq_along(vec), \(x) vec[x])}() |> # Transform buffered points to reducible list
      reduce(.init = ch, st_difference) 
    
    sampled_points <- st_sample(ch_minus, 10)
    
    ch_minus |> 
      ggplot() +
      geom_sf() + 
      geom_sf(data = sampled_points)