1 package org.opentrafficsim.road.network.lane.object;
2
3 import java.util.LinkedHashSet;
4 import java.util.List;
5 import java.util.Set;
6
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.djutils.immutablecollections.Immutable;
9 import org.djutils.immutablecollections.ImmutableHashSet;
10 import org.djutils.immutablecollections.ImmutableMap;
11 import org.djutils.immutablecollections.ImmutableSet;
12 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class BusStop extends AbstractLaneBasedObject
38 {
39
40
41 private static final long serialVersionUID = 20170124L;
42
43
44 private final Set<String> lines = new LinkedHashSet<>();
45
46
47 private final String name;
48
49
50 private Set<Conflict> conflicts = null;
51
52
53
54
55
56
57
58
59
60 public BusStop(final String id, final Lane lane, final Length longitudinalPosition, final String name,
61 final OTSSimulatorInterface simulator) throws NetworkException
62 {
63 super(id, lane, LongitudinalDirectionality.DIR_PLUS, longitudinalPosition,
64 LaneBasedObject.makeGeometry(lane, longitudinalPosition), Length.ZERO);
65 this.name = name;
66
67 init();
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 ImmutableMap<Lane, GTUDirectionality> downstreamLanes =
121 lane.downstreamLanes(dir, lane.getNetwork().getGtuType(GTUType.DEFAULTS.BUS));
122 int numLanes = 0;
123 for (Lane nextLane : downstreamLanes.keySet())
124 {
125 if (nextLane.getParentLink().getPriority().isBusStop())
126 {
127 numLanes++;
128 lane = nextLane;
129 dir = downstreamLanes.get(lane);
130 position = dir.isPlus() ? Length.ZERO : lane.getLength();
131 }
132 }
133 if (numLanes != 1)
134 {
135 lane = null;
136 }
137 }
138 }
139 return this.conflicts;
140 }
141
142
143 @Override
144 public final int hashCode()
145 {
146 final int prime = 31;
147 int result = 1;
148 result = prime * result + this.getId().hashCode();
149 return result;
150 }
151
152
153 @Override
154 public final boolean equals(final Object obj)
155 {
156 if (this == obj)
157 {
158 return true;
159 }
160 if (obj == null)
161 {
162 return false;
163 }
164 if (getClass() != obj.getClass())
165 {
166 return false;
167 }
168 BusStop other = (BusStop) obj;
169 if (!this.getId().equals(other.getId()))
170 {
171 return false;
172 }
173 return true;
174 }
175
176
177 @Override
178 public final String toString()
179 {
180 String out = "BusStop [id=" + getId() + ", lines=";
181 String delim = "";
182 for (String line : this.lines)
183 {
184 out = out + delim + line;
185 delim = "/";
186 }
187 return out + "]";
188 }
189
190
191 @Override
192 public final AbstractLaneBasedObject clone(final CrossSectionElement newCSE,
193 final OTSSimulatorInterface newSimulator) throws NetworkException
194 {
195 BusStop busStop = new BusStop(getId(), (Lane) newCSE, getLongitudinalPosition(), this.name, newSimulator);
196 busStop.setLines(this.lines);
197 return busStop;
198 }
199
200 }