diff --git a/anyway/models.py b/anyway/models.py index 35e21d76f..7e546c165 100755 --- a/anyway/models.py +++ b/anyway/models.py @@ -894,25 +894,36 @@ def set_critical( from anyway.widgets.all_locations_widgets.injured_count_by_severity_widget import ( InjuredCountBySeverityWidget, ) - from anyway.request_params import get_latest_accident_date + from anyway.request_params import get_latest_accident_date, LocationInfo - if self.road1 is None or self.road_segment_name is None: + if (self.road1 is None or self.road_segment_name is None) and (self.yishuv_name is None or self.street1_hebrew is None) : return None last_accident_date = get_latest_accident_date(table_obj=AccidentMarkerView, filters=None) + resolution = BE_CONST.ResolutionCategories(self.resolution) end_time = last_accident_date.to_pydatetime().date() start_time = datetime.date(end_time.year + 1 - years_before, 1, 1) - critical_values = InjuredCountBySeverityWidget.get_injured_count_by_severity( - self.road1, self.road_segment_name, start_time, end_time - ) + location_info = LocationInfo() + if resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD: + location_info["road1"] + location_info["road_segment_name"] + elif resolution == BE_CONST.ResolutionCategories.STREET: + location_info["yishuv_name"] = self.yishuv_name + location_info["street1_hebrew"] = self.street1_hebrew + + critical_values = InjuredCountBySeverityWidget.get_injured_count_by_severity(resolution, location_info, start_time, end_time) if critical_values == {}: return None critical = None - resolution = BE_CONST.ResolutionCategories(self.resolution) if resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD: critical = ( (critical_values["severe_injured_count"] / suburban_road_severe_value) + (critical_values["killed_count"] / suburban_road_killed_value) ) >= 1 + elif resolution == BE_CONST.ResolutionCategories.STREET: + critical = ( + (critical_values["severe_injured_count"] / urban_severe_value) + + (critical_values["killed_count"] / urban_severe_value) + ) >= 1 self.critical = critical def serialize(self): diff --git a/anyway/widgets/all_locations_widgets/__init__.py b/anyway/widgets/all_locations_widgets/__init__.py index 4f55bfa5e..77a6630c3 100644 --- a/anyway/widgets/all_locations_widgets/__init__.py +++ b/anyway/widgets/all_locations_widgets/__init__.py @@ -1,9 +1,14 @@ from . import ( accident_count_by_severity_widget, injured_count_by_severity_widget, + injured_count_by_accident_year_widget, most_severe_accidents_widget, most_severe_accidents_table_widget, seriously_injured_killed_in_bicycles_scooter_widget, killed_and_injured_count_per_age_group_stacked_widget, + accidents_heat_map_widget, + accident_count_by_day_night_widget, + accident_count_by_accident_type_widget, + accident_count_by_accident_year_widget, killed_and_injured_count_per_age_group_widget ) diff --git a/anyway/widgets/road_segment_widgets/accident_count_by_accident_type_widget.py b/anyway/widgets/all_locations_widgets/accident_count_by_accident_type_widget.py similarity index 84% rename from anyway/widgets/road_segment_widgets/accident_count_by_accident_type_widget.py rename to anyway/widgets/all_locations_widgets/accident_count_by_accident_type_widget.py index fa30ef4fb..2ddefca59 100644 --- a/anyway/widgets/road_segment_widgets/accident_count_by_accident_type_widget.py +++ b/anyway/widgets/all_locations_widgets/accident_count_by_accident_type_widget.py @@ -1,8 +1,8 @@ from anyway.request_params import RequestParams -from anyway.widgets.widget_utils import get_accidents_stats +from anyway.widgets.widget_utils import get_accidents_stats, get_location_text from anyway.models import AccidentMarkerView from anyway.widgets.widget import register -from anyway.widgets.road_segment_widgets.road_segment_widget import RoadSegmentWidget +from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget from typing import Dict # noinspection PyProtectedMember @@ -11,7 +11,7 @@ @register -class AccidentCountByAccidentTypeWidget(RoadSegmentWidget): +class AccidentCountByAccidentTypeWidget(AllLocationsWidget): name: str = "accident_count_by_accident_type" files = [__file__] @@ -54,8 +54,11 @@ def get_accident_count_by_accident_type(location_info, start_time, end_time): @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: - items["data"]["text"] = {"title": _("Number of accidents by accident type"), - "subtitle": f'{_("in segment")} {_(request_params.location_info["road_segment_name"])}'} + location_text = get_location_text(request_params) + items["data"]["text"] = { + "title": _("Number of accidents by accident type"), + "subtitle": _(location_text), + } for item in items["data"]["items"]: to_translate = item["accident_type"] item["accident_type"] = _(to_translate) diff --git a/anyway/widgets/road_segment_widgets/accident_count_by_accident_year_widget.py b/anyway/widgets/all_locations_widgets/accident_count_by_accident_year_widget.py similarity index 85% rename from anyway/widgets/road_segment_widgets/accident_count_by_accident_year_widget.py rename to anyway/widgets/all_locations_widgets/accident_count_by_accident_year_widget.py index b5c12521e..8846f8139 100644 --- a/anyway/widgets/road_segment_widgets/accident_count_by_accident_year_widget.py +++ b/anyway/widgets/all_locations_widgets/accident_count_by_accident_year_widget.py @@ -3,21 +3,21 @@ from flask_babel import _ from anyway.backend_constants import AccidentSeverity -from anyway.infographics_dictionaries import segment_dictionary from anyway.models import AccidentMarkerView from anyway.request_params import RequestParams -from anyway.widgets.road_segment_widgets.road_segment_widget import RoadSegmentWidget +from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget from anyway.widgets.widget import register from anyway.widgets.widget_utils import ( get_accidents_stats, gen_entity_labels, format_2_level_items, sort_and_fill_gaps_for_stacked_bar, + get_location_text, ) @register -class AccidentCountByAccidentYearWidget(RoadSegmentWidget): +class AccidentCountByAccidentYearWidget(AllLocationsWidget): name: str = "accident_count_by_accident_year" files = [__file__] @@ -30,7 +30,6 @@ def __init__(self, request_params: RequestParams): self.information = "Fatal, severe and light accidents count in the specified years, split by accident severity" def generate_items(self) -> None: - res1 = get_accidents_stats( table_obj=AccidentMarkerView, filters=self.request_params.location_info, @@ -52,9 +51,10 @@ def generate_items(self) -> None: @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: + location_text = get_location_text(request_params) items["data"]["text"] = { "title": _("Number of accidents, per year, split by severity"), - "subtitle": f'{_("in segment")} {_(segment_dictionary[request_params.location_info["road_segment_name"]])}', + "subtitle": _(location_text), "labels_map": gen_entity_labels(AccidentSeverity), } return items diff --git a/anyway/widgets/road_segment_widgets/accident_count_by_day_night_widget.py b/anyway/widgets/all_locations_widgets/accident_count_by_day_night_widget.py similarity index 79% rename from anyway/widgets/road_segment_widgets/accident_count_by_day_night_widget.py rename to anyway/widgets/all_locations_widgets/accident_count_by_day_night_widget.py index af7abfdad..ecbe03ba8 100644 --- a/anyway/widgets/road_segment_widgets/accident_count_by_day_night_widget.py +++ b/anyway/widgets/all_locations_widgets/accident_count_by_day_night_widget.py @@ -1,14 +1,14 @@ from anyway.request_params import RequestParams -from anyway.widgets.widget_utils import get_accidents_stats +from anyway.widgets.widget_utils import get_accidents_stats, get_location_text from anyway.models import AccidentMarkerView from anyway.widgets.widget import register -from anyway.widgets.road_segment_widgets.road_segment_widget import RoadSegmentWidget +from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget from typing import Dict from flask_babel import _ @register -class AccidentCountByDayNightWidget(RoadSegmentWidget): +class AccidentCountByDayNightWidget(AllLocationsWidget): name: str = "accident_count_by_day_night" files = [__file__] @@ -32,8 +32,8 @@ def generate_items(self) -> None: @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: - items["data"]["text"] = {"title": _("Accidents by time"), - "subtitle": f'{_("in segment")} {_(request_params.location_info["road_segment_name"])}'} + location_text = get_location_text(request_params) + items["data"]["text"] = {"title": _("Accidents by time"), "subtitle": _(location_text)} return items diff --git a/anyway/widgets/all_locations_widgets/accident_count_by_severity_widget.py b/anyway/widgets/all_locations_widgets/accident_count_by_severity_widget.py index 0cc6b95f9..dd73e8758 100644 --- a/anyway/widgets/all_locations_widgets/accident_count_by_severity_widget.py +++ b/anyway/widgets/all_locations_widgets/accident_count_by_severity_widget.py @@ -61,41 +61,41 @@ def get_accident_count_by_severity(location_info, start_time, end_time): def get_transcription(request_params: RequestParams, items: Dict): total_accidents_count = items.get("total_accidents_count") if total_accidents_count == 0: - return '' + return "" severity_light_count = items.get("severity_light_count") if severity_light_count == 0: - severity_light_count_text = '' + severity_light_count_text = "" elif severity_light_count == 1: severity_light_count_text = _("one light") else: - severity_light_count_text = f'{severity_light_count} ' + _("light plural") + severity_light_count_text = f"{severity_light_count} " + _("light plural") severity_severe_count = items.get("severity_severe_count") if severity_severe_count == 0: - severity_severe_count_text = '' + severity_severe_count_text = "" elif severity_severe_count == 1: severity_severe_count_text = _("one severe") else: - severity_severe_count_text = f'{severity_severe_count} '+ _("severe plural") + severity_severe_count_text = f"{severity_severe_count} " + _("severe plural") severity_fatal_count = items.get("severity_fatal_count") if severity_fatal_count == 0: - severity_fatal_count_text = '' + severity_fatal_count_text = "" elif severity_fatal_count == 1: severity_fatal_count_text = _("one fatal") else: - severity_fatal_count_text = f'{severity_fatal_count} ' + _("fatal plural") + severity_fatal_count_text = f"{severity_fatal_count} " + _("fatal plural") if request_params.resolution == BE_CONST.ResolutionCategories.STREET: text = "{in_yishuv_keyword} {yishuv_name} {in_street_keyword} {street_name} ".format( in_yishuv_keyword=_("in yishuv"), - yishuv_name=_(request_params.location_info.get('yishuv_name')), + yishuv_name=_(request_params.location_info.get("yishuv_name")), in_street_keyword=_("in street"), - street_name=_(request_params.location_info.get('street1_hebrew')), + street_name=_(request_params.location_info.get("street1_hebrew")), ) elif request_params.resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD: text = "{in_road_keyword} {road_num} {in_segment_keyword} {segment_name} ".format( in_road_keyword=_("in road"), - road_num=request_params.location_info.get('road1'), + road_num=request_params.location_info.get("road1"), in_segment_keyword=_("in segment"), - segment_name=_(request_params.location_info.get('road_segment_name')), + segment_name=_(request_params.location_info.get("road_segment_name")), ) else: raise Exception(f"cannot convert to hebrew for resolution : {request_params.resolution.value}") @@ -108,24 +108,32 @@ def get_transcription(request_params: RequestParams, items: Dict): incident_keyword=_("accidents"), out_of_them_keywoard=_("out of them"), ) - text += join_strings([severity_fatal_count_text, severity_severe_count_text, severity_light_count_text], - sep_a=" ,", - sep_b=_(" and ")) + text += join_strings( + [severity_fatal_count_text, severity_severe_count_text, severity_light_count_text], + sep_a=" ,", + sep_b=_(" and "), + ) return text @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: - if request_params.resolution in (BE_CONST.ResolutionCategories.SUBURBAN_ROAD, - BE_CONST.ResolutionCategories.SUBURBAN_JUNCTION): + if request_params.resolution in ( + BE_CONST.ResolutionCategories.SUBURBAN_ROAD, + BE_CONST.ResolutionCategories.SUBURBAN_JUNCTION, + ): is_segment = request_params.resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD items["data"]["text"] = { "title": _("Number of accidents by severity"), - "subtitle": _(request_params.location_info['road_segment_name']) if is_segment else - _(request_params.location_info['non_urban_intersection_hebrew']), - "transcription": AccidentCountBySeverityWidget.get_transcription(request_params=request_params, - items=items["data"]["items"]) + "subtitle": _(request_params.location_info["road_segment_name"]) + if is_segment + else _(request_params.location_info["non_urban_intersection_hebrew"]), + "transcription": AccidentCountBySeverityWidget.get_transcription( + request_params=request_params, items=items["data"]["items"] + ), } - items["meta"]["information"] = "{incident_description}{incident_location} {incident_time}.".format( + items["meta"][ + "information" + ] = "{incident_description}{incident_location} {incident_time}.".format( incident_description=_("Fatal, severe and light accidents count in "), incident_location=_("segment") if is_segment else _("junction"), incident_time=_("in the selected time"), @@ -141,11 +149,22 @@ def localize_items(request_params: RequestParams, items: Dict) -> Dict: incidents_num=num_accidents, incident_keyword=_("accidents"), ) - subtitle = _("{street_name}, {yishuv_name}".format(street_name=request_params.location_info["street1_hebrew"], - yishuv_name=request_params.location_info["yishuv_name"])) - items["data"]["text"] = {"title": s, "subtitle": subtitle, "transcription": AccidentCountBySeverityWidget.get_transcription(request_params=request_params, - items=items["data"]["items"])} - items["meta"]["information"] = "{incident_description}{incident_location} {incident_time}.".format( + subtitle = _( + "{street_name}, {yishuv_name}".format( + street_name=request_params.location_info["street1_hebrew"], + yishuv_name=request_params.location_info["yishuv_name"], + ) + ) + items["data"]["text"] = { + "title": s, + "subtitle": subtitle, + "transcription": AccidentCountBySeverityWidget.get_transcription( + request_params=request_params, items=items["data"]["items"] + ), + } + items["meta"][ + "information" + ] = "{incident_description}{incident_location} {incident_time}.".format( incident_description=_("Fatal, severe and light accidents count in "), incident_location=_("street"), incident_time=_("in the selected time"), diff --git a/anyway/widgets/road_segment_widgets/accidents_heat_map_widget.py b/anyway/widgets/all_locations_widgets/accidents_heat_map_widget.py similarity index 83% rename from anyway/widgets/road_segment_widgets/accidents_heat_map_widget.py rename to anyway/widgets/all_locations_widgets/accidents_heat_map_widget.py index b355f6c8b..7e7a7f0c0 100644 --- a/anyway/widgets/road_segment_widgets/accidents_heat_map_widget.py +++ b/anyway/widgets/all_locations_widgets/accidents_heat_map_widget.py @@ -5,15 +5,14 @@ from anyway.request_params import RequestParams from anyway.backend_constants import AccidentSeverity, BE_CONST -from anyway.infographics_dictionaries import segment_dictionary -from anyway.widgets.widget_utils import get_query +from anyway.widgets.widget_utils import get_query, get_location_text from anyway.models import AccidentMarkerView from anyway.widgets.widget import register -from anyway.widgets.road_segment_widgets.road_segment_widget import RoadSegmentWidget +from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget @register -class AccidentsHeatMapWidget(RoadSegmentWidget): +class AccidentsHeatMapWidget(AllLocationsWidget): name: str = "accidents_heat_map" files = [__file__] @@ -49,8 +48,9 @@ def get_accidents_heat_map(filters, start_time, end_time): @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: + location_text = get_location_text(request_params) items["data"]["text"] = { "title": _("Fatal and severe accidents heat map"), - "subtitle": _(segment_dictionary[request_params.location_info["road_segment_name"]]) + "subtitle": _(location_text), } return items diff --git a/anyway/widgets/road_segment_widgets/injured_count_by_accident_year_widget.py b/anyway/widgets/all_locations_widgets/injured_count_by_accident_year_widget.py similarity index 82% rename from anyway/widgets/road_segment_widgets/injured_count_by_accident_year_widget.py rename to anyway/widgets/all_locations_widgets/injured_count_by_accident_year_widget.py index c66264f9b..8307559fe 100644 --- a/anyway/widgets/road_segment_widgets/injured_count_by_accident_year_widget.py +++ b/anyway/widgets/all_locations_widgets/injured_count_by_accident_year_widget.py @@ -3,10 +3,9 @@ from flask_babel import _ from anyway.backend_constants import InjurySeverity -from anyway.infographics_dictionaries import segment_dictionary from anyway.models import InvolvedMarkerView from anyway.request_params import RequestParams -from anyway.widgets.road_segment_widgets.road_segment_widget import RoadSegmentWidget +from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget from anyway.widgets.widget import register from anyway.widgets.widget_utils import ( get_accidents_stats, @@ -14,11 +13,12 @@ get_injured_filters, format_2_level_items, sort_and_fill_gaps_for_stacked_bar, + get_location_text, ) @register -class InjuredCountByAccidentYearWidget(RoadSegmentWidget): +class InjuredCountByAccidentYearWidget(AllLocationsWidget): name: str = "injured_count_by_accident_year" files = [__file__] @@ -32,7 +32,7 @@ def __init__(self, request_params: RequestParams): def generate_items(self) -> None: res1 = get_accidents_stats( table_obj=InvolvedMarkerView, - filters=get_injured_filters(self.request_params.location_info), + filters=get_injured_filters(self.request_params), group_by=("accident_year", "injury_severity"), count="injury_severity", start_time=self.request_params.start_time, @@ -51,9 +51,10 @@ def generate_items(self) -> None: @staticmethod def localize_items(request_params: RequestParams, items: Dict) -> Dict: + location_text = get_location_text(request_params) items["data"]["text"] = { "title": _("Number of injured in accidents, per year, split by severity"), - "subtitle": f'{_("in segment")} {_(segment_dictionary[request_params.location_info["road_segment_name"]])}', + "subtitle": _(location_text), "labels_map": gen_entity_labels(InjurySeverity), } return items diff --git a/anyway/widgets/all_locations_widgets/injured_count_by_severity_widget.py b/anyway/widgets/all_locations_widgets/injured_count_by_severity_widget.py index 5b04cad8f..830615770 100644 --- a/anyway/widgets/all_locations_widgets/injured_count_by_severity_widget.py +++ b/anyway/widgets/all_locations_widgets/injured_count_by_severity_widget.py @@ -1,10 +1,16 @@ +import datetime from typing import Dict -from anyway.request_params import RequestParams +from anyway.request_params import RequestParams, LocationInfo from anyway.backend_constants import InjurySeverity from anyway.models import InvolvedMarkerView from anyway.widgets.all_locations_widgets.all_locations_widget import AllLocationsWidget from anyway.widgets.widget import register -from anyway.widgets.widget_utils import get_accidents_stats, join_strings, get_location_text +from anyway.widgets.widget_utils import ( + get_accidents_stats, + join_strings, + get_location_text, + get_involved_marker_view_location_filters, +) from anyway.backend_constants import BE_CONST from flask_babel import _ @@ -28,21 +34,19 @@ def generate_items(self) -> None: ) @staticmethod - def get_injured_count_by_severity(resolution, location_info, start_time, end_time): - filters = {} + def get_injured_count_by_severity( + resolution: BE_CONST.ResolutionCategories, + location_info: LocationInfo, + start_time: datetime.date, + end_time: datetime.date, + ): + filters = get_involved_marker_view_location_filters(resolution, location_info) filters["injury_severity"] = [ InjurySeverity.KILLED.value, InjurySeverity.SEVERE_INJURED.value, InjurySeverity.LIGHT_INJURED.value, ] - if resolution == BE_CONST.ResolutionCategories.STREET: - filters["involve_yishuv_name"] = location_info.get("yishuv_name") - filters["street1_hebrew"] = location_info.get("street1_hebrew") - elif resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD: - filters["road1"] = location_info.get("road1") - filters["road_segment_name"] = location_info.get("road_segment_name") - count_by_severity = get_accidents_stats( table_obj=InvolvedMarkerView, filters=filters, diff --git a/anyway/widgets/road_segment_widgets/__init__.py b/anyway/widgets/road_segment_widgets/__init__.py index 6edf15e2b..1817b95a3 100644 --- a/anyway/widgets/road_segment_widgets/__init__.py +++ b/anyway/widgets/road_segment_widgets/__init__.py @@ -7,17 +7,12 @@ accident_count_by_road_light_widget, accident_count_pedestrians_per_vehicle_street_vs_all_widget, accident_severity_by_cross_location_widget, - accidents_heat_map_widget, head_on_collisions_comparison_widget, pedestrian_injured_in_junctions_widget, accident_count_by_hour_widget, accident_count_by_driver_type_widget, - accident_count_by_day_night_widget, accident_type_vehicle_type_road_comparison_widget, - accident_count_by_accident_year_widget, - accident_count_by_accident_type_widget, accident_count_by_car_type_widget, - injured_count_by_accident_year_widget, motorcycle_accidents_vs_all_accidents_widget, suburban_crosswalk_widget, fatal_accident_yoy_same_month, diff --git a/anyway/widgets/road_segment_widgets/accident_count_by_driver_type_widget.py b/anyway/widgets/road_segment_widgets/accident_count_by_driver_type_widget.py index 43581fc4e..10ab09ff5 100644 --- a/anyway/widgets/road_segment_widgets/accident_count_by_driver_type_widget.py +++ b/anyway/widgets/road_segment_widgets/accident_count_by_driver_type_widget.py @@ -29,7 +29,7 @@ def generate_items(self) -> None: @staticmethod def count_accidents_by_driver_type(request_params): - filters = get_injured_filters(request_params.location_info) + filters = get_injured_filters(request_params) filters["involved_type"] = [ consts.InvolvedType.DRIVER.value, consts.InvolvedType.INJURED_DRIVER.value, diff --git a/anyway/widgets/widget_utils.py b/anyway/widgets/widget_utils.py index bbd2864c8..7336e3543 100644 --- a/anyway/widgets/widget_utils.py +++ b/anyway/widgets/widget_utils.py @@ -173,14 +173,29 @@ def gen_entity_labels(entity: Type[LabeledCode]) -> dict: return res -def get_injured_filters(location_info): - new_filters = {} - for curr_filter, curr_values in location_info.items(): +def get_involved_marker_view_location_filters( + resolution: BE_CONST.ResolutionCategories, location_info: LocationInfo +): + filters = {} + if resolution == BE_CONST.ResolutionCategories.STREET: + filters["involve_yishuv_name"] = location_info.get("yishuv_name") + filters["street1_hebrew"] = location_info.get("street1_hebrew") + elif resolution == BE_CONST.ResolutionCategories.SUBURBAN_ROAD: + filters["road1"] = location_info.get("road1") + filters["road_segment_name"] = location_info.get("road_segment_name") + + return filters + + +def get_injured_filters(request_params: RequestParams): + new_filters = get_involved_marker_view_location_filters( + request_params.resolution, request_params.location_info + ) + for curr_filter, curr_values in request_params.location_info.items(): if curr_filter in ["region_hebrew", "district_hebrew", "yishuv_name"]: new_filter_name = "accident_" + curr_filter new_filters[new_filter_name] = curr_values - else: - new_filters[curr_filter] = curr_values + new_filters["injury_severity"] = [1, 2, 3, 4, 5] return new_filters