View Javadoc
1   package org.opentrafficsim.animation.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.Supplier;
8   
9   import javax.naming.NamingException;
10  
11  import org.djunits.unit.LengthUnit;
12  import org.djunits.value.vdouble.scalar.Length;
13  import org.opentrafficsim.animation.LineLocatable;
14  import org.opentrafficsim.animation.RenderableTextSource;
15  import org.opentrafficsim.animation.TextAlignment;
16  import org.opentrafficsim.animation.road.AbstractLineAnimation.LaneBasedObjectData;
17  import org.opentrafficsim.animation.road.LaneDetectorAnimation.LaneDetectorData;
18  import org.opentrafficsim.animation.road.LaneDetectorAnimation.Text;
19  
20  import nl.tudelft.simulation.naming.context.Contextualized;
21  
22  /**
23   * Draw lane detector.
24   * <p>
25   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands.<br>
26   * All rights reserved. <br>
27   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
28   * </p>
29   * @author Alexander Verbraeck
30   * @author Peter Knoppers
31   * @author Wouter Schakel
32   * @param <L> detector data type
33   */
34  public class LaneDetectorAnimation<L extends LaneDetectorData> extends AbstractLineAnimation<L, Text<L>>
35  {
36  
37      /** The color of the detector. */
38      private final Color color;
39  
40      /**
41       * This constructor uses a provider for the text animation. This should provide an animation that extends
42       * {@code TextAnimation} and implements the right tagging interface to toggle the correct label belonging to L.
43       * Alternatively, the toggle can be specified to the class that extends {@code TextAnimation} directly.
44       * @param laneDetector the lane detector to draw
45       * @param contextualized context provider
46       * @param color the display color of the detector
47       */
48      public LaneDetectorAnimation(final L laneDetector, final Contextualized contextualized, final Color color)
49      {
50          this(laneDetector, contextualized, color, "");
51      }
52  
53      /**
54       * This constructor uses a provider for the text animation. This should provide an animation that extends
55       * {@code TextAnimation} and implements the right tagging interface to toggle the correct label belonging to L.
56       * Alternatively, the toggle can be specified to the class that extends {@code TextAnimation} directly.
57       * @param laneDetector the lane detector to draw
58       * @param contextualized context provider
59       * @param color the display color of the detector
60       * @param prefix label prefix
61       */
62      public LaneDetectorAnimation(final L laneDetector, final Contextualized contextualized, final Color color,
63              final String prefix)
64      {
65          super(laneDetector, contextualized, new Length(0.5, LengthUnit.SI), prefix);
66          this.color = color;
67      }
68  
69      @Override
70      protected Text<L> createText(final L source, final Contextualized contextualized, final String prefix)
71      {
72          float halfLength = (float) (source.getLine().getLength() / 2.0);
73          return new Text<L>(source, () -> prefix + source.getId(), 0.0f, halfLength + 0.2f, contextualized);
74      }
75  
76      @Override
77      public final void paint(final Graphics2D graphics, final ImageObserver observer)
78      {
79          graphics.setColor(this.color);
80          super.paint(graphics, observer);
81      }
82  
83      @Override
84      public final String toString()
85      {
86          return "DetectorAnimation [getSource()=" + this.getSource() + "]";
87      }
88  
89      /**
90       * Text animation for the detector.
91       * @param <L> source type
92       */
93      public static class Text<L extends LaneDetectorData> extends RenderableTextSource<L, Text<L>> implements DetectorData.Text
94      {
95          /**
96           * Constructor.
97           * @param source the object for which the text is displayed
98           * @param text the text to display
99           * @param dx the horizontal movement of the text, in meters
100          * @param dy the vertical movement of the text, in meters
101          * @param contextualized context provider
102          */
103         public Text(final L source, final Supplier<String> text, final float dx, final float dy,
104                 final Contextualized contextualized)
105         {
106             super(source, text, dx, dy, TextAlignment.CENTER, Color.BLACK, contextualized, RenderableTextSource.RENDERWHEN10);
107         }
108 
109         @Override
110         public final String toString()
111         {
112             return "Text []";
113         }
114     }
115 
116     /**
117      * Provides the information required to draw a lane detector.
118      */
119     public interface LaneDetectorData extends LaneBasedObjectData, DetectorData, LineLocatable
120     {
121     }
122 
123     /**
124      * Provides the information required to draw a loop detector.
125      */
126     public interface LoopDetectorData extends LaneDetectorData
127     {
128         /**
129          * Tagging implementation for loop detector IDs.
130          */
131         class LoopDetectorText extends RenderableTextSource<LoopDetectorData, LoopDetectorText>
132         {
133             /**
134              * Constructor.
135              * @param laneDetector loop detector data
136              * @param dy vertical spacing
137              * @param contextualized context provider
138              * @throws NamingException when animation context cannot be created or retrieved
139              * @throws RemoteException when remote context cannot be found
140              */
141             public LoopDetectorText(final LoopDetectorData laneDetector, final float dy, final Contextualized contextualized)
142                     throws RemoteException, NamingException
143             {
144                 super(laneDetector, laneDetector::getId, 0.0f, dy, TextAlignment.CENTER, Color.BLACK, contextualized,
145                         RenderableTextSource.RENDERWHEN10);
146             }
147         }
148     }
149 
150     /**
151      * Provides the information required to draw a sink.
152      */
153     public interface SinkData extends LaneDetectorData
154     {
155         /**
156          * Tagging implementation for sink IDs.
157          */
158         class SinkText extends RenderableTextSource<SinkData, SinkText>
159         {
160             /**
161              * Constructor.
162              * @param sink loop detector data
163              * @param dy vertical spacing
164              * @param contextualized context provider
165              */
166             public SinkText(final SinkData sink, final float dy, final Contextualized contextualized)
167             {
168                 super(sink, sink::getId, 0.0f, dy, TextAlignment.CENTER, Color.BLACK, contextualized,
169                         RenderableTextSource.RENDERWHEN10);
170             }
171         }
172     }
173 
174 }