I am trying to create a dataset of roads data to do shortest path analysis. To do this, my roads data needs to be connected: it should be possible to jump from one road to another. I am planning to use the R
library shp2graph
for this. This library contains a function nt.connect
that finds the largest connected network. However, this function finds that my data hardly overlaps, despite appearing to overlap on visual inspection. The function returns the following image to visualise these separate networks:
How can I connect these overlapping pieces of road to each other?
What I've tried:
- Buffering the roads network. This returns a
SpatialPolygon
object whichnt.connect
does not accept: it wants aSpatialLines
object. If I would convert theSpatialPolygon
object to aSpatialLines
object it would take the boundary of the Polygon, which would result in two roads right next to each other. I am worried this will mess with the subsequent analysis.
Some notes:
- I am using
OpenStreetMap
data. The dataset (a subset of my full dataset) can be downloaded here: https://www.dropbox.com/sh/qu2fg3f9fy5tk7k/AABjv81Vv1R9c0RHuMJwIHH2a?dl=0 - This is only a (very small) portion of the full roads network I want to use. Manually making sure they overlap is therefore not feasible
- This library I am planning to use uses
R
. An answer usingPython
orQGIS3
is also possible as I use these regularly. Most important is that the approach is scriptable. My work needs to be fully reproducible and this is difficult when working with a GUI. - Some pieces of the road are true "orphans": they do not overlap with the larger network. I would prefer if these can be incorporated into the main network, for example by drawing the shortest possible line to the full network. I would also be fine with just dropping these orphans.
Below is the code to check that the network is connected:
require(sf)
require(sp)
require(shp2graph)
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
roads <- read_sf("../GIS Stack example", "roads")
roads_sp <- as(roads, "Spatial")
roads_connected <- nt.connect(roads_sp)