1 package org.opentrafficsim.road.gtu.tactical.pt;
2
3 import java.util.LinkedHashMap;
4 import java.util.List;
5 import java.util.Map;
6 import java.util.Optional;
7 import java.util.Set;
8
9 import org.djunits.value.vdouble.scalar.Duration;
10 import org.djutils.exceptions.Throw;
11 import org.opentrafficsim.core.gtu.GtuType;
12 import org.opentrafficsim.core.network.NetworkException;
13 import org.opentrafficsim.core.network.Node;
14 import org.opentrafficsim.core.network.route.Route;
15
16
17
18
19
20
21
22
23
24
25 public class BusSchedule extends Route
26 {
27
28
29 private final String line;
30
31
32 private final Map<String, BusStopInfo> schedule = new LinkedHashMap<>();
33
34
35 private final Map<String, Duration> actualDeparturesBusStop = new LinkedHashMap<>();
36
37
38 private final Map<String, Duration> actualDeparturesConflict = new LinkedHashMap<>();
39
40
41
42
43
44
45
46
47
48 public BusSchedule(final String id, final GtuType gtuType, final List<Node> nodes, final String line)
49 throws NetworkException
50 {
51 super(id, gtuType, nodes);
52 this.line = line;
53 }
54
55
56
57
58
59
60
61 public BusSchedule(final String id, final GtuType gtuType, final String line)
62 {
63 super(id, gtuType);
64 this.line = line;
65 }
66
67
68
69
70
71
72
73
74 public void addBusStop(final String busStopId, final Duration departureTime, final Duration dwellTime,
75 final boolean forceSchedule)
76 {
77 Throw.whenNull(busStopId, "Bus stop id may not be null.");
78 Throw.whenNull(departureTime, "Departure time may not be null.");
79 Throw.whenNull(dwellTime, "Dwell time may not be null.");
80 this.schedule.put(busStopId, new BusStopInfo(departureTime, dwellTime, forceSchedule));
81 }
82
83
84
85
86
87
88
89 public boolean isLineStop(final String busStopId, final Duration time)
90 {
91 return this.schedule.containsKey(busStopId) && (!this.actualDeparturesConflict.containsKey(busStopId)
92 || time.lt(this.actualDeparturesConflict.get(busStopId)));
93 }
94
95
96
97
98
99
100 public Duration getDepartureTime(final String busStopId)
101 {
102 checkStop(busStopId);
103 return this.schedule.get(busStopId).getDepartureTime();
104 }
105
106
107
108
109
110
111 public Duration getDwellTime(final String busStopId)
112 {
113 checkStop(busStopId);
114 return this.schedule.get(busStopId).getDwellTime();
115 }
116
117
118
119
120
121
122 public boolean isForceSchedule(final String busStopId)
123 {
124 checkStop(busStopId);
125 return this.schedule.get(busStopId).isForceSchedule();
126 }
127
128
129
130
131
132
133 private void checkStop(final String busStopId)
134 {
135 Throw.when(!this.schedule.containsKey(busStopId), IllegalArgumentException.class, "Bus stop %s is not for schedule %s.",
136 busStopId, this);
137 }
138
139
140
141
142
143
144
145 public void setActualDeparture(final String busStopId, final Set<String> conflictIds, final Duration time)
146 {
147 this.actualDeparturesBusStop.put(busStopId, time);
148 for (String conflictId : conflictIds)
149 {
150 this.actualDeparturesConflict.put(conflictId, time);
151 }
152 }
153
154
155
156
157
158
159 public Optional<Duration> getActualDepartureBusStop(final String busStopId)
160 {
161 return Optional.ofNullable(this.actualDeparturesBusStop.get(busStopId));
162 }
163
164
165
166
167
168
169 public Optional<Duration> getActualDepartureConflict(final String conflictId)
170 {
171 return Optional.ofNullable(this.actualDeparturesConflict.get(conflictId));
172 }
173
174
175
176
177
178 public String getLine()
179 {
180 return this.line;
181 }
182
183 @Override
184 public String toString()
185 {
186 return "BusSchedule [id=" + getId() + ", line=" + this.line + "]";
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200 private class BusStopInfo
201 {
202
203
204 private final Duration departureTime;
205
206
207 private final Duration dwellTime;
208
209
210 private final boolean forceSchedule;
211
212
213
214
215
216
217 BusStopInfo(final Duration departureTime, final Duration dwellTime, final boolean forceSchedule)
218 {
219 this.departureTime = departureTime;
220 this.dwellTime = dwellTime;
221 this.forceSchedule = forceSchedule;
222 }
223
224
225
226
227 public final Duration getDepartureTime()
228 {
229 return this.departureTime;
230 }
231
232
233
234
235 public final Duration getDwellTime()
236 {
237 return this.dwellTime;
238 }
239
240
241
242
243 public final boolean isForceSchedule()
244 {
245 return this.forceSchedule;
246 }
247
248 @Override
249 public String toString()
250 {
251 return "BusStopInfo [departureTime=" + this.departureTime + ", dwellTime=" + this.dwellTime + ", forceSchedule="
252 + this.forceSchedule + "]";
253 }
254
255 }
256
257 }