Graph Coverage Analysis for Service Points

This notebook demonstrates how to calculate coverage zones from service points through a multimodal transportation network using Dijkstra’s algorithm and Voronoi diagrams.

# Install required packages (uncomment if needed)
# !pip install iduedu pyarrow objectnat
# Import dependencies
from iduedu import get_intermodal_graph, get_4326_boundary
import geopandas as gpd
from objectnat import get_graph_coverage,get_stepped_graph_coverage,get_radius_coverage

1. Load Transportation Network

First, we retrieve the multimodal graph (roads, public transport, etc.) for a specified region using its OSM ID.

# Get city boundary and transportation network
poly = get_4326_boundary(osm_id=1114252)  # Example OSM ID for a city
G_intermodal = get_intermodal_graph(territory=poly, clip_by_territory=True)

2. Load Service Points

These represent locations (e.g., healthcare facilities, schools) for which we want to calculate coverage zones.

# Load service points (replace with your actual data path)
services = gpd.read_parquet('examples_data/services.parquet')

3. Calculate Coverage by Distance

Creates service areas based on maximum travel distance (800 meters in this example).

# Calculate coverage zones by distance (800m cutoff)
result_length = get_graph_coverage(
    gdf_to=services,
    nx_graph=G_intermodal,
    weight_type="length_meter",
    weight_value_cutoff=800
)

# Visualize results
result_length.explore(column='name', tiles='CartoDB Positron')

4. Calculate Coverage by Travel Time

Creates service areas based on maximum travel time (10 minutes in this example), clipped to the city boundary.

# Prepare zone boundary
zone = gpd.GeoDataFrame(geometry=[poly], crs=4326)

# Calculate coverage zones by time (10min cutoff)
result_time = get_graph_coverage(
    gdf_to=services,
    nx_graph=G_intermodal,
    weight_type="time_min",
    weight_value_cutoff=10,
    zone=zone
)
# Visualize results
result_time.explore(column='name', tiles='CartoDB Positron')

Key Parameters Explained:

  • weight_type:

    • "length_meter" for distance-based coverage

    • "time_min" for time-based coverage

  • weight_value_cutoff: Maximum travel distance/time threshold

  • zone (optional): Boundary polygon to clip results

5. Calculate stepped Coverage by Travel Time

This method divides the total travel time threshold into steps (e.g. every 2 minutes), creating incremental zones. Useful for visualizing service accessibility gradients.

You can choose the visualization method:

  • "voronoi": polygons based on proximity to reachable network nodes

  • "separate": independent buffer zones for each interval

stepped_cov_voronoi = get_stepped_graph_coverage(
    gdf_to=services,
    nx_graph=G_intermodal,
    weight_type="time_min",
    step_type='voronoi',
    weight_value_cutoff=15,
    step=2,
    zone=zone
)
# Visualize stepped coverage
stepped_cov_voronoi.explore(column='dist', tiles='CartoDB Positron')
stepped_cov_voronoi = get_stepped_graph_coverage(
    gdf_to=services,
    nx_graph=G_intermodal,
    weight_type="time_min",
    step_type='separate',
    weight_value_cutoff=15,
    step=2,
)
# Visualize stepped coverage
stepped_cov_voronoi.explore(column='dist', tiles='CartoDB Positron',vmin=0)

6. Calculate Radius-Based Coverage

If a transport network is unavailable or unnecessary, use simple circular buffers around service points.

This method creates geometric buffers with specified radius (e.g., 500 meters).

radius_cov = get_radius_coverage(gdf_from=services, radius=500)
# Visualize radius coverage
radius_cov.explore(column='name', tiles='CartoDB Positron')