View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   
9   import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
10  import org.opentrafficsim.core.geometry.OTSLine3D;
11  import org.opentrafficsim.core.gtu.GTUType;
12  import org.opentrafficsim.core.network.LinkType;
13  import org.opentrafficsim.core.network.LongitudinalDirectionality;
14  import org.opentrafficsim.core.network.Network;
15  import org.opentrafficsim.core.network.NetworkException;
16  import org.opentrafficsim.core.network.Node;
17  import org.opentrafficsim.core.network.OTSLink;
18  import org.opentrafficsim.core.network.OTSNode;
19  import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
20  
21  import nl.tudelft.simulation.event.EventType;
22  
23  /**
24   * A CrossSectionLink is a link with lanes where GTUs can possibly switch between lanes.
25   * <p>
26   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
27   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
28   * <p>
29   * $LastChangedDate: 2015-09-16 19:20:07 +0200 (Wed, 16 Sep 2015) $, @version $Revision: 1405 $, by $Author: averbraeck $,
30   * initial version Aug 19, 2014 <br>
31   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
32   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
33   * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a>
34   */
35  public class CrossSectionLink extends OTSLink implements Serializable
36  {
37      /** */
38      private static final long serialVersionUID = 20141015L;
39  
40      /** List of cross-section elements. */
41      private final List<CrossSectionElement> crossSectionElementList = new ArrayList<>();
42  
43      /** List of lanes. */
44      private final List<Lane> lanes = new ArrayList<>();
45  
46      /** The policy to generally keep left, keep right, or keep lane. */
47      private final LaneKeepingPolicy laneKeepingPolicy;
48  
49      /**
50       * The (regular, not timed) event type for pub/sub indicating the addition of a Lane to a CrossSectionLink. <br>
51       * Payload: Object[] { String networkId, String linkId, String LaneId, Lane lane, int laneNumber } <br>
52       * TODO work in a different way with lane numbers to align to standard lane numbering.
53       */
54      public static final EventType LANE_ADD_EVENT = new EventType("LANE.ADD");
55  
56      /**
57       * The (regular, not timed) event type for pub/sub indicating the removal of a Lane from a CrossSectionLink. <br>
58       * Payload: Object[] { String networkId, String linkId, String LaneId } <br>
59       * TODO allow for the removal of a Lane; currently this is not possible.
60       */
61      public static final EventType LANE_REMOVE_EVENT = new EventType("LANE.REMOVE");
62  
63      /**
64       * Construction of a cross section link.
65       * @param network Network; the network
66       * @param id String; the link id.
67       * @param startNode OTSNode; the start node (directional).
68       * @param endNode OTSNode; the end node (directional).
69       * @param linkType LinkType; the link type
70       * @param designLine OTSLine3D; the design line of the Link
71       * @param directionalityMap Map&lt;GTUType, LongitudinalDirectionality&gt;; the directions (FORWARD, BACKWARD, BOTH, NONE)
72       *            that various GTUtypes can traverse this link
73       * @param laneKeepingPolicy LaneKeepingPolicy; the policy to generally keep left, keep right, or keep lane
74       * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
75       *             or the end node of the link are not registered in the network.
76       */
77      @SuppressWarnings("checkstyle:parameternumber")
78      public CrossSectionLink(final Network network, final String id, final Node startNode, final Node endNode,
79              final LinkType linkType, final OTSLine3D designLine,
80              final Map<GTUType, LongitudinalDirectionality> directionalityMap, final LaneKeepingPolicy laneKeepingPolicy)
81              throws NetworkException
82      {
83          super(network, id, startNode, endNode, linkType, designLine, directionalityMap);
84          this.laneKeepingPolicy = laneKeepingPolicy;
85      }
86  
87      /**
88       * Construction of a link, with a general directionality for GTUType.ALL. Other directionalities can be added with the
89       * method addDirectionality(...) later.
90       * @param network Network; the network
91       * @param id String; the link id.
92       * @param startNode OTSnode; the start node (directional).
93       * @param endNode OTSNode; the end node (directional).
94       * @param linkType LinkType; the link type
95       * @param designLine OTSLine3D; the design line of the Link
96       * @param directionality LongitudinalDirectionality; the default directionality for all GTUs
97       * @param laneKeepingPolicy LaneKeepingPolicy; the policy to generally keep left, keep right, or keep lane
98       * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
99       *             or the end node of the link are not registered in the network.
100      */
101     @SuppressWarnings("checkstyle:parameternumber")
102     public CrossSectionLink(final Network network, final String id, final Node startNode, final Node endNode,
103             final LinkType linkType, final OTSLine3D designLine, final LongitudinalDirectionality directionality,
104             final LaneKeepingPolicy laneKeepingPolicy) throws NetworkException
105     {
106         super(network, id, startNode, endNode, linkType, designLine, directionality);
107         this.laneKeepingPolicy = laneKeepingPolicy;
108     }
109 
110     /**
111      * Construction of a link, on which no traffic is allowed after construction of the link. Directionality for GTUTypes can be
112      * added with the method addDirectionality(...) later.
113      * @param network Network; the network
114      * @param id String; the link id.
115      * @param startNode OTSNode; the start node (directional).
116      * @param endNode OTSNode; the end node (directional).
117      * @param linkType LinkType; the link type
118      * @param designLine OTSLine3D; the design line of the Link
119      * @param laneKeepingPolicy LaneKeepingPolicy; the policy to generally keep left, keep right, or keep lane
120      * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
121      *             or the end node of the link are not registered in the network.
122      */
123     public CrossSectionLink(final Network network, final String id, final OTSNode startNode, final OTSNode endNode,
124             final LinkType linkType, final OTSLine3D designLine, final LaneKeepingPolicy laneKeepingPolicy)
125             throws NetworkException
126     {
127         this(network, id, startNode, endNode, linkType, designLine, new HashMap<GTUType, LongitudinalDirectionality>(),
128                 laneKeepingPolicy);
129     }
130 
131     /**
132      * Clone a CrossSectionLink for a new network.
133      * @param newNetwork the new network to which the clone belongs
134      * @param newSimulator the new simulator for this network
135      * @param animation whether to (re)create animation or not
136      * @param link the link to clone from
137      * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
138      *             or the end node of the link are not registered in the network.
139      */
140     protected CrossSectionLink(final Network newNetwork, final OTSSimulatorInterface newSimulator, final boolean animation,
141             final CrossSectionLink link) throws NetworkException
142     {
143         super(newNetwork, newSimulator, animation, link);
144         this.laneKeepingPolicy = link.laneKeepingPolicy;
145         for (CrossSectionElement cse : link.crossSectionElementList)
146         {
147             addCrossSectionElement(cse.clone(this, newSimulator, animation));
148         }
149 
150     }
151 
152     /**
153      * Add a cross section element at the end of the list. <br>
154      * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction.
155      * @param cse CrossSectionElement; the cross section element to add.
156      */
157     protected final void addCrossSectionElement(final CrossSectionElement cse)
158     {
159         this.crossSectionElementList.add(cse);
160         if (cse instanceof Lane)
161         {
162             this.lanes.add((Lane) cse);
163             fireEvent(LANE_ADD_EVENT,
164                     new Object[] { getNetwork().getId(), getId(), cse.getId(), (Lane) cse, this.lanes.indexOf(cse) });
165         }
166     }
167 
168     /**
169      * Retrieve a safe copy of the cross section element list.
170      * @return List&lt;CrossSectionElement&gt;; the cross section element list.
171      */
172     public final List<CrossSectionElement> getCrossSectionElementList()
173     {
174         return this.crossSectionElementList == null ? new ArrayList<>() : new ArrayList<>(this.crossSectionElementList);
175     }
176 
177     /**
178      * Retrieve the lane keeping policy.
179      * @return LaneKeepingPolicy; the lane keeping policy on this CrossSectionLink
180      */
181     public final LaneKeepingPolicy getLaneKeepingPolicy()
182     {
183         return this.laneKeepingPolicy;
184     }
185 
186     /**
187      * Find a cross section element with a specified id.
188      * @param id String; the id to search for
189      * @return CrossSectionElement; the cross section element with the given id, or null if not found
190      */
191     public final CrossSectionElement getCrossSectionElement(final String id)
192     {
193         for (CrossSectionElement cse : this.crossSectionElementList)
194         {
195             if (cse.getId().equals(id))
196             {
197                 return cse;
198             }
199         }
200         return null;
201     }
202 
203     /**
204      * Return a safe copy of the list of lanes of this CrossSectionLink.
205      * @return List&lt;Lane&gt;; the list of lanes.
206      */
207     public final List<Lane> getLanes()
208     {
209         return this.lanes == null ? new ArrayList<>() : new ArrayList<>(this.lanes);
210     }
211 
212     /** {@inheritDoc} */
213     @Override
214     public final String toString()
215     {
216         return "CrossSectionLink [crossSectionElementList=" + this.crossSectionElementList + ", lanes=" + this.lanes
217                 + ", laneKeepingPolicy=" + this.laneKeepingPolicy + "]";
218     }
219 
220     /** {@inheritDoc} */
221     @Override
222     @SuppressWarnings("checkstyle:designforextension")
223     public CrossSectionLink clone(final Network newNetwork, final OTSSimulatorInterface newSimulator, final boolean animation)
224             throws NetworkException
225     {
226         return new CrossSectionLink(newNetwork, newSimulator, animation, this);
227     }
228 
229 }