如何修正R代码以准确移除预定义多边形外的空间点?
问题解决:正确筛选多边形内的空间点
问题原因
代码出现误删/漏删的核心问题是多边形顶点顺序错误,导致生成的多边形存在自交叉,不是一个简单的闭合区域,空间判断逻辑因此混乱。其次,空间点的归属判断可以用更简洁准确的方式实现。
修改步骤
- 修正多边形顶点顺序:按顺时针或逆时针连续排列顶点,确保多边形无交叉、闭合。
- 用
st_within简化点归属判断:直接返回每个点是否在多边形内的逻辑向量,无需额外apply操作。 - 简化空间点创建流程:直接从数据框生成sf格式点对象,无需先转
SpatialPoints。
完整修正代码
library(tidyverse) library(openxlsx) library(sf) library(rnaturalearth) # 下载数据 zooWide <- read.xlsx("https://dassh.ac.uk/downloads/mba_rdm/NWAtl_CPR%20data.xlsx", cols = c(1:6, 8:20)) %>% rename(YEAR = Year) # 直接创建sf格式空间点 sp <- st_as_sf(zooWide, coords = c("Longitude", "Latitude"), crs = "+proj=longlat +datum=WGS84") # 修正顶点顺序,生成无交叉的闭合多边形 poly_coords <- data.frame( lon = c(-6, -50, -64, -54, -6), lat = c(45, 66, 70, 51, 45) ) poly <- st_polygon(list(as.matrix(poly_coords))) %>% st_sfc(crs = "+proj=longlat +datum=WGS84") # 判断点是否在多边形内 samples <- st_within(sp, poly, sparse = FALSE)[,1] # 筛选数据 zooRetained <- filter(zooWide, samples) zooRemoved <- filter(zooWide, !samples) # 绘制地图 world <- ne_countries(scale = "medium", returnclass = "sf") ggplot() + geom_point(data = zooRemoved, aes(x = Longitude, y = Latitude), alpha = 0.1, col = "red") + geom_point(data = zooRetained, aes(x = Longitude, y = Latitude), alpha = 0.1) + geom_sf(data = poly, col = "navy", fill = "transparent", linewidth = 2) + geom_sf(data = world, colour = NA, fill = "grey75") + scale_y_continuous(labels = ~.x, limits = c(43, 72), breaks = seq(45, 70, 5)) + scale_x_continuous(labels = ~.x, limits = c(-68, -2), breaks = seq(-70, 0, 10)) + labs(x = NULL, y = NULL)
关键说明
- 多边形顶点规则:必须保证顶点按连续方向排列,不能出现交叉路径,否则sf无法正确识别多边形内部区域。
st_within的优势:严格判断点是否在多边形内部(不含边界),如果需要包含边界,可替换为st_intersects。- 简化空间对象创建:直接用
st_as_sf指定坐标列,比先转SpatialPoints再转sf更高效。
内容的提问来源于stack exchange,提问作者tnt
相关产品推荐
相关产品推荐

