From 03ea16b1ab4da83c35332d8b7e57b81c159f1f68 Mon Sep 17 00:00:00 2001 From: SoulKindred Date: Sun, 7 Jan 2024 17:20:16 +0100 Subject: [PATCH 1/2] some refractoring for big html --- analysis/map.py | 2 +- analysis/plots.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/analysis/map.py b/analysis/map.py index c47520a..4edccc1 100644 --- a/analysis/map.py +++ b/analysis/map.py @@ -300,4 +300,4 @@ if __name__ == "__main__": ## Save Maps ============================================================================================ save_map_as_html(toggle_map, "heat_map_toggle") - save_map_as_html(time_map, "heat_map_time") + save_map_as_html(time_map, "html/heat_map_time") diff --git a/analysis/plots.py b/analysis/plots.py index bc15213..55df4c7 100644 --- a/analysis/plots.py +++ b/analysis/plots.py @@ -73,6 +73,7 @@ def plt_acc_by_day_year(db): animation_frame='year', labels={'weekday': 'Weekday', 'count': 'Number of Accidents'}, category_orders={'weekday': ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']}, + orientation='h' ) fig.update_yaxes(range=[0, 1000]) # Customize the layout to include a slider @@ -137,9 +138,9 @@ def plt_acc_by_daytime(db): result = db.execute_query(acc_weekday_sql) result_df = pd.DataFrame(result) - fig = px.bar(result_df, y='hour', x='count', orientation='h') - fig.write_image("fig/acc_by_day.png") - fig.write_html("html/acc_by_day.html") + fig = px.bar(result_df, y='hour', x='count', orientation='h', title='Accidents by day') + fig.write_image("fig/acc_by_daytime.png") + fig.write_html("html/acc_by_daytime.html") # Time Series charts ================================================================================================== def acc_by_type(db): From bbfd93fc050b2b6cf37455235835fe174511a86e Mon Sep 17 00:00:00 2001 From: SoulKindred Date: Mon, 8 Jan 2024 10:52:48 +0100 Subject: [PATCH 2/2] Calculations.py goes through all speed-limit zones and calculates how many accidents happened in a 5 meter radius around the line --- analysis/calculations.py | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 analysis/calculations.py diff --git a/analysis/calculations.py b/analysis/calculations.py new file mode 100644 index 0000000..abfa20e --- /dev/null +++ b/analysis/calculations.py @@ -0,0 +1,68 @@ +import logging +from shapely.geometry import Point, LineString +from shapely import wkb +from db_connector import RemoteDB +import pandas as pd + +speedLimits = ["T0", "T20", "T30", "T50","T60", "T80", "T100"] + + +def is_point_near_multilinestring(point, multilinestring, threshold_distance): + point_geometry = Point(point) + return point_geometry.distance(multilinestring) < threshold_distance + + +def get_data(db): + get_speeds_sql = """ + SELECT wkb_geometry, + temporegime_technical + FROM signaled_speeds; + """ + + result = db.execute_query(get_speeds_sql) + sig_speed_df = pd.DataFrame(result) + sig_speed_df.rename(columns={'wkb_geometry': 'geometry'}, inplace=True) + sig_speed_df['geometry'] = sig_speed_df['geometry'].apply(lambda x: wkb.loads(x, hex=True)) + + get_accidents = """ + SELECT geometry + FROM accidents; + """ + result = db.execute_query(get_accidents) + accident_df = pd.DataFrame(result) + accident_df['geometry'] = accident_df['geometry'].apply(lambda x: wkb.loads(x, hex=True)) + + process_data(sig_speed_df, accident_df) + + +def process_data(sig_speed_df, accident_df): + result_df = pd.DataFrame(columns= ['TempoLim', 'Accidents_total']) + for speed in speedLimits: + print("Checking for zone: " + speed) + filtered_df = sig_speed_df[sig_speed_df["temporegime_technical"].str.contains(speed, case=False, na=False)] + current_result = count_points_near_multilinestrings(accident_df, filtered_df, 0.000005) + result_df.loc[len(result_df)] = {'TempoLim': speed, 'Accidents_total': current_result} + print("FINAL RESULT") + print(result_df) + + +def count_points_near_multilinestrings(points_df, multilinestrings_df, threshold_distance): + result_counts = [] + + for idx, multilinestring_row in multilinestrings_df.iterrows(): + multilinestring = multilinestring_row['geometry'] + count_near = sum(points_df['geometry'].apply( + lambda point: is_point_near_multilinestring(point, multilinestring, threshold_distance))) + result_counts.append({'temporegime_technical': multilinestring_row['temporegime_technical'], 'CountNear': count_near}) + result_df = pd.DataFrame(result_counts) + return result_df['CountNear'].sum() + + +if __name__ == "__main__": + remote_db = RemoteDB() + try: + get_data(remote_db) + except Exception as e: + print(f"Exception {e} in plots.py") + finally: + remote_db.close()