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.rmi.RemoteException;
7   import java.util.function.Function;
8   import java.util.function.Supplier;
9   
10  import javax.naming.NamingException;
11  
12  import org.djunits.unit.LengthUnit;
13  import org.djunits.value.vdouble.scalar.Length;
14  import org.opentrafficsim.draw.LineLocatable;
15  import org.opentrafficsim.draw.RenderableTextSource;
16  import org.opentrafficsim.draw.TextAlignment;
17  import org.opentrafficsim.draw.road.LaneDetectorAnimation.LaneDetectorData;
18  
19  import nl.tudelft.simulation.naming.context.Contextualized;
20  
21  /**
22   * Draw LaneDetectorData.
23   * <p>
24   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands.<br>
25   * All rights reserved. <br>
26   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
27   * </p>
28   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
29   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
30   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
31   * @param <L> detector data type
32   * @param <T> text type
33   */
34  public class LaneDetectorAnimation<L extends LaneDetectorData, T extends RenderableTextSource<L, T>>
35          extends AbstractLineAnimation<L>
36  {
37      /** The color of the detector. */
38      private final Color color;
39  
40      /** the Text object to destroy when the animation is destroyed. */
41      private T text;
42  
43      /**
44       * Constructor. This constructor creates no text type. The method {@code ofGenericType()} uses this.
45       * @param laneDetector the lane detector to draw.
46       * @param contextualized context provider.
47       * @param color the display color of the detector.
48       * @throws NamingException in case of registration failure of the animation
49       * @throws RemoteException in case of remote registration failure of the animation
50       */
51      private LaneDetectorAnimation(final L laneDetector, final Contextualized contextualized, final Color color)
52              throws NamingException, RemoteException
53      {
54          super(laneDetector, contextualized, new Length(0.5, LengthUnit.SI));
55          this.color = color;
56      }
57  
58      /**
59       * This method produces a detector animation that toggles generally for all LaneDetectorData and its respective text id.
60       * @param laneDetector detector data.
61       * @param contextualized context provider.
62       * @param color color.
63       * @return animation for generic lane detector type.
64       * @throws NamingException in case of registration failure of the animation
65       * @throws RemoteException in case of remote registration failure of the animation
66       */
67      public static LaneDetectorAnimation<LaneDetectorData, Text> ofGenericType(final LaneDetectorData laneDetector,
68              final Contextualized contextualized, final Color color) throws RemoteException, NamingException
69      {
70          LaneDetectorAnimation<LaneDetectorData, Text> animation =
71                  new LaneDetectorAnimation<>(laneDetector, contextualized, color);
72          float halfLength = (float) (laneDetector.getLine().getLength() / 2.0);
73          animation.text = new Text(laneDetector, laneDetector::getId, 0.0f, halfLength + 0.2f, TextAlignment.CENTER, Color.BLACK,
74                  contextualized);
75          return animation;
76      }
77  
78      /**
79       * This constructor uses a provider for the text animation. This should provide an animation that extends
80       * {@code TextAnimation} and implements the right tagging interface to toggle the correct label belonging to L.
81       * Alternatively, the toggle can be specified to the class that extends {@code TextAnimation} directly.
82       * @param laneDetector the lane detector to draw.
83       * @param contextualized context provider.
84       * @param color the display color of the detector.
85       * @param textSupplier text supplier.
86       * @throws NamingException in case of registration failure of the animation
87       * @throws RemoteException in case of remote registration failure of the animation
88       */
89      public LaneDetectorAnimation(final L laneDetector, final Contextualized contextualized, final Color color,
90              final Function<LaneDetectorAnimation<L, T>, T> textSupplier) throws NamingException, RemoteException
91      {
92          super(laneDetector, contextualized, new Length(0.5, LengthUnit.SI));
93          this.color = color;
94          this.text = textSupplier.apply(this);
95      }
96  
97      /**
98       * Returns text object.
99       * @return text.
100      */
101     public final T getText()
102     {
103         return this.text;
104     }
105 
106     @Override
107     public final void paint(final Graphics2D graphics, final ImageObserver observer)
108     {
109         graphics.setColor(this.color);
110         super.paint(graphics, observer);
111     }
112 
113     @Override
114     public void destroy(final Contextualized contextProvider)
115     {
116         super.destroy(contextProvider);
117         this.text.destroy(contextProvider);
118     }
119 
120     @Override
121     public final String toString()
122     {
123         return "DetectorAnimation [getSource()=" + this.getSource() + "]";
124     }
125 
126     /**
127      * Text animation for the Detector. Separate class to be able to turn it on and off...
128      * <p>
129      * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
130      * <br>
131      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
132      * </p>
133      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
134      * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
135      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
136      */
137     public static class Text extends RenderableTextSource<LaneDetectorData, Text> implements DetectorData.Text
138     {
139         /**
140          * Constructor.
141          * @param source the object for which the text is displayed
142          * @param text the text to display
143          * @param dx the horizontal movement of the text, in meters
144          * @param dy the vertical movement of the text, in meters
145          * @param textPlacement where to place the text
146          * @param color the color of the text
147          * @param contextualized context provider
148          * @throws NamingException when animation context cannot be created or retrieved
149          * @throws RemoteException - when remote context cannot be found
150          */
151         public Text(final LaneDetectorData source, final Supplier<String> text, final float dx, final float dy,
152                 final TextAlignment textPlacement, final Color color, final Contextualized contextualized)
153                 throws RemoteException, NamingException
154         {
155             super(source, text, dx, dy, textPlacement, color, contextualized, RenderableTextSource.RENDERWHEN10);
156         }
157 
158         @Override
159         public final String toString()
160         {
161             return "Text []";
162         }
163     }
164 
165     /**
166      * LaneDetectorData provides the information required to draw a lane detector.
167      * <p>
168      * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
169      * <br>
170      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
171      * </p>
172      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
173      */
174     public interface LaneDetectorData extends LaneBasedObjectData, DetectorData, LineLocatable
175     {
176     }
177 
178     /**
179      * SinkData provides the information required to draw a sink.
180      * <p>
181      * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
182      * <br>
183      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
184      * </p>
185      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
186      */
187     public interface LoopDetectorData extends LaneDetectorData
188     {
189         /**
190          * Tagging implementation for loop detector ids.
191          * <p>
192          * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
193          * reserved. <br>
194          * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
195          * </p>
196          * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
197          */
198         class LoopDetectorText extends RenderableTextSource<LoopDetectorData, LoopDetectorText>
199         {
200             /**
201              * Constructor.
202              * @param laneDetector loop detector data.
203              * @param dy vertical spacing.
204              * @param contextualized context provider.
205              * @throws NamingException when animation context cannot be created or retrieved
206              * @throws RemoteException when remote context cannot be found
207              */
208             public LoopDetectorText(final LoopDetectorData laneDetector, final float dy, final Contextualized contextualized)
209                     throws RemoteException, NamingException
210             {
211                 super(laneDetector, laneDetector::getId, 0.0f, dy, TextAlignment.CENTER, Color.BLACK, contextualized,
212                         RenderableTextSource.RENDERWHEN10);
213             }
214         }
215     }
216 
217     /**
218      * SinkData provides the information required to draw a sink.
219      * <p>
220      * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
221      * <br>
222      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
223      * </p>
224      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
225      */
226     public interface SinkData extends LaneDetectorData
227     {
228         /**
229          * Tagging implementation for sink ids.
230          * <p>
231          * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
232          * reserved. <br>
233          * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
234          * </p>
235          * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
236          */
237         class SinkText extends RenderableTextSource<SinkData, SinkText>
238         {
239             /**
240              * Constructor.
241              * @param sink loop detector data.
242              * @param dy vertical spacing.
243              * @param contextualized context provider.
244              * @throws NamingException when animation context cannot be created or retrieved
245              * @throws RemoteException when remote context cannot be found
246              */
247             public SinkText(final SinkData sink, final float dy, final Contextualized contextualized)
248                     throws RemoteException, NamingException
249             {
250                 super(sink, sink::getId, 0.0f, dy, TextAlignment.CENTER, Color.BLACK, contextualized,
251                         RenderableTextSource.RENDERWHEN10);
252             }
253         }
254     }
255 
256 }