1 package org.opentrafficsim.road.network.lane.object;
2
3 import java.rmi.RemoteException;
4 import java.util.HashSet;
5 import java.util.LinkedHashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import javax.naming.NamingException;
11
12 import org.djunits.value.vdouble.scalar.Length;
13 import org.opentrafficsim.core.gtu.GTUDirectionality;
14 import org.opentrafficsim.core.gtu.GTUType;
15 import org.opentrafficsim.core.network.LongitudinalDirectionality;
16 import org.opentrafficsim.core.network.NetworkException;
17 import org.opentrafficsim.road.network.animation.BusStopAnimation;
18 import org.opentrafficsim.road.network.lane.CrossSectionElement;
19 import org.opentrafficsim.road.network.lane.Lane;
20 import org.opentrafficsim.road.network.lane.conflict.BusStopConflictRule;
21 import org.opentrafficsim.road.network.lane.conflict.Conflict;
22
23 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
24 import nl.tudelft.simulation.immutablecollections.Immutable;
25 import nl.tudelft.simulation.immutablecollections.ImmutableHashSet;
26 import nl.tudelft.simulation.immutablecollections.ImmutableSet;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public class BusStop extends AbstractLaneBasedObject
44 {
45
46
47 private static final long serialVersionUID = 20170124L;
48
49
50 private final Set<String> lines = new HashSet<>();
51
52
53 private final String name;
54
55
56 private Set<Conflict> conflicts = null;
57
58
59
60
61
62
63
64
65
66 public BusStop(final String id, final Lane lane, final Length longitudinalPosition, final String name,
67 final SimulatorInterface.TimeDoubleUnit simulator) throws NetworkException
68 {
69 super(id, lane, LongitudinalDirectionality.DIR_PLUS, longitudinalPosition,
70 LaneBasedObject.makeGeometry(lane, longitudinalPosition), Length.ZERO);
71 this.name = name;
72
73 try
74 {
75 new BusStopAnimation(this, simulator);
76 }
77 catch (RemoteException | NamingException exception)
78 {
79 throw new NetworkException(exception);
80 }
81 }
82
83
84
85
86
87 public final void setLines(final Set<String> lines)
88 {
89 this.lines.clear();
90 this.lines.addAll(lines);
91 }
92
93
94
95
96
97 public final ImmutableSet<String> getLines()
98 {
99 return new ImmutableHashSet<>(this.lines, Immutable.COPY);
100 }
101
102
103
104
105
106 public final Set<Conflict> getConflicts()
107 {
108 if (this.conflicts == null)
109 {
110 this.conflicts = new LinkedHashSet<>();
111 Lane lane = getLane();
112
113 GTUDirectionality dir = getDirection().isForward() ? GTUDirectionality.DIR_PLUS : GTUDirectionality.DIR_MINUS;
114 Length position = getLongitudinalPosition();
115 while (lane != null)
116 {
117 List<LaneBasedObject> objects = lane.getObjectAhead(position, dir);
118 while (objects != null)
119 {
120 for (LaneBasedObject object : objects)
121 {
122 if (object instanceof Conflict)
123 {
124 Conflict conflict = (Conflict) object;
125 if (conflict.getConflictRule() instanceof BusStopConflictRule)
126 {
127 this.conflicts.add(conflict);
128 }
129 }
130 }
131 objects = lane.getObjectAhead(objects.get(0).getLongitudinalPosition(), dir);
132 }
133 Map<Lane, GTUDirectionality> downstreamLanes = lane.downstreamLanes(dir, GTUType.BUS);
134 int numLanes = 0;
135 for (Lane nextLane : downstreamLanes.keySet())
136 {
137 if (nextLane.getParentLink().getPriority().isBusStop())
138 {
139 numLanes++;
140 lane = nextLane;
141 dir = downstreamLanes.get(lane);
142 position = dir.isPlus() ? Length.ZERO : lane.getLength();
143 }
144 }
145 if (numLanes != 1)
146 {
147 lane = null;
148 }
149 }
150 }
151 return this.conflicts;
152 }
153
154
155 @Override
156 public final int hashCode()
157 {
158 final int prime = 31;
159 int result = 1;
160 result = prime * result + this.getId().hashCode();
161 return result;
162 }
163
164
165 @Override
166 public final boolean equals(final Object obj)
167 {
168 if (this == obj)
169 {
170 return true;
171 }
172 if (obj == null)
173 {
174 return false;
175 }
176 if (getClass() != obj.getClass())
177 {
178 return false;
179 }
180 BusStop other = (BusStop) obj;
181 if (!this.getId().equals(other.getId()))
182 {
183 return false;
184 }
185 return true;
186 }
187
188
189 @Override
190 public final String toString()
191 {
192 String out = "BusStop [id=" + getId() + ", lines=";
193 String delim = "";
194 for (String line : this.lines)
195 {
196 out = out + delim + line;
197 delim = "/";
198 }
199 return out + "]";
200 }
201
202
203 @Override
204 public final AbstractLaneBasedObject clone(final CrossSectionElement newCSE, final SimulatorInterface.TimeDoubleUnit newSimulator,
205 final boolean animation) throws NetworkException
206 {
207 BusStop busStop = new BusStop(getId(), (Lane) newCSE, getLongitudinalPosition(), this.name, newSimulator);
208 busStop.setLines(this.lines);
209 return busStop;
210 }
211
212 }