def off_distance(distance_limit=None, **kwargs): # faverolles 12/27/2019: ??? not defined anywhere # distance_limit = abs(distance_limit) if distance_limit else DEFAULT_DOWNSTREAM_DISTANCE_LIMIT distance_limit = abs(distance_limit) if distance_limit else 0 return ExtFilter(SLOT_INCIDENT, [ lambda item: -distance_limit <= item.off_distance <= distance_limit, ], **kwargs)
def _iris_type(itype, **kwargs): distance_limit = _get_distance_limit(**kwargs) return ExtFilter(SLOT_INCIDENT, [ _distance_checker(**kwargs), lambda item: item._incident._incident_type.iris_class and item. _incident._incident_type.iris_class.lower() == itype.lower(), ], **kwargs)
def severity_injury_all(**kwargs): f1 = severity_injury_personal(**kwargs) f2 = severity_injury_serious(**kwargs) def _check(item): return f1.check(item) or f2.check(item) return ExtFilter(SLOT_INCIDENT, [_check], **kwargs)
def severity_other(**kwargs): f1 = severity_injury_all(**kwargs) f2 = severity_property_damage(**kwargs) f3 = severity_fatal(**kwargs) def _check(item): return not f1.check(item) and not f2.check(item) and not f3.check(item) return ExtFilter(SLOT_INCIDENT, [_check], **kwargs)
def has_weather_implicit(**kwargs): """ :rtype: pyticas_tetres.rengine.filter.ftypes.IExtFilter """ return Or_( _type([1, 2, 3, 4, 5, 6, 7, 8], **kwargs), ExtFilter(SLOT_WEATHER, [lambda item: item._weather.precip not in [0, None, '']], **kwargs))
def no_workzone(**kwargs): kwargs['pass_on_nodata'] = True kwargs['all_items_should_pass'] = True dn_distance_limit, up_distance_limit = _get_distance_limit(**kwargs) return ExtFilter(SLOT_WORKZONE, [ lambda item: ((item.off_distance < 0 and -up_distance_limit > item.off_distance) or (item.off_distance > 0 and dn_distance_limit < item.off_distance)) ], **kwargs)
def normal_implicit(**kwargs): """ :rtype: pyticas_tetres.rengine.filter.ftypes.IExtFilter """ return And_( _type([0, 9, 99], **kwargs), # including Unknown, Missing ExtFilter(SLOT_WEATHER, [lambda item: item._weather.precip in [0, None, '']], **kwargs))
def has_closed(**kwargs): def _func(item): for f in item._workzone._features: if f.has_closed: return True return False return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), _func, ], **kwargs)
def lane_config(origin_lanes, open_lanes, **kwargs): def _func(item): for f in item._workzone._laneconfigs: if f.origin_lanes == origin_lanes and f.open_lanes == open_lanes: return True return False return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), _func, ], **kwargs)
def closed_length(min_length, max_length, **kwargs): def _func(item): for f in item._workzone._features: if min_length <= f.closed_length <= max_length: return True return False return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), _func, ], **kwargs)
def has_crossover(**kwargs): def _func(item): for f in item._workzone._features: if f.use_opposing_lane or f.use_opposing_lane: return True return False return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), _func, ], **kwargs)
def length(min_length, max_length, **kwargs): def _func(item): try: return min_length <= item._workzone.workzone_length <= max_length except: return False return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), _func, ], **kwargs)
def precip(min_precip, max_precip, **kwargs): """ :type min_precip: float :type max_precip: float :rtype: pyticas_tetres.rengine.filter.ftypes.ExtFilter """ wtypes = [1, 2, 3, 4, 5, 6, 7, 8] return ExtFilter(SLOT_WEATHER, [ lambda item: (min_precip <= item._weather.precip <= max_precip and item ._weather.precip_type in wtypes) ], **kwargs)
def _intensity(intensities, **kwargs): """ :type intensities: Union(list, object) :rtype: pyticas_tetres.rengine.filter.ftypes.ExtFilter """ # `intensity` is saved as string into database if isinstance(intensities, list): intensities = [str(intensity) for intensity in intensities] else: intensities = str(intensities) return ExtFilter(SLOT_WEATHER, [ lambda item: (item._weather.precip_intensity in intensities) if isinstance(intensities, list) else (item._weather.precip_intensity == intensities) ], **kwargs)
def _loc(loc_type, **kwargs): if isinstance(loc_type, list): loc_type = [str(wt) for wt in loc_type] else: loc_type = str(loc_type) def _check_loc(item): """ :type item: pyticas_tetres.ttypes.TTWorkzoneInfo :return: """ if isinstance(loc_type, list): # print('----- check_loc : ', item.loc_type in loc_type, ' : ', item.loc_type, loc_type) return str(item.loc_type) in loc_type else: return str(item.loc_type) == loc_type return ExtFilter(SLOT_WORKZONE, [_distance_checker(**kwargs), _check_loc], **kwargs)
def iris_impact_blocked(n, op='eq', **kwargs): """ 'n' lanes are blocked ? Caution: number of blocked lanes includes shoulder Args: op : can be 'eq', 'gt', 'gte', 'lt', 'lte' :param int n: number of blocked lanes :param str op: operator """ symbols = kwargs.get('symbols', '!?') distance_limit = _get_distance_limit(**kwargs) def _check_impact(item): """ :type item: pyticas_tetres.ttypes.TTIncidentInfo :rtype: """ impact = item._incident.impact if not impact: return False count = sum([impact.count(s) for s in symbols]) if op == 'eq': return count == n elif op == 'gt': return count > n elif op == 'gte': return count >= n elif op == 'lt': return count < n elif op == 'lte': return count <= n else: raise Exception('Not supported operator') return ExtFilter( SLOT_INCIDENT, [lambda item: 0 <= item.off_distance <= distance_limit, _check_impact], **kwargs)
def _flag(flag_names, target_value, **kwargs): """ :type flag_names: list[str] :type target_value: bool :rtype: callable """ def _check(item): """ :type item: pyticas_tetres.ttypes.TTIncidentInfo :rtype: """ for fn in flag_names: if getattr(item._incident._incident_type, fn, False) == target_value: return True return False return ExtFilter(SLOT_INCIDENT, [_distance_checker(**kwargs), _check], **kwargs)
def _has_attr(attr_name, target_strings, **kwargs): """ :type target_strings: list[str] :rtype: """ def _check_etype(item): """ :type item: pyticas_tetres.ttypes.TTIncidentInfo :rtype: """ etype = getattr(item._incident._incident_type, attr_name, '').lower() if not attr_name: return False for ts in target_strings: if ts.lower() in etype: return True return False return ExtFilter(SLOT_INCIDENT, [_distance_checker(**kwargs), _check_etype], **kwargs)
def _type(data, **kwargs): distance_limit = _get_distance_limit(**kwargs) if isinstance(data, list): data = [str(wt) for wt in data] else: data = str(data) def _check_type(item): """ :type item: pyticas_tetres.ttypes.TTSpecialeventInfo :return: """ if isinstance(data, list): return item.event_type in data else: return item.event_type == data return ExtFilter(SLOT_SPECIALEVENT, [ lambda item: item.distance < distance_limit, _check_type, ], **kwargs)
def _type(wtypes, **kwargs): """ :type wtypes: Union(list, object) :rtype: pyticas_tetres.rengine.filter.ftypes.ExtFilter """ # `precip_type` is saved as string into database if isinstance(wtypes, list): wtypes = [str(wt) for wt in wtypes] else: wtypes = str(wtypes) def _check_type(item): """ :type item: pyticas_tetres.db.model.TTWeather :return: """ if isinstance(wtypes, list): return item._weather.precip_type in wtypes else: return item._weather.precip_type == wtypes return ExtFilter(SLOT_WEATHER, [_check_type], **kwargs)
def distance(min_distance, max_distance, **kwargs): return ExtFilter(SLOT_SPECIALEVENT, [ lambda item: min_distance <= item.distance < max_distance, ], **kwargs)
def no_snowmanagement(**kwargs): kwargs['pass_on_nodata'] = True kwargs['all_items_should_pass'] = True return ExtFilter(SLOT_SNOWMANAGEMENT, [ lambda item: item.loc_type not in OVERLAPPED_LOC_TYPES, ], **kwargs)
def has_workzone(**kwargs): return ExtFilter(SLOT_WORKZONE, [ _distance_checker(**kwargs), ], **kwargs)
def loc_inside(**kwargs): distance_limit = _get_distance_limit(**kwargs) return ExtFilter(SLOT_INCIDENT, [ lambda item: 0 <= item.off_distance <= distance_limit, lambda item: item.off_distance == 0, ], **kwargs)
def loc_downstream(**kwargs): distance_limit = _get_distance_limit(**kwargs) return ExtFilter(SLOT_INCIDENT, [ lambda item: 0 <= item.off_distance <= distance_limit, lambda item: item.off_distance > 0, ], **kwargs)
def has_incident(**kwargs): return ExtFilter(SLOT_INCIDENT, [ _distance_checker(**kwargs), ], **kwargs)
def _impact(impact_value, **kwargs): def _check_impact(item): return impact_value == item._workzone._wz_group.impact return ExtFilter(SLOT_WORKZONE, [_distance_checker(**kwargs), _check_impact], **kwargs)
def has_specialevent(**kwargs): distance_limit = _get_distance_limit(**kwargs) return ExtFilter(SLOT_SPECIALEVENT, [ lambda item: item.distance <= distance_limit, ], **kwargs)
def has_snowmanagement(**kwargs): return ExtFilter(SLOT_SNOWMANAGEMENT, [ lambda item: item.loc_type in OVERLAPPED_LOC_TYPES, ], **kwargs)
def attendance(min_attendance, max_attendance, **kwargs): return ExtFilter(SLOT_SPECIALEVENT, [ lambda item: min_attendance <= item._specialevent.attendance < max_attendance, ], **kwargs)