R语言:如何围绕经纬度点绘制半径缓冲区并筛选范围内的点
解决方法:用
sf包实现点缓冲区与点筛选 我来帮你搞定这个需求!现在处理空间数据最推荐用sf包,它比传统的sp工具链更直观,能轻松完成你要的「创建缓冲区+筛选点」操作。下面是一步步的具体实现:
步骤1:准备工作与数据预处理
首先,你需要加载sf包,同时注意把数据里的字符串类型经纬度转成数值(不然没法做空间计算),再转换成空间对象:
# 加载包 library(sf) # 商店数据集:先把lat/long转成数值类型 stores <- data.frame( store_id = 1:3, lat = as.numeric(c("40.7505","40.7502","40.6045")), long = as.numeric(c("-73.8456","-73.8453","-73.8012")) ) # 我的位置:同样转成数值 me <- data.frame( lat = as.numeric("40.7504"), long = as.numeric("-73.8456") ) # 转换成sf空间对象,设置坐标系为WGS84(EPSG:4326,全球通用的经纬度坐标系) stores_sf <- st_as_sf(stores, coords = c("long", "lat"), crs = 4326) me_sf <- st_as_sf(me, coords = c("long", "lat"), crs = 4326)
步骤2:创建100米半径缓冲区
这里要注意:WGS84坐标系的单位是度,不能直接用米来创建缓冲区,必须先转换成以米为单位的投影坐标系(比如UTM投影)。你的坐标在纽约,对应的UTM带是18N,EPSG代码是32618:
# 转换到UTM投影(米为单位) me_utm <- st_transform(me_sf, crs = 32618) stores_utm <- st_transform(stores_sf, crs = 32618) # 创建100米半径的缓冲区 buffer_utm <- st_buffer(me_utm, dist = 100) # 可选:如果需要转回WGS84坐标系(方便查看经纬度) buffer_wgs84 <- st_transform(buffer_utm, crs = 4326)
步骤3:筛选落在缓冲区内的商店点
用sf的st_within函数可以直接判断哪些商店点在缓冲区内,结果是一个逻辑向量,我们可以用它来筛选数据:
# 判断每个商店点是否在缓冲区内(返回逻辑向量) in_buffer <- st_within(stores_utm, buffer_utm, sparse = FALSE)[,1] # 筛选出落在缓冲区内的商店 stores_in_buffer <- stores_sf[in_buffer, ] # 查看结果 print(stores_in_buffer)
运行后你会看到,store_id为1和2的点会被筛选出来,它们离你的位置都在100米以内,而store_id3离得远会被排除。
如果你习惯用over函数(基于sp包)
如果你更熟悉sp包的over函数,也可以这么实现:
library(sp) library(rgeos) # 转换成SpatialPoints对象 stores_sp <- SpatialPointsDataFrame( coords = stores[, c("long", "lat")], data = stores, proj4string = CRS("+init=epsg:4326") ) me_sp <- SpatialPoints( coords = me[, c("long", "lat")], proj4string = CRS("+init=epsg:4326") ) # 转成UTM投影 me_sp_utm <- spTransform(me_sp, CRS("+init=epsg:32618")) stores_sp_utm <- spTransform(stores_sp, CRS("+init=epsg:32618")) # 创建缓冲区 buffer_sp_utm <- gBuffer(me_sp_utm, width = 100) # 用over函数筛选 stores_in_buffer_sp <- stores_sp[!is.na(over(stores_sp_utm, buffer_sp_utm)), ]
不过还是更推荐sf包,它的语法更贴近tidyverse,代码可读性更高,也是当前空间数据处理的主流工具。
内容的提问来源于stack exchange,提问作者LoF10
相关产品推荐
相关产品推荐

