1   package org.opentrafficsim.draw.road;
2   
3   import java.awt.Color;
4   import java.awt.Graphics2D;
5   import java.awt.Shape;
6   import java.awt.geom.Ellipse2D;
7   import java.awt.image.ImageObserver;
8   import java.io.Serializable;
9   import java.rmi.RemoteException;
10  
11  import javax.naming.NamingException;
12  
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.language.d2.Angle;
24  import nl.tudelft.simulation.language.d3.DirectedPoint;
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  public class LaneAnimation extends Renderable2D<Lane> implements ClonableRenderable2DInterface<Lane>, Serializable
36  {
37      
38      private static final long serialVersionUID = 20141017L;
39  
40      
41      private final Color color;
42  
43      
44      private final boolean drawCenterLine;
45  
46      
47      private final Text text;
48  
49      
50  
51  
52  
53  
54  
55  
56  
57  
58      public LaneAnimation(final Lane lane, final SimulatorInterface.TimeDoubleUnit simulator, final Color color,
59              final boolean drawCenterLine) throws NamingException, RemoteException
60      {
61          super(lane, simulator);
62          this.color = color;
63          this.drawCenterLine = drawCenterLine;
64          this.text = new Text(lane, lane.getParentLink().getId() + "." + lane.getId(), 0.0f, 0.0f, TextAlignment.CENTER,
65                  Color.BLACK, simulator);
66      }
67  
68      
69  
70  
71      public final Text getText()
72      {
73          return this.text;
74      }
75  
76      
77      @Override
78      public final void paint(final Graphics2D graphics, final ImageObserver observer)
79      {
80          Lane lane = getSource();
81          if (this.color != null)
82          {
83              PaintPolygons.paintMultiPolygon(graphics, this.color, lane.getLocation(), lane.getContour(), true);
84          }
85  
86          if (this.drawCenterLine)
87          {
88              PaintLine.paintLine(graphics, Color.RED, 0.25, lane.getLocation(), lane.getCenterLine());
89              Shape startCircle = new Ellipse2D.Double(lane.getCenterLine().getFirst().x - lane.getLocation().x - 0.25,
90                      -lane.getCenterLine().getFirst().y + lane.getLocation().y - 0.25, 0.5, 0.5);
91              Shape endCircle = new Ellipse2D.Double(lane.getCenterLine().getLast().x - lane.getLocation().x - 0.25,
92                      -lane.getCenterLine().getLast().y + lane.getLocation().y - 0.25, 0.5, 0.5);
93              graphics.setColor(Color.BLUE);
94              graphics.fill(startCircle);
95              graphics.setColor(Color.RED);
96              graphics.fill(endCircle);
97          }
98      }
99  
100     
101     @Override
102     public final void destroy() throws NamingException
103     {
104         super.destroy();
105         this.text.destroy();
106     }
107 
108     
109     @Override
110     @SuppressWarnings("checkstyle:designforextension")
111     public ClonableRenderable2DInterface<Lane> clone(final Lane newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
112             throws NamingException, RemoteException
113     {
114         
115         return new LaneAnimation(newSource, newSimulator, this.color, this.drawCenterLine);
116     }
117 
118     
119     @Override
120     public final String toString()
121     {
122         return "LaneAnimation [lane = " + getSource().toString() + ", color=" + this.color + ", drawCenterLine="
123                 + this.drawCenterLine + "]";
124     }
125 
126     
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139     public class Text extends TextAnimation
140     {
141         
142         private static final long serialVersionUID = 20161211L;
143 
144         
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155         public Text(final Locatable source, final String text, final float dx, final float dy,
156                 final TextAlignment textPlacement, final Color color, final SimulatorInterface.TimeDoubleUnit simulator)
157                 throws RemoteException, NamingException
158         {
159             super(source, text, dx, dy, textPlacement, color, simulator);
160         }
161 
162         
163         @Override
164         @SuppressWarnings("checkstyle:designforextension")
165         public DirectedPoint getLocation() throws RemoteException
166         {
167             
168             DirectedPoint p = ((Lane) getSource()).getCenterLine().getLocationFractionExtended(0.5);
169             double a = Angle.normalizePi(p.getRotZ());
170             if (a > Math.PI / 2.0 || a < -0.99 * Math.PI / 2.0)
171             {
172                 a += Math.PI;
173             }
174             return new DirectedPoint(p.x, p.y, Double.MAX_VALUE, 0.0, 0.0, a);
175         }
176 
177         
178         @Override
179         @SuppressWarnings("checkstyle:designforextension")
180         public TextAnimation clone(final Locatable newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
181                 throws RemoteException, NamingException
182         {
183             return new Text(newSource, getText(), getDx(), getDy(), getTextAlignment(), getColor(), newSimulator);
184         }
185 
186         
187         @Override
188         public final String toString()
189         {
190             return "Text []";
191         }
192 
193     }
194 
195 }