View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.util.LinkedHashMap;
4   import java.util.LinkedHashSet;
5   import java.util.List;
6   import java.util.Map;
7   import java.util.Set;
8   import java.util.UUID;
9   
10  import org.djunits.unit.LengthUnit;
11  import org.djunits.value.vdouble.scalar.Length;
12  import org.djutils.draw.line.Polygon2d;
13  import org.djutils.exceptions.Throw;
14  import org.opentrafficsim.core.geometry.OtsLine2d;
15  import org.opentrafficsim.core.gtu.GtuType;
16  import org.opentrafficsim.core.network.LateralDirectionality;
17  import org.opentrafficsim.core.network.NetworkException;
18  
19  /**
20   * <p>
21   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
22   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
23   * </p>
24   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
25   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
26   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
27   */
28  public class Stripe extends CrossSectionElement
29  {
30      /** */
31      private static final long serialVersionUID = 20141025L;
32  
33      /** Type of the stripe, defining default permeability. */
34      private final Type type;
35  
36      /** Type to overrule the normal type, e.g. rush-hour lanes without changing the appearance of the stripe. */
37      private Type overruleType;
38  
39      /** Lateral permeability per GTU type and direction. */
40      private final Map<GtuType, Set<LateralDirectionality>> permeabilityMap = new LinkedHashMap<>();
41  
42      /**
43       * Constructor specifying geometry.
44       * @param type Type; stripe type defining appearance and default permeability.
45       * @param link CrossSectionLink; link.
46       * @param centerLine OtsLine2d; center line.
47       * @param contour Polygon2d; contour shape.
48       * @param crossSectionSlices List&lt;CrossSectionSlice&gt;; cross-section slices.
49       * @throws NetworkException when no cross-section slice is defined.
50       */
51      public Stripe(final Type type, final CrossSectionLink link, final OtsLine2d centerLine, final Polygon2d contour,
52              final List<CrossSectionSlice> crossSectionSlices) throws NetworkException
53      {
54          super(link, UUID.randomUUID().toString(), centerLine, contour, crossSectionSlices);
55          Throw.whenNull(type, "Type may not be null.");
56          this.type = type;
57      }
58  
59      /**
60       * Returns the stripe type.
61       * @return Type; stripe type.
62       */
63      public Type getType()
64      {
65          return this.type;
66      }
67  
68      /**
69       * Sets an overruling stripe type. This can be used for e.g. rush-hour lanes, without changing the appearance of the stripe.
70       * Note that custom set permeabilities (addPermeability()) remain active.
71       * @param overruleType Type; overruling stripe type.
72       */
73      public void setOverruleType(final Type overruleType)
74      {
75          this.overruleType = overruleType;
76      }
77  
78      /**
79       * Clears the overrule type, after which the normal type will hold.
80       */
81      public void clearOverruleType()
82      {
83          this.overruleType = null;
84      }
85  
86      /**
87       * Returns the currently active stripe type.
88       * @return Type; the currently active stripe type.
89       */
90      private Type activeType()
91      {
92          return this.overruleType == null ? this.type : this.overruleType;
93      }
94  
95      /**
96       * Add lateral permeability for a GTU type in the direction of the design line of the overarching CrossSectionLink. Add NONE
97       * to prevent lane changes relative to the stripe type. Add LEFT or RIGHT, or both in two calls, to enable lane changes
98       * relative to the stripe type.
99       * @param gtuType GtuType; GTU type to add permeability for.
100      * @param lateralDirection LateralDirectionality; direction to add compared to the direction of the design line.
101      */
102     public void addPermeability(final GtuType gtuType, final LateralDirectionality lateralDirection)
103     {
104         if (!this.permeabilityMap.containsKey(gtuType))
105         {
106             this.permeabilityMap.put(gtuType, new LinkedHashSet<LateralDirectionality>(2));
107         }
108         this.permeabilityMap.get(gtuType).add(lateralDirection);
109     }
110 
111     /**
112      * Returns whether the given GTU type is allowed to cross the line in the given lateral direction.
113      * @param gtuType GtuType; GTU type to look for.
114      * @param lateralDirection LateralDirectionality; direction to look for (LEFT or RIGHT) compared to the direction of the
115      *            design line.
116      * @return whether the road marker is permeable for the GTU type.
117      */
118     public final boolean isPermeable(final GtuType gtuType, final LateralDirectionality lateralDirection)
119     {
120         Throw.when(lateralDirection.isNone(), RuntimeException.class,
121                 "May not request NONE lateral direction for permeability.");
122         for (GtuType testGtuType = gtuType; null != testGtuType; testGtuType = testGtuType.getParent())
123         {
124             Set<LateralDirectionality> set = this.permeabilityMap.get(testGtuType);
125             if (null != set)
126             {
127                 return set.contains(lateralDirection);
128             }
129         }
130         return lateralDirection.isLeft() ? activeType().left() : activeType().right;
131     }
132 
133     /**
134      * Defines the visible type of the stripe, and the standard permeability that pertains to it.
135      * <p>
136      * Copyright (c) 2022-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
137      * <br>
138      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
139      * </p>
140      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
141      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
142      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
143      */
144     public enum Type
145     {
146         /** Single solid line. */
147         SOLID(false, false),
148 
149         /** Line |¦ allow to go to left, but not to right. */
150         LEFT(true, false, new Length(60.0, LengthUnit.CENTIMETER)),
151 
152         /** Line ¦| allow to go to right, but not to left. */
153         RIGHT(false, true, new Length(60.0, LengthUnit.CENTIMETER)),
154 
155         /** Dashes ¦ allow to cross in both directions. */
156         DASHED(true, true),
157 
158         /** Double solid line ||, don't cross. */
159         DOUBLE(false, false, new Length(60.0, LengthUnit.CENTIMETER)),
160 
161         /** Block : allow to cross in both directions. */
162         BLOCK(true, true, new Length(40.0, LengthUnit.CENTIMETER));
163 
164         /** Left permeable. */
165         private final boolean left;
166 
167         /** Right permeable. */
168         private final boolean right;
169         
170         /** Default width. */
171         private final Length defaultWidth;
172 
173         /**
174          * Constructor setting permeability.
175          * @param left boolean; left permeability.
176          * @param right boolean; right permeability.
177          */
178         Type(final boolean left, final boolean right)
179         {
180             this(left, right, new Length(20.0, LengthUnit.CENTIMETER));
181         }
182         
183         /**
184          * Constructor setting permeability.
185          * @param left boolean; left permeability.
186          * @param right boolean; right permeability.
187          * @param defaultWidth Length; default width.
188          */
189         Type(final boolean left, final boolean right, final Length defaultWidth)
190         {
191             this.left = left;
192             this.right = right;
193             this.defaultWidth = defaultWidth;
194         }
195 
196         /**
197          * Returns the left permeability.
198          * @return boolean; left permeability.
199          */
200         public boolean left()
201         {
202             return this.left;
203         }
204 
205         /**
206          * Returns the right permeability.
207          * @return boolean; right permeability.
208          */
209         public boolean right()
210         {
211             return this.right;
212         }
213         
214         /**
215          * Returns the default width.
216          * @return Length; default width.
217          */
218         public Length defaultWidth()
219         {
220             return this.defaultWidth;
221         }
222     }
223 
224 }