Skip to main content
Ctrl+K

RA2CE

  • Overview
  • Getting Started
  • Showcases
  • Tutorials
  • Docstrings Reference
    • Technical Documentation
    • Contributing
  • GitHub
  • Deltares
  • Overview
  • Getting Started
  • Showcases
  • Tutorials
  • Docstrings Reference
  • Technical Documentation
  • Contributing
  • GitHub
  • Deltares

Section Navigation

Table of Contents

  • Getting Started
  • Showcases
  • Tutorials
    • Network
      • Network from shapefile
      • Network from OSM download
    • Criticality Analysis
      • Single Link Redundancy Tutorial
      • Multi Link Redundancy
    • Accessibility Analysis
      • Origins and Destinations Data Preparation
      • Defined Origin–Destination Pairs Tutorial
      • Origins to Closest Destinations Tutorial
    • Damages Analysis
      • Reference Damage Curves Tutorial
      • Manual Damage Curves Tutorial
      • Expected Annual Damage (EAD) Tutorial
    • Losses Analysis
      • Losses Tutorial
    • Adaptation Tutorial
    • Equity Tutorial
      • RA2CE feature: Equity analysis
  • Docstrings Reference
    • ra2ce.network package
      • ra2ce.network.network_config_data package
        • ra2ce.network.network_config_data.enums package
    • ra2ce.analysis package
      • ra2ce.analysis.analysis_config_data package
        • ra2ce.analysis.analysis_config_data.enums package
    • ra2ce.handler package
  • Technical Documentation
    • Network
    • Analysis
  • Contributing
    • Design principles
    • Implementation decisions
  • Overview
  • Criticality Analysis
  • Multi Link...

Multi Link Redundancy#

The multi-link redundancy analysis returns the same types of results as the single-link redundancy analysis, but it considers multiple links failing simultaneously. This is particularly useful for assessing the resilience of a network to natural disasters that may affect several links at once.

Run Multi-Link Redundancy Analysis#

The workflow is therefore very similar to the single-link redundancy analysis, with the difference being that a hazard map must be specified. See the Single Link Redundancy tutorial for more details on the workflow.

We select the analysis type as AnalysisLossesEnum.MULTI_LINK_REDUNDANCY, for which we can also set a threshold for the water depth. The threshold defines the hazard value above which a link is considered impassable/disrupted.

Step 1: Import Libraries and Set Paths#

We start by importing the required libraries and defining the root directory and network path.

[1]:
from pathlib import Path
import geopandas as gpd
from IPython.core.display_functions import display

from ra2ce.analysis.analysis_config_data.analysis_config_data import AnalysisSectionLosses, AnalysisConfigData
from ra2ce.analysis.analysis_config_data.enums.analysis_losses_enum import AnalysisLossesEnum
from ra2ce.analysis.analysis_config_data.enums.weighing_enum import WeighingEnum
from ra2ce.network.network_config_data.enums.aggregate_wl_enum import AggregateWlEnum
from ra2ce.network.network_config_data.network_config_data import NetworkSection, NetworkConfigData, HazardSection
from ra2ce.network.network_config_data.enums.source_enum import SourceEnum
from ra2ce.ra2ce_handler import Ra2ceHandler

root_dir = Path('data', 'multi_link_redundancy')

network_path = root_dir / "network"
hazard_path = root_dir / "hazard"

c:\Users\hauth\miniforge3\envs\ra2ce_env\Lib\site-packages\tqdm\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Step 2: Define Network and Analysis Configuration#

[3]:
network_section = NetworkSection(
    source=SourceEnum.SHAPEFILE,
    primary_file=network_path.joinpath("base_shapefile.shp"),
    file_id="ID",
    save_gpkg=True)

hazard_section = HazardSection(
    hazard_map=[hazard_path.joinpath("max_flood_depth.tif")],
    hazard_id='Flood',
    hazard_field_name="waterdepthtt",
    aggregate_wl=AggregateWlEnum.MIN,
    hazard_crs="EPSG:32736",
    )

network_config_data = NetworkConfigData(
    root_path= root_dir,
    static_path=root_dir.joinpath('static'),
    network=network_section,
    hazard=hazard_section,
    )

analyse_section = AnalysisSectionLosses(
    name="tutorial_multi_link_redundancy",
    analysis=AnalysisLossesEnum.MULTI_LINK_REDUNDANCY,
    threshold=0.3,  # roads with a flood depth above this value are considered impassable
    weighing=WeighingEnum.LENGTH,
    save_csv=True,
    save_gpkg=True,
)

analysis_config_data = AnalysisConfigData(
    output_path=root_dir.joinpath("output"),
    static_path=root_dir.joinpath('static'),
    analyses=[analyse_section],
    aggregate_wl=AggregateWlEnum.MIN,
)

handler = Ra2ceHandler.from_config(network=network_config_data, analysis=analysis_config_data)
handler.configure()
handler.run_analysis()
100%|██████████| 4217/4217 [00:00<00:00, 370052.09it/s]
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:175] - root - WARNING - No valid file found with average speeds data\multi_link_redundancy\static\output_graph\avg_speed.csv, calculating and saving them instead.
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:175] - root - WARNING - No valid file found with average speeds data\multi_link_redundancy\static\output_graph\avg_speed.csv, calculating and saving them instead.
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:150] - root - WARNING - Default speed have been assigned to road type [<RoadTypeEnum.SECONDARY_LINK: 8>]. Please check the average speed CSV, enter the right average speed for this road type and run RA2CE again.
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:150] - root - WARNING - Default speed have been assigned to road type [<RoadTypeEnum.SECONDARY_LINK: 8>]. Please check the average speed CSV, enter the right average speed for this road type and run RA2CE again.
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:150] - root - WARNING - Default speed have been assigned to road type [<RoadTypeEnum.SECONDARY: 7>]. Please check the average speed CSV, enter the right average speed for this road type and run RA2CE again.
2025-10-01 05:04:27 PM - [avg_speed_calculator.py:150] - root - WARNING - Default speed have been assigned to road type [<RoadTypeEnum.SECONDARY: 7>]. Please check the average speed CSV, enter the right average speed for this road type and run RA2CE again.
2025-10-01 05:04:29 PM - [hazard_overlay.py:380] - root - WARNING - Hazard crs EPSG:32736 and graph crs EPSG:4326 are inconsistent, we try to reproject the graph crs
2025-10-01 05:04:29 PM - [hazard_overlay.py:380] - root - WARNING - Hazard crs EPSG:32736 and graph crs EPSG:4326 are inconsistent, we try to reproject the graph crs
Graph hazard overlay with max_flood_depth: 100%|██████████| 2109/2109 [00:02<00:00, 785.28it/s]
Graph fraction with hazard overlay with max_flood_depth: 100%|██████████| 2109/2109 [00:29<00:00, 71.65it/s]
2025-10-01 05:05:02 PM - [hazard_overlay.py:461] - root - WARNING - Hazard crs EPSG:32736 and gdf crs EPSG:4326 are inconsistent, we try to reproject the gdf crs
2025-10-01 05:05:02 PM - [hazard_overlay.py:461] - root - WARNING - Hazard crs EPSG:32736 and gdf crs EPSG:4326 are inconsistent, we try to reproject the gdf crs
2025-10-01 05:05:02 PM - [hazard_intersect_builder_for_tif.py:225] - root - WARNING - Some geometries have NoneType objects (no coordinate information), namely: Empty GeoDataFrame
Columns: [link_id, ID, highway, avgspeed, geometry, lanes, length, maxspeed, bridge, node_A, node_B, edge_fid, rfid_c, rfid, time]
Index: [].This could be due to segmentation, and might cause an exception in hazard overlay
2025-10-01 05:05:02 PM - [hazard_intersect_builder_for_tif.py:225] - root - WARNING - Some geometries have NoneType objects (no coordinate information), namely: Empty GeoDataFrame
Columns: [link_id, ID, highway, avgspeed, geometry, lanes, length, maxspeed, bridge, node_A, node_B, edge_fid, rfid_c, rfid, time]
Index: [].This could be due to segmentation, and might cause an exception in hazard overlay
Network hazard overlay with max_flood_depth: 100%|██████████| 2121/2121 [00:01<00:00, 1092.98it/s]
Network fraction with hazard overlay with max_flood_depth: 100%|██████████| 2121/2121 [00:37<00:00, 57.18it/s]
[3]:
[AnalysisResultWrapper(results_collection=[AnalysisResult(analysis_result=         u     v link_id    ID      highway  avgspeed  \
 0        0     1    None  None     tertiary      60.0
 1        0     2    None  None     tertiary      58.0
 2        0     3    None  None     tertiary      58.0
 3        1   465    None  None     tertiary      60.0
 4        1   663    None  None  residential      60.0
 ...    ...   ...     ...   ...          ...       ...
 4213  1481  1482    None  None  residential      60.0
 4214  1481  1483    None  None  residential      60.0
 4215  1481  1484    None  None  residential      60.0
 4216  1508  1512    None  None  residential      60.0
 4217  1513  1514    None  None  residential      60.0

                                                geometry lanes  length_x  \
 0     LINESTRING (34.87673 -19.85047, 34.87737 -19.8...   nan      70.0
 1     LINESTRING (34.87673 -19.85047, 34.87642 -19.8...   nan      70.0
 2     LINESTRING (34.87606 -19.85055, 34.87628 -19.8...   nan      71.0
 3     LINESTRING (34.87780 -19.85016, 34.87737 -19.8...   nan      47.0
 4     LINESTRING (34.87717 -19.84969, 34.87737 -19.8...   nan      69.0
 ...                                                 ...   ...       ...
 4213  LINESTRING (34.85976 -19.83977, 34.86006 -19.8...   nan     113.0
 4214  LINESTRING (34.86077 -19.84001, 34.86071 -19.8...   nan      68.0
 4215  LINESTRING (34.86003 -19.83896, 34.86014 -19.8...   nan      78.0
 4216  LINESTRING (34.88623 -19.83527, 34.88641 -19.8...   nan     139.0
 4217  LINESTRING (34.85359 -19.83575, 34.85383 -19.8...   nan      55.0

      maxspeed  ...  rfid   time    EV1_mi    EV1_fr alt_length alt_nodes  \
 0          60  ...     4  0.001  0.000000  0.000000        NaN       nan
 1         nan  ...     7  0.001  0.000000  0.000000        NaN       nan
 2         nan  ...    10  0.001  0.000000  0.000000        NaN       nan
 3          60  ...  1470  0.001  0.000000  0.000000        NaN       nan
 4         nan  ...  2066  0.001  0.000000  0.000000        NaN       nan
 ...       ...  ...   ...    ...       ...       ...        ...       ...
 4213      nan  ...  4175  0.002  0.000000  0.000000        NaN       nan
 4214      nan  ...  4176  0.001  0.000000  0.000000        NaN       nan
 4215      nan  ...  4177  0.001  0.000000  0.000000        NaN       nan
 4216      nan  ...  4209  0.002  0.056350  0.983086        NaN       nan
 4217      nan  ...  4213  0.001  0.180663  0.167520        NaN       nan

       diff_length  connected  length_y  hazard
 0             NaN        nan       NaN  EV1_mi
 1             NaN        nan       NaN  EV1_mi
 2             NaN        nan       NaN  EV1_mi
 3             NaN        nan       NaN  EV1_mi
 4             NaN        nan       NaN  EV1_mi
 ...           ...        ...       ...     ...
 4213          NaN        nan       NaN  EV1_mi
 4214          NaN        nan       NaN  EV1_mi
 4215          NaN        nan       NaN  EV1_mi
 4216          NaN        nan       NaN  EV1_mi
 4217          NaN        nan       NaN  EV1_mi

 [4218 rows x 25 columns], analysis_config=AnalysisSectionLosses(name='tutorial_multi_link_redundancy', save_gpkg=True, save_csv=True, analysis=<AnalysisLossesEnum.MULTI_LINK_REDUNDANCY: 2>, weighing=<WeighingEnum.LENGTH: 1>, production_loss_per_capita_per_hour=nan, traffic_period=<TrafficPeriodEnum.DAY: 1>, hours_per_traffic_period=0, trip_purposes=[<TripPurposeEnum.NONE: 0>], resilience_curves_file=None, traffic_intensities_file=None, values_of_time_file=None, threshold=0.3, threshold_destinations=nan, equity_weight='', calculate_route_without_disruption=False, buffer_meters=nan, category_field_name='', save_traffic=False, event_type=<EventTypeEnum.NONE: 0>, risk_calculation_mode=<RiskCalculationModeEnum.NONE: 0>, risk_calculation_year=0), output_path=WindowsPath('data/multi_link_redundancy/output'), _custom_name='')])]

Inspect Results#

[ ]:
analysis_output_folder = root_dir.joinpath("output", "multi_link_redundancy")
redundancy_gdf = gpd.read_file(analysis_output_folder/"tutorial_multi_link_redundancy.gpkg") # specify the name of the geopackage holding your results (can be found in the analysis output folder)
redundancy_gdf.head() # display the attributes of the file

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 10))
redundancy_gdf.plot(column='alt_length', ax=ax, legend=False, cmap='viridis')
plt.title('Multi Link Redundancy Analysis Results')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.grid(True)
plt.show()

previous

Single Link Redundancy Tutorial

next

Accessibility Analysis

On this page
  • Run Multi-Link Redundancy Analysis
  • Step 1: Import Libraries and Set Paths
  • Step 2: Define Network and Analysis Configuration
  • Inspect Results
Edit on GitHub
Show Source

© Copyright 2024, Deltares.

Created using Sphinx 8.2.3.

Built with the PyData Sphinx Theme 0.15.4.