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