基于tidyverse判断点是否落入重叠多边形的简易方法
解决方法
我们可以用sf结合tidyverse工具来实现需求,核心思路是先判断每个点是否在多边形A、B内,再根据两个条件的组合生成分类标记:
- 将原始点数据转换为
sf点对象,和多边形统一空间类型 - 分别判断每个点是否在A、B内部
- 根据两个判断结果的组合,标记点的归属
完整代码
library(tidyverse) library(sf) # 点子集 pts <- structure(list(Longitude = c(-26.775, -27.3167, -30.2717, -30.7267, -37.8683, -38.2733, -44.3033, -44.8233, -57.42, -57.8717, -52.235, -52.54, -54.2317, -54.6883, -63.6033, -65.415, -66.31, -66.7533), Latitude = c(62.5183, 62.3, 60.8367, 60.59, 56.6383, 56.3917, 52.8, 52.45, 45.56, 45.46, 47.3917, 47.1317, 46.26, 46.16, 44.29, 43.2633, 43.0983, 43.0267)), row.names = c(NA, -18L), class = c("tbl_df", "tbl", "data.frame")) # 多边形A和B pA <- st_polygon(list(as.matrix(data.frame(lon = c(-40, -40, -64, -64, -54, -54, -40), lat = c(45, 61, 61, 51, 51, 45, 45))))) %>% st_sfc(crs = st_crs("+proj=longlat +datum=WGS84")) pB <- st_polygon(list(as.matrix(data.frame(lon = c(-6, -6, -50, -50, -64, -64, -54, -54, -6), lat = c(45, 66, 66, 70, 70, 51, 51, 45, 45))))) %>% st_sfc(crs = st_crs("+proj=longlat +datum=WGS84")) # 处理逻辑:转换点为sf对象,判断归属 result <- pts %>% # 转换为sf点对象,指定经纬度列和坐标系(WGS84对应EPSG:4326) st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326) %>% # 判断每个点是否在A、B内部 mutate( in_A = st_within(geometry, pA) %>% map_lgl(~length(.x) > 0), in_B = st_within(geometry, pB) %>% map_lgl(~length(.x) > 0) ) %>% # 根据条件生成标记 mutate( polygon_group = case_when( in_A ~ "A", in_B & !in_A ~ "B", TRUE ~ NA_character_ ) ) %>% # 可选:移除中间判断列(如果不需要保留) select(-in_A, -in_B) # 查看结果 print(result)
代码说明
st_as_sf:将普通数据框转换为空间点对象,确保和多边形使用相同的坐标系(WGS84)st_within:判断点是否在多边形内部,返回的是列表,用map_lgl转换为逻辑向量(存在交集则为TRUE)case_when:按优先级判断:- 只要在A内就标记"A"(因为A被B完全覆盖,所以在A内的点一定也在B内)
- 不在A但在B内的点标记"B"
- 其余情况标记NA
内容的提问来源于stack exchange,提问作者tnt
相关产品推荐
相关产品推荐

