Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

392-multi_link_redundancy-adjust-calculating-diff_time-or-diff_length #393

35 changes: 26 additions & 9 deletions ra2ce/analysis/indirect/multi_link_redundancy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import osmnx
import pandas as pd
from geopandas import GeoDataFrame
import geopandas as gpd

from ra2ce.analysis.analysis_config_data.analysis_config_data import (
AnalysisSectionIndirect,
Expand All @@ -20,6 +21,9 @@
from ra2ce.network.hazard.hazard_names import HazardNames





class MultiLinkRedundancy(AnalysisIndirectProtocol):
analysis: AnalysisSectionIndirect
graph_file_hazard: GraphFile
Expand All @@ -39,6 +43,21 @@ def __init__(
self.output_path = analysis_input.output_path
self.hazard_names = analysis_input.hazard_names

def _update_time(self, gdf_calculated: pd.DataFrame, gdf_graph: gpd.GeoDataFrame):
"""
updates the time column with the calculated dataframe and updates the rest of the gdf_graph if time is None.
"""
gdf_graph[self.analysis.weighing.config_value] = gdf_calculated[self.analysis.weighing.config_value]
for i, row in gdf_graph.iterrows():
row_avgspeed = row.get("avgspeed", None)
row_length = row.get("length", None)
if pd.isna(row[WeighingEnum.TIME.config_value]) and row_avgspeed and row_length:
gdf_graph.at[i, WeighingEnum.TIME.config_value] = row_length * 1e-3 / row_avgspeed
else:
gdf_graph.at[i, WeighingEnum.TIME.config_value] = row.get(WeighingEnum.TIME.config_value, None)
return gdf_graph


def execute(self) -> GeoDataFrame:
"""Calculates the multi-link redundancy of a NetworkX graph.

Expand Down Expand Up @@ -79,6 +98,7 @@ def execute(self) -> GeoDataFrame:
"v",
f"alt_{self.analysis.weighing.config_value}",
"alt_nodes",
f"diff_{self.analysis.weighing.config_value}",
"connected",
]

Expand Down Expand Up @@ -106,11 +126,16 @@ def execute(self) -> GeoDataFrame:
alt_value = _weighing_analyser.calculate_distance()
alt_nodes, connected = np.NaN, 0

diff = round(
alt_value - _weighing_analyser.weighing_data[self.analysis.weighing.config_value], 3
)

data = {
"u": [u],
"v": [v],
f"alt_{self.analysis.weighing.config_value}": [alt_value],
"alt_nodes": [alt_nodes],
f"diff_{self.analysis.weighing.config_value}": diff,
"connected": [connected],
}
_weighing_analyser.extend_graph(data)
Expand All @@ -132,15 +157,7 @@ def execute(self) -> GeoDataFrame:
else:
gdf = gdf.merge(df_calculated, how="left", on=["u", "v"])

# calculate the differences in distance and time
# previously here you find if dist==dist which is a critical bug. Replaced by verifying dist is a value.
gdf[f"diff_{self.analysis.weighing.config_value}"] = [
round(alt - base, 2) if alt else np.NaN
for (alt, base) in zip(
gdf[f"alt_{self.analysis.weighing.config_value}"],
gdf[f"{self.analysis.weighing.config_value}"],
)
]
gdf = self._update_time(df_calculated, gdf)

gdf["hazard"] = hazard_name

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import geopandas as gpd

from ra2ce.analysis.analysis_config_data.enums.weighing_enum import WeighingEnum
from ra2ce.analysis.indirect.weighing_analysis.weighing_analysis_protocol import (
WeighingAnalysisProtocol,
Expand All @@ -15,10 +16,10 @@ def __init__(self) -> None:
def _calculate_time(self) -> float:
_calculated_time = round(
(self.weighing_data["length"] * 1e-3) / self.weighing_data["avgspeed"],
2,
3,
) # in hours and avg speed in km/h
self.weighing_data[WeighingEnum.TIME.config_value] = _calculated_time
return round(_calculated_time, 2)
return round(_calculated_time, 3)

def calculate_distance(self) -> float:
self.time_list.append(self._calculate_time())
Expand All @@ -30,4 +31,9 @@ def calculate_alternative_distance(self, alt_dist: float) -> float:
return alt_time

def extend_graph(self, gdf_graph: gpd.GeoDataFrame | dict) -> None:
gdf_graph[WeighingEnum.TIME.config_value] = self.time_list
if isinstance(gdf_graph, gpd.GeoDataFrame):
gdf_graph[WeighingEnum.TIME.config_value] = self.time_list
elif isinstance(gdf_graph, dict):
gdf_graph[WeighingEnum.TIME.config_value] = [self.time_list[-1]]