View Javadoc
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.naming.NamingException;
10  
11  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
12  import org.opentrafficsim.core.geometry.Bounds;
13  import org.opentrafficsim.core.geometry.DirectedPoint;
14  import org.opentrafficsim.core.geometry.OtsLine3d;
15  import org.opentrafficsim.draw.core.PaintLine;
16  import org.opentrafficsim.draw.core.PaintPolygons;
17  import org.opentrafficsim.draw.core.TextAlignment;
18  import org.opentrafficsim.draw.core.TextAnimation;
19  import org.opentrafficsim.road.network.lane.Lane;
20  
21  import nl.tudelft.simulation.dsol.animation.Locatable;
22  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
23  import nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface;
24  import nl.tudelft.simulation.language.d2.Angle;
25  import nl.tudelft.simulation.naming.context.Contextualized;
26  
27  /**
28   * <p>
29   * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
30   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
31   * </p>
32   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
33   */
34  public class LaneAnimation extends Renderable2D<Lane> implements Renderable2DInterface<Lane>, Serializable
35  {
36      /** */
37      private static final long serialVersionUID = 20141017L;
38  
39      /** Color of the lane. */
40      private final Color color;
41  
42      /** the Text object to destroy when the animation is destroyed. */
43      private final Text text;
44  
45      /**
46       * Animate a Lane.
47       * @param lane Lane; the lane
48       * @param simulator OtsSimulatorInterface; the simulator
49       * @param color Color; Color of the lane.
50       * @throws NamingException in case of registration failure of the animation
51       * @throws RemoteException on communication failure
52       */
53      public LaneAnimation(final Lane lane, final OtsSimulatorInterface simulator, final Color color)
54              throws NamingException, RemoteException
55      {
56          super(lane, simulator);
57          this.color = color;
58          this.text = new Text(lane, lane.getParentLink().getId() + "." + lane.getId(), 0.0f, 0.0f, TextAlignment.CENTER,
59                  Color.BLACK, simulator);
60          new CenterLineAnimation(new CenterLine(lane.getCenterLine()), simulator);
61      }
62  
63      /**
64       * @return text.
65       */
66      public final Text getText()
67      {
68          return this.text;
69      }
70  
71      /** {@inheritDoc} */
72      @Override
73      public final void paint(final Graphics2D graphics, final ImageObserver observer)
74      {
75          Lane lane = getSource();
76          if (this.color != null)
77          {
78              PaintPolygons.paintMultiPolygon(graphics, this.color, lane.getLocation(), lane.getContour(), true);
79          }
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public void destroy(final Contextualized contextProvider)
85      {
86          super.destroy(contextProvider);
87          this.text.destroy(contextProvider);
88      }
89  
90      /** {@inheritDoc} */
91      @Override
92      public final String toString()
93      {
94          return "LaneAnimation [lane = " + getSource().toString() + ", color=" + this.color + "]";
95      }
96  
97      /**
98       * Draw center line of a lane.
99       */
100     public static class CenterLine implements Locatable
101     {
102         /** The center line. */
103         private final OtsLine3d centerLine;
104 
105         /**
106          * Construct a new CenterLine.
107          * @param centerLine OtsLine3d; the center line of a lane
108          */
109         CenterLine(final OtsLine3d centerLine)
110         {
111             this.centerLine = centerLine;
112         }
113 
114         @Override
115         public final DirectedPoint getLocation()
116         {
117             DirectedPoint dp = this.centerLine.getLocation();
118             return new DirectedPoint(dp.x, dp.y, dp.z + 0.1);
119         }
120 
121         @Override
122         public final Bounds getBounds() throws RemoteException
123         {
124             return this.centerLine.getBounds();
125         }
126 
127         /**
128          * Retrieve the center line.
129          * @return OtsLine3d; the center line
130          */
131         public OtsLine3d getCenterLine()
132         {
133             return this.centerLine;
134         }
135 
136     }
137 
138     /**
139      * Animation for center line of a lane.
140      */
141     public static class CenterLineAnimation extends Renderable2D<CenterLine>
142             implements Renderable2DInterface<CenterLine>, Serializable
143     {
144         /** Drawing color for the center line. */
145         private static final Color COLOR = Color.MAGENTA.darker().darker();
146 
147         /**  */
148         private static final long serialVersionUID = 20180426L;
149 
150         /**
151          * Construct a new CenterLineAnimation.
152          * @param centerLine CemterLine; the center line of a lane
153          * @param simulator OtsSimulatorInterface; the simulator
154          * @throws NamingException when the name of this object is not unique
155          * @throws RemoteException when communication with a remote process fails
156          */
157         public CenterLineAnimation(final CenterLine centerLine, final OtsSimulatorInterface simulator)
158                 throws NamingException, RemoteException
159         {
160             super(centerLine, simulator);
161         }
162 
163         @Override
164         public final void paint(final Graphics2D graphics, final ImageObserver observer)
165         {
166             PaintLine.paintLine(graphics, COLOR, 0.1, getSource().getLocation(), getSource().getCenterLine());
167         }
168 
169     }
170 
171     /**
172      * Text animation for the Node. Separate class to be able to turn it on and off...
173      * <p>
174      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
175      * <br>
176      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
177      * </p>
178      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
179      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
180      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
181      */
182     public class Text extends TextAnimation
183     {
184         /** */
185         private static final long serialVersionUID = 20161211L;
186 
187         /**
188          * @param source Locatable; the object for which the text is displayed
189          * @param text String; the text to display
190          * @param dx float; the horizontal movement of the text, in meters
191          * @param dy float; the vertical movement of the text, in meters
192          * @param textPlacement TextAlignment; where to place the text
193          * @param color Color; the color of the text
194          * @param simulator OtsSimulatorInterface; the simulator
195          * @throws NamingException when animation context cannot be created or retrieved
196          * @throws RemoteException - when remote context cannot be found
197          */
198         public Text(final Locatable source, final String text, final float dx, final float dy,
199                 final TextAlignment textPlacement, final Color color, final OtsSimulatorInterface simulator)
200                 throws RemoteException, NamingException
201         {
202             super(source, text, dx, dy, textPlacement, color, simulator, TextAnimation.RENDERALWAYS);
203         }
204 
205         /** {@inheritDoc} */
206         @Override
207         @SuppressWarnings("checkstyle:designforextension")
208         public DirectedPoint getLocation()
209         {
210             // draw always on top.
211             DirectedPoint p = ((Lane) getSource()).getCenterLine().getLocationFractionExtended(0.5);
212             double a = Angle.normalizePi(p.getRotZ());
213             if (a > Math.PI / 2.0 || a < -0.99 * Math.PI / 2.0)
214             {
215                 a += Math.PI;
216             }
217             return new DirectedPoint(p.x, p.y, Double.MAX_VALUE, 0.0, 0.0, a);
218         }
219 
220         /** {@inheritDoc} */
221         @Override
222         public final String toString()
223         {
224             return "Text []";
225         }
226 
227     }
228 
229 }