gboeing/osmnx

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.