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