R语言 确定点A中的哪些点在其它点B的半径内

bkhjykvo  于 2023-05-04  发布在  其他
关注(0)|答案(2)|浏览(151)

我想使用sf来确定哪些people位于任何cities的5km范围内。在本例中,people 1和2应返回“Yes”。它们分别位于罗利和格林斯伯勒的5公里范围内。3不在这些城市的5公里范围内。
(This是一个突出真实的用例的玩具示例。)

library(tidyverse)
library(sf)

cities <- data.frame(city = c("Raleigh", "Greensboro", "Wilmington"),
                     x = c(-78.633333, -79.819444, -77.912222),
                     y = c(35.766667, 36.08, 34.223333)) %>% 
  st_as_sf(coords = c("x", "y"), crs = 4326) %>% 
  st_transform(2264) 

people <- data.frame(person = c(1:3),
                     x = c(-78.634899, -79.821140, -103.236804),
                     y = c(35.766266, 36.077911, 30.551109)) %>% 
  st_as_sf(coords = c("x", "y"), crs = 4326) %>% 
  st_transform(2264) 

# adapted toy example from
# https://community.rstudio.com/t/sf-function-that-can-find-all-available-polygones-to-a-point-within-a-certain-radius/114318/2

期望输出:

# A tibble: 3 × 2
  person insideRad
   <dbl> <chr>    
1      1 Yes      
2      2 Yes      
3      3 No

或者:

# A tibble: 9 × 3
  person city       insideRad
   <dbl> <chr>      <chr>    
1      1 Raleigh    Yes      
2      1 Greensboro No       
3      1 Wilmington No       
4      2 Raleigh    No       
5      2 Greensboro Yes      
6      2 Wilmington No       
7      3 Raleigh    No       
8      3 Greensboro No       
9      3 Wilmington No
ccgok5k5

ccgok5k51#

考虑这段代码;它的作用是:

  • 将所有城市合并为一个多点,丢弃数据
  • 在所述多点周围创建缓冲对象;链接的例子是有点舌头在脸颊,并使用CRS在调查英尺。度量crs(如3857)可能更合适。
  • 计算点对象是否包含在缓冲区中;注意sparse = F设置,否则会得到稀疏矩阵
  • 删除点几何图形并报告结果
any_city_neigborhood <- cities %>% 
  st_geometry() %>% # geometry only
  st_union() %>% # combine to 1 row
  st_buffer(15000) # too lazy to calculate 5 Km in a feety CRS properly

# calculate intersection with the buffer object
people$close <- st_contains(any_city_neigborhood, people, sparse = F) [1,]

# report results
st_drop_geometry(people)
#   person close
# 1      1  TRUE
# 2      2  TRUE
# 3      3 FALSE
x6h2sr28

x6h2sr282#

从OP中提供的玩具示例链接中获得灵感:

cities_buffer <- st_buffer(cities, 3280.84 * 5)

out1 <- people %>%
  mutate(insideRad = ifelse(sf::st_intersects(people, buffer, sparse = F),
                            "Yes", 
                            "No")) %>%
  st_drop_geometry() %>%
  as_tibble()

out2 <- as_tibble(out1$insideRad)

out3 <- bind_cols(people$person, out2)
  
colnames(out3) <- c("person", cities$city)

out4 <- out3 %>%
  rowwise() %>%
  mutate(insideRad = if(any(str_detect(c_across(where(is.character)), 'Yes'))) 
    'Yes' else 'No') %>%
  ungroup() %>%
  select(person, insideRad)

我不认为我的争吵是有效的,但它返回:

# A tibble: 3 × 2
  person insideRad
   <int> <chr>    
1      1 Yes      
2      2 Yes      
3      3 No

相关问题