I am trying to build a road network by using sfnetworks package in R, and I ran into an issue while running the last code chunk.
The below is my R code and data available here:
# Read in Data
## London borough boundary
LondonBoroughs <- st_read(here::here('data', 'boundary', 'London_Borough_Excluding_MHW.shp')) %>%
st_transform(., 27700)
## street nodes
street_nodes <- st_read(here::here('data', 'cleaned_nodes.geojson')) %>% st_transform(., 27700)
## street edges
street_edges <- st_read(here::here('data', 'cleaned_edges.geojson')) %>% st_transform(., 27700)
The street_nodes variable has 6 columns and osmid(int64) as row index: y(float64), x(float64), highway(object), ref(object), geometry(geometry).
The street_edges variable has 12 columns: u(int64), v(int64), key(int64), osmid(object), oneway(boolean), length(float64), from(int64), to(int64), junction(object), area(object), landuse(object), geometry(geomtery)
# Data cleaning
## remove duplicate street nodes - no duplicates
street_nodes <- street_nodes %>%
distinct()
## street nodes within London boundary
street_nodes <- street_nodes[LondonBoroughs, ]
## street edges within London boundary
street_edges <- street_edges[LondonBoroughs, ]
## remove duplicate street edges - no duplicates
street_edges <- street_edges %>%
distinct()
# create network
net = sfnetwork(street_nodes, street_edges, directed = FALSE)
When I run the last code chunk, it throws the following error message:
Error in (function (edges, n = max(edges), directed = TRUE) : At core/graph/type_indexededgelist.c:117 : Number of vertices must not be negative. Invalid value
The below are what I did in Python:
I queried the OSM road networks in Python and did a bit of data preprocessing, such as converting datatype and filling na values. The initially preprocessed edge and node data were saved in geojson format.
import os
import wget
import osmnx as ox
import geopandas as gpd
# bounding box of London
bbox = (-0.5108706, 51.28117, 0.322123, 51.68948)
# get road network and save as .shp
G = ox.graph_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], network_type='all')
ox.save_graph_shapefile(G, filepath='data/london_street/raw_osm_data', encoding='utf-8')
# load as GeoDataFrame
nodes = gpd.read_file('data/london_street/raw_osm_data/nodes.shp')
edges = gpd.read_file('data/london_street/raw_osm_data/edges.shp')
# node column rename
nodes.rename(columns = {'street_cou' : 'street_count'}, inplace = True)
# replace 'None' to empty string in node data
nodes.fillna("",inplace=True)
cleaned_nodes = nodes.copy()
cleaned_nodes.set_index('osmid', inplace = True)
cleaned_nodes.head(3)
# replace 'None' to empty string in edge data
edges.fillna("",inplace=True)
# select columns of interest
cleaned_edges = edges[['u', 'v', 'key', 'osmid', 'oneway', 'length', 'from', 'to', 'junction',
'area', 'landuse', 'geometry']].copy()
cleaned_edges.head(1)
# convert 'oneway' datatype to boolean
cleaned_edges['oneway'] = cleaned_edges['oneway'].astype(bool)
# save the cleaned nodes and edges
file_path_nodes = "data/london_street/cleaned_osm_data/cleaned_nodes.geojson"
cleaned_nodes.to_file(file_path_nodes, driver = "GeoJSON")
file_path_edges = "data/london_street/cleaned_osm_data/cleaned_edges.geojson"
cleaned_edges.to_file(file_path_edges, driver = "GeoJSON")
In case, the function assumes that there should be nodes for every integer between min(street_nodes$osmid) (2) and max(street_nodes$osmid) I experimented to change the datatypes of "to" and "from" columns in edge data and 'osmid' column in node data to a 'character' type. But nothing worked and still got the same error message.
Could anyone help?