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