View Javadoc
1   package org.opentrafficsim.draw.network;
2   
3   import java.awt.BasicStroke;
4   import java.awt.Color;
5   import java.awt.Graphics2D;
6   import java.awt.geom.Ellipse2D;
7   import java.awt.geom.GeneralPath;
8   import java.awt.geom.Path2D;
9   import java.awt.image.ImageObserver;
10  import java.io.Serializable;
11  import java.rmi.RemoteException;
12  
13  import javax.naming.NamingException;
14  
15  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
16  import org.opentrafficsim.core.geometry.Bounds;
17  import org.opentrafficsim.core.geometry.DirectedPoint;
18  import org.opentrafficsim.core.network.Link;
19  import org.opentrafficsim.core.network.LinkType;
20  import org.opentrafficsim.core.network.Node;
21  import org.opentrafficsim.draw.core.ClonableRenderable2DInterface;
22  import org.opentrafficsim.draw.core.TextAlignment;
23  import org.opentrafficsim.draw.core.TextAnimation;
24  import org.opentrafficsim.draw.core.TextAnimation.ScaleDependentRendering;
25  
26  import nl.tudelft.simulation.dsol.animation.Locatable;
27  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
28  import nl.tudelft.simulation.introspection.DelegateIntrospection;
29  import nl.tudelft.simulation.naming.context.Contextualized;
30  
31  /**
32   * <p>
33   * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
34   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
35   * <p>
36   * $LastChangedDate: 2018-10-11 22:54:04 +0200 (Thu, 11 Oct 2018) $, @version $Revision: 4696 $, by $Author: averbraeck $,
37   * initial version Oct 17, 2014 <br>
38   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
39   */
40  @SuppressWarnings("rawtypes")
41  public class NodeAnimation extends Renderable2D<NodeAnimation.ElevatedNode>
42          implements ClonableRenderable2DInterface<NodeAnimation.ElevatedNode>, Serializable
43  {
44      /** */
45      private static final long serialVersionUID = 20140000L;
46  
47      /** the Text object to destroy when the animation is destroyed. */
48      private Text text;
49  
50      /** Ensure that node animations are slightly above lane surface. */
51      public static final double ZOFFSET = 0.01;
52  
53      /**
54       * @param node Node; n
55       * @param simulator OTSSimulatorInterface; s
56       * @throws NamingException when animation context cannot be found.
57       * @throws RemoteException on communication failure
58       */
59      @SuppressWarnings("unchecked")
60      public NodeAnimation(final Node node, final OTSSimulatorInterface simulator)
61              throws NamingException, RemoteException
62      {
63          super(new ElevatedNode(node), simulator);
64          // Figure out the relevance of this node
65          ScaleDependentRendering sizeLimiter = TextAnimation.RENDERWHEN1;
66          for (Link link : node.getLinks())
67          {
68              if (link.getLinkType().getId().equals(LinkType.DEFAULTS.FREEWAY.getId()))
69              {
70                  sizeLimiter = TextAnimation.RENDERWHEN10;
71              }
72          }
73          this.text = new Text(node, node.getId(), 0.0f, 3.0f, TextAlignment.CENTER, Color.BLACK, simulator, sizeLimiter);
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      public final void paint(final Graphics2D graphics, final ImageObserver observer)
79      {
80          graphics.setColor(Color.BLACK);
81          graphics.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
82          graphics.draw(new Ellipse2D.Double(-0.5, -0.5, 1.0, 1.0));
83          double direction = getSource().getLocation().getZ();
84          if (!Double.isNaN(direction))
85          {
86              GeneralPath arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
87              arrow.moveTo(0.5, -0.5);
88              arrow.lineTo(2, 0);
89              arrow.lineTo(0.5, 0.5);
90              graphics.draw(arrow);
91          }
92      }
93  
94      /** {@inheritDoc} */
95      @Override
96      public void destroy(final Contextualized contextProvider)
97      {
98          super.destroy(contextProvider);
99          this.text.destroy(contextProvider);
100     }
101 
102     /** {@inheritDoc} */
103     @Override
104     public ClonableRenderable2DInterface<NodeAnimation.ElevatedNode> clone(final ElevatedNode newSource,
105             final OTSSimulatorInterface newSimulator) throws NamingException, RemoteException
106     {
107         // the constructor also constructs the corresponding Text object and ElevatedNode
108         return new NodeAnimation(newSource.getNode(), newSimulator);
109     }
110 
111     /** {@inheritDoc} */
112     @Override
113     public final String toString()
114     {
115         return "NodeAnimation [node=" + super.getSource() + "]";
116     }
117 
118     /** Class for elevating the node for animation purposes. */
119     public static class ElevatedNode implements Locatable, DelegateIntrospection
120     {
121         /** the node for introspection. */
122         private final Node node;
123 
124         /** the location of the node to which the animation belongs. */
125         private DirectedPoint location;
126 
127         /** the bounds of the node to which the animation belongs. */
128         private Bounds bounds;
129 
130         /**
131          * @param node Node; the node to which the animation belongs
132          */
133         public ElevatedNode(final Node node)
134         {
135             this.node = node;
136             DirectedPoint p = node.getLocation();
137             this.location = new DirectedPoint(p.x, p.y, p.z + ZOFFSET, p.getRotX(), p.getRotY(), p.getRotZ());
138             this.bounds = node.getBounds();
139         }
140 
141         /** {@inheritDoc} */
142         @Override
143         public DirectedPoint getLocation()
144         {
145             return this.location;
146         }
147 
148         /**
149          * @return node
150          */
151         public Node getNode()
152         {
153             return this.node;
154         }
155 
156         /** {@inheritDoc} */
157         @Override
158         public Bounds getBounds() throws RemoteException
159         {
160             return this.bounds;
161         }
162 
163         /** {@inheritDoc} */
164         @Override
165         public Object getParentIntrospectionObject()
166         {
167             return this.node;
168         }
169 
170     }
171 
172     /**
173      * Text animation for the Node. Separate class to be able to turn it on and off...
174      * <p>
175      * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
176      * <br>
177      * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
178      * </p>
179      * $LastChangedDate: 2018-10-11 22:54:04 +0200 (Thu, 11 Oct 2018) $, @version $Revision: 4696 $, by $Author: averbraeck $,
180      * initial version Dec 11, 2016 <br>
181      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
182      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
183      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
184      */
185     public class Text extends TextAnimation
186     {
187         /** */
188         private static final long serialVersionUID = 20161211L;
189 
190         /**
191          * @param source Locatable; the object for which the text is displayed
192          * @param text String; the text to display
193          * @param dx float; the horizontal movement of the text, in meters
194          * @param dy float; the vertical movement of the text, in meters
195          * @param textPlacement TextAlignment; where to place the text
196          * @param color Color; the color of the text
197          * @param simulator OTSSimulatorInterface; the simulator
198          * @param scaleDependentRendering ScaleDependendentRendering; size limiter for text animation
199          * @throws NamingException when animation context cannot be created or retrieved
200          * @throws RemoteException - when remote context cannot be found
201          */
202         @SuppressWarnings("checkstyle:parameternumber")
203         public Text(final Locatable source, final String text, final float dx, final float dy,
204                 final TextAlignment textPlacement, final Color color, final OTSSimulatorInterface simulator,
205                 final ScaleDependentRendering scaleDependentRendering) throws RemoteException, NamingException
206         {
207             super(source, text, dx, dy, textPlacement, color, 2.0f, 12.0f, 50f, simulator, scaleDependentRendering);
208             setFlip(false);
209             setRotate(false);
210         }
211 
212         /** {@inheritDoc} */
213         @Override
214         @SuppressWarnings("checkstyle:designforextension")
215         public TextAnimation clone(final Locatable newSource, final OTSSimulatorInterface newSimulator)
216                 throws RemoteException, NamingException
217         {
218             return new Text(newSource, getText(), getDx(), getDy(), getTextAlignment(), getColor(), newSimulator,
219                     getScaleDependentRendering());
220         }
221 
222         /** {@inheritDoc} */
223         @Override
224         public final String toString()
225         {
226             return "NodeAnimation.Text []";
227         }
228     }
229 
230 }