View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.io.Serializable;
4   
5   import org.djutils.exceptions.Throw;
6   import org.opentrafficsim.base.HierarchicalType;
7   import org.opentrafficsim.core.compatibility.Compatibility;
8   import org.opentrafficsim.core.compatibility.GTUCompatibility;
9   import org.opentrafficsim.core.gtu.GTUDirectionality;
10  import org.opentrafficsim.core.gtu.GTUType;
11  import org.opentrafficsim.core.network.LongitudinalDirectionality;
12  import org.opentrafficsim.road.network.RoadNetwork;
13  
14  /**
15   * Lane type to indicate compatibility with GTU types. The id of a LaneType should be unique. This is, however, not checked or
16   * enforced, as the LaneType is not a singleton as the result of the compatibilitySet. Different simulations running in the same
17   * GTU can have different compatibilitySets for LaneTypes with the same id. Therefore, uniqueness is not enforced.
18   * <p>
19   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
20   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
21   * <p>
22   * $LastChangedDate: 2015-08-30 00:16:51 +0200 (Sun, 30 Aug 2015) $, @version $Revision: 1329 $, by $Author: averbraeck $,
23   * initial version Aug 21, 2014 <br>
24   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
25   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
26   * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a>
27   */
28  public class LaneType extends HierarchicalType<LaneType> implements Serializable, Compatibility<GTUType, LaneType>
29  {
30      /** */
31      private static final long serialVersionUID = 20140821L;
32  
33      /** The compatibility of GTUs with this lane type. */
34      private final GTUCompatibility<LaneType> compatibility;
35  
36      /** the network to which the LinkType belongs. */
37      private final RoadNetwork network;
38  
39      /** Default types with their name. */
40      public enum DEFAULTS
41      {
42          /** The lane type used for lanes that are forbidden to all GTU types. */
43          NONE("NONE"),
44  
45          /** Vehicular roads (Dutch: weg); allows all road vehicles and pedestrians. */
46          TWO_WAY_LANE("TWO_WAY_LANE"),
47  
48          /** Vehicular lane that is two-way for PEDESTRIANS but only permitted in design direction for all other road users. */
49          ONE_WAY_LANE("ONE_WAY_LANE"),
50  
51          /** Controlled access roads (Dutch: snelweg). */
52          FREEWAY("FREEWAY"),
53  
54          /** High speed vehicular roads (Dutch: autoweg). */
55          HIGHWAY("HIGHWAY"),
56  
57          /** Lane on rural vehicular roads (Dutch: weg buiten bebouwde kom). */
58          RURAL_ROAD_LANE("RURAL_ROAD_LANE"),
59  
60          /** Lane on urban vehicular roads (Dutch: weg binnen bebouwde kom). */
61          URBAN_ROAD_LANE("URBAN_ROAD_LANE"),
62  
63          /** Residential vehicular roads (Dutch: woonerf). */
64          RESIDENTIAL_ROAD_LANE("RESIDENTIAL_ROAD_LANE"),
65  
66          /** Bidirectional bus lane (Dutch: busstrook). */
67          BUS_LANE("BUS_LANE"),
68  
69          /** Bidirectional bicycle lane (Dutch: (brom)fietspad). */
70          MOPED_PATH("MOPED_PATH"),
71  
72          /** Bicycle path (Dutch: fietspad). */
73          BICYCLE_PATH("BICYCLE_PATH"),
74  
75          /** Bidirectional footpath (Dutch: voetpad). */
76          FOOTPATH("FOOTPATH");
77  
78          /** The name. */
79          private final String id;
80  
81          /**
82           * Construct the enum.
83           * @param id String; the id
84           */
85          DEFAULTS(final String id)
86          {
87              this.id = id;
88          }
89  
90          /** @return the id */
91          public String getId()
92          {
93              return this.id;
94          }
95      }
96  
97      /**
98       * Create a new Lane type with a compatibility set.
99       * @param id String; the id of the lane type.
100      * @param compatibility GTUCompatibility&lt;LaneType&gt;; the collection of compatible GTUTypes for this LaneType.
101      *            Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub
102      *            types.
103      * @param network RoadNetwork; The network to which the LaneType belongs
104      * @throws NullPointerException if either the id is null, or the compatibilitySet is null
105      */
106     public LaneType(final String id, final GTUCompatibility<LaneType> compatibility, final RoadNetwork network)
107             throws NullPointerException
108     {
109         super(id);
110         Throw.whenNull(compatibility, "compatibility collection cannot be null for LaneType with id = %s", id);
111         Throw.whenNull(network, "network cannot be null for LaneType with id = %s", id);
112         this.compatibility = new GTUCompatibility<>(compatibility);
113         this.network = network;
114         this.network.addLaneType(this);
115     }
116 
117     /**
118      * Create a new Lane type with a compatibility set.
119      * @param id String; the id of the lane type.
120      * @param parent LaneType; parent type
121      * @param compatibility GTUCompatibility&lt;LaneType&gt;; the collection of compatible GTUTypes for this LaneType.
122      *            Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub
123      *            types.
124      * @param network RoadNetwork; The network to which the LaneType belongs
125      * @throws NullPointerException if either the id is null, or the compatibilitySet is null
126      */
127     public LaneType(final String id, final LaneType parent, final GTUCompatibility<LaneType> compatibility,
128             final RoadNetwork network) throws NullPointerException
129     {
130         super(id, parent);
131         Throw.whenNull(compatibility, "compatibility collection cannot be null for LaneType with id = %s", id);
132         Throw.whenNull(parent, "parent cannot be null for LaneType with id = %s", id);
133         this.compatibility = new GTUCompatibility<>(compatibility);
134         this.network = network;
135         this.network.addLaneType(this);
136     }
137 
138     /**
139      * Private constructor for a LaneType.
140      * @param id String; id of the new LaneType
141      * @param inverted boolean; if true; the compatibility is longitudinally inverted
142      * @param network RoadNetwork; The network to which the LaneType belongs
143      */
144     private LaneType(final String id, final boolean inverted, final RoadNetwork network)
145     {
146         super(id);
147         this.compatibility = null;
148         this.network = network;
149         this.network.addLaneType(this);
150     }
151 
152     /**
153      * Whether this, or any of the parent types, equals the given type.
154      * @param type DEFAULTS; type
155      * @return whether this, or any of the parent types, equals the given type
156      */
157     public boolean isOfType(final DEFAULTS type)
158     {
159         if (this.getId().equals(type.getId()))
160         {
161             return true;
162         }
163         if (getParent() != null)
164         {
165             return getParent().isOfType(type);
166         }
167         return false;
168     }
169 
170     /**
171      * Construct a new Lane type based on another Lane type with longitudinally inverted compatibility.
172      * @return LaneType; the new lane type
173      */
174     public final LaneType inv()
175     {
176         return new LaneType(getId(), true, getNetwork());
177     }
178 
179     /**
180      * @return the gtu compatibility for this LaneType
181      */
182     public GTUCompatibility<LaneType> getCompatibility()
183     {
184         return this.compatibility;
185     }
186 
187     /**
188      * @return the network to which the LinkType belongs
189      */
190     public RoadNetwork getNetwork()
191     {
192         return this.network;
193     }
194 
195     /**
196      * Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub types.
197      * @param gtuType GTUType; GTU type to look for compatibility.
198      * @param direction GTUDirectionality; the direction that the GTU is moving (with respect to the direction of the design
199      *            line of the Link)
200      * @return boolean; true if this LaneType permits GTU type in the given direction
201      */
202     @Override
203     public final Boolean isCompatible(final GTUType gtuType, final GTUDirectionality direction)
204     {
205         // OTS-338
206         // return this.compatibilitySet.contains(gtuType) || this.compatibilitySet.contains(GTUType.ALL);
207         return getDirectionality(gtuType).permits(direction);
208     }
209 
210     /**
211      * Get the permitted driving directions for a given GTU type on this Lane.
212      * @param gtuType GTUType; the GTU type
213      * @return LongitudinalDirectionality; the permitted directions of the GTU type on this Lane
214      */
215     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
216     {
217         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, true);
218         if (null == this.compatibility)
219         {
220             return result.invert();
221         }
222         return result;
223     }
224 
225     /**
226      * Add GTU type to compatibility.
227      * @param gtuType GTUType; the GTU type to add
228      * @param direction LongitudinalDirectionality; permitted direction of movement
229      */
230     public final void addGtuCompatability(final GTUType gtuType, final LongitudinalDirectionality direction)
231     {
232         if (null == this.compatibility)
233         {
234             getParent().addGtuCompatability(gtuType, direction.invert());
235         }
236         else
237         {
238             this.compatibility.addAllowedGTUType(gtuType, direction);
239         }
240     }
241 
242     /** {@inheritDoc} */
243     @Override
244     @SuppressWarnings("checkstyle:designforextension")
245     public String toString()
246     {
247         return "LaneType [id=" + this.getId() + ", compatibilitySet=" + this.compatibility + "]";
248     }
249 
250     /** {@inheritDoc} */
251     @Override
252     @SuppressWarnings("checkstyle:designforextension")
253     public int hashCode()
254     {
255         final int prime = 31;
256         int result = super.hashCode();
257         result = prime * result + ((this.compatibility == null) ? 0 : this.compatibility.hashCode());
258         return result;
259     }
260 
261     /** {@inheritDoc} */
262     @Override
263     @SuppressWarnings("checkstyle:designforextension")
264     public boolean equals(final Object obj)
265     {
266         if (this == obj)
267         {
268             return true;
269         }
270         if (!super.equals(obj))
271         {
272             return false;
273         }
274         if (getClass() != obj.getClass())
275         {
276             return false;
277         }
278         LaneType other = (LaneType) obj;
279         if (this.compatibility == null)
280         {
281             if (other.compatibility != null)
282             {
283                 return false;
284             }
285         }
286         else if (!this.compatibility.equals(other.compatibility))
287         {
288             return false;
289         }
290         return true;
291     }
292 
293     /** {@inheritDoc} */
294     @Override
295     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType, final boolean tryParentsOfGTUType)
296     {
297         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, tryParentsOfGTUType);
298         if (null == this.compatibility)
299         {
300             return result.invert();
301         }
302         return result;
303     }
304 
305 }