OTSLink.java

  1. package org.opentrafficsim.core.network;

  2. import java.io.Serializable;
  3. import java.util.LinkedHashSet;
  4. import java.util.Set;

  5. import javax.media.j3d.Bounds;

  6. import org.djunits.value.vdouble.scalar.Length;
  7. import org.djutils.exceptions.Throw;
  8. import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
  9. import org.opentrafficsim.core.geometry.OTSLine3D;
  10. import org.opentrafficsim.core.gtu.GTU;
  11. import org.opentrafficsim.core.gtu.GTUType;

  12. import nl.tudelft.simulation.dsol.animation.Locatable;
  13. import nl.tudelft.simulation.event.EventProducer;
  14. import nl.tudelft.simulation.language.d3.DirectedPoint;

  15. /**
  16.  * A standard implementation of a link between two OTSNodes.
  17.  * <p>
  18.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  19.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  20.  * <p>
  21.  * $LastChangedDate: 2020-01-23 11:14:19 +0100 (Thu, 23 Jan 2020) $, @version $Revision: 6010 $, by $Author: averbraeck $,
  22.  * initial version Aug 19, 2014 <br>
  23.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  24.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  25.  */
  26. public class OTSLink extends EventProducer implements Link, Serializable, Locatable
  27. {
  28.     /** */
  29.     private static final long serialVersionUID = 20150101L;

  30.     /** the Network. */
  31.     private final Network network;

  32.     /** Link id. */
  33.     private final String id;

  34.     /** Start node (directional). */
  35.     private final Node startNode;

  36.     /** End node (directional). */
  37.     private final Node endNode;

  38.     /** Link type to indicate compatibility with GTU types. */
  39.     private final LinkType linkType;

  40.     /** Design line of the link. */
  41.     private final OTSLine3D designLine;

  42.     /** The simulator on which events can be scheduled. */
  43.     private final OTSSimulatorInterface simulator;

  44.     /** The GTUs on this Link. */
  45.     private final Set<GTU> gtus = new LinkedHashSet<>();

  46.     /**
  47.      * Construct a new link.
  48.      * @param network Network; the network to which the link belongs
  49.      * @param id String; the link id
  50.      * @param startNode Node; start node (directional)
  51.      * @param endNode Node; end node (directional)
  52.      * @param linkType LinkType; Link type to indicate compatibility with GTU types
  53.      * @param designLine OTSLine3D; the OTSLine3D design line of the Link
  54.      * @param simulator OTSSimulatorInterface; the simulator on which events can be scheduled
  55.      * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
  56.      *             or the end node of the link are not registered in the network.
  57.      */
  58.     @SuppressWarnings("checkstyle:parameternumber")
  59.     public OTSLink(final Network network, final String id, final Node startNode, final Node endNode, final LinkType linkType,
  60.             final OTSLine3D designLine, final OTSSimulatorInterface simulator) throws NetworkException
  61.     {
  62.         Throw.whenNull(network, "network cannot be null");
  63.         Throw.whenNull(id, "id cannot be null");
  64.         Throw.whenNull(startNode, "startNode cannot be null (link %s)", id);
  65.         Throw.whenNull(endNode, "endNode cannot be null (link %s)", id);
  66.         Throw.whenNull(linkType, "linkType cannot be null (link %s)", id);
  67.         Throw.whenNull(designLine, "designLine cannot be null (link %s)", id);
  68.         Throw.whenNull(simulator, "simulator cannot be null");

  69.         this.network = network;
  70.         this.id = id;
  71.         this.startNode = startNode;
  72.         this.endNode = endNode;
  73.         this.linkType = linkType;
  74.         this.startNode.addLink(this);
  75.         this.endNode.addLink(this);
  76.         this.designLine = designLine;
  77.         this.simulator = simulator;
  78.         this.network.addLink(this);
  79.     }

  80.     /**
  81.      * Clone a link for a new network.
  82.      * @param newNetwork Network; the new network to which the clone belongs
  83.      * @param newSimulator OTSSimulatorInterface; the new simulator for this network
  84.      * @param link OTSLink; the link to clone from
  85.      * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
  86.      *             or the end node of the link are not registered in the network.
  87.      */
  88.     protected OTSLink(final Network newNetwork, final OTSSimulatorInterface newSimulator, final OTSLink link)
  89.             throws NetworkException
  90.     {
  91.         this(newNetwork, link.id, newNetwork.getNode(link.startNode.getId()), newNetwork.getNode(link.endNode.getId()),
  92.                 link.linkType, link.designLine, newSimulator);
  93.     }

  94.     /** {@inheritDoc} */
  95.     @Override
  96.     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
  97.     {
  98.         return this.getLinkType().getDirectionality(gtuType, true);
  99.     }

  100.     /** {@inheritDoc} */
  101.     @Override
  102.     public final void addGTU(final GTU gtu)
  103.     {
  104.         if (!this.gtus.contains(gtu))
  105.         {
  106.             this.gtus.add(gtu);
  107.             fireTimedEvent(Link.GTU_ADD_EVENT, new Object[] {gtu.getId(), gtu, this.gtus.size()},
  108.                     gtu.getSimulator().getSimulatorTime());
  109.         }
  110.     }

  111.     /** {@inheritDoc} */
  112.     @Override
  113.     public final void removeGTU(final GTU gtu)
  114.     {
  115.         if (this.gtus.contains(gtu))
  116.         {
  117.             this.gtus.remove(gtu);
  118.             fireTimedEvent(Link.GTU_REMOVE_EVENT, new Object[] {gtu.getId(), gtu, this.gtus.size()},
  119.                     gtu.getSimulator().getSimulatorTime());
  120.         }
  121.     }

  122.     /** {@inheritDoc} */
  123.     @Override
  124.     public final Set<GTU> getGTUs()
  125.     {
  126.         return new LinkedHashSet<>(this.gtus);
  127.     }

  128.     /** {@inheritDoc} */
  129.     @Override
  130.     public final int getGTUCount()
  131.     {
  132.         return this.gtus.size();
  133.     }

  134.     /** {@inheritDoc} */
  135.     @Override
  136.     public Network getNetwork()
  137.     {
  138.         return this.network;
  139.     }

  140.     /** {@inheritDoc} */
  141.     @Override
  142.     public final String getId()
  143.     {
  144.         return this.id;
  145.     }

  146.     /** {@inheritDoc} */
  147.     @Override
  148.     public final Node getStartNode()
  149.     {
  150.         return this.startNode;
  151.     }

  152.     /** {@inheritDoc} */
  153.     @Override
  154.     public final Node getEndNode()
  155.     {
  156.         return this.endNode;
  157.     }

  158.     /** {@inheritDoc} */
  159.     @Override
  160.     public final LinkType getLinkType()
  161.     {
  162.         return this.linkType;
  163.     }

  164.     /** {@inheritDoc} */
  165.     @Override
  166.     public final OTSLine3D getDesignLine()
  167.     {
  168.         return this.designLine;
  169.     }

  170.     /** {@inheritDoc} */
  171.     @Override
  172.     public final OTSSimulatorInterface getSimulator()
  173.     {
  174.         return this.simulator;
  175.     }

  176.     /** {@inheritDoc} */
  177.     @Override
  178.     public final Length getLength()
  179.     {
  180.         return this.designLine.getLength();
  181.     }

  182.     /** the location with 0.01 m extra height. */
  183.     private DirectedPoint zLocation = null;

  184.     /** {@inheritDoc} */
  185.     @Override
  186.     @SuppressWarnings("checkstyle:designforextension")
  187.     public DirectedPoint getLocation()
  188.     {
  189.         if (this.zLocation == null)
  190.         {
  191.             DirectedPoint p = this.designLine.getLocation();
  192.             this.zLocation = new DirectedPoint(p.x, p.y, p.z + 0.01, p.getRotX(), p.getRotY(), p.getRotZ());
  193.         }
  194.         return this.zLocation;
  195.     }

  196.     /** {@inheritDoc} */
  197.     @Override
  198.     @SuppressWarnings("checkstyle:designforextension")
  199.     public Bounds getBounds()
  200.     {
  201.         return this.designLine.getBounds();
  202.     }

  203.     /** {@inheritDoc} */
  204.     @Override
  205.     @SuppressWarnings("checkstyle:designforextension")
  206.     public String toString()
  207.     {
  208.         return this.id.toString();
  209.     }

  210.     /** {@inheritDoc} */
  211.     @Override
  212.     @SuppressWarnings("checkstyle:designforextension")
  213.     public int hashCode()
  214.     {
  215.         final int prime = 31;
  216.         int result = 1;
  217.         result = prime * result + ((this.endNode == null) ? 0 : this.endNode.hashCode());
  218.         result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
  219.         result = prime * result + ((this.linkType == null) ? 0 : this.linkType.hashCode());
  220.         result = prime * result + ((this.startNode == null) ? 0 : this.startNode.hashCode());
  221.         return result;
  222.     }

  223.     /** {@inheritDoc} */
  224.     @Override
  225.     @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces"})
  226.     public boolean equals(final Object obj)
  227.     {
  228.         if (this == obj)
  229.             return true;
  230.         if (obj == null)
  231.             return false;
  232.         if (getClass() != obj.getClass())
  233.             return false;
  234.         OTSLink other = (OTSLink) obj;
  235.         if (this.endNode == null)
  236.         {
  237.             if (other.endNode != null)
  238.                 return false;
  239.         }
  240.         else if (!this.endNode.equals(other.endNode))
  241.             return false;
  242.         if (this.id == null)
  243.         {
  244.             if (other.id != null)
  245.                 return false;
  246.         }
  247.         else if (!this.id.equals(other.id))
  248.             return false;
  249.         if (this.linkType == null)
  250.         {
  251.             if (other.linkType != null)
  252.                 return false;
  253.         }
  254.         else if (!this.linkType.equals(other.linkType))
  255.             return false;
  256.         if (this.startNode == null)
  257.         {
  258.             if (other.startNode != null)
  259.                 return false;
  260.         }
  261.         else if (!this.startNode.equals(other.startNode))
  262.             return false;
  263.         return true;
  264.     }

  265.     /**
  266.      * Clone the OTSLink for e.g., copying a network.
  267.      * @param newNetwork Network; the new network to which the clone belongs
  268.      * @param newSimulator OTSSimulatorInterface; the new simulator for this network
  269.      * @return a clone of this object
  270.      * @throws NetworkException in case the cloning fails
  271.      */
  272.     @SuppressWarnings("checkstyle:designforextension")
  273.     public OTSLink clone(final Network newNetwork, final OTSSimulatorInterface newSimulator) throws NetworkException
  274.     {
  275.         return new OTSLink(newNetwork, newSimulator, this);
  276.     }
  277. }