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