openstreetmaposmnx

Setting a custom_filter in graph_from_bbox results in more nodes than not having a filter


I want to download a lean map (less number of nodes), removing walkways or service roads, and removing the nodes that are not intersections of two or more streets. I made a call to graph_from_bbox and set a custom_filter but this resulted in downloading more nodes than not setting a custom_filter.

Below is my code:

import osmnx as ox
import networkx as nx
ox.settings.bidirectional_network_types = ["drive"]

# bounds is a dictionary of the bounding box I want to download

cf = ('["area"!~"yes"]["highway"!~"footway|service"]["highway"~"."]')
G4 = ox.graph_from_bbox(
            bounds["max_lat"], bounds["min_lat"], bounds["max_lon"], bounds["min_lon"], 
            simplify = False,
            retain_all = False,
            network_type = 'drive',
            custom_filter=cf
            )
print(len(G4.nodes))

The code above prints 580347. However, when I don't pass a custom_filter such as the code below

G3 = ox.graph_from_bbox(
            bounds["max_lat"], bounds["min_lat"], bounds["max_lon"], bounds["min_lon"], 
            simplify = True,
            retain_all = False,
            network_type = 'drive'
            )
print(len(G3.nodes))

The code prints 130831.

Thus, the code with a custom_filter returned more nodes than the one without. Why is that? Also, is my code correct for "removing removing walkways or service roads, and removing the nodes that are not intersections of two or more streets"?

Thanks in advance.


Solution

  • Custom filters override network types.

    Here's what the documentation says about this:

    custom_filter (string) – a custom ways filter to be used instead of the network_type presets e.g., ‘[“power”~”line”]’ or ‘[“highway”~”motorway|trunk”]’. Also pass in a network_type that is in settings.bidirectional_network_types if you want graph to be fully bi-directional.

    In other words, if there is a custom filter, then network_type is ignored.

    You can also see this in the code. Here's how the code handles this.

        osm_filter = custom_filter if custom_filter is not None else _get_osm_filter(network_type)
    

    Source.

    Here is the default filter for network_type=drive.

        # driving: filter out un-drivable roads, service roads, private ways, and
        # anything specifying motor=no. also filter out any non-service roads that
        # are tagged as providing certain services
        filters["drive"] = (
            f'["highway"]["area"!~"yes"]{settings.default_access}'
            f'["highway"!~"abandoned|bridleway|bus_guideway|construction|corridor|cycleway|elevator|'
            f"escalator|footway|no|path|pedestrian|planned|platform|proposed|raceway|razed|service|"
            f'steps|track"]'
            f'["motor_vehicle"!~"no"]["motorcar"!~"no"]'
            f'["service"!~"alley|driveway|emergency_access|parking|parking_aisle|private"]'
        )
    

    Source

    In order for your query to get fewer results, it must be more selective than this query.