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