Node Identification within Buffer Zone (if buffer was to be implemented)
timverlaan opened this issue · 1 comments
Contributing guidelines
- I understand the contributing guidelines
Documentation
- My proposal is not addressed by the documentation or examples
Existing issues
- Nothing similar appears in an existing issue
What problem does your feature proposal solve?
This additional on Issue #1072 being considered for adding
The problem is (would be) that OSMnx lacks a feature to identify and retain only critical nodes within a specified buffer zone, which is instrumental as part of shortest paths between edge nodes of the initial polygon (excluding the buffer). This limitation makes it challenging to focus analysis on essential components of the street network, often resulting in unnecessary details from the buffer zone. I implemented this as follows:
# Identify nodes within the city boundary
nodes_within_area = gdf_nodes[gdf_nodes.within(area)]
nodes_within_area_ids = set(nodes_within_area.index)
# Initialize an empty set to store nodes that are part of shortest paths
nodes_in_shortest_paths = set()
# Identify boundary nodes
boundary_nodes = set()
for node in nodes_within_area_ids:
neighbors = list(G.neighbors(node))
if any(neighbor not in nodes_within_area_ids for neighbor in neighbors):
boundary_nodes.add(node)
# Iterate through each pair of nodes within the city to find shortest paths
for source_node in boundary_nodes:
for target_node in boundary_nodes:
if source_node != target_node:
# Find the shortest path from source_node to target_node
try:
path = nx.shortest_path(G, source=source_node, target=target_node, weight='travel_time', method='dijkstra')
# Add nodes in the path to nodes_in_shortest_paths
nodes_in_shortest_paths.update(path)
except nx.NetworkXNoPath:
# If no path exists, continue to the next pair
continue
# Combine nodes_within_city_ids and nodes_in_shortest_paths
nodes_to_keep = nodes_within_area_ids.union(nodes_in_shortest_paths)
# Remove nodes that are neither within the city nor part of any shortest paths
nodes_to_remove = set(G.nodes) - nodes_to_keep
G.remove_nodes_from(nodes_to_remove)
What is your proposed solution?
I propose adding a feature to OSMnx that allows users to identify and retain nodes within a buffer zone that are critical as part of the shortest paths between edge nodes of the initial polygon (excluding the buffer). This feature will provide users with the option to keep only these essential nodes, resulting in a more concise and meaningful street network representation.
What alternatives have you considered?
Currently, users can manually identify and filter nodes within a buffer zone using custom code, as shown in the provided code example. However, this approach is cumbersome and lacks the convenience and efficiency of a built-in OSMnx feature.
Additional context
Here's a code example demonstrating how the proposed feature could be used:
import osmnx as ox
# Retrieve the street network with the buffer zone
G = ox.graph.graph_from_polygon(polygon, buffer=buffer_meters)
# Identify critical nodes within the buffer zone
critical_nodes = ox.utils.get_critical_nodes(G, polygon, buffer=buffer_meters)
I'm not clear on how you mean the term "critical" here. Can you explain? In general, the OSMnx truncate
module can be used to easily constrain a graph's spatial extent to certain nodes, distances, polygons, etc.
Beyond that, also note from the documentation's getting started guide:
Refer to the graph module’s documentation for more details. Under the hood, OSMnx does several things to generate the best possible model. It initially creates a 500m-buffered graph before truncating it to your desired query area, to ensure accurate streets-per-node stats and to attenuate graph perimeter effects.