使用 R 查找哪些点位于缓冲区内?

Finding which points lie within buffered area using R?

我正在尝试设置一个脚本来查找轨迹上的点是否在多边形的特定距离内。对于上下文,我使用了两个数据集:第一个是 HYSPLIT 模型的结果,显示了空气轨迹以及该空气包裹在特定时间的预计位置。第二个是县内邮政编码质心的数据框。

我的目标是了解某个点是否穿过邮政编码质心的缓冲区,如果是,它是哪个邮政编码以及发生在什么时间点?


traj <- data.frame(
    hour = c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23),
    lat = c(33.176, 33.236, 33.304, 33.397, 33.536, 33.693, 33.850, 34.011,
            34.181, 34.382, 34.612, 34.825, 35.025, 35.210, 35.382, 35.511, 
            35.558, 35.640, 35.715, 35.795, 35.845, 35.885, 35.918, 35.927),
    lon = c(-115.623, -115.488, -115.322, -115.132, -114.938, -114.787, -114.699, 
            -114.640, -114.561, -114.472, -114.399,-114.324, -114.207, -114.050, 
            -113.794, -113.280, -112.605, -111.907, -111.230, -110.708, -110.036, 
            -109.314, -108.520, -107.810),
    date = c(2012-03-01 00:00:00, 2012-03-01 01:00:00, 2012-03-01 02:00:00, 2012-03-01 03:00:00, 
             2012-03-01 04:00:00, 2012-03-01 05:00:00, 2012-03-01 06:00:00, 2012-03-01 07:00:00, 
             2012-03-01 08:00:00, 2012-03-01 09:00:00, 2012-03-01 10:00:00, 2012-03-01 11:00:00, 
             2012-03-01 12:00:00, 2012-03-01 13:00:00, 2012-03-01 14:00:00, 2012-03-01 15:00:00, 
             2012-03-01 16:00:00, 2012-03-01 17:00:00, 2012-03-01 18:00:00, 2012-03-01 19:00:00,
             2012-03-01 20:00:00, 2012-03-01 21:00:00)
)

#Convert hysplit data frame to an sf object
traj.sf <- st_as_sf(traj, coords = c("lon", "lat"), crs=4326)
traj.sf
plot(traj.sf$geometry)


#Create the same dataframe for median pop centroids

medpop <- data.frame(
  longitude = c(-116.305303, -115.524899, -115.497389, -115.514936, 
                -115.566751, -115.505786, -115.361211, -115.575202, 
                -115.535597, -115.993063, -114.73435, -115.692165, 
                -116.040401, -115.956263, -115.621221, -114.628562), 
  latitude = c(33.211896, 32.980541, 32.680197, 33.127061, 
               32.784691, 32.729742, 32.807613, 32.848569, 
               33.280736, 32.734248, 33.372017, 32.795324, 
               33.409293, 33.289944, 33.039245, 32.77435), 

  Name = c("92004", "92227", "92231", "92233", "92243", "92249", "92250", "92251", 
           "92257", "92259", "92266", "92273", "92274", "92275", "92281", "92283"))
medpop

#convert the population centroid points data frame to an sf object
centroids <- st_as_sf(medpop, coords = c("longitude", "latitude"), crs=4326)
centroids

#Buffer the points
buffers <- st_buffer(centroids, dist = 0.2)

#Finding points within centroid buffers
over <- st_intersects(buffers, traj.sf)

我尝试使用 sf 包中的 st_intersects。我 运行 遇到的问题是 R 似乎返回了一个对象列表,但我实际上需要知道相交发生的时间以及该点实际接近哪个邮政编码。

我是 R 作为 GIS 的新手,非常感谢您的帮助!

使用函数 st_intersection 而不是 st_intersects 可以解决这个问题。这个 returns 一个数据框而不是一个列表:

over <- st_intersection(bufers, traj.sf) 
### the polygon, followed by the points that might cross the polygon

````

您走在正确的轨道上,关闭...

您将需要使用 sf::st_intersectssparse = F 设置来取回一个向量,然后使用它来对您的 centroids 数据框进行子集化。

我正在绘制结果,我希望红点(与轨迹相交的缓冲区的质心)是您想要的...

library(sf)
library(ggplot2)

traj <- data.frame(
  hour = c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23),
  lat = c(33.176, 33.236, 33.304, 33.397, 33.536, 33.693, 33.850, 34.011,
          34.181, 34.382, 34.612, 34.825, 35.025, 35.210, 35.382, 35.511, 
          35.558, 35.640, 35.715, 35.795, 35.845, 35.885, 35.918, 35.927),
  lon = c(-115.623, -115.488, -115.322, -115.132, -114.938, -114.787, -114.699, 
          -114.640, -114.561, -114.472, -114.399,-114.324, -114.207, -114.050, 
          -113.794, -113.280, -112.605, -111.907, -111.230, -110.708, -110.036, 
          -109.314, -108.520, -107.810))

#Convert hysplit data frame to an sf object
traj.sf <- st_as_sf(traj, coords = c("lon", "lat"), crs=4326)


#Create the same dataframe for median pop centroids

medpop <- data.frame(
  longitude = c(-116.305303, -115.524899, -115.497389, -115.514936, 
                -115.566751, -115.505786, -115.361211, -115.575202, 
                -115.535597, -115.993063, -114.73435, -115.692165, 
                -116.040401, -115.956263, -115.621221, -114.628562), 
  latitude = c(33.211896, 32.980541, 32.680197, 33.127061, 
               32.784691, 32.729742, 32.807613, 32.848569, 
               33.280736, 32.734248, 33.372017, 32.795324, 
               33.409293, 33.289944, 33.039245, 32.77435), 

  Name = c("92004", "92227", "92231", "92233", "92243", "92249", "92250", "92251", 
           "92257", "92259", "92266", "92273", "92274", "92275", "92281", "92283"))
#convert the population centroid points data frame to an sf object
centroids <- st_as_sf(medpop, coords = c("longitude", "latitude"), crs=4326)

#Buffer the points
buffers <- st_buffer(centroids, dist = .2)

#Finding points within centroid buffers
over <- centroids[st_intersects(buffers, traj.sf, sparse = F)[,1], ]
over

ggplot() +
  geom_sf(data = over, col = "red") +
  geom_sf(data = traj.sf, pch = 4, col = "gray40") +
  geom_sf(data = buffers, fill = NA) +
  theme_minimal()