View Javadoc
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-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   */
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&lt;?&gt;; {@code Trajectory} trajectory
42       * @param trajectoryGroup &lt;TrajectoryGroup&gt;; {@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 &lt; 0 || index &gt;= 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 &lt; 0 || index &gt;= 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&lt;?&gt;; 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&lt;?&gt;; 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&lt;?&gt;; 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&lt;?&gt;; 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 }