View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.io.Serializable;
4   
5   import org.opentrafficsim.base.HierarchicalType;
6   import org.opentrafficsim.core.compatibility.Compatibility;
7   import org.opentrafficsim.core.compatibility.GTUCompatibility;
8   import org.opentrafficsim.core.gtu.GTUDirectionality;
9   import org.opentrafficsim.core.gtu.GTUType;
10  import org.opentrafficsim.core.network.LongitudinalDirectionality;
11  
12  import nl.tudelft.simulation.language.Throw;
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-2018 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 lane type used for lanes that are forbidden to all GTU types. */
37      public static final LaneType NONE;
38  
39      /** Vehicular roads (Dutch: weg); allows all road vehicles and pedestrians. */
40      public static final LaneType TWO_WAY_LANE;
41  
42      /** Vehicular lane that is two-way for PEDESTRIANS but only permitted in design direction for all other road users. */
43      public static final LaneType ONE_WAY_LANE;
44  
45      /** Controlled access roads (Dutch: snelweg). */
46      public static final LaneType FREEWAY;
47  
48      /** High speed vehicular roads (Dutch: autoweg). */
49      public static final LaneType HIGHWAY;
50  
51      /** Lane on rural vehicular roads (Dutch: weg buiten bebouwde kom). */
52      public static final LaneType RURAL_ROAD_LANE;
53  
54      /** Lane on urban vehicular roads (Dutch: weg binnen bebouwde kom). */
55      public static final LaneType URBAN_ROAD_LANE;
56  
57      /** Residential vehicular roads (Dutch: woonerf). */
58      public static final LaneType RESIDENTIAL_ROAD_LANE;
59  
60      /** Bidirectional bus lane (Dutch: busstrook). */
61      public static final LaneType BUS_LANE;
62  
63      /** Bidirectional bicycle lane (Dutch: (brom)fietspad). */
64      public static final LaneType MOPED_PATH;
65  
66      /** Bicycle path (Dutch: fietspad). */
67      public static final LaneType BICYCLE_PATH;
68  
69      /** Bidirectional footpath (Dutch: voetpad). */
70      public static final LaneType FOOTPATH;
71  
72      static
73      {
74          GTUCompatibility<LaneType> noTrafficCompatibility = new GTUCompatibility<>((LaneType) null);
75          NONE = new LaneType("NONE", null, noTrafficCompatibility);
76          GTUCompatibility<LaneType> roadCompatibility = new GTUCompatibility<>((LaneType) null);
77          roadCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_BOTH);
78          TWO_WAY_LANE = new LaneType("TWO_WAY_LANE", null, roadCompatibility);
79          RURAL_ROAD_LANE = new LaneType("RURAL_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
80          URBAN_ROAD_LANE = new LaneType("URBAN_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
81          RESIDENTIAL_ROAD_LANE = new LaneType("RESIDENTIAL_ROAD", TWO_WAY_LANE, new GTUCompatibility<>(roadCompatibility));
82          GTUCompatibility<LaneType> oneWayLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
83          oneWayLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_PLUS);
84          oneWayLaneCompatibility.addAllowedGTUType(GTUType.PEDESTRIAN, LongitudinalDirectionality.DIR_BOTH);
85          ONE_WAY_LANE = new LaneType("ONE_WAY_LANE", oneWayLaneCompatibility);
86          GTUCompatibility<LaneType> highwayLaneCompatibility = new GTUCompatibility<>(oneWayLaneCompatibility)
87                  .addAllowedGTUType(GTUType.PEDESTRIAN, LongitudinalDirectionality.DIR_NONE);
88          FREEWAY = new LaneType("FREEWAY", highwayLaneCompatibility);
89          HIGHWAY = new LaneType("FREEWAY", highwayLaneCompatibility);
90          GTUCompatibility<LaneType> busLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
91          busLaneCompatibility.addAllowedGTUType(GTUType.BUS, LongitudinalDirectionality.DIR_BOTH);
92          busLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
93          BUS_LANE = new LaneType("BUS_LANE", busLaneCompatibility);
94          GTUCompatibility<LaneType> mopedAndBicycleLaneCompatibility = new GTUCompatibility<>(roadCompatibility);
95          mopedAndBicycleLaneCompatibility.addAllowedGTUType(GTUType.BICYCLE, LongitudinalDirectionality.DIR_BOTH);
96          mopedAndBicycleLaneCompatibility.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
97          MOPED_PATH = new LaneType("MOPED_PATH", mopedAndBicycleLaneCompatibility);
98          GTUCompatibility<LaneType> bicycleOnlyCompatibility = new GTUCompatibility<>(mopedAndBicycleLaneCompatibility);
99          bicycleOnlyCompatibility.addAllowedGTUType(GTUType.MOPED, LongitudinalDirectionality.DIR_NONE);
100         BICYCLE_PATH = new LaneType("BICYCLE_PATH", bicycleOnlyCompatibility);
101         GTUCompatibility<LaneType> pedestriansOnly = new GTUCompatibility<>(roadCompatibility);
102         pedestriansOnly.addAllowedGTUType(GTUType.ROAD_USER, LongitudinalDirectionality.DIR_NONE);
103         FOOTPATH = new LaneType("FOOTPATH", pedestriansOnly);
104     }
105 
106     /**
107      * Create a new Lane type with a compatibility set.
108      * @param id the id of the lane type.
109      * @param compatibility the collection of compatible GTUTypes for this LaneType. Compatibility is solely determined by a
110      *            specific lane type, and independent of compatibility in super or sub 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 the id of the lane type.
143      * @param parent parent type
144      * @param compatibility the collection of compatible GTUTypes for this LaneType. Compatibility is solely determined by a
145      *            specific lane type, and independent of compatibility in super or sub types.
146      * @throws NullPointerException if either the id is null, or the compatibilitySet is null
147      */
148     public LaneType(final String id, final LaneType parent, final GTUCompatibility<LaneType> compatibility)
149             throws NullPointerException
150     {
151         super(id, parent);
152         Throw.whenNull(compatibility, "compatibility collection cannot be null for LaneType with id = %s", id);
153         this.compatibility = new GTUCompatibility<>(compatibility);
154     }
155 
156     /**
157      * Compatibility is solely determined by a specific lane type, and independent of compatibility in super or sub types.
158      * @param gtuType GTU type to look for compatibility.
159      * @param direction GTUDirectionality; the direction that the GTU is moving (with respect to the direction of the design
160      *            line of the Link)
161      * @return boolean; true if this LaneType permits GTU type in the given direction
162      */
163     @Override
164     public final Boolean isCompatible(final GTUType gtuType, final GTUDirectionality direction)
165     {
166         // OTS-338
167         // return this.compatibilitySet.contains(gtuType) || this.compatibilitySet.contains(GTUType.ALL);
168         return getDirectionality(gtuType).permits(direction);
169     }
170 
171     /**
172      * Get the permitted driving directions for a given GTU type on this Lane.
173      * @param gtuType GTUType; the GTU type
174      * @return LongitudinalDirectionality; the permitted directions of the GTU type on this Lane
175      */
176     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType)
177     {
178         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, true);
179         if (null == this.compatibility)
180         {
181             return result.invert();
182         }
183         return result;
184     }
185 
186     /**
187      * Add GTU type to compatibility.
188      * @param gtuType GTUType; the GTU type to add
189      * @param direction LongitudinalDirectionality; permitted direction of movement
190      */
191     public final void addGtuCompatability(final GTUType gtuType, final LongitudinalDirectionality direction)
192     {
193         if (null == this.compatibility)
194         {
195             getParent().addGtuCompatability(gtuType, direction.invert());
196         }
197         else
198         {
199             this.compatibility.addAllowedGTUType(gtuType, direction);
200         }
201     }
202 
203     /** {@inheritDoc} */
204     @Override
205     @SuppressWarnings("checkstyle:designforextension")
206     public String toString()
207     {
208         return "LaneType [id=" + this.getId() + ", compatibilitySet=" + this.compatibility + "]";
209     }
210 
211     /** {@inheritDoc} */
212     @Override
213     @SuppressWarnings("checkstyle:designforextension")
214     public int hashCode()
215     {
216         final int prime = 31;
217         int result = super.hashCode();
218         result = prime * result + ((this.compatibility == null) ? 0 : this.compatibility.hashCode());
219         return result;
220     }
221 
222     /** {@inheritDoc} */
223     @Override
224     @SuppressWarnings("checkstyle:designforextension")
225     public boolean equals(final Object obj)
226     {
227         if (this == obj)
228         {
229             return true;
230         }
231         if (!super.equals(obj))
232         {
233             return false;
234         }
235         if (getClass() != obj.getClass())
236         {
237             return false;
238         }
239         LaneType other = (LaneType) obj;
240         if (this.compatibility == null)
241         {
242             if (other.compatibility != null)
243             {
244                 return false;
245             }
246         }
247         else if (!this.compatibility.equals(other.compatibility))
248         {
249             return false;
250         }
251         return true;
252     }
253 
254     /** {@inheritDoc} */
255     @Override
256     public final LongitudinalDirectionality getDirectionality(final GTUType gtuType, final boolean tryParentsOfGTUType)
257     {
258         LongitudinalDirectionality result = this.compatibility.getDirectionality(gtuType, tryParentsOfGTUType);
259         if (null == this.compatibility)
260         {
261             return result.invert();
262         }
263         return result;
264     }
265 
266 }