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