1 package org.opentrafficsim.core.network;
2
3 import java.io.Serializable;
4 import java.util.LinkedHashSet;
5 import java.util.Set;
6
7 import javax.media.j3d.Bounds;
8
9 import org.djunits.value.vdouble.scalar.Length;
10 import org.opentrafficsim.core.geometry.OTSLine3D;
11 import org.opentrafficsim.core.gtu.GTU;
12 import org.opentrafficsim.core.gtu.GTUType;
13
14 import nl.tudelft.simulation.dsol.animation.Locatable;
15 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
16 import nl.tudelft.simulation.event.EventProducer;
17 import nl.tudelft.simulation.language.Throw;
18 import nl.tudelft.simulation.language.d3.DirectedPoint;
19
20
21
22
23
24
25
26
27
28
29
30
31 public class OTSLink extends EventProducer implements Link, Serializable, Locatable
32 {
33
34 private static final long serialVersionUID = 20150101L;
35
36
37 private final Network network;
38
39
40 private final String id;
41
42
43 private final Node startNode;
44
45
46 private final Node endNode;
47
48
49 private final LinkType linkType;
50
51
52 private final OTSLine3D designLine;
53
54
55 private final SimulatorInterface.TimeDoubleUnit simulator;
56
57
58 private final Set<GTU> gtus = new LinkedHashSet<>();
59
60
61
62
63
64
65
66
67
68
69
70
71
72 @SuppressWarnings("checkstyle:parameternumber")
73 public OTSLink(final Network network, final String id, final Node startNode, final Node endNode, final LinkType linkType,
74 final OTSLine3D designLine, final SimulatorInterface.TimeDoubleUnit simulator) throws NetworkException
75 {
76 Throw.whenNull(network, "network cannot be null");
77 Throw.whenNull(id, "id cannot be null");
78 Throw.whenNull(startNode, "startNode cannot be null");
79 Throw.whenNull(endNode, "endNode cannot be null");
80 Throw.whenNull(linkType, "linkType cannot be null");
81 Throw.whenNull(designLine, "designLine cannot be null");
82 Throw.whenNull(simulator, "simulator cannot be null");
83
84 this.network = network;
85 this.id = id;
86 this.startNode = startNode;
87 this.endNode = endNode;
88 this.linkType = linkType;
89 this.startNode.addLink(this);
90 this.endNode.addLink(this);
91 this.designLine = designLine;
92 this.simulator = simulator;
93 this.network.addLink(this);
94 }
95
96
97
98
99
100
101
102
103
104
105 protected OTSLink(final Network newNetwork, final SimulatorInterface.TimeDoubleUnit newSimulator, final boolean animation,
106 final OTSLink link) throws NetworkException
107 {
108 this(newNetwork, link.id, newNetwork.getNode(link.startNode.getId()), newNetwork.getNode(link.endNode.getId()),
109 link.linkType, link.designLine, newSimulator);
110 }
111
112
113 @Override
114 public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
115 {
116 return this.getLinkType().getDirectionality(gtuType, true);
117 }
118
119
120 @Override
121 public final void addGTU(final GTU gtu)
122 {
123 if (!this.gtus.contains(gtu))
124 {
125 this.gtus.add(gtu);
126 fireTimedEvent(Link.GTU_ADD_EVENT, new Object[] { gtu.getId(), gtu, this.gtus.size() },
127 gtu.getSimulator().getSimulatorTime());
128 }
129 }
130
131
132 @Override
133 public final void removeGTU(final GTU gtu)
134 {
135 if (this.gtus.contains(gtu))
136 {
137 this.gtus.remove(gtu);
138 fireTimedEvent(Link.GTU_REMOVE_EVENT, new Object[] { gtu.getId(), gtu, this.gtus.size() },
139 gtu.getSimulator().getSimulatorTime());
140 }
141 }
142
143
144 @Override
145 public final Set<GTU> getGTUs()
146 {
147 return new LinkedHashSet<>(this.gtus);
148 }
149
150
151 @Override
152 public final int getGTUCount()
153 {
154 return this.gtus.size();
155 }
156
157
158 @Override
159 public final Network getNetwork()
160 {
161 return this.network;
162 }
163
164
165 @Override
166 public final String getId()
167 {
168 return this.id;
169 }
170
171
172 @Override
173 public final Node getStartNode()
174 {
175 return this.startNode;
176 }
177
178
179 @Override
180 public final Node getEndNode()
181 {
182 return this.endNode;
183 }
184
185
186 @Override
187 public final LinkType getLinkType()
188 {
189 return this.linkType;
190 }
191
192
193 @Override
194 public final OTSLine3D getDesignLine()
195 {
196 return this.designLine;
197 }
198
199
200 @Override
201 public final SimulatorInterface.TimeDoubleUnit getSimulator()
202 {
203 return this.simulator;
204 }
205
206
207 @Override
208 public final Length getLength()
209 {
210 return this.designLine.getLength();
211 }
212
213
214 private DirectedPoint zLocation = null;
215
216
217 @Override
218 @SuppressWarnings("checkstyle:designforextension")
219 public DirectedPoint getLocation()
220 {
221 if (this.zLocation == null)
222 {
223 DirectedPoint p = this.designLine.getLocation();
224 this.zLocation = new DirectedPoint(p.x, p.y, p.z + 0.01, p.getRotX(), p.getRotY(), p.getRotZ());
225 }
226 return this.zLocation;
227 }
228
229
230 @Override
231 @SuppressWarnings("checkstyle:designforextension")
232 public Bounds getBounds()
233 {
234 return this.designLine.getBounds();
235 }
236
237
238 @Override
239 @SuppressWarnings("checkstyle:designforextension")
240 public String toString()
241 {
242 return this.id.toString();
243 }
244
245
246 @Override
247 @SuppressWarnings("checkstyle:designforextension")
248 public int hashCode()
249 {
250 final int prime = 31;
251 int result = 1;
252 result = prime * result + ((this.endNode == null) ? 0 : this.endNode.hashCode());
253 result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
254 result = prime * result + ((this.linkType == null) ? 0 : this.linkType.hashCode());
255 result = prime * result + ((this.startNode == null) ? 0 : this.startNode.hashCode());
256 return result;
257 }
258
259
260 @Override
261 @SuppressWarnings({ "checkstyle:designforextension", "checkstyle:needbraces" })
262 public boolean equals(final Object obj)
263 {
264 if (this == obj)
265 return true;
266 if (obj == null)
267 return false;
268 if (getClass() != obj.getClass())
269 return false;
270 OTSLink other = (OTSLink) obj;
271 if (this.endNode == null)
272 {
273 if (other.endNode != null)
274 return false;
275 }
276 else if (!this.endNode.equals(other.endNode))
277 return false;
278 if (this.id == null)
279 {
280 if (other.id != null)
281 return false;
282 }
283 else if (!this.id.equals(other.id))
284 return false;
285 if (this.linkType == null)
286 {
287 if (other.linkType != null)
288 return false;
289 }
290 else if (!this.linkType.equals(other.linkType))
291 return false;
292 if (this.startNode == null)
293 {
294 if (other.startNode != null)
295 return false;
296 }
297 else if (!this.startNode.equals(other.startNode))
298 return false;
299 return true;
300 }
301
302
303
304
305
306
307
308
309
310 @SuppressWarnings("checkstyle:designforextension")
311 public OTSLink clone(final Network newNetwork, final SimulatorInterface.TimeDoubleUnit newSimulator,
312 final boolean animation) throws NetworkException
313 {
314 return new OTSLink(newNetwork, newSimulator, animation, this);
315 }
316 }