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