View Javadoc
1   package org.opentrafficsim.draw.road;
2   
3   import java.awt.Color;
4   import java.awt.Graphics2D;
5   import java.awt.geom.Path2D;
6   import java.awt.image.ImageObserver;
7   import java.rmi.RemoteException;
8   import java.util.function.Supplier;
9   
10  import javax.naming.NamingException;
11  
12  import org.djutils.base.Identifiable;
13  import org.djutils.draw.line.PolyLine2d;
14  import org.djutils.draw.point.OrientedPoint2d;
15  import org.opentrafficsim.base.geometry.BoundingPolygon;
16  import org.opentrafficsim.base.geometry.ClickableBounds;
17  import org.opentrafficsim.base.geometry.OtsBounds2d;
18  import org.opentrafficsim.base.geometry.OtsLocatable;
19  import org.opentrafficsim.base.geometry.OtsRenderable;
20  import org.opentrafficsim.draw.DrawLevel;
21  import org.opentrafficsim.draw.PaintLine;
22  import org.opentrafficsim.draw.TextAlignment;
23  import org.opentrafficsim.draw.TextAnimation;
24  import org.opentrafficsim.draw.road.CrossSectionElementAnimation.CrossSectionElementData;
25  import org.opentrafficsim.draw.road.LaneAnimation.LaneData;
26  
27  import nl.tudelft.simulation.naming.context.Contextualized;
28  
29  /**
30   * Draws LaneData.
31   * <p>
32   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
33   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
34   * </p>
35   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
36   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
37   */
38  public class LaneAnimation extends CrossSectionElementAnimation<LaneData>
39  {
40      /** */
41      private static final long serialVersionUID = 20141017L;
42  
43      /** Color of the lane. */
44      private final Color color;
45  
46      /** the Text object to destroy when the animation is destroyed. */
47      private final Text text;
48  
49      /** Center line animation. */
50      private final CenterLineAnimation centerLineAnimation;
51  
52      /**
53       * Animate a Lane.
54       * @param lane LaneData; the lane
55       * @param contextualized Contextualized; context provider
56       * @param color Color; Color of the lane.
57       * @throws NamingException in case of registration failure of the animation
58       * @throws RemoteException on communication failure
59       */
60      public LaneAnimation(final LaneData lane, final Contextualized contextualized, final Color color)
61              throws NamingException, RemoteException
62      {
63          super(lane, contextualized, color);
64          this.color = color;
65          this.text = new Text(lane, lane::getId, 0.0f, 0.0f, TextAlignment.CENTER, Color.BLACK, contextualized);
66          this.centerLineAnimation = new CenterLineAnimation(
67                  new CenterLine(lane.getCenterLine(), lane.getLinkId() + "." + lane.getId()), contextualized);
68      }
69  
70      /**
71       * @return text.
72       */
73      public final Text getText()
74      {
75          return this.text;
76      }
77  
78      /** {@inheritDoc} */
79      @Override
80      public void destroy(final Contextualized contextProvider)
81      {
82          super.destroy(contextProvider);
83          this.text.destroy(contextProvider);
84          this.centerLineAnimation.destroy(contextProvider);
85      }
86  
87      /** {@inheritDoc} */
88      @Override
89      public final String toString()
90      {
91          return "LaneAnimation [lane = " + getSource().toString() + ", color=" + this.color + "]";
92      }
93  
94      /**
95       * Draw center line of a lane.
96       */
97      public static class CenterLine implements OtsLocatable
98      {
99          /** The center line. */
100         private final PolyLine2d centerLine;
101 
102         /** Location. */
103         private final OrientedPoint2d location;
104 
105         /** Bounds. */
106         private final OtsBounds2d bounds;
107 
108         /** Lane id. */
109         private final String fullId;
110 
111         /**
112          * Construct a new CenterLine.
113          * @param centerLine OtsLine2d; the center line of a lane
114          * @param fullId String; lane id.
115          */
116         CenterLine(final PolyLine2d centerLine, final String fullId)
117         {
118             this.centerLine = centerLine;
119             this.location = new OrientedPoint2d(this.centerLine.getBounds().midPoint(), 0.0);
120             this.bounds = ClickableBounds.get(BoundingPolygon.geometryToBounds(this.location, centerLine).asPolygon());
121             this.fullId = fullId;
122         }
123 
124         /** {@inheritDoc} */
125         @Override
126         public final OrientedPoint2d getLocation()
127         {
128             return this.location;
129         }
130 
131         /** {@inheritDoc} */
132         @Override
133         public final OtsBounds2d getBounds()
134         {
135             return this.bounds;
136         }
137 
138         /**
139          * Retrieve the center line.
140          * @return OtsLine2d; the center line
141          */
142         public PolyLine2d getCenterLine()
143         {
144             return this.centerLine;
145         }
146 
147         /** {@inheritDoc} */
148         @Override
149         public double getZ()
150         {
151             return DrawLevel.CENTER_LINE.getZ();
152         }
153 
154         /** {@inheritDoc} */
155         @Override
156         public String toString()
157         {
158             return "Center line " + this.fullId;
159         }
160     }
161 
162     /**
163      * Animation for center line of a lane.
164      */
165     public static class CenterLineAnimation extends OtsRenderable<CenterLine>
166     {
167         /** Drawing color for the center line. */
168         private static final Color COLOR = Color.MAGENTA.darker().darker();
169 
170         /**  */
171         private static final long serialVersionUID = 20180426L;
172 
173         /** Drawable path. */
174         private final Path2D.Float path;
175 
176         /**
177          * Construct a new CenterLineAnimation.
178          * @param centerLine CemterLine; the center line of a lane
179          * @param contextualized Contextualized; context provider
180          * @throws NamingException when the name of this object is not unique
181          * @throws RemoteException when communication with a remote process fails
182          */
183         public CenterLineAnimation(final CenterLine centerLine, final Contextualized contextualized)
184                 throws NamingException, RemoteException
185         {
186             super(centerLine, contextualized);
187             this.path = PaintLine.getPath(getSource().getLocation(), getSource().getCenterLine());
188         }
189 
190         /** {@inheritDoc} */
191         @Override
192         public final void paint(final Graphics2D graphics, final ImageObserver observer)
193         {
194             setRendering(graphics);
195             PaintLine.paintLine(graphics, COLOR, 0.1, this.path);
196             resetRendering(graphics);
197         }
198 
199     }
200 
201     /**
202      * Text animation for the Node. Separate class to be able to turn it on and off...
203      * <p>
204      * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
205      * <br>
206      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
207      * </p>
208      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
209      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
210      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
211      */
212     public class Text extends TextAnimation<LaneData, Text>
213     {
214         /** */
215         private static final long serialVersionUID = 20161211L;
216 
217         /**
218          * @param source LaneData; the object for which the text is displayed
219          * @param text Supplier&lt;String&gt;; the text to display
220          * @param dx float; the horizontal movement of the text, in meters
221          * @param dy float; the vertical movement of the text, in meters
222          * @param textPlacement TextAlignment; where to place the text
223          * @param color Color; the color of the text
224          * @param contextualized Contextualized; context provider
225          * @throws NamingException when animation context cannot be created or retrieved
226          * @throws RemoteException - when remote context cannot be found
227          */
228         public Text(final LaneData source, final Supplier<String> text, final float dx, final float dy,
229                 final TextAlignment textPlacement, final Color color, final Contextualized contextualized)
230                 throws RemoteException, NamingException
231         {
232             super(source, text, dx, dy, textPlacement, color, contextualized, TextAnimation.RENDERWHEN10);
233         }
234 
235         /** {@inheritDoc} */
236         @Override
237         public final String toString()
238         {
239             return "Text []";
240         }
241 
242     }
243 
244     /**
245      * LaneData provides the information required to draw a lane.
246      * <p>
247      * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
248      * <br>
249      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
250      * </p>
251      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
252      */
253     public interface LaneData extends CrossSectionElementData, Identifiable
254     {
255         /** {@inheritDoc} */
256         @Override
257         default double getZ()
258         {
259             return DrawLevel.LANE.getZ();
260         }
261     }
262 
263 }