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.djutils.exceptions.Throw;
11 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
12 import org.opentrafficsim.core.geometry.OTSLine3D;
13 import org.opentrafficsim.core.gtu.GTU;
14 import org.opentrafficsim.core.gtu.GTUType;
15
16 import nl.tudelft.simulation.dsol.animation.Locatable;
17 import nl.tudelft.simulation.event.EventProducer;
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 OTSSimulatorInterface 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 OTSSimulatorInterface 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 (link %s)", id);
79 Throw.whenNull(endNode, "endNode cannot be null (link %s)", id);
80 Throw.whenNull(linkType, "linkType cannot be null (link %s)", id);
81 Throw.whenNull(designLine, "designLine cannot be null (link %s)", id);
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 protected OTSLink(final Network newNetwork, final OTSSimulatorInterface newSimulator, final OTSLink link)
105 throws NetworkException
106 {
107 this(newNetwork, link.id, newNetwork.getNode(link.startNode.getId()), newNetwork.getNode(link.endNode.getId()),
108 link.linkType, link.designLine, newSimulator);
109 }
110
111
112 @Override
113 public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
114 {
115 return this.getLinkType().getDirectionality(gtuType, true);
116 }
117
118
119 @Override
120 public final void addGTU(final GTU gtu)
121 {
122 if (!this.gtus.contains(gtu))
123 {
124 this.gtus.add(gtu);
125 fireTimedEvent(Link.GTU_ADD_EVENT, new Object[] {gtu.getId(), gtu, this.gtus.size()},
126 gtu.getSimulator().getSimulatorTime());
127 }
128 }
129
130
131 @Override
132 public final void removeGTU(final GTU gtu)
133 {
134 if (this.gtus.contains(gtu))
135 {
136 this.gtus.remove(gtu);
137 fireTimedEvent(Link.GTU_REMOVE_EVENT, new Object[] {gtu.getId(), gtu, this.gtus.size()},
138 gtu.getSimulator().getSimulatorTime());
139 }
140 }
141
142
143 @Override
144 public final Set<GTU> getGTUs()
145 {
146 return new LinkedHashSet<>(this.gtus);
147 }
148
149
150 @Override
151 public final int getGTUCount()
152 {
153 return this.gtus.size();
154 }
155
156
157 @Override
158 public Network getNetwork()
159 {
160 return this.network;
161 }
162
163
164 @Override
165 public final String getId()
166 {
167 return this.id;
168 }
169
170
171 @Override
172 public final Node getStartNode()
173 {
174 return this.startNode;
175 }
176
177
178 @Override
179 public final Node getEndNode()
180 {
181 return this.endNode;
182 }
183
184
185 @Override
186 public final LinkType getLinkType()
187 {
188 return this.linkType;
189 }
190
191
192 @Override
193 public final OTSLine3D getDesignLine()
194 {
195 return this.designLine;
196 }
197
198
199 @Override
200 public final OTSSimulatorInterface getSimulator()
201 {
202 return this.simulator;
203 }
204
205
206 @Override
207 public final Length getLength()
208 {
209 return this.designLine.getLength();
210 }
211
212
213 private DirectedPoint zLocation = null;
214
215
216 @Override
217 @SuppressWarnings("checkstyle:designforextension")
218 public DirectedPoint getLocation()
219 {
220 if (this.zLocation == null)
221 {
222 DirectedPoint p = this.designLine.getLocation();
223 this.zLocation = new DirectedPoint(p.x, p.y, p.z + 0.01, p.getRotX(), p.getRotY(), p.getRotZ());
224 }
225 return this.zLocation;
226 }
227
228
229 @Override
230 @SuppressWarnings("checkstyle:designforextension")
231 public Bounds getBounds()
232 {
233 return this.designLine.getBounds();
234 }
235
236
237 @Override
238 @SuppressWarnings("checkstyle:designforextension")
239 public String toString()
240 {
241 return this.id.toString();
242 }
243
244
245 @Override
246 @SuppressWarnings("checkstyle:designforextension")
247 public int hashCode()
248 {
249 final int prime = 31;
250 int result = 1;
251 result = prime * result + ((this.endNode == null) ? 0 : this.endNode.hashCode());
252 result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
253 result = prime * result + ((this.linkType == null) ? 0 : this.linkType.hashCode());
254 result = prime * result + ((this.startNode == null) ? 0 : this.startNode.hashCode());
255 return result;
256 }
257
258
259 @Override
260 @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces"})
261 public boolean equals(final Object obj)
262 {
263 if (this == obj)
264 return true;
265 if (obj == null)
266 return false;
267 if (getClass() != obj.getClass())
268 return false;
269 OTSLink other = (OTSLink) obj;
270 if (this.endNode == null)
271 {
272 if (other.endNode != null)
273 return false;
274 }
275 else if (!this.endNode.equals(other.endNode))
276 return false;
277 if (this.id == null)
278 {
279 if (other.id != null)
280 return false;
281 }
282 else if (!this.id.equals(other.id))
283 return false;
284 if (this.linkType == null)
285 {
286 if (other.linkType != null)
287 return false;
288 }
289 else if (!this.linkType.equals(other.linkType))
290 return false;
291 if (this.startNode == null)
292 {
293 if (other.startNode != null)
294 return false;
295 }
296 else if (!this.startNode.equals(other.startNode))
297 return false;
298 return true;
299 }
300
301
302
303
304
305
306
307
308 @SuppressWarnings("checkstyle:designforextension")
309 public OTSLink clone(final Network newNetwork, final OTSSimulatorInterface newSimulator) throws NetworkException
310 {
311 return new OTSLink(newNetwork, newSimulator, this);
312 }
313 }