1616 RoadUserAssignments ,
1717)
1818from OTAnalytics .application .analysis .traffic_counting_specification import (
19+ CountingEvent ,
1920 CountingSpecificationDto ,
2021 ExportCounts ,
2122 ExportFormat ,
@@ -488,12 +489,17 @@ def create_tag(self, assignment: RoadUserAssignment) -> Tag:
488489
489490
490491class TimeslotTagger (Tagger ):
491- def __init__ (self , interval : timedelta ) -> None :
492+ def __init__ (
493+ self ,
494+ interval : timedelta ,
495+ counting_event : CountingEvent = CountingEvent .START ,
496+ ) -> None :
492497 self ._interval = interval
498+ self ._counting_event = counting_event
493499
494500 def create_tag (self , assignment : RoadUserAssignment ) -> Tag :
495501 return create_timeslot_tag (
496- assignment . events . start . interpolated_occurrence , self ._interval
502+ aggregation_time ( assignment , self . _counting_event ) , self ._interval
497503 )
498504
499505
@@ -881,7 +887,8 @@ def create_tagger(self, specification: CountingSpecificationDto) -> Tagger:
881887 """
882888 mode_tagger = ModeTagger ()
883889 time_tagger = TimeslotTagger (
884- timedelta (minutes = specification .interval_in_minutes )
890+ timedelta (minutes = specification .interval_in_minutes ),
891+ counting_event = specification .counting_event ,
885892 )
886893 return CombinedTagger (mode_tagger , time_tagger )
887894
@@ -969,6 +976,14 @@ def end_of(rua: RoadUserAssignment) -> datetime:
969976 return rua .events .end .interpolated_occurrence
970977
971978
979+ def aggregation_time (
980+ rua : RoadUserAssignment , counting_event : CountingEvent
981+ ) -> datetime :
982+ if counting_event == CountingEvent .END :
983+ return end_of (rua )
984+ return start_of (rua )
985+
986+
972987class TrafficCounting :
973988 """
974989 Use case to produce traffic counts.
@@ -1031,19 +1046,22 @@ def __assignment_filter_for(
10311046 specification : CountingSpecificationDto ,
10321047 ) -> Callable [[RoadUserAssignment ], bool ]:
10331048 """Create a filter interval using the given specifications start and end time
1034- as lower and upper bounds respectively.
1049+ as lower and upper bounds respectively. The interval is always closed at the
1050+ start time and open at the end time: [specification-start, specification-end).
1051+ The start time is always inside the interval while the end time is always
1052+ outside the interval.
10351053
10361054 The resulting filter determines whether RoadUserAssignments fall into the
10371055 desired observation interval and should be counted.
10381056
10391057 The is_upper/lower_strict parameters of this TrafficCounting object
10401058 can be used to configure the filter.
10411059 A strict bound does not allow the assignment to overlap the respective bound.
1042- The four combinations are as follows (open = '('; closed = '[') :
1043- - [lower, upper] : both start and end of the rua must be inside the interval
1044- - [lower, upper ): the start of the rua must be inside the interval
1045- - (lower, upper] : the end of the rua must be inside the interval
1046- - (lower, upper ): either start or end of the rua must be in the interval,
1060+ The four combinations are as follows:
1061+ - (True, True) : both start and end of the rua must be inside the interval
1062+ - (True, False ): the start of the rua must be inside the interval
1063+ - (False, True) : the end of the rua must be inside the interval
1064+ - (False, False ): either start or end of the rua must be in the interval,
10471065 or [start, end] must enclose the interval
10481066
10491067 Args:
@@ -1061,18 +1079,18 @@ def __assignment_filter_for(
10611079 is_upper_strict = self ._filter_upper_bound_strict
10621080
10631081 if is_lower_strict and is_upper_strict :
1064- return lambda rua : lower <= start_of (rua ) and end_of (rua ) <= upper
1082+ return lambda rua : lower <= start_of (rua ) and end_of (rua ) < upper
10651083
10661084 elif is_lower_strict and not is_upper_strict :
1067- return lambda rua : lower <= start_of (rua ) <= upper
1085+ return lambda rua : lower <= start_of (rua ) < upper
10681086
10691087 elif not is_lower_strict and is_upper_strict :
1070- return lambda rua : lower <= end_of (rua ) <= upper
1088+ return lambda rua : lower <= end_of (rua ) < upper
10711089
10721090 else :
10731091 return (
1074- lambda rua : lower <= start_of (rua ) <= upper
1075- or lower <= end_of (rua ) <= upper
1092+ lambda rua : lower <= start_of (rua ) < upper
1093+ or lower <= end_of (rua ) < upper
10761094 or (start_of (rua ) <= lower and upper <= end_of (rua ))
10771095 )
10781096
0 commit comments