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.DoubleScalar; 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-2024 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://github.com/wjschakel">Wouter Schakel</a> 22 * @param <T> class of the value 23 */ 24 public abstract class AbstractIndicator<T extends DoubleScalar<?, ?>> 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 }