R语言 根据距离和边界条件创建随机点

e1xvtsh3  于 2023-02-17  发布在  其他
关注(0)|答案(3)|浏览(167)

在我的例子中,我有:

# 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")

现在,我想创建10个随机点,但条件是这些点必须位于ch边界内,并且与ch区域内的每个df.laea点的最小距离为10米。
拜托,能帮上忙吗?

amrnrhlw

amrnrhlw1#

我认为这里唯一棘手的事情是,一个简单的st_difference()的多边形和缓冲点将返回十个多边形,每个都删除了其中一个点。因此,您必须使用for循环或reduce()从多边形中逐个删除缓冲点。要使用reduce(),你必须把向量转换成一个sf的列表,而不是一个sfc向量,这就是我下面所做的。

# 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)

w9apscun

w9apscun2#

你可以按照你想要的距离缓冲这些点,然后将这些多边形与ch多边形相交,然后使用st_sample和相关的参数来得到你想要的点。
示例代码:

## buffer df.laea 10m
laea_buff <- st_buffer(df.laea, dist = 10000) #changed dist to 10km to make it noticable in plot

# area to sample from:
sample_area <- st_intersection(ch, laea_buff)

# sample above area, all within 10km of a point and inside the `ch` polygon
points <- st_sample(sample_area, size = 10)

#plotting:
ggplot() + 
  geom_sf(data = points, color = 'red') + 
  geom_sf(data = laea_buff, color = 'black', fill = NA) + 
  geom_sf(data = ch, color = 'black', fill = NA) + 
  geom_sf(data = sample_area, color = 'pink', fill = NA) + 
  geom_sf(data = df.laea, color = 'black', size = .5)

reprex package(v2.0.1)于2023年2月14日创建

ryevplcw

ryevplcw3#

作为对shs的回答的评论:可以首先对DF.LaEA对象使用X1 M0 N1 X调用,并将10个点合并为单个多点几何形状。
当缓冲时,这将作为必要的sf::st_difference()调用的输入,以形成带有孔的采样区域,从而消除对for cycle / map & reduce调用的需要。

# 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"
) 

# merge 10 points to 1 multipoing
mod_laea <- df.laea %>% 
  st_combine()

# sampling area = difference between hull and buffered points
sampling_area <- mod_laea %>% 
  st_convex_hull() %>% 
  st_difference(st_buffer(mod_laea, 10000))

# sample over sampling area 
sampled_points <- st_sample(sampling_area, 10)

# a visual overview
ggplot() + 
  geom_sf(data = sampling_area, fill = "white", color = "black") +
  geom_sf(data = df.laea, color = "black")  +
  geom_sf(data = sampled_points, color = "red", pch = 4)

相关问题