1 package org.opentrafficsim.kpi.sampling.indicator;
2
3 import java.util.List;
4
5 import org.djunits.value.vdouble.scalar.Time;
6 import org.djunits.value.vdouble.scalar.base.DoubleScalarInterface;
7 import org.djutils.exceptions.Throw;
8 import org.opentrafficsim.kpi.interfaces.GtuData;
9 import org.opentrafficsim.kpi.sampling.Query;
10 import org.opentrafficsim.kpi.sampling.TrajectoryGroup;
11
12 /**
13 * Abstract indicator which stores the last calculated value and returns it in {@code getValue()} for an equal query, start time
14 * and end time.
15 * <p>
16 * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
18 * </p>
19 * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
20 * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
21 * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
22 * @param <T> class of the value
23 */
24 public abstract class AbstractIndicator<T extends DoubleScalarInterface<?, ?>>
25 {
26
27 /** Last query. */
28 private Query<?, ?> lastQuery;
29
30 /** Last start time. */
31 private Time lastStartTime;
32
33 /** Last end time. */
34 private Time lastEndTime;
35
36 /** Last value. */
37 private T lastValue;
38
39 /**
40 * Get value for given query over time interval, returning earlier calculated value if possible. This method uses
41 * {@code Time.ZERO} as start time.
42 * @param query Query<G, ?>; query
43 * @param endTime Time; start time of interval to calculate indicator over
44 * @param trajectoryGroups List<TrajectoryGroup<G>>; group of trajectories to calculate the indicator for
45 * @param <G> gtu data type
46 * @return value for given query
47 */
48 public final <G extends GtuData> T getValue(final Query<G, ?> query, final Time endTime,
49 final List<TrajectoryGroup<G>> trajectoryGroups)
50 {
51 return getValue(query, Time.ZERO, endTime, trajectoryGroups);
52 }
53
54 /**
55 * Get value for given query over time interval, returning earlier calculated value if possible.
56 * @param query Query<G, ?>; query
57 * @param startTime Time; start time of interval to calculate indicator over
58 * @param endTime Time; start time of interval to calculate indicator over
59 * @param trajectoryGroups List<TrajectoryGroup<G>>; group of trajectories to calculate the indicator for
60 * @param <G> gtu data type
61 * @return value for given query
62 */
63 public final <G extends GtuData> T getValue(final Query<G, ?> query, final Time startTime, final Time endTime,
64 final List<TrajectoryGroup<G>> trajectoryGroups)
65 {
66 Throw.whenNull(query, "Query may not be null.");
67 Throw.whenNull(startTime, "Start time may not be null.");
68 Throw.whenNull(endTime, "End time may not be null.");
69 if (this.lastQuery == null || !this.lastQuery.equals(query) || !this.lastStartTime.equals(startTime)
70 || !this.lastEndTime.equals(endTime))
71 {
72 this.lastQuery = query;
73 this.lastStartTime = startTime;
74 this.lastEndTime = endTime;
75 this.lastValue = calculate(query, startTime, endTime, trajectoryGroups);
76 }
77 return this.lastValue;
78 }
79
80 /**
81 * Calculate value for given trajectory group.
82 * @param query Query<G, ?>; query
83 * @param startTime Time; start time of interval to calculate indicator over
84 * @param endTime Time; start time of interval to calculate indicator over
85 * @param trajectoryGroups List<TrajectoryGroup<G>>; group of trajectories to calculate the indicator for
86 * @param <G> gtu data type
87 * @return value for given trajectory group
88 */
89 protected abstract <G extends GtuData> T calculate(Query<G, ?> query, Time startTime, Time endTime,
90 List<TrajectoryGroup<G>> trajectoryGroups);
91
92 }