Distance between points along network path

Hi,

I am trying to calculate distances along roads, from start points to stop points. For example:

library(tidyverse)
library(sf)
#> Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0
library(osmdata)
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(maptools)
#> Loading required package: sp
#> Checking rgeos availability: TRUE

#set up some test data
c <- getbb("London, UK")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("primary", 
                            "secondary", "tertiary")) %>%
  osmdata_sf()

c <- st_as_sf(c$osm_lines, crs = 4326)

ggplot(c) +
  geom_sf()


#Get some random start and stop points


bb <- getbb("London, UK")

bb_sf <-st_as_sfc(st_bbox(c(xmin = bb[1,1], xmax = bb[1,2], ymin=bb[2,1], ymax=bb[2,2]), crs = 4326))

set.seed(13)
starts <- st_sample(bb_sf, size=10, type="random", exact = TRUE)
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar
stops <- st_sample(bb_sf, size=10, type="random", exact = TRUE)
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar

ggplot() + 
  geom_sf(data = bb_sf) + 
  geom_sf(data=c) +
  geom_sf(data = starts, colour="green") +
  geom_sf(data = stops, colour="firebrick")


#Snap start and stop points to the nearest road.

# Max distance
cut_dist = 200 # meters

# convert sf to sp
c_sp <-  as_Spatial(c)
starts_sp <-  as_Spatial(starts)
stops_sp <-  as_Spatial(stops)

# snap start points to closest road
start_roads <- snapPointsToLines(starts_sp, c_sp, maxDist = cut_dist)
#> Warning in RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance"): Spatial
#> object 1 is not projected; GEOS expects planar coordinates
#> Warning in RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance"): Spatial
#> object 2 is not projected; GEOS expects planar coordinates
start_roads_sf <- st_as_sf(start_roads)

# snap stop points to closest road
stop_roads <- snapPointsToLines(stops_sp, c_sp, maxDist = cut_dist)
#> Warning in RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance"): Spatial
#> object 1 is not projected; GEOS expects planar coordinates

#> Warning in RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance"): Spatial
#> object 2 is not projected; GEOS expects planar coordinates
stop_roads_sf <- st_as_sf(stop_roads)


# Plot these to check worked
ggplot() + 
  geom_sf(data = bb_sf) + 
  geom_sf(data=c) +
  geom_sf(data = start_roads_sf, colour="green") +
  geom_sf(data = stop_roads_sf, colour="firebrick")

Created on 2020-01-16 by the reprex package (v0.3.0)

Now I need to calculate the distance along roads between start points and stop points, and filter down to the shortest distance for each start point.

By reading around, it seems possible to do this, but I am struggling to get the data set up correctly to allow me to do this.

In reality, I have about 5000 start points, and 20 stop points, so efficiency is important.

Many thanks

I don't have the time to follow up on the reprex you provided right now; but I believe you will find this article interesting - note however that it uses a detour from R via GRASS GIS to clean up the road network structure (one of the reasons I am not able to follow up on your data).

https://www.r-spatial.org/r/2019/09/26/spatial-networks.html

Thanks so much! I have had an initial read through the linked example, and looks exactly to be the workflow I am looking for - very much appreciated. I will go through in greater detail, and let you know if I have any specific examples.

All the best,
Peter

1 Like