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