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