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  
13  /**
14   * Lane type to indicate compatibility with GTU types. The id of a LaneType should be unique. This is, however, not checked or
15   * enforced, as the LaneType is not a singleton as the result of the compatibilitySet. Different simulations running in the same
16   * GTU can have different compatibilitySets for LaneTypes with the same id. Therefore, uniqueness is not enforced.
17   * <p>
18   * Copyright (c) 2013-2019 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: 2015-08-30 00:16:51 +0200 (Sun, 30 Aug 2015) $, @version $Revision: 1329 $, by $Author: averbraeck $,
22   * initial version Aug 21, 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   * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a>
26   */
27  public class LaneType extends HierarchicalType<LaneType> implements Serializable, Compatibility<GTUType, LaneType>
28  {
29      /** */
30      private static final long serialVersionUID = 20140821L;
31  
32      /** The compatibility of GTUs with this lane type. */
33      private final GTUCompatibility<LaneType> compatibility;
34  
35      /** The lane type used for lanes that are forbidden to all GTU types. */
36      public static final LaneType NONE;
37  
38      /** Vehicular roads (Dutch: weg); allows all road vehicles and pedestrians. */
39      public static final LaneType TWO_WAY_LANE;
40  
41      /** Vehicular lane that is two-way for PEDESTRIANS but only permitted in design direction for all other road users. */
42      public static final LaneType ONE_WAY_LANE;
43  
44      /** Controlled access roads (Dutch: snelweg). */
45      public static final LaneType FREEWAY;
46  
47      /** High speed vehicular roads (Dutch: autoweg). */
48      public static final LaneType HIGHWAY;
49  
50      /** Lane on rural vehicular roads (Dutch: weg buiten bebouwde kom). */
51      public static final LaneType RURAL_ROAD_LANE;
52  
53      /** Lane on urban vehicular roads (Dutch: weg binnen bebouwde kom). */
54      public static final LaneType URBAN_ROAD_LANE;
55  
56      /** Residential vehicular roads (Dutch: woonerf). */
57      public static final LaneType RESIDENTIAL_ROAD_LANE;
58  
59      /** Bidirectional bus lane (Dutch: busstrook). */
60      public static final LaneType BUS_LANE;
61  
62      /** Bidirectional bicycle lane (Dutch: (brom)fietspad). */
63      public static final LaneType MOPED_PATH;
64  
65      /** Bicycle path (Dutch: fietspad). */
66      public static final LaneType BICYCLE_PATH;
67  
68      /** Bidirectional footpath (Dutch: voetpad). */
69      public static final LaneType FOOTPATH;
70  
71      static
72      {
73          GTUCompatibility<LaneType> noTrafficCompatibility = new GTUCompatibility<>((LaneType) null);
74          NONE = new LaneType("NONE", null, noTrafficCompatibility);
75          GTUCompatibility<LaneType> roadCompatibility = new GTUCompatibility<>((LaneType) null);
76          roadCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_BOTH);
77          TWO_WAY_LANE = new LaneType("TWO_WAY_LANE", null, roadCompatibility);
78          RURAL_ROAD_LANE = new LaneType("RURAL_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
79          URBAN_ROAD_LANE = new LaneType("URBAN_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
80          RESIDENTIAL_ROAD_LANE = new LaneType("RESIDENTIAL_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
81          GTUCompatibility<LaneType> oneWayLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
82          oneWayLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_PLUS);
83          oneWayLaneCompatibility.addAllowedGTUType(GTUType.PEDESTRIAN, LongitudinalDirectionality.DIR_BOTH);
84          ONE_WAY_LANE = new LaneType("ONE_WAY_LANE", oneWayLaneCompatibility);
85          GTUCompatibility<LaneType> highwayLaneCompatibility = new GTUCompatibility<>(oneWayLaneCompatibility)
86                  .addAllowedGTUType(GTUType.PEDESTRIAN, LongitudinalDirectionality.DIR_NONE);
87          FREEWAY = new LaneType("FREEWAY", highwayLaneCompatibility);
88          HIGHWAY = new LaneType("FREEWAY", highwayLaneCompatibility);
89          GTUCompatibility<LaneType> busLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
90          busLaneCompatibility.addAllowedGTUType(GTUType.BUS, LongitudinalDirectionality.DIR_BOTH);
91          busLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
92          BUS_LANE = new LaneType("BUS_LANE", busLaneCompatibility);
93          GTUCompatibility<LaneType> mopedAndBicycleLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
94          mopedAndBicycleLaneCompatibility.addAllowedGTUType(GTUType.BICYCLE, LongitudinalDirectionality.DIR_BOTH);
95          mopedAndBicycleLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
96          MOPED_PATH = new LaneType("MOPED_PATH", mopedAndBicycleLaneCompatibility);
97          GTUCompatibility<LaneType> bicycleOnlyCompatibility = new GTUCompatibility<>(mopedAndBicycleLaneCompatibility);
98          bicycleOnlyCompatibility.addAllowedGTUType(GTUType.MOPED, LongitudinalDirectionality.DIR_NONE);
99          BICYCLE_PATH = new LaneType("BICYCLE_PATH", bicycleOnlyCompatibility);
100         GTUCompatibility<LaneType> pedestriansOnly = new GTUCompatibility<>(roadCompatibility);
101         pedestriansOnly.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
102         FOOTPATH = new LaneType("FOOTPATH", pedestriansOnly);
103     }
104 
105     /**
106      * Create a new Lane type with a compatibility set.
107      * @param id String; the id of the lane type.
108      * @param compatibility GTUCompatibility&lt;LaneType&gt;; the collection of compatible GTUTypes for this LaneType.
109      *            Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub
110      *            types.
111      * @throws NullPointerException if either the id is null, or the compatibilitySet is null
112      */
113     private LaneType(final String id, final GTUCompatibility<LaneType> compatibility) throws NullPointerException
114     {
115         super(id);
116         Throw.whenNull(compatibility, "compatibility collection cannot be null for LaneType with id = %s", id);
117         this.compatibility = new GTUCompatibility<>(compatibility);
118     }
119 
120     /**
121      * Private constructor for a LaneType.
122      * @param id String; id of the new LaneType
123      * @param inverted boolean; if true; the compatibility is longitudinally inverted
124      */
125     private LaneType(final String id, final boolean inverted)
126     {
127         super(id);
128         this.compatibility = null;
129     }
130 
131     /**
132      * Construct a new Lane type based on another Lane type with longitudinally inverted compatibility.
133      * @return LaneType; the new lane type
134      */
135     public final LaneType inv()
136     {
137         return new LaneType(getId(), true);
138     }
139 
140     /**
141      * Create a new Lane type with a compatibility set.
142      * @param id String; the id of the lane type.
143      * @param parent LaneType; parent type
144      * @param compatibility GTUCompatibility&lt;LaneType&gt;; the collection of compatible GTUTypes for this LaneType.
145      *            Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub
146      *            types.
147      * @throws NullPointerException if either the id is null, or the compatibilitySet is null
148      */
149     public LaneType(final String id, final LaneType parent, final GTUCompatibility<LaneType> compatibility)
150             throws NullPointerException
151     {
152         super(id, parent);
153         Throw.whenNull(compatibility, "compatibility collection cannot be null for LaneType with id = %s", id);
154         this.compatibility = new GTUCompatibility<>(compatibility);
155     }
156 
157     /**
158      * Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub types.
159      * @param gtuType GTUType; GTU type to look for compatibility.
160      * @param direction GTUDirectionality; the direction that the GTU is moving (with respect to the direction of the design
161      *            line of the Link)
162      * @return boolean; true if this LaneType permits GTU type in the given direction
163      */
164     @Override
165     public final Boolean isCompatible(final GTUType gtuType, final GTUDirectionality direction)
166     {
167         // OTS-338
168         // return this.compatibilitySet.contains(gtuType) || this.compatibilitySet.contains(GTUType.ALL);
169         return getDirectionality(gtuType).permits(direction);
170     }
171 
172     /**
173      * Get the permitted driving directions for a given GTU type on this Lane.
174      * @param gtuType GTUType; the GTU type
175      * @return LongitudinalDirectionality; the permitted directions of the GTU type on this Lane
176      */
177     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
178     {
179         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, true);
180         if (null == this.compatibility)
181         {
182             return result.invert();
183         }
184         return result;
185     }
186 
187     /**
188      * Add GTU type to compatibility.
189      * @param gtuType GTUType; the GTU type to add
190      * @param direction LongitudinalDirectionality; permitted direction of movement
191      */
192     public final void addGtuCompatability(final GTUType gtuType, final LongitudinalDirectionality direction)
193     {
194         if (null == this.compatibility)
195         {
196             getParent().addGtuCompatability(gtuType, direction.invert());
197         }
198         else
199         {
200             this.compatibility.addAllowedGTUType(gtuType, direction);
201         }
202     }
203 
204     /** {@inheritDoc} */
205     @Override
206     @SuppressWarnings("checkstyle:designforextension")
207     public String toString()
208     {
209         return "LaneType [id=" + this.getId() + ", compatibilitySet=" + this.compatibility + "]";
210     }
211 
212     /** {@inheritDoc} */
213     @Override
214     @SuppressWarnings("checkstyle:designforextension")
215     public int hashCode()
216     {
217         final int prime = 31;
218         int result = super.hashCode();
219         result = prime * result + ((this.compatibility == null) ? 0 : this.compatibility.hashCode());
220         return result;
221     }
222 
223     /** {@inheritDoc} */
224     @Override
225     @SuppressWarnings("checkstyle:designforextension")
226     public boolean equals(final Object obj)
227     {
228         if (this == obj)
229         {
230             return true;
231         }
232         if (!super.equals(obj))
233         {
234             return false;
235         }
236         if (getClass() != obj.getClass())
237         {
238             return false;
239         }
240         LaneType other = (LaneType) obj;
241         if (this.compatibility == null)
242         {
243             if (other.compatibility != null)
244             {
245                 return false;
246             }
247         }
248         else if (!this.compatibility.equals(other.compatibility))
249         {
250             return false;
251         }
252         return true;
253     }
254 
255     /** {@inheritDoc} */
256     @Override
257     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType, final boolean tryParentsOfGTUType)
258     {
259         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, tryParentsOfGTUType);
260         if (null == this.compatibility)
261         {
262             return result.invert();
263         }
264         return result;
265     }
266 
267 }