1 package org.opentrafficsim.road.gtu.lane.tactical.pt;
2
3 import java.util.LinkedHashMap;
4 import java.util.List;
5 import java.util.Map;
6 import java.util.Set;
7
8 import org.djunits.value.vdouble.scalar.Duration;
9 import org.djunits.value.vdouble.scalar.Time;
10 import org.djutils.exceptions.Throw;
11 import org.opentrafficsim.core.network.Node;
12 import org.opentrafficsim.core.network.route.Route;
13
14 /**
15 * <p>
16 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
18 * <p>
19 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 24 jan. 2017 <br>
20 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
21 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
22 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
23 */
24 public class BusSchedule extends Route
25 {
26
27 /** */
28 private static final long serialVersionUID = 20170124L;
29
30 /** Line of the bus schedule. */
31 private final String line;
32
33 /** List of bus stops. */
34 private final Map<String, BusStopInfo> schedule = new LinkedHashMap<>();
35
36 /** Map of actual departures stored per bus stop. */
37 private final Map<String, Time> actualDeparturesBusStop = new LinkedHashMap<>();
38
39 /** Map of actual departures stored per conflict. */
40 private final Map<String, Time> actualDeparturesConflict = new LinkedHashMap<>();
41
42 /**
43 * @param id String; id
44 * @param nodes List<Node>; nodes
45 * @param line String; line of the bus schedule
46 */
47 public BusSchedule(final String id, final List<Node> nodes, final String line)
48 {
49 super(id, nodes);
50 this.line = line;
51 }
52
53 /**
54 * @param id String; id
55 * @param line String; line of the bus schedule
56 */
57 public BusSchedule(final String id, final String line)
58 {
59 super(id);
60 this.line = line;
61 }
62
63 /**
64 * Adds a stop to the schedule.
65 * @param busStopId String; bus stop id
66 * @param departureTime Time; departure time
67 * @param dwellTime Duration; dwell time
68 * @param forceSchedule boolean; whether to wait until departure time
69 */
70 public final void addBusStop(final String busStopId, final Time departureTime, final Duration dwellTime,
71 final boolean forceSchedule)
72 {
73 Throw.whenNull(busStopId, "Bus stop id may not be null.");
74 Throw.whenNull(departureTime, "Departure time may not be null.");
75 Throw.whenNull(dwellTime, "Dwell time may not be null.");
76 this.schedule.put(busStopId, new BusStopInfo(departureTime, dwellTime, forceSchedule));
77 }
78
79 /**
80 * Whether the bus of this line should stop for this bus stop. False if not the correct line, or already stopped.
81 * @param busStopId String; id of bus stop
82 * @param time Time; time to check
83 * @return whether the bus of this line should stop for this bus stop
84 */
85 public final boolean isLineStop(final String busStopId, final Time time)
86 {
87 return this.schedule.containsKey(busStopId) && (!this.actualDeparturesConflict.containsKey(busStopId)
88 || time.lt(this.actualDeparturesConflict.get(busStopId)));
89 }
90
91 /**
92 * Returns departure time for the given bus stop.
93 * @param busStopId String; id of bus stop
94 * @return departure time for the given bus stop
95 */
96 public final Time getDepartureTime(final String busStopId)
97 {
98 checkStop(busStopId);
99 return this.schedule.get(busStopId).getDepartureTime();
100 }
101
102 /**
103 * Returns dwell time for the given bus stop.
104 * @param busStopId String; id of bus stop
105 * @return dwell time for the given bus stop
106 */
107 public final Duration getDwellTime(final String busStopId)
108 {
109 checkStop(busStopId);
110 return this.schedule.get(busStopId).getDwellTime();
111 }
112
113 /**
114 * Returns whether the departure time is enforced.
115 * @param busStopId String; id of bus stop
116 * @return whether the departure time is enforced
117 */
118 public final boolean isForceSchedule(final String busStopId)
119 {
120 checkStop(busStopId);
121 return this.schedule.get(busStopId).isForceSchedule();
122 }
123
124 /**
125 * Throws exception when the bus stop is not part of this schedule.
126 * @param busStopId String; id of bus stop
127 * @throws IllegalArgumentException if the bus stop is not part of this schedule
128 */
129 private void checkStop(final String busStopId)
130 {
131 Throw.when(!this.schedule.containsKey(busStopId), IllegalArgumentException.class, "Bus stop %s is not for schedule %s.",
132 busStopId, this);
133 }
134
135 /**
136 * Set actual departure time.
137 * @param busStopId String; bus stop id
138 * @param conflictIds Set<String>; conflicts downstream of the bus stop
139 * @param time Time; actual departure time
140 */
141 public final void setActualDeparture(final String busStopId, final Set<String> conflictIds, final Time time)
142 {
143 this.actualDeparturesBusStop.put(busStopId, time);
144 for (String conflictId : conflictIds)
145 {
146 this.actualDeparturesConflict.put(conflictId, time);
147 }
148 }
149
150 /**
151 * Return the actual departure time.
152 * @param busStopId String; bus stop id
153 * @return actual departure time, {@code null} if not given
154 */
155 public final Time getActualDepartureBusStop(final String busStopId)
156 {
157 return this.actualDeparturesBusStop.get(busStopId);
158 }
159
160 /**
161 * Return the actual departure time.
162 * @param conflictId String; conflict id
163 * @return actual departure time, {@code null} if not given
164 */
165 public final Time getActualDepartureConflict(final String conflictId)
166 {
167 return this.actualDeparturesConflict.get(conflictId);
168 }
169
170 /**
171 * @return line.
172 */
173 public final String getLine()
174 {
175 return this.line;
176 }
177
178 /** {@inheritDoc} */
179 @Override
180 public final String toString()
181 {
182 return "BusSchedule [id=" + getId() + ", line=" + this.line + "]";
183 }
184
185 /**
186 * Class to contain info regarding a stop in the schedule.
187 * <p>
188 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
189 * <br>
190 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
191 * <p>
192 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 24 jan. 2017 <br>
193 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
194 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
195 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
196 */
197 private class BusStopInfo
198 {
199
200 /** Departure time. */
201 private final Time departureTime;
202
203 /** Dwell time. */
204 private final Duration dwellTime;
205
206 /** Whether to wait until departure time. */
207 private final boolean forceSchedule;
208
209 /**
210 * @param departureTime Time; departure time
211 * @param dwellTime Duration; dwell time
212 * @param forceSchedule boolean; whether to wait until departure time
213 */
214 BusStopInfo(final Time departureTime, final Duration dwellTime, final boolean forceSchedule)
215 {
216 this.departureTime = departureTime;
217 this.dwellTime = dwellTime;
218 this.forceSchedule = forceSchedule;
219 }
220
221 /**
222 * @return departureTime.
223 */
224 public final Time getDepartureTime()
225 {
226 return this.departureTime;
227 }
228
229 /**
230 * @return dwellTime.
231 */
232 public final Duration getDwellTime()
233 {
234 return this.dwellTime;
235 }
236
237 /**
238 * @return forceSchedule.
239 */
240 public final boolean isForceSchedule()
241 {
242 return this.forceSchedule;
243 }
244
245 /** {@inheritDoc} */
246 @Override
247 public String toString()
248 {
249 return "BusStopInfo [departureTime=" + this.departureTime + ", dwellTime=" + this.dwellTime + ", forceSchedule="
250 + this.forceSchedule + "]";
251 }
252
253 }
254
255 }