1 package org.opentrafficsim.kpi.sampling;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.djutils.exceptions.Throw;
10 import org.djutils.immutablecollections.ImmutableIterator;
11
12 /**
13 * Set of trajectories to be accepted or rejected for a query. All the trajectories pertain to one GTU. A {@code Query} may
14 * reject or accept all, or a specific subset, based on the specific needs of different {@code FilterDataType}s.
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 */
23 public class TrajectoryAcceptList
24 {
25
26 /** GTU id of the contained trajectories. */
27 private String gtuId;
28
29 /** List of trajectory's. */
30 private final List<Trajectory<?>> trajectoryList = new ArrayList<>();
31
32 /** List of trajectory groups. */
33 private final List<TrajectoryGroup<?>> trajectoryGroupList = new ArrayList<>();
34
35 /** Map of trajectory's and acceptance boolean. */
36 private final Map<Trajectory<?>, Boolean> trajectoryMap = new LinkedHashMap<>();
37
38 /**
39 * Adds a {@code Trajectory} with the {@code TrajectoryGroup} it is from to the accept list. By default it is registered to
40 * be not accepted for a query.
41 * @param trajectory Trajectory<?>; {@code Trajectory} trajectory
42 * @param trajectoryGroup <TrajectoryGroup>; {@code TrajectoryGroup} trajectories
43 * @throws IllegalArgumentException if the {@code Trajectory} is not within the {@code TrajectoryGroup}
44 * @throws IllegalArgumentException if the {@code Trajectory} belongs to a different GTU than an earlier provided
45 * {@code Trajectory}
46 */
47 public final void addTrajectory(final Trajectory<?> trajectory, final TrajectoryGroup<?> trajectoryGroup)
48 {
49 Throw.whenNull(trajectory, "Trajectory may not be null.");
50 Throw.whenNull(trajectoryGroup, "Trajectory group may not be null.");
51 // This is quite a costly check
52 // Throw.when(!trajectoryGroup.contains(trajectory), IllegalArgumentException.class,
53 // "The trajectory should be contained within the trajectory group.");
54 Throw.when(this.gtuId != null && !this.gtuId.equals(trajectory.getGtuId()), IllegalArgumentException.class,
55 "Trajectories of different GTU's may not be in a single trajectory accept list.");
56 this.gtuId = trajectory.getGtuId();
57 this.trajectoryList.add(trajectory);
58 this.trajectoryGroupList.add(trajectoryGroup);
59 this.trajectoryMap.put(trajectory, false);
60 }
61
62 /**
63 * Returns the number of trajectories.
64 * @return number of trajectories
65 */
66 public final int size()
67 {
68 return this.trajectoryList.size();
69 }
70
71 /**
72 * Returns trajectory by index.
73 * @param i int; number of {@code trajectory} to get
74 * @return i'th {@code trajectory}
75 * @throws IndexOutOfBoundsException if the index is out of range (<code>index < 0 || index >= size()</code>)
76 */
77 public final Trajectory<?> getTrajectory(final int i)
78 {
79 return this.trajectoryList.get(i);
80 }
81
82 /**
83 * Returns a trajectory group by index.
84 * @param i int; number of {@code TrajectoryGroup} to get
85 * @return i'th {@code TrajectoryGroup}
86 * @throws IndexOutOfBoundsException if the index is out of range (<code>index < 0 || index >= size()</code>)
87 */
88 public final TrajectoryGroup<?> getTrajectoryGroup(final int i)
89 {
90 return this.trajectoryGroupList.get(i);
91 }
92
93 /**
94 * Returns an iterator over the trajectories.
95 * @return iterator over {@code trajectory}'s, does not allow removal
96 */
97 public final Iterator<Trajectory<?>> getTrajectoryIterator()
98 {
99 return new ImmutableIterator<>(this.trajectoryList.iterator());
100 }
101
102 /**
103 * Returns an iterator over the trajectory groups.
104 * @return iterator over {@code TrajectoryGroup}'s, does not allow removal
105 */
106 public final Iterator<TrajectoryGroup<?>> getTrajectoryGroupIterator()
107 {
108 return new ImmutableIterator<>(this.trajectoryGroupList.iterator());
109 }
110
111 /**
112 * Accept given trajectory.
113 * @param trajectory Trajectory<?>; trajectory to accept
114 * @throws IllegalArgumentException if the trajectory is not part of the trajectory accept list
115 */
116 public final void acceptTrajectory(final Trajectory<?> trajectory)
117 {
118 acceptTrajectory(trajectory, true);
119 }
120
121 /**
122 * Reject given trajectory.
123 * @param trajectory Trajectory<?>; trajectory to reject
124 * @throws IllegalArgumentException if the trajectory is not part of the trajectory accept list
125 */
126 public final void rejectTrajectory(final Trajectory<?> trajectory)
127 {
128 acceptTrajectory(trajectory, false);
129 }
130
131 /**
132 * Accept or reject given trajectory.
133 * @param trajectory Trajectory<?>; trajectory to accept or reject
134 * @param accept boolean; whether to accept the trajectory
135 * @throws IllegalArgumentException if the trajectory is not part of the trajectory accept list
136 */
137 public final void acceptTrajectory(final Trajectory<?> trajectory, final boolean accept)
138 {
139 Throw.when(!this.trajectoryList.contains(trajectory), IllegalArgumentException.class,
140 "The trajectory is not part of the trajectory accept list.");
141 this.trajectoryMap.put(trajectory, accept);
142 }
143
144 /**
145 * Accept all trajectories.
146 */
147 public final void acceptAll()
148 {
149 for (Trajectory<?> trajectory : this.trajectoryList)
150 {
151 this.trajectoryMap.put(trajectory, true);
152 }
153 }
154
155 /**
156 * Reject all trajectories.
157 */
158 public final void rejectAll()
159 {
160 for (Trajectory<?> trajectory : this.trajectoryList)
161 {
162 this.trajectoryMap.put(trajectory, false);
163 }
164 }
165
166 /**
167 * Returns whether the given trajectory is accepted or not.
168 * @param trajectory Trajectory<?>; trajectory
169 * @return whether the given trajectory is accepted or not
170 * @throws IllegalArgumentException if the trajectory is not part of the trajectory accept list
171 */
172 public final boolean isAccepted(final Trajectory<?> trajectory)
173 {
174 Boolean out = this.trajectoryMap.get(trajectory);
175 Throw.when(out == null, IllegalArgumentException.class, "The trajectory is not part of the trajectory accept list.");
176 return out;
177 }
178
179 /** {@inheritDoc} */
180 @Override
181 public final String toString()
182 {
183 return "TrajectoryAcceptList [gtuId=" + this.gtuId + ", " + this.trajectoryList.size() + " trajectories]";
184 }
185
186 }