1 package org.opentrafficsim.kpi.sampling;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.djunits.value.vdouble.scalar.Time;
8
9 import nl.tudelft.simulation.language.Throw;
10
11
12
13
14
15
16
17
18
19
20
21
22
23 public class TrajectoryGroup
24 {
25
26
27 private final Time startTime;
28
29
30 private final Length startPosition;
31
32
33 private final Length endPosition;
34
35
36 private final KpiLaneDirection laneDirection;
37
38
39 private final List<Trajectory> trajectories = new ArrayList<>();
40
41
42
43
44
45
46 public TrajectoryGroup(final Time startTime, final KpiLaneDirection laneDirection)
47 {
48 this(startTime, Length.ZERO, laneDirection == null ? null : laneDirection.getLaneData().getLength(), laneDirection);
49 }
50
51
52
53
54
55
56
57 public TrajectoryGroup(final Time startTime, final Length startPosition, final Length endPosition,
58 final KpiLaneDirection laneDirection)
59 {
60 Throw.whenNull(startTime, "Start time may not be null.");
61
62 Throw.whenNull(laneDirection, "Lane direction time may not be null.");
63 Throw.whenNull(startPosition, "Start position may not be null");
64 Throw.whenNull(endPosition, "End position may not be null");
65 Length length0 = laneDirection.getPositionInDirection(startPosition);
66 Length length1 = laneDirection.getPositionInDirection(endPosition);
67 Throw.when(length0.gt(length1), IllegalArgumentException.class,
68 "Start position should be smaller than end position in the direction of travel");
69 this.startTime = startTime;
70 this.startPosition = startPosition;
71 this.endPosition = endPosition;
72 this.laneDirection = laneDirection;
73 }
74
75
76
77
78
79 public final void addTrajectory(final Trajectory trajectory)
80 {
81 this.trajectories.add(trajectory);
82 }
83
84
85
86
87 public final Time getStartTime()
88 {
89 return this.startTime;
90 }
91
92
93
94
95 public final Length getLength()
96 {
97 return this.endPosition.minus(this.startPosition);
98 }
99
100
101
102
103
104
105
106 public final boolean contains(final Trajectory trajectory)
107 {
108 return this.trajectories.contains(trajectory);
109 }
110
111
112
113
114
115 public final int size()
116 {
117 return this.trajectories.size();
118 }
119
120
121
122
123
124 public final List<Trajectory> getTrajectories()
125 {
126 return new ArrayList<>(this.trajectories);
127 }
128
129
130
131
132
133
134
135 public final TrajectoryGroup getTrajectoryGroup(final Length x0, final Length x1)
136 {
137 Length minLenght = Length.max(x0, this.startPosition);
138 Length maxLenght = Length.min(x1, this.endPosition);
139 TrajectoryGroup out = new TrajectoryGroup(this.startTime, minLenght, maxLenght, this.laneDirection);
140 for (Trajectory trajectory : this.trajectories)
141 {
142 out.addTrajectory(trajectory.subSet(x0, x1));
143 }
144 return out;
145 }
146
147
148
149
150
151
152
153 public final TrajectoryGroup getTrajectoryGroup(final Time t0, final Time t1)
154 {
155 TrajectoryGroup out = new TrajectoryGroup(this.startTime.lt(t0) ? t0 : this.startTime, this.laneDirection);
156 for (Trajectory trajectory : this.trajectories)
157 {
158 out.addTrajectory(trajectory.subSet(t0, t1));
159 }
160 return out;
161 }
162
163
164
165
166
167
168
169
170
171 public final TrajectoryGroup getTrajectoryGroup(final Length x0, final Length x1, final Time t0, final Time t1)
172 {
173 TrajectoryGroup out = new TrajectoryGroup(this.startTime.lt(t0) ? t0 : this.startTime, this.laneDirection);
174 for (Trajectory trajectory : this.trajectories)
175 {
176 out.addTrajectory(trajectory.subSet(x0, x1, t0, t1));
177 }
178 return out;
179 }
180
181
182
183
184
185 public final KpiLaneDirection getLaneDirection()
186 {
187 return this.laneDirection;
188 }
189
190
191 @Override
192 public final int hashCode()
193 {
194 final int prime = 31;
195 int result = 1;
196 result = prime * result + ((this.laneDirection == null) ? 0 : this.laneDirection.hashCode());
197 result = prime * result + ((this.endPosition == null) ? 0 : this.endPosition.hashCode());
198 result = prime * result + ((this.startPosition == null) ? 0 : this.startPosition.hashCode());
199 result = prime * result + ((this.startTime == null) ? 0 : this.startTime.hashCode());
200 result = prime * result + ((this.trajectories == null) ? 0 : this.trajectories.hashCode());
201 return result;
202 }
203
204
205 @Override
206 public final boolean equals(final Object obj)
207 {
208 if (this == obj)
209 {
210 return true;
211 }
212 if (obj == null)
213 {
214 return false;
215 }
216 if (getClass() != obj.getClass())
217 {
218 return false;
219 }
220 TrajectoryGroup other = (TrajectoryGroup) obj;
221 if (this.laneDirection == null)
222 {
223 if (other.laneDirection != null)
224 {
225 return false;
226 }
227 }
228 else if (!this.laneDirection.equals(other.laneDirection))
229 {
230 return false;
231 }
232 if (this.endPosition == null)
233 {
234 if (other.endPosition != null)
235 {
236 return false;
237 }
238 }
239 else if (!this.endPosition.equals(other.endPosition))
240 {
241 return false;
242 }
243 if (this.startPosition == null)
244 {
245 if (other.startPosition != null)
246 {
247 return false;
248 }
249 }
250 else if (!this.startPosition.equals(other.startPosition))
251 {
252 return false;
253 }
254 if (this.startTime == null)
255 {
256 if (other.startTime != null)
257 {
258 return false;
259 }
260 }
261 else if (!this.startTime.equals(other.startTime))
262 {
263 return false;
264 }
265 if (this.trajectories == null)
266 {
267 if (other.trajectories != null)
268 {
269 return false;
270 }
271 }
272 else if (!this.trajectories.equals(other.trajectories))
273 {
274 return false;
275 }
276 return true;
277 }
278
279
280 @Override
281 public final String toString()
282 {
283 return "TrajectoryGroup [startTime=" + this.startTime + ", minLength=" + this.startPosition + ", maxLength="
284 + this.endPosition + ", laneDirection=" + this.laneDirection + "]";
285 }
286
287 }