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