使用 SF 连接点和线

Joining points and lines using SF

我正在做一个关于北卡罗来纳州自行车与机动车相撞的项目。我最初的目标是能够确定哪些街道(和十字路口)最容易发生事故。

使用 2D 核密度估计器,我设法确定了该州最容易发生事故的县是梅克伦堡县。现在我正试图进一步缩小到个别街道。这是我需要您的帮助和建议的地方!

我的问题是:如何将点数据与线连接起来?

我有两个要加入的数据集:

  1. 自行车碰撞坐标:
# Read in data from link
bike_crash <- read_csv("https://raw.githubusercontent.com/sdavidsson90/bike_crash/main/raw_data/bike_crash.csv")

# Filter points to area of interest
bike_crash <- bike_crash %>% filter(County == "Mecklenburg")

# Read as Simple Feature Object
bike_crash <- st_as_sf(bike_crash, coords = c(x = "X", y = "Y"), crs = "NAD83")

  1. 以及北卡罗来纳州梅克伦堡县的公路网 (形状文件下载自): https://www2.census.gov/geo/tiger/TIGER2019/ROADS/tl_2019_37119_roads.zip
# Read in shapefile (after downloading and unzipping)
roads <- st_read("......working_directory....../tl_2019_37119_roads/tl_2019_37119_roads.shp")

我已经尝试了以下产生了一些结果的方法,但是距离阈值似乎没有正常工作。

st_intersects(roads, bike_crash)

st_intersects(roads, bike_crash, dist = 10)

我是否正确地解决了这个问题?

期待您的建议!

这看起来是个有趣的小项目!

为了让答案更笼统 - 并且让未来的读者感兴趣:点和线的交点很少是可靠的。

即使不是因为数据输入不准确,浮点数学的简单事实也会造成许多(表面上的)失误。距离可能有所帮助,但也可以考虑其他选择。

您有两种可能性,具体取决于您如何构建问题:

  • 从您的道路对象开始,您可以在道路周围创建一个 buffer 多边形作为线,并计算该缓冲区内的点数(崩溃)
  • 从您的碰撞对象开始,您可以找到最近的道路对象 - 每个碰撞地点都保证有一条最近的道路,即使“最近”是一个相对术语。

要获得快速粗略的概述,请考虑这段代码:

library(sf)
library(dplyr)

# Read in data from link
bike_crash <- readr::read_csv("https://raw.githubusercontent.com/sdavidsson90/bike_crash/main/raw_data/bike_crash.csv")

# Filter points to area of interest
bike_crash <- bike_crash %>% 
  filter(County == "Mecklenburg")

# Read as Simple Feature Object
bike_crash <- st_as_sf(bike_crash, coords = c(x = "X", y = "Y"), crs = "NAD83")

# roads / via {tigris} to make it cleaner
roads <- tigris::roads(state = "NC",
                       county = "Mecklenburg")

# find the nearest road / subset fullname by the index of nearest road to crash site
bike_crash$nearest_road <- roads$FULLNAME[st_nearest_feature(bike_crash, roads)]

bike_crash %>% 
  st_drop_geometry() %>%  # no need of geometry in summary stats
  group_by(nearest_road) %>% 
  tally() %>% 
  slice_max(order_by = n, n = 10)
# A tibble: 11 × 2
#    nearest_road         n
#    <chr>            <int>
#  1 S Tryon St          36
#  2 Central Ave         31
#  3 N Tryon St          31
#  4 NA                  24
#  5 Beatties Ford Rd    23
#  6 The Plaza           22
#  7 Albemarle Rd        20
#  8 East Blvd           17
#  9 Monroe Rd           17
# 10 State Hwy 51        16
# 11 State Rd 3687       16