1 package org.opentrafficsim.draw.factory;
2
3 import java.awt.Color;
4 import java.rmi.RemoteException;
5 import java.util.Collections;
6 import java.util.LinkedHashMap;
7 import java.util.Map;
8
9 import javax.naming.NamingException;
10
11 import org.djutils.logger.CategoryLogger;
12 import org.opentrafficsim.core.animation.gtu.colorer.GTUColorer;
13 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
14 import org.opentrafficsim.core.geometry.OTSGeometryException;
15 import org.opentrafficsim.core.gtu.GTU;
16 import org.opentrafficsim.core.gtu.GTUType;
17 import org.opentrafficsim.core.gtu.GtuGenerator;
18 import org.opentrafficsim.core.network.LateralDirectionality;
19 import org.opentrafficsim.core.network.Link;
20 import org.opentrafficsim.core.network.Network;
21 import org.opentrafficsim.core.network.Node;
22 import org.opentrafficsim.core.network.OTSNetwork;
23 import org.opentrafficsim.core.object.ObjectInterface;
24 import org.opentrafficsim.draw.core.OTSDrawingException;
25 import org.opentrafficsim.draw.gtu.DefaultCarAnimation;
26 import org.opentrafficsim.draw.network.LinkAnimation;
27 import org.opentrafficsim.draw.network.NodeAnimation;
28 import org.opentrafficsim.draw.road.BusStopAnimation;
29 import org.opentrafficsim.draw.road.ConflictAnimation;
30 import org.opentrafficsim.draw.road.DestinationAnimation;
31 import org.opentrafficsim.draw.road.LaneAnimation;
32 import org.opentrafficsim.draw.road.SensorAnimation;
33 import org.opentrafficsim.draw.road.ShoulderAnimation;
34 import org.opentrafficsim.draw.road.SinkAnimation;
35 import org.opentrafficsim.draw.road.SpeedSignAnimation;
36 import org.opentrafficsim.draw.road.StripeAnimation;
37 import org.opentrafficsim.draw.road.StripeAnimation.TYPE;
38 import org.opentrafficsim.draw.road.TrafficLightAnimation;
39 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
40 import org.opentrafficsim.road.network.lane.CrossSectionElement;
41 import org.opentrafficsim.road.network.lane.CrossSectionLink;
42 import org.opentrafficsim.road.network.lane.Lane;
43 import org.opentrafficsim.road.network.lane.Shoulder;
44 import org.opentrafficsim.road.network.lane.Stripe;
45 import org.opentrafficsim.road.network.lane.conflict.Conflict;
46 import org.opentrafficsim.road.network.lane.object.BusStop;
47 import org.opentrafficsim.road.network.lane.object.SpeedSign;
48 import org.opentrafficsim.road.network.lane.object.sensor.DestinationSensor;
49 import org.opentrafficsim.road.network.lane.object.sensor.SingleSensor;
50 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
51 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
52
53 import nl.tudelft.simulation.dsol.SimRuntimeException;
54 import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
55 import nl.tudelft.simulation.dsol.logger.SimLogger;
56 import nl.tudelft.simulation.event.EventInterface;
57 import nl.tudelft.simulation.event.EventListenerInterface;
58
59
60
61
62
63
64
65
66
67 public class DefaultAnimationFactory implements EventListenerInterface
68 {
69
70 private final OTSSimulatorInterface simulator;
71
72
73 private final GTUColorer gtuColorer;
74
75
76 private Map<LaneBasedGTU, Renderable2D<LaneBasedGTU>> animatedGTUs = Collections.synchronizedMap(new LinkedHashMap<>());
77
78
79 public Map<ObjectInterface, Renderable2D<?>> animatedObjects = Collections.synchronizedMap(new LinkedHashMap<>());
80
81
82
83
84
85
86
87
88
89
90 protected DefaultAnimationFactory(final OTSNetwork network, final OTSSimulatorInterface simulator,
91 final GTUColorer gtuColorer, final boolean animateNetwork) throws OTSDrawingException
92 {
93 this.simulator = simulator;
94 this.gtuColorer = gtuColorer;
95
96
97 network.addListener(this, Network.ANIMATION_GTU_ADD_EVENT);
98 network.addListener(this, Network.ANIMATION_GTU_REMOVE_EVENT);
99 network.addListener(this, Network.ANIMATION_OBJECT_ADD_EVENT);
100 network.addListener(this, Network.ANIMATION_OBJECT_REMOVE_EVENT);
101 network.addListener(this, Network.ANIMATION_GENERATOR_ADD_EVENT);
102 network.addListener(this, Network.ANIMATION_GENERATOR_REMOVE_EVENT);
103
104
105 try
106 {
107 if (animateNetwork)
108 {
109 for (Node node : network.getNodeMap().values())
110 {
111 new NodeAnimation(node, simulator);
112 }
113 for (Link link : network.getLinkMap().values())
114 {
115 new LinkAnimation(link, simulator, 0.5f);
116 if (link instanceof CrossSectionLink)
117 {
118 for (CrossSectionElement element : ((CrossSectionLink) link).getCrossSectionElementList())
119 {
120 if (element instanceof Lane)
121 {
122 new LaneAnimation((Lane) element, simulator, Color.GRAY.brighter());
123 }
124 else if (element instanceof Shoulder)
125 {
126 new ShoulderAnimation((Shoulder) element, simulator, Color.DARK_GRAY);
127 }
128 else if (element instanceof Stripe)
129 {
130 Stripe stripe = (Stripe) element;
131 TYPE type;
132 if (stripe.isPermeable(network.getGtuType(GTUType.DEFAULTS.CAR), LateralDirectionality.LEFT))
133 {
134 type = stripe.isPermeable(network.getGtuType(GTUType.DEFAULTS.CAR),
135 LateralDirectionality.RIGHT) ? TYPE.DASHED : TYPE.LEFTONLY;
136 }
137 else
138 {
139 type = stripe.isPermeable(network.getGtuType(GTUType.DEFAULTS.CAR),
140 LateralDirectionality.RIGHT) ? TYPE.RIGHTONLY : TYPE.SOLID;
141 }
142 new StripeAnimation((Stripe) element, simulator, type);
143 }
144 }
145 }
146 }
147
148 for (TrafficLight tl : network.getObjectMap(TrafficLight.class).values())
149 {
150 new TrafficLightAnimation(tl, simulator);
151 }
152
153 }
154
155 for (GTU gtu : network.getGTUs())
156 {
157 Renderable2D<LaneBasedGTU> gtuAnimation =
158 new DefaultCarAnimation((LaneBasedGTU) gtu, simulator, this.gtuColorer);
159 this.animatedGTUs.put((LaneBasedGTU) gtu, gtuAnimation);
160 }
161
162 for (ObjectInterface object : network.getObjectMap().values())
163 {
164 animateStaticObject(object);
165 }
166 }
167 catch (RemoteException | NamingException | OTSGeometryException exception)
168 {
169 throw new OTSDrawingException("Exception while creating network animation.", exception);
170 }
171
172 }
173
174
175
176
177
178
179
180
181
182
183 public static DefaultAnimationFactory animateNetwork(final OTSNetwork network, final OTSSimulatorInterface simulator,
184 final GTUColorer gtuColorer) throws OTSDrawingException
185 {
186 return new DefaultAnimationFactory(network, simulator, gtuColorer, true);
187 }
188
189
190
191
192
193
194
195
196
197
198 public static DefaultAnimationFactory animateXmlNetwork(final OTSNetwork network, final OTSSimulatorInterface simulator,
199 final GTUColorer gtuColorer) throws OTSDrawingException
200 {
201 return new DefaultAnimationFactory(network, simulator, gtuColorer, false);
202 }
203
204
205 @Override
206 public void notify(final EventInterface event) throws RemoteException
207 {
208 try
209 {
210 if (event.getType().equals(Network.ANIMATION_GTU_ADD_EVENT))
211 {
212
213 LaneBasedGTU gtu = (LaneBasedGTU) event.getContent();
214 this.simulator.scheduleEventNow(this, this, "animateGTU", new Object[] {gtu});
215 }
216 else if (event.getType().equals(Network.ANIMATION_GTU_REMOVE_EVENT))
217 {
218 LaneBasedGTU gtu = (LaneBasedGTU) event.getContent();
219 if (this.animatedGTUs.containsKey(gtu))
220 {
221 this.animatedGTUs.get(gtu).destroy();
222 this.animatedGTUs.remove(gtu);
223 }
224 }
225 else if (event.getType().equals(Network.ANIMATION_OBJECT_ADD_EVENT))
226 {
227 ObjectInterface object = (ObjectInterface) event.getContent();
228 animateStaticObject(object);
229 }
230 else if (event.getType().equals(Network.ANIMATION_OBJECT_REMOVE_EVENT))
231 {
232 ObjectInterface object = (ObjectInterface) event.getContent();
233 if (this.animatedObjects.containsKey(object))
234 {
235 this.animatedObjects.get(object).destroy();
236 this.animatedObjects.remove(object);
237 }
238 }
239 else if (event.getType().equals(Network.ANIMATION_GENERATOR_ADD_EVENT))
240 {
241 GtuGenerator gtuGenerator = (GtuGenerator) event.getContent();
242 animateGTUGenerator(gtuGenerator);
243 }
244 else if (event.getType().equals(Network.ANIMATION_GENERATOR_REMOVE_EVENT))
245 {
246
247 }
248 }
249 catch (NamingException | SimRuntimeException exception)
250 {
251 SimLogger.always().error(exception, "Exception while updating network animation.");
252 }
253 }
254
255
256
257
258
259 protected void animateGTU(final LaneBasedGTU gtu)
260 {
261 try
262 {
263 Renderable2D<LaneBasedGTU> gtuAnimation = new DefaultCarAnimation(gtu, this.simulator, this.gtuColorer);
264 this.animatedGTUs.put(gtu, gtuAnimation);
265 }
266 catch (RemoteException | NamingException exception)
267 {
268 SimLogger.always().error(exception, "Exception while drawing GTU.");
269 }
270 }
271
272
273
274
275
276 protected void animateStaticObject(final ObjectInterface object)
277 {
278 try
279 {
280 if (object instanceof SinkSensor)
281 {
282 SinkSensor sensor = (SinkSensor) object;
283
284 Renderable2D<SingleSensor> objectAnimation =
285 new SensorAnimation(sensor, sensor.getLongitudinalPosition(), this.simulator, Color.YELLOW);
286 this.animatedObjects.put(object, objectAnimation);
287 }
288 else if (object instanceof DestinationSensor)
289 {
290 DestinationSensor sensor = (DestinationSensor) object;
291
292 Renderable2D<SingleSensor> objectAnimation =
293 new SensorAnimation(sensor, sensor.getLongitudinalPosition(), this.simulator, Color.ORANGE);
294 this.animatedObjects.put(object, objectAnimation);
295 }
296 else if (object instanceof SingleSensor)
297 {
298 SingleSensor sensor = (SingleSensor) object;
299 Renderable2D<SingleSensor> objectAnimation =
300 new SensorAnimation(sensor, sensor.getLongitudinalPosition(), this.simulator, Color.GREEN);
301 this.animatedObjects.put(object, objectAnimation);
302 }
303 else if (object instanceof Conflict)
304 {
305 Conflict conflict = (Conflict) object;
306 Renderable2D<Conflict> objectAnimation = new ConflictAnimation(conflict, this.simulator);
307 this.animatedObjects.put(object, objectAnimation);
308 }
309 else if (object instanceof SpeedSign)
310 {
311 SpeedSign speedSign = (SpeedSign) object;
312 Renderable2D<SpeedSign> objectAnimation = new SpeedSignAnimation(speedSign, this.simulator);
313 this.animatedObjects.put(object, objectAnimation);
314 }
315 else if (object instanceof BusStop)
316 {
317 BusStop busStop = (BusStop) object;
318 Renderable2D<BusStop> objectAnimation = new BusStopAnimation(busStop, this.simulator);
319 this.animatedObjects.put(object, objectAnimation);
320 }
321 }
322 catch (RemoteException | NamingException exception)
323 {
324 CategoryLogger.always().error(exception, "Exception while drawing Object of class ObjectInterface.");
325 }
326 }
327
328
329
330
331
332 protected void animateGTUGenerator(final GtuGenerator gtuGenerator)
333 {
334
335 }
336
337 }