1   package org.opentrafficsim.draw.road;
2   
3   import java.awt.Color;
4   import java.awt.Graphics2D;
5   import java.awt.image.ImageObserver;
6   import java.io.Serializable;
7   import java.rmi.RemoteException;
8   
9   import javax.media.j3d.Bounds;
10  import javax.naming.NamingException;
11  
12  import org.opentrafficsim.core.geometry.OTSLine3D;
13  import org.opentrafficsim.draw.core.ClonableRenderable2DInterface;
14  import org.opentrafficsim.draw.core.PaintLine;
15  import org.opentrafficsim.draw.core.PaintPolygons;
16  import org.opentrafficsim.draw.core.TextAlignment;
17  import org.opentrafficsim.draw.core.TextAnimation;
18  import org.opentrafficsim.road.network.lane.Lane;
19  
20  import nl.tudelft.simulation.dsol.animation.Locatable;
21  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
22  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
23  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface.TimeDoubleUnit;
24  import nl.tudelft.simulation.language.d2.Angle;
25  import nl.tudelft.simulation.language.d3.DirectedPoint;
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  public class LaneAnimation extends Renderable2D<Lane> implements ClonableRenderable2DInterface<Lane>, Serializable
37  {
38      
39      private static final long serialVersionUID = 20141017L;
40  
41      
42      private final Color color;
43  
44      
45      private final Text text;
46  
47      
48  
49  
50  
51  
52  
53  
54  
55      public LaneAnimation(final Lane lane, final SimulatorInterface.TimeDoubleUnit simulator, final Color color)
56              throws NamingException, RemoteException
57      {
58          super(lane, simulator);
59          this.color = color;
60          this.text = new Text(lane, lane.getParentLink().getId() + "." + lane.getId(), 0.0f, 0.0f, TextAlignment.CENTER,
61                  Color.BLACK, simulator);
62          new CenterLineAnimation(new CenterLine(lane.getCenterLine()), simulator);
63      }
64  
65      
66  
67  
68      public final Text getText()
69      {
70          return this.text;
71      }
72  
73      
74      @Override
75      public final void paint(final Graphics2D graphics, final ImageObserver observer)
76      {
77          Lane lane = getSource();
78          if (this.color != null)
79          {
80              PaintPolygons.paintMultiPolygon(graphics, this.color, lane.getLocation(), lane.getContour(), true);
81          }
82      }
83  
84      
85      @Override
86      public final void destroy() throws NamingException
87      {
88          super.destroy();
89          this.text.destroy();
90      }
91  
92      
93      @Override
94      @SuppressWarnings("checkstyle:designforextension")
95      public ClonableRenderable2DInterface<Lane> clone(final Lane newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
96              throws NamingException, RemoteException
97      {
98          
99          return new LaneAnimation(newSource, newSimulator, this.color);
100     }
101 
102     
103     @Override
104     public final String toString()
105     {
106         return "LaneAnimation [lane = " + getSource().toString() + ", color=" + this.color + "]";
107     }
108 
109     
110 
111 
112     public static class CenterLine implements Locatable
113     {
114         
115         private final OTSLine3D centerLine;
116 
117         
118 
119 
120 
121         CenterLine(final OTSLine3D centerLine)
122         {
123             this.centerLine = centerLine;
124         }
125 
126         @Override
127         public final DirectedPoint getLocation() throws RemoteException
128         {
129             DirectedPoint dp = this.centerLine.getLocation();
130             return new DirectedPoint(dp.x, dp.y, dp.z + 0.1);
131         }
132 
133         @Override
134         public final Bounds getBounds() throws RemoteException
135         {
136             return this.centerLine.getBounds();
137         }
138 
139         
140 
141 
142 
143         public OTSLine3D getCenterLine()
144         {
145             return centerLine;
146         }
147 
148     }
149 
150     
151 
152 
153     public static class CenterLineAnimation extends Renderable2D<CenterLine>
154             implements ClonableRenderable2DInterface<CenterLine>, Serializable
155     {
156         
157         private static final Color COLOR = Color.MAGENTA.darker().darker();
158         
159         
160         private static final long serialVersionUID = 20180426L;
161 
162         
163 
164 
165 
166 
167 
168 
169         public CenterLineAnimation(final CenterLine centerLine, final SimulatorInterface.TimeDoubleUnit simulator)
170                 throws NamingException, RemoteException
171         {
172             super(centerLine, simulator);
173         }
174 
175         @Override
176         public final ClonableRenderable2DInterface<CenterLine> clone(final CenterLine newSource,
177                 final TimeDoubleUnit newSimulator) throws NamingException, RemoteException
178         {
179             
180             return null;
181         }
182 
183         @Override
184         public final void paint(final Graphics2D graphics, final ImageObserver observer) throws RemoteException
185         {
186             PaintLine.paintLine(graphics, COLOR, 0.1, getSource().getLocation(),
187                     ((CenterLine) getSource()).getCenterLine());
188         }
189 
190     }
191 
192     
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205     public class Text extends TextAnimation
206     {
207         
208         private static final long serialVersionUID = 20161211L;
209 
210         
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221         public Text(final Locatable source, final String text, final float dx, final float dy,
222                 final TextAlignment textPlacement, final Color color, final SimulatorInterface.TimeDoubleUnit simulator)
223                 throws RemoteException, NamingException
224         {
225             super(source, text, dx, dy, textPlacement, color, simulator, TextAnimation.RENDERALWAYS);
226         }
227 
228         
229         @Override
230         @SuppressWarnings("checkstyle:designforextension")
231         public DirectedPoint getLocation() throws RemoteException
232         {
233             
234             DirectedPoint p = ((Lane) getSource()).getCenterLine().getLocationFractionExtended(0.5);
235             double a = Angle.normalizePi(p.getRotZ());
236             if (a > Math.PI / 2.0 || a < -0.99 * Math.PI / 2.0)
237             {
238                 a += Math.PI;
239             }
240             return new DirectedPoint(p.x, p.y, Double.MAX_VALUE, 0.0, 0.0, a);
241         }
242 
243         
244         @Override
245         @SuppressWarnings("checkstyle:designforextension")
246         public TextAnimation clone(final Locatable newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
247                 throws RemoteException, NamingException
248         {
249             return new Text(newSource, getText(), getDx(), getDy(), getTextAlignment(), getColor(), newSimulator);
250         }
251 
252         
253         @Override
254         public final String toString()
255         {
256             return "Text []";
257         }
258 
259     }
260 
261 }