From e6c011b312ef0267f2bd5a259c5e9716fc2a6064 Mon Sep 17 00:00:00 2001 From: Manuel-Knepper Date: Fri, 7 Aug 2026 11:17:55 +0200 Subject: [PATCH] added settings.py and function for import of street network. Implemented function in linkbikenet.py --- linkbikenet/functions.py | 43 ++++++++++++++++++++++++++++++++++++++ linkbikenet/linkbikenet.py | 34 ++++++++++++++++++++++-------- linkbikenet/settings.py | 4 ++++ 3 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 linkbikenet/settings.py diff --git a/linkbikenet/functions.py b/linkbikenet/functions.py index ec685fd..30415e9 100644 --- a/linkbikenet/functions.py +++ b/linkbikenet/functions.py @@ -1,9 +1,52 @@ from . import config +from . import settings +import osmnx as ox import geopandas as gpd import numpy as np from scipy.spatial import cKDTree from shapely.geometry import LineString +def import_network(street_network, import_path=settings.import_path): + """Import and project a street network from gpkg file + + For all edges between a pair of nodes u and v there must be one edge with key 0. + + Parameters + ---------- + street_network : str + The street network will be loaded from this file. Must be a gpkg file in unprojected crs EPSG:4326 with layers nodes and edges, with the structure that a osmnx street network g has after saving its undirected version via ox.io.save_graph_geopackage(). For example: + >>> g = ox.graph_from_place("Barcelona", network_type='all_public', simplify=False, retain_all=True) + >>> ox.io.save_graph_geopackage(g, "Barcelona_streets.gpkg") + import_path : str, default settings.import_path + Path to import files. + + Returns + ------- + nodes : geopandas.geodataframe.GeoDataFrame + Extracted OSM nodes, projected + edges : geopandas.geodataframe.GeoDataFrame + Extracted OSM edges, projected + g_undir : networkx.classes.multigraph.MultiGraph + Extracted networkX graph, undirected + city_boundary_gdf : geopandas.geodataframe.GeoDataFrame + Convex hull of the street network + """ + + nodes = gpd.read_file(import_path+street_network, layer='nodes') + edges = gpd.read_file(import_path+street_network, layer='edges') + + # Set indices as required by osmnx.convert.graph_from_gdfs + # See: https://osmnx.readthedocs.io/en/stable/user-reference.html#osmnx.utils_graph.graph_from_gdfs + nodes = nodes.set_index(['osmid']) + edges = edges.set_index(['u', 'v', 'key']) + + g = ox.convert.graph_from_gdfs(nodes, edges) + + #city_boundary_gdf = gpd.GeoDataFrame(gpd.GeoSeries(nodes.union_all().convex_hull), geometry=0, crs=nodes.crs) # We do this before the projection of nodes below + # To do: To be super-correct, the hull should be buffered by settings.seed_point_snap_distance (in degrees due to being unprojected) + + return g + def map_edges_to_bike_infrastructure(g): """ map if edges in graph have bike infrastructure as specified in config.py diff --git a/linkbikenet/linkbikenet.py b/linkbikenet/linkbikenet.py index 4579c6a..45c0a18 100644 --- a/linkbikenet/linkbikenet.py +++ b/linkbikenet/linkbikenet.py @@ -11,7 +11,8 @@ def linkbikenet( connection_strategy = "largest", proj_crs = "3857", export_data = True, - export_file_format = "geojson" + export_file_format = "geojson", + import_files={}, ): """ Creates links between components of bicycle networks in cities. How components are connected depends on the connection strategy that was chosen. @@ -27,6 +28,14 @@ def linkbikenet( If set to True, data will be saved to a file. The filename is [slug].gpkg, where slug is a string id made out of city_name export_file_format : str, optional, default "geojson" File format for the data export, relevant if export_data set to True. Default "geojson", also possible "gpkg". If exporting as geojson, generates extra files for street network and city boundary. If exporting as gkpg, these are added all in one file as extra layers. + import_files: dict, default {} + The following key:value entries can be set: + "street_network" : str | None, default None + If not set to None, the street network is loaded from this file. Must be a gpkg file in unprojected crs EPSG:4326 with layers nodes and edges, with the structure that an undirected osmnx street network g has after saved via ox.io.save_graph_geopackage(). For example: + >>> ox.settings.useful_tags_way = ["highway", "cycleway", "cycleway:right", "cycleway:left", "cycleway:both", "cyclestreet"] + >>> g = ox.graph_from_place("Barcelona", network_type='all_public', simplify=False, retain_all=True) + >>> g = nx.MultiGraph(ox.convert.to_digraph(g)) + >>> ox.io.save_graph_geopackage(g, "Barcelona_streets.gpkg"). Returns ------- gdf: geopandas.GeoDataFrame @@ -44,16 +53,23 @@ def linkbikenet( if export_file_format != "geojson" and export_file_format != "gpkg": raise ValueError("export_file_format must be 'geojson' or 'gpkg'") - ### downloading and preprocessing data from OSM - print("Downloading OSM data..") - ox.settings.useful_tags_way = ["highway", "cycleway", "cycleway:right", "cycleway:left", "cycleway:both", - "cyclestreet"] + if import_files['street_network'] is not None: + print("Importing street network..") + g = import_network(import_files['street_network']) + + else: + ### downloading and preprocessing data from OSM + print("Downloading OSM data..") + + ox.settings.useful_tags_way = ["highway", "cycleway", "cycleway:right", "cycleway:left", "cycleway:both", + "cyclestreet"] + + # fetch street network from OSM + g = ox.graph_from_place( + city_name, network_type='all_public', simplify=False, retain_all=True + ) - # fetch street network from OSM - g = ox.graph_from_place( - city_name, network_type='all_public', simplify=False, retain_all=True - ) g = ox.simplify_graph( g, edge_attrs_differ=['cycleway', 'highway', 'cycleway:right', 'cycleway:left', 'cycleway:both'], diff --git a/linkbikenet/settings.py b/linkbikenet/settings.py new file mode 100644 index 0000000..2894fa8 --- /dev/null +++ b/linkbikenet/settings.py @@ -0,0 +1,4 @@ +"""Global settings for linkbikenet that can be configured by the user.""" + +import_path = "./" +crs_projected = '3857' \ No newline at end of file